Skip to content

Commit 229dfb3

Browse files
committed
Way better logging routine for Spans. props @hypest
1 parent c8dbb17 commit 229dfb3

File tree

2 files changed

+97
-27
lines changed

2 files changed

+97
-27
lines changed

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,11 +1124,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
11241124
} catch (e: Exception) {
11251125
// FIXME: Remove this log once we've data to replicate the issue, and fix it in some way.
11261126
AppLog.e(AppLog.T.EDITOR, "There was an error creating SpannableStringBuilder. See #452 and #582 for details.")
1127-
when (e) {
1128-
is java.lang.ArrayIndexOutOfBoundsException, is java.lang.RuntimeException -> {
1129-
AztecLog.logContentDetails(this)
1130-
}
1131-
}
1127+
// No need to log details here. The default AztecExceptionHandler does this for us.
11321128
throw e
11331129
}
11341130

Lines changed: 96 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package org.wordpress.aztec.util
22

3-
import android.text.Spannable
4-
import org.json.JSONArray
5-
import org.json.JSONException
6-
import org.json.JSONObject
3+
import android.text.Spanned
4+
import android.text.TextUtils
75
import org.wordpress.android.util.AppLog
86
import org.wordpress.aztec.AztecText
7+
import java.util.Arrays
8+
import java.util.Collections
99

1010
class AztecLog {
1111
interface ExternalLogger {
@@ -15,32 +15,106 @@ class AztecLog {
1515
}
1616

1717
companion object {
18+
private const val MARK = 1
19+
private const val POINT = 2
20+
private const val PARAGRAPH = 3
21+
1822
fun logContentDetails(aztecText: AztecText) {
1923
AppLog.d(AppLog.T.EDITOR, "Below are the details of the content in the editor:")
2024
logContentDetails(aztecText.text)
2125
}
2226

23-
fun logContentDetails(text: Spannable) {
27+
fun logContentDetails(text: Spanned) {
2428
try {
25-
val logContentJSON = JSONObject()
26-
logContentJSON.put("content", text.toString())
27-
logContentJSON.put("length", text.length)
28-
val spansJSON = JSONArray()
29-
val spans = text.getSpans(0, text.length, Any::class.java)
30-
spans.forEach {
31-
val currenSpanJSON = JSONObject()
32-
currenSpanJSON.put("clazz", it.javaClass.name)
33-
currenSpanJSON.put("start", text.getSpanStart(it))
34-
currenSpanJSON.put("end", text.getSpanEnd(it))
35-
currenSpanJSON.put("flags", text.getSpanFlags(it))
36-
spansJSON.put(currenSpanJSON)
37-
}
38-
logContentJSON.put("spans", spansJSON)
39-
AppLog.d(AppLog.T.EDITOR, logContentJSON.toString())
40-
} catch (e: JSONException) {
41-
AppLog.e(AppLog.T.EDITOR, "Uhh ohh! There was an error logging the content of the Editor. This should" +
29+
AppLog.d(AppLog.T.EDITOR, logSpansDetails(text))
30+
} catch (e: Exception) {
31+
AppLog.e(AppLog.T.EDITOR, "Uhh ohh! There was an error logging the spans details of the Editor. This should" +
4232
"never happen.", e)
4333
}
4434
}
35+
36+
private fun logSpansDetails(text: Spanned): String {
37+
val spans = text.getSpans(0, text.length, Any::class.java)
38+
val spansList = Arrays.asList<Any>(*spans)
39+
40+
val sb = StringBuilder()
41+
sb.append('\n').append(text.toString().replace('\n', '').replace('\u200B', '¬')) // ␤↵↭
42+
sb.append(" length = " + text.length)
43+
44+
for (span in spansList) {
45+
val start = text.getSpanStart(span)
46+
val end = text.getSpanEnd(span)
47+
48+
var gap = text.length + 5
49+
50+
sb.append('\n')
51+
52+
if (start > 0) {
53+
sb.append(spaces(start))
54+
gap -= start
55+
}
56+
57+
val spanMode = text.getSpanFlags(span) and Spanned.SPAN_POINT_MARK_MASK
58+
val leftMode = (spanMode and 0x30) ushr 4
59+
val rightMode = spanMode and 0x03
60+
61+
if (end - start > 0) {
62+
when (leftMode) {
63+
MARK -> sb.append('>')
64+
POINT -> sb.append('<')
65+
PARAGRAPH -> sb.append(if (start == 0) '<' else '>')
66+
}
67+
68+
gap--
69+
} else {
70+
if (spanMode == Spanned.SPAN_INCLUSIVE_INCLUSIVE) {
71+
sb.append('x')
72+
} else if (spanMode == Spanned.SPAN_INCLUSIVE_EXCLUSIVE) {
73+
sb.append('>')
74+
} else if (spanMode == Spanned.SPAN_EXCLUSIVE_INCLUSIVE) {
75+
sb.append('<')
76+
} else if (spanMode == Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) {
77+
sb.append('!')
78+
} else if (spanMode == Spanned.SPAN_PARAGRAPH) {
79+
if (start == 0) {
80+
sb.append('!')
81+
} else if (start == text.length) {
82+
sb.append('<')
83+
} else {
84+
sb.append('>')
85+
}
86+
}
87+
}
88+
89+
if (end - start - 1 > 0) {
90+
sb.append(spaces(end - start - 1, "-"))
91+
gap -= end - start - 1
92+
}
93+
94+
if (end - start > 0) {
95+
when (rightMode) {
96+
MARK -> sb.append('>')
97+
POINT -> sb.append('<')
98+
PARAGRAPH -> sb.append(if (end == text.length) '<' else '>')
99+
}
100+
gap--
101+
}
102+
103+
sb.append(spaces(gap))
104+
105+
sb.append(" ")
106+
.append(String.format("%03d", start))
107+
.append(" -> ")
108+
.append(String.format("%03d", end))
109+
.append(" : ")
110+
.append(span.javaClass.simpleName)
111+
}
112+
113+
return sb.toString()
114+
}
115+
116+
private fun spaces(count: Int, char: String = " "): String {
117+
return TextUtils.join("", Collections.nCopies(count, char))
118+
}
45119
}
46120
}

0 commit comments

Comments
 (0)