Skip to content

Commit bdb7fa7

Browse files
authored
Merge pull request #302 from wordpress-mobile/issue/293-editing-special-comments
Issue/293 editing special comments
2 parents 9660f62 + 2a22c5b commit bdb7fa7

File tree

18 files changed

+153
-87
lines changed

18 files changed

+153
-87
lines changed

aztec/src/main/java/org/wordpress/aztec/Html.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -684,29 +684,35 @@ public void comment(char[] chars, int start, int length) throws SAXException {
684684

685685
String comment = new String(chars, start, length);
686686
int spanStart = spannableStringBuilder.length();
687-
spannableStringBuilder.append(comment);
688687

689688
if (comment.equalsIgnoreCase(AztecCommentSpan.Comment.MORE.getHtml())) {
689+
spannableStringBuilder.append(Constants.INSTANCE.getMAGIC_CHAR());
690690
spannableStringBuilder.setSpan(
691691
new AztecCommentSpan(
692+
comment,
692693
context,
693-
context.getResources().getDrawable(R.drawable.img_more)
694+
context.getResources().getDrawable(R.drawable.img_more),
695+
nestingLevel
694696
),
695697
spanStart,
696698
spannableStringBuilder.length(),
697699
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
698700
);
699701
} else if (comment.equalsIgnoreCase(AztecCommentSpan.Comment.PAGE.getHtml())) {
702+
spannableStringBuilder.append(Constants.INSTANCE.getMAGIC_CHAR());
700703
spannableStringBuilder.setSpan(
701704
new AztecCommentSpan(
705+
comment,
702706
context,
703-
context.getResources().getDrawable(R.drawable.img_page)
707+
context.getResources().getDrawable(R.drawable.img_page),
708+
nestingLevel
704709
),
705710
spanStart,
706711
spannableStringBuilder.length(),
707712
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
708713
);
709714
} else {
715+
spannableStringBuilder.append(comment);
710716
spannableStringBuilder.setSpan(
711717
new CommentSpan(),
712718
spanStart,

aztec/src/main/kotlin/org/wordpress/aztec/AztecParser.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class AztecParser {
9393
}
9494

9595
private fun markBlockElementLineBreak(text: Spannable, startPos: Int) {
96-
text.setSpan(BlockElementLinebreak(), startPos, startPos, Spanned.SPAN_MARK_MARK)
96+
text.setSpan(AztecVisualLinebreak(), startPos, startPos, Spanned.SPAN_MARK_MARK)
9797
}
9898

9999
fun addVisualNewlinesToBlockElements(spanned: Editable) {
@@ -145,7 +145,7 @@ class AztecParser {
145145

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

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

@@ -225,12 +225,12 @@ class AztecParser {
225225
return@forEach
226226
}
227227

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

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

291291
do {
292292
val paragraphs = text.getSpans(i, end, AztecNestable::class.java)
293-
.filter{ it !is AztecHorizontalLineSpan}
293+
.filter{ it !is AztecFullWidthImageSpan}
294294
.toTypedArray()
295295

296296
paragraphs.sortWith(Comparator { a, b ->
@@ -352,7 +352,7 @@ class AztecParser {
352352

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

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

376376
if (!isVisualLinebreak) {
377377
nl++
@@ -404,10 +404,16 @@ class AztecParser {
404404
out.append("<${span.getStartTag()}>")
405405
}
406406

407-
if (span is AztecCommentSpan || span is CommentSpan) {
407+
if (span is CommentSpan) {
408408
out.append("<!--")
409409
}
410410

411+
if (span is AztecCommentSpan) {
412+
out.append("<!--")
413+
out.append(span.commentText)
414+
i = next
415+
}
416+
411417
if (span is AztecHorizontalLineSpan) {
412418
out.append("<${span.getStartTag()}>")
413419
i = next

aztec/src/main/kotlin/org/wordpress/aztec/AztecTagHandler.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ class AztecTagHandler : Html.TagHandler {
8888
// Add an extra newline above the line to prevent weird typing on the line above
8989
start(output, AztecHorizontalLineSpan(context, ContextCompat.getDrawable(context, R.drawable.img_hr), nestingLevel))
9090

91-
// the placeholder text ~must~ contain at least 2 characters, otherwise extra newline is appended to the HTML
92-
output.append("HR")
91+
output.append(Constants.MAGIC_CHAR)
9392
} else {
9493
end(output, AztecHorizontalLineSpan::class.java)
9594
}
@@ -101,7 +100,6 @@ class AztecTagHandler : Html.TagHandler {
101100
return true
102101
}
103102
}
104-
105103
}
106104
return false
107105
}

aztec/src/main/kotlin/org/wordpress/aztec/formatting/LineBlockFormatter.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,21 @@ class LineBlockFormatter(editor: AztecText) : AztecFormatter(editor) {
9999
editor.removeInlineStylesFromRange(selectionStart, selectionEnd)
100100
editor.removeBlockStylesFromRange(selectionStart, selectionEnd, true)
101101

102+
val nestingLevel = AztecNestable.getNestingLevelAt(editableText, selectionStart)
103+
102104
val span = AztecCommentSpan(
105+
comment.html,
103106
editor.context,
104107
when (comment) {
105108
AztecCommentSpan.Comment.MORE -> ContextCompat.getDrawable(editor.context, R.drawable.img_more)
106109
AztecCommentSpan.Comment.PAGE -> ContextCompat.getDrawable(editor.context, R.drawable.img_page)
107-
}
110+
},
111+
nestingLevel,
112+
editor
108113
)
109-
val ssb = SpannableStringBuilder(comment.html)
110-
ssb.setSpan(span, 0, comment.html.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
114+
115+
val ssb = SpannableStringBuilder(Constants.MAGIC_STRING)
116+
ssb.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
111117

112118
editableText.replace(selectionStart, selectionEnd, ssb)
113119

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

118124
fun insertMedia(drawable: Drawable?, attributes: Attributes, onMediaTappedListener: OnMediaTappedListener?) {
119-
val span = AztecMediaSpan(editor.context, drawable, attributes, onMediaTappedListener)
120-
span.textView = editor
125+
val span = AztecMediaSpan(editor.context, drawable, attributes, onMediaTappedListener, editor)
121126

122127
val spanBeforeMedia = editableText.getSpans(selectionStart, selectionEnd, AztecBlockSpan::class.java)
123128
.firstOrNull {

aztec/src/main/kotlin/org/wordpress/aztec/formatting/LinkFormatter.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,10 @@ import org.wordpress.aztec.AztecText
1010
import org.wordpress.aztec.spans.AztecURLSpan
1111

1212

13-
class LinkFormatter(editor: AztecText, linkStyle: LinkStyle):AztecFormatter(editor) {
13+
class LinkFormatter(editor: AztecText, val linkStyle: LinkStyle):AztecFormatter(editor) {
1414

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

17-
val linkStyle: LinkStyle
18-
19-
init {
20-
this.linkStyle = linkStyle
21-
}
22-
23-
2417
fun isUrlSelected(): Boolean {
2518
val urlSpans = editableText.getSpans(selectionStart, selectionEnd, AztecURLSpan::class.java)
2619
return !urlSpans.isEmpty()

aztec/src/main/kotlin/org/wordpress/aztec/source/Format.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.util.regex.Pattern
77
object Format {
88

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

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

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package org.wordpress.aztec.spans
22

33
import android.content.Context
4-
import android.graphics.Paint
5-
import android.graphics.Rect
64
import android.graphics.drawable.Drawable
7-
import android.text.style.ImageSpan
5+
import org.wordpress.aztec.AztecText
86

9-
import org.wordpress.android.util.DisplayUtils
7+
class AztecCommentSpan @JvmOverloads constructor(val commentText: String, context: Context, drawable: Drawable, override var nestingLevel: Int, editor: AztecText? = null) :
8+
AztecDynamicImageSpan(context, drawable), AztecFullWidthImageSpan {
9+
10+
init {
11+
textView = editor
12+
}
1013

11-
class AztecCommentSpan(val context: Context, drawable: Drawable) : ImageSpan(drawable) {
1214
companion object {
13-
private val rect: Rect = Rect()
1415
private val HTML_MORE: String = "more"
1516
private val HTML_PAGE: String = "nextpage"
1617
}
@@ -19,39 +20,4 @@ class AztecCommentSpan(val context: Context, drawable: Drawable) : ImageSpan(dra
1920
MORE(HTML_MORE),
2021
PAGE(HTML_PAGE)
2122
}
22-
23-
override fun getSize(paint: Paint?, text: CharSequence?, start: Int, end: Int, metrics: Paint.FontMetricsInt?): Int {
24-
val drawable = drawable
25-
val bounds = getBounds(drawable)
26-
27-
if (metrics != null) {
28-
metrics.ascent = -bounds.bottom
29-
metrics.descent = 0
30-
31-
metrics.top = metrics.ascent
32-
metrics.bottom = 0
33-
}
34-
35-
return bounds.right
36-
}
37-
38-
private fun getBounds(drawable: Drawable): Rect {
39-
if (drawable.intrinsicWidth === 0) {
40-
rect.set(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
41-
return rect
42-
}
43-
44-
/*
45-
* Following Android guidelines for keylines and spacing, screen edge margins should
46-
* be 16dp. Therefore, the width of images should be the width of the screen minus
47-
* 16dp on both sides (i.e. 16 * 2 = 32).
48-
*
49-
* https://material.io/guidelines/layout/metrics-keylines.html#metrics-keylines-baseline-grids
50-
*/
51-
val width = context.resources.displayMetrics.widthPixels - DisplayUtils.dpToPx(context, 32)
52-
val height = drawable.intrinsicHeight * width / drawable.intrinsicWidth
53-
drawable.setBounds(0, 0, width, height)
54-
55-
return drawable.bounds
56-
}
5723
}

aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecDynamicImageSpan.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ abstract class AztecDynamicImageSpan(val context: Context, protected var imageDr
9191
return Rect(imageDrawable?.bounds ?: Rect(0, 0, 0, 0))
9292
}
9393

94-
if (measuring) {
94+
val layout = textView?.layout
95+
96+
if (measuring || layout == null) {
9597
// if we're in pre-layout phase, just return a tiny rect
9698
return Rect(0, 0, 1, 1)
9799
}
@@ -103,8 +105,7 @@ abstract class AztecDynamicImageSpan(val context: Context, protected var imageDr
103105

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

110111
val line = layout.getLineForOffset(start)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package org.wordpress.aztec.spans
22

3-
interface AztecFullWidthImageSpan : AztecSurroundedWithNewlines, AztecSpan
3+
interface AztecFullWidthImageSpan : AztecSurroundedWithNewlines

aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecHorizontalLineSpan.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import org.wordpress.android.util.DisplayUtils
1616
import org.wordpress.aztec.AztecText
1717

1818
class AztecHorizontalLineSpan(context: Context, drawable: Drawable, override var nestingLevel: Int) :
19-
AztecDynamicImageSpan(context, drawable), AztecFullWidthImageSpan {
19+
AztecDynamicImageSpan(context, drawable), AztecFullWidthImageSpan, AztecSpan {
2020

2121
private val TAG: String = "hr"
2222

0 commit comments

Comments
 (0)