Skip to content

Commit c955d9f

Browse files
authored
Merge pull request #721 from wordpress-mobile/try/nested-tags-cleanup
Added cleaning utility to cope with nested <b> tags
2 parents 621ec1f + 67708e0 commit c955d9f

File tree

5 files changed

+157
-1
lines changed

5 files changed

+157
-1
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.wordpress.aztec.spans.IAztecParagraphStyle;
5959
import org.wordpress.aztec.spans.UnknownClickableSpan;
6060
import org.wordpress.aztec.spans.UnknownHtmlSpan;
61+
import org.wordpress.aztec.util.CleaningUtils;
6162
import org.xml.sax.Attributes;
6263
import org.xml.sax.InputSource;
6364
import org.xml.sax.Locator;
@@ -188,6 +189,8 @@ public static Spanned fromHtml(String source, TagHandler tagHandler,
188189
throw new RuntimeException(e);
189190
}
190191

192+
source = CleaningUtils.cleanNestedBoldTags(source);
193+
191194
source = preprocessSource(source, plugins);
192195

193196
HtmlToSpannedConverter converter =

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import org.wordpress.aztec.spans.UnknownHtmlSpan
8787
import org.wordpress.aztec.toolbar.IAztecToolbar
8888
import org.wordpress.aztec.toolbar.ToolbarAction
8989
import org.wordpress.aztec.util.AztecLog
90+
import org.wordpress.aztec.util.CleaningUtils
9091
import org.wordpress.aztec.util.InstanceStateUtils
9192
import org.wordpress.aztec.util.SpanWrapper
9293
import org.wordpress.aztec.util.coerceToHtmlText
@@ -1015,7 +1016,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
10151016
val builder = SpannableStringBuilder()
10161017
val parser = AztecParser(plugins)
10171018

1018-
val cleanSource = Format.removeSourceEditorFormatting(source, isInCalypsoMode)
1019+
var cleanSource = CleaningUtils.cleanNestedBoldTags(source)
1020+
cleanSource = Format.removeSourceEditorFormatting(cleanSource, isInCalypsoMode)
10191021
builder.append(parser.fromHtml(cleanSource, context))
10201022

10211023
Format.preProcessSpannedText(builder, isInCalypsoMode)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.wordpress.aztec.spans.AztecVisualLinebreak
1010
import org.wordpress.aztec.spans.EndOfParagraphMarker
1111
import org.wordpress.aztec.spans.IAztecParagraphStyle
1212
import org.wordpress.aztec.spans.ParagraphSpan
13+
import org.wordpress.aztec.util.CleaningUtils
1314
import java.util.regex.Matcher
1415
import java.util.regex.Pattern
1516

@@ -25,6 +26,7 @@ object Format {
2526
html = html.replace("<aztec_cursor>", "")
2627

2728
val doc = Jsoup.parseBodyFragment(html).outputSettings(Document.OutputSettings().prettyPrint(!isCalypsoFormat))
29+
CleaningUtils.cleanNestedBoldTags(doc)
2830
if (isCalypsoFormat) {
2931
// remove empty span tags
3032
doc.select("*")
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.wordpress.aztec.util
2+
3+
import org.jsoup.Jsoup
4+
import org.jsoup.nodes.Document
5+
import org.jsoup.parser.Parser
6+
7+
object CleaningUtils {
8+
9+
@JvmStatic
10+
fun cleanNestedBoldTags(doc: Document) {
11+
// clean all nested <b> tags that don't contain anything
12+
doc.select("b > b")
13+
.filter { !it.hasText() }
14+
.forEach { it.remove() }
15+
16+
// unwrap text in between nested <b> tags that have some text in them
17+
doc.select("b > b")
18+
.filter { it.hasText() }
19+
.forEach { it.unwrap() }
20+
}
21+
22+
@JvmStatic
23+
fun cleanNestedBoldTags(html: String) : String {
24+
val doc = Jsoup.parse(html, "", Parser.xmlParser()).outputSettings(Document.OutputSettings().prettyPrint(false))
25+
cleanNestedBoldTags(doc)
26+
return doc.html()
27+
}
28+
}

aztec/src/test/kotlin/org/wordpress/aztec/HtmlFormattingTest.kt

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,100 @@ class HtmlFormattingTest : AndroidTestCase() {
7474
private val HTML_BLOCK_WITH_NEWLINES = "\n\n<div>Division</div>\n\n"
7575
private val HTML_BLOCK_WITHOUT_NEWLINES = "<div>Division</div>"
7676

77+
private val HTML_NESTED_BOLD_TAGS = "<b><b><b><b><b><b><b>Test post</b></b></b></b></b></b></b> \n" +
78+
"\n" +
79+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
80+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
81+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
82+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
83+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
84+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
85+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
86+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
87+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
88+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
89+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
90+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
91+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
92+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b>" +
93+
"<b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
94+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
95+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
96+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
97+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
98+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
99+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
100+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
101+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
102+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
103+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
104+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
105+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
106+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
107+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
108+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
109+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
110+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
111+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
112+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
113+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
114+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
115+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
116+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
117+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
118+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
119+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
120+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
121+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
122+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
123+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
124+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
125+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
126+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
127+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
128+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
129+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
130+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b>" +
131+
"</b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b><b></b>" +
132+
"<b></b>" +
133+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
134+
"</b></b></b></b></b></b></b></b></b>" +
135+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
136+
"</b></b></b></b></b></b></b></b></b>" +
137+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
138+
"</b></b></b></b></b></b></b></b></b>" +
139+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
140+
"</b></b></b></b></b></b></b></b></b>" +
141+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
142+
"</b></b></b></b></b></b></b></b></b>" +
143+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
144+
"</b></b></b></b></b></b></b></b></b>" +
145+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
146+
"</b></b></b></b></b></b></b></b></b>" +
147+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
148+
"</b></b></b></b></b></b></b></b></b>" +
149+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
150+
"</b></b></b></b></b></b></b></b></b>" +
151+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
152+
"</b></b></b></b></b></b></b></b></b>" +
153+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
154+
"</b></b></b></b></b></b></b></b></b>" +
155+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
156+
"</b></b></b></b></b></b></b></b></b>" +
157+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
158+
"</b></b></b></b></b></b></b></b></b>" +
159+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
160+
"</b></b></b></b></b></b></b></b></b>" +
161+
"</b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b></b>" +
162+
"<br /><br />Our room with a view[/caption]\n" +
163+
"\n" +
164+
"Test end"
165+
166+
private val HTML_NESTED_BOLD_TAGS_VISUAL2HTML_OUTPUT =
167+
"<b>Test post</b><b> </b><br><br>Our room with a view[/caption] Test end"
168+
private val HTML_NESTED_BOLD_TAGS_HTML_PROCESSING_OUTPUT =
169+
"<b>Test post</b> <b></b><br><br>Our room with a view[/caption] Test end"
170+
77171
/**
78172
* Initialize variables.
79173
*/
@@ -137,4 +231,31 @@ class HtmlFormattingTest : AndroidTestCase() {
137231
val output = Format.removeSourceEditorFormatting(Format.addSourceEditorFormatting(parser.toHtml(span)))
138232
Assert.assertEquals(HTML_BLOCK_WITHOUT_NEWLINES, output)
139233
}
234+
235+
/**
236+
* Test block conversion from HTML to visual mode with nested <b> blocks
237+
*
238+
* @throws Exception
239+
*/
240+
@Test
241+
@Throws(Exception::class)
242+
fun noNestedBoldTagsConversion() {
243+
val input = HTML_NESTED_BOLD_TAGS
244+
val span = SpannableString(parser.fromHtml(input, RuntimeEnvironment.application.applicationContext))
245+
val output = Format.removeSourceEditorFormatting(Format.addSourceEditorFormatting(parser.toHtml(span)))
246+
Assert.assertEquals(HTML_NESTED_BOLD_TAGS_VISUAL2HTML_OUTPUT, output)
247+
}
248+
249+
/**
250+
* Test adding source editor formatting handles nested <b> blocks
251+
*
252+
* @throws Exception
253+
*/
254+
@Test
255+
@Throws(Exception::class)
256+
fun noNestedBoldTagsFromSource() {
257+
val input = HTML_NESTED_BOLD_TAGS
258+
val output = Format.removeSourceEditorFormatting(Format.addSourceEditorFormatting(input))
259+
Assert.assertEquals(HTML_NESTED_BOLD_TAGS_HTML_PROCESSING_OUTPUT, output)
260+
}
140261
}

0 commit comments

Comments
 (0)