Skip to content

Commit

Permalink
Merge pull request #302 from wordpress-mobile/issue/293-editing-speci…
Browse files Browse the repository at this point in the history
…al-comments

Issue/293 editing special comments
  • Loading branch information
hypest authored Apr 11, 2017
2 parents 9660f62 + 2a22c5b commit bdb7fa7
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 87 deletions.
12 changes: 9 additions & 3 deletions aztec/src/main/java/org/wordpress/aztec/Html.java
Original file line number Diff line number Diff line change
Expand Up @@ -684,29 +684,35 @@ public void comment(char[] chars, int start, int length) throws SAXException {

String comment = new String(chars, start, length);
int spanStart = spannableStringBuilder.length();
spannableStringBuilder.append(comment);

if (comment.equalsIgnoreCase(AztecCommentSpan.Comment.MORE.getHtml())) {
spannableStringBuilder.append(Constants.INSTANCE.getMAGIC_CHAR());
spannableStringBuilder.setSpan(
new AztecCommentSpan(
comment,
context,
context.getResources().getDrawable(R.drawable.img_more)
context.getResources().getDrawable(R.drawable.img_more),
nestingLevel
),
spanStart,
spannableStringBuilder.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
} else if (comment.equalsIgnoreCase(AztecCommentSpan.Comment.PAGE.getHtml())) {
spannableStringBuilder.append(Constants.INSTANCE.getMAGIC_CHAR());
spannableStringBuilder.setSpan(
new AztecCommentSpan(
comment,
context,
context.getResources().getDrawable(R.drawable.img_page)
context.getResources().getDrawable(R.drawable.img_page),
nestingLevel
),
spanStart,
spannableStringBuilder.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
} else {
spannableStringBuilder.append(comment);
spannableStringBuilder.setSpan(
new CommentSpan(),
spanStart,
Expand Down
24 changes: 15 additions & 9 deletions aztec/src/main/kotlin/org/wordpress/aztec/AztecParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class AztecParser {
}

private fun markBlockElementLineBreak(text: Spannable, startPos: Int) {
text.setSpan(BlockElementLinebreak(), startPos, startPos, Spanned.SPAN_MARK_MARK)
text.setSpan(AztecVisualLinebreak(), startPos, startPos, Spanned.SPAN_MARK_MARK)
}

fun addVisualNewlinesToBlockElements(spanned: Editable) {
Expand Down Expand Up @@ -145,7 +145,7 @@ class AztecParser {

// no need for newline if there's one and marked as visual
if (spanned[spanEnd] == '\n'
&& spanned.getSpans(spanEnd, spanEnd, BlockElementLinebreak::class.java).isNotEmpty()) {
&& spanned.getSpans(spanEnd, spanEnd, AztecVisualLinebreak::class.java).isNotEmpty()) {

// but still, expand the span to include the newline for block spans, because they are paragraphs
if (it is AztecBlockSpan) {
Expand All @@ -170,7 +170,7 @@ class AztecParser {
// Always try to put a visual newline before block elements and only put one after if needed
fun syncVisualNewlinesOfBlockElements(spanned: Editable) {
// clear any visual newline marking. We'll mark them with a fresh set of passes
spanned.getSpans(0, spanned.length, BlockElementLinebreak::class.java).forEach {
spanned.getSpans(0, spanned.length, AztecVisualLinebreak::class.java).forEach {
spanned.removeSpan(it)
}

Expand Down Expand Up @@ -225,12 +225,12 @@ class AztecParser {
return@forEach
}

if (!repelling && spanned[spanStart - 2] == '\n' && it is AztecBlockSpan) {
if (!repelling && spanned[spanStart - 2] == '\n') {
// there's another newline before and we're not repelling a parent so, the adjacent one is not a visual one so, return
return@forEach
}

if (spanned.getSpans(spanStart - 1, spanStart - 1, BlockElementLinebreak::class.java).isNotEmpty()) {
if (spanned.getSpans(spanStart - 1, spanStart - 1, AztecVisualLinebreak::class.java).isNotEmpty()) {
// the newline is already marked as visual so, nothing more to do here
return@forEach
}
Expand Down Expand Up @@ -290,7 +290,7 @@ class AztecParser {

do {
val paragraphs = text.getSpans(i, end, AztecNestable::class.java)
.filter{ it !is AztecHorizontalLineSpan}
.filter{ it !is AztecFullWidthImageSpan}
.toTypedArray()

paragraphs.sortWith(Comparator { a, b ->
Expand Down Expand Up @@ -352,7 +352,7 @@ class AztecParser {

if (end > 0
&& text[end - 1] == Constants.NEWLINE
&& text.getSpans(end - 1, end, BlockElementLinebreak::class.java).isEmpty()
&& text.getSpans(end - 1, end, AztecVisualLinebreak::class.java).isEmpty()
&& !(parents?.any { it != blockSpan && text.getSpanEnd(it) == end } ?: false)) {
out.append("<br>")
}
Expand All @@ -371,7 +371,7 @@ class AztecParser {

var nl = 0
while (next < end && text[next] == '\n') {
val isVisualLinebreak = text.getSpans(next, next, BlockElementLinebreak::class.java).isNotEmpty()
val isVisualLinebreak = text.getSpans(next, next, AztecVisualLinebreak::class.java).isNotEmpty()

if (!isVisualLinebreak) {
nl++
Expand Down Expand Up @@ -404,10 +404,16 @@ class AztecParser {
out.append("<${span.getStartTag()}>")
}

if (span is AztecCommentSpan || span is CommentSpan) {
if (span is CommentSpan) {
out.append("<!--")
}

if (span is AztecCommentSpan) {
out.append("<!--")
out.append(span.commentText)
i = next
}

if (span is AztecHorizontalLineSpan) {
out.append("<${span.getStartTag()}>")
i = next
Expand Down
4 changes: 1 addition & 3 deletions aztec/src/main/kotlin/org/wordpress/aztec/AztecTagHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ class AztecTagHandler : Html.TagHandler {
// Add an extra newline above the line to prevent weird typing on the line above
start(output, AztecHorizontalLineSpan(context, ContextCompat.getDrawable(context, R.drawable.img_hr), nestingLevel))

// the placeholder text ~must~ contain at least 2 characters, otherwise extra newline is appended to the HTML
output.append("HR")
output.append(Constants.MAGIC_CHAR)
} else {
end(output, AztecHorizontalLineSpan::class.java)
}
Expand All @@ -101,7 +100,6 @@ class AztecTagHandler : Html.TagHandler {
return true
}
}

}
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,21 @@ class LineBlockFormatter(editor: AztecText) : AztecFormatter(editor) {
editor.removeInlineStylesFromRange(selectionStart, selectionEnd)
editor.removeBlockStylesFromRange(selectionStart, selectionEnd, true)

val nestingLevel = AztecNestable.getNestingLevelAt(editableText, selectionStart)

val span = AztecCommentSpan(
comment.html,
editor.context,
when (comment) {
AztecCommentSpan.Comment.MORE -> ContextCompat.getDrawable(editor.context, R.drawable.img_more)
AztecCommentSpan.Comment.PAGE -> ContextCompat.getDrawable(editor.context, R.drawable.img_page)
}
},
nestingLevel,
editor
)
val ssb = SpannableStringBuilder(comment.html)
ssb.setSpan(span, 0, comment.html.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

val ssb = SpannableStringBuilder(Constants.MAGIC_STRING)
ssb.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

editableText.replace(selectionStart, selectionEnd, ssb)

Expand All @@ -116,8 +122,7 @@ class LineBlockFormatter(editor: AztecText) : AztecFormatter(editor) {
}

fun insertMedia(drawable: Drawable?, attributes: Attributes, onMediaTappedListener: OnMediaTappedListener?) {
val span = AztecMediaSpan(editor.context, drawable, attributes, onMediaTappedListener)
span.textView = editor
val span = AztecMediaSpan(editor.context, drawable, attributes, onMediaTappedListener, editor)

val spanBeforeMedia = editableText.getSpans(selectionStart, selectionEnd, AztecBlockSpan::class.java)
.firstOrNull {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,10 @@ import org.wordpress.aztec.AztecText
import org.wordpress.aztec.spans.AztecURLSpan


class LinkFormatter(editor: AztecText, linkStyle: LinkStyle):AztecFormatter(editor) {
class LinkFormatter(editor: AztecText, val linkStyle: LinkStyle):AztecFormatter(editor) {

data class LinkStyle(val linkColor: Int, val linkUnderline: Boolean)

val linkStyle: LinkStyle

init {
this.linkStyle = linkStyle
}


fun isUrlSelected(): Boolean {
val urlSpans = editableText.getSpans(selectionStart, selectionEnd, AztecURLSpan::class.java)
return !urlSpans.isEmpty()
Expand Down
2 changes: 1 addition & 1 deletion aztec/src/main/kotlin/org/wordpress/aztec/source/Format.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.util.regex.Pattern
object Format {

// list of block elements
private val block = "div|br|blockquote|ul|ol|li|p|h1|h2|h3|h4|h5|h6|iframe|hr"
private val block = "div|br|blockquote|ul|ol|li|p|h1|h2|h3|h4|h5|h6|iframe|hr|aztec_cursor"

private val iframePlaceholder = "iframe-replacement-0x0"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package org.wordpress.aztec.spans

import android.content.Context
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.text.style.ImageSpan
import org.wordpress.aztec.AztecText

import org.wordpress.android.util.DisplayUtils
class AztecCommentSpan @JvmOverloads constructor(val commentText: String, context: Context, drawable: Drawable, override var nestingLevel: Int, editor: AztecText? = null) :
AztecDynamicImageSpan(context, drawable), AztecFullWidthImageSpan {

init {
textView = editor
}

class AztecCommentSpan(val context: Context, drawable: Drawable) : ImageSpan(drawable) {
companion object {
private val rect: Rect = Rect()
private val HTML_MORE: String = "more"
private val HTML_PAGE: String = "nextpage"
}
Expand All @@ -19,39 +20,4 @@ class AztecCommentSpan(val context: Context, drawable: Drawable) : ImageSpan(dra
MORE(HTML_MORE),
PAGE(HTML_PAGE)
}

override fun getSize(paint: Paint?, text: CharSequence?, start: Int, end: Int, metrics: Paint.FontMetricsInt?): Int {
val drawable = drawable
val bounds = getBounds(drawable)

if (metrics != null) {
metrics.ascent = -bounds.bottom
metrics.descent = 0

metrics.top = metrics.ascent
metrics.bottom = 0
}

return bounds.right
}

private fun getBounds(drawable: Drawable): Rect {
if (drawable.intrinsicWidth === 0) {
rect.set(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
return rect
}

/*
* Following Android guidelines for keylines and spacing, screen edge margins should
* be 16dp. Therefore, the width of images should be the width of the screen minus
* 16dp on both sides (i.e. 16 * 2 = 32).
*
* https://material.io/guidelines/layout/metrics-keylines.html#metrics-keylines-baseline-grids
*/
val width = context.resources.displayMetrics.widthPixels - DisplayUtils.dpToPx(context, 32)
val height = drawable.intrinsicHeight * width / drawable.intrinsicWidth
drawable.setBounds(0, 0, width, height)

return drawable.bounds
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ abstract class AztecDynamicImageSpan(val context: Context, protected var imageDr
return Rect(imageDrawable?.bounds ?: Rect(0, 0, 0, 0))
}

if (measuring) {
val layout = textView?.layout

if (measuring || layout == null) {
// if we're in pre-layout phase, just return a tiny rect
return Rect(0, 0, 1, 1)
}
Expand All @@ -103,8 +105,7 @@ abstract class AztecDynamicImageSpan(val context: Context, protected var imageDr

// do a local pre-layout to measure the TextView's basic sizes and line margins
measuring = true
val layout = StaticLayout(textView?.text ?: "", 0, textView?.text?.length ?: 0, textView?.paint, want,
Layout.Alignment.ALIGN_NORMAL, 1f, 0f, true)

measuring = false

val line = layout.getLineForOffset(start)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package org.wordpress.aztec.spans

interface AztecFullWidthImageSpan : AztecSurroundedWithNewlines, AztecSpan
interface AztecFullWidthImageSpan : AztecSurroundedWithNewlines
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.wordpress.android.util.DisplayUtils
import org.wordpress.aztec.AztecText

class AztecHorizontalLineSpan(context: Context, drawable: Drawable, override var nestingLevel: Int) :
AztecDynamicImageSpan(context, drawable), AztecFullWidthImageSpan {
AztecDynamicImageSpan(context, drawable), AztecFullWidthImageSpan, AztecSpan {

private val TAG: String = "hr"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ import org.xml.sax.Attributes
import java.util.*

class AztecMediaSpan(context: Context, drawable: Drawable?, var attributes: Attributes?,
val onMediaTappedListener: OnMediaTappedListener?) : AztecDynamicImageSpan(context, drawable) {
val onMediaTappedListener: OnMediaTappedListener?, editor: AztecText? = null) :
AztecDynamicImageSpan(context, drawable) {

private val TAG: String = "img"

private val overlays: ArrayList<Pair<Drawable?, Int>> = ArrayList()

init {
textView = editor
}

fun setDrawable(newDrawable: Drawable?) {
imageDrawable = newDrawable

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package org.wordpress.aztec.spans

class BlockElementLinebreak
class AztecVisualLinebreak
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ class FullWidthImageElementWatcher(val aztecText: AztecText) : TextWatcher {
private fun normalizeEditingAroundImageSpans(count: Int, start: Int) {
if (!aztecText.isTextChangedListenerDisabled()) {
val end = start + count
val line = aztecText.text.getSpans(end, end, AztecFullWidthImageSpan::class.java).firstOrNull() ?:
aztecText.text.getSpans(start, start, AztecFullWidthImageSpan::class.java).firstOrNull()
var lines = aztecText.text.getSpans(start, start, AztecFullWidthImageSpan::class.java)
lines += aztecText.text.getSpans(end, end, AztecFullWidthImageSpan::class.java)

if (line != null) {
val changedLineBeginning = aztecText.text.getSpanStart(line) == end && end - 1 >= 0 &&
lines.distinct().forEach {
val changedLineBeginning = aztecText.text.getSpanStart(it) == end && end - 1 >= 0 &&
aztecText.text[end - 1] != Constants.NEWLINE
val changedLineEnd = aztecText.text.getSpanEnd(line) == start &&
val changedLineEnd = aztecText.text.getSpanEnd(it) == start && start < aztecText.length() &&
aztecText.text[start] != Constants.NEWLINE

aztecText.disableTextChangedListener()
Expand Down Expand Up @@ -66,7 +66,7 @@ class FullWidthImageElementWatcher(val aztecText: AztecText) : TextWatcher {
insertVisualNewline(start)
} else {
// if text deleted, remove the line
aztecText.text.delete(start - 2, start)
aztecText.text.delete(aztecText.text.getSpanStart(it), start)
}
}

Expand Down
2 changes: 1 addition & 1 deletion aztec/src/test/kotlin/org/wordpress/aztec/AttributeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class AttributeTest {
private val QUOTE = "<blockquote n=\"N\">Quote</blockquote>"
private val LINK = "<a o=\"O\" href=\"https://github.com/wordpress-mobile/WordPress-Aztec-Android\">Link</a>"
private val UNKNOWN = "<iframe class=\"classic\" p=\"P\">Menu</iframe>"
private val COMMENT = "<!--Comment--><br>"
private val COMMENT = "<!--Comment-->"
private val COMMENT_MORE = "<!--more--><br>"
private val COMMENT_PAGE = "<!--nextpage--><br>"
private val LIST = "<ol><li a=\"1\">Ordered</li></ol>"
Expand Down
Loading

0 comments on commit bdb7fa7

Please sign in to comment.