Skip to content

Commit fbd0503

Browse files
committed
Merge branch 'develop' into issue/288-quote-gets-removed
2 parents 0cddac9 + 24d9ef7 commit fbd0503

26 files changed

+427
-225
lines changed

app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class MainActivity : AppCompatActivity(),
5858
private val UNDERLINE = "<u>Underline</u><br>"
5959
private val STRIKETHROUGH = "<s class=\"test\">Strikethrough</s><br>" // <s> or <strike> or <del>
6060
private val ORDERED = "<ol><li>Ordered</li><li></li></ol>"
61+
private val LINE = "<hr>"
6162
private val UNORDERED = "<ul><li>Unordered</li><li></li></ul>"
6263
private val QUOTE = "<blockquote>Quote</blockquote>"
6364
private val LINK = "<a href=\"https://github.com/wordpress-mobile/WordPress-Aztec-Android\">Link</a><br>"
@@ -89,6 +90,7 @@ class MainActivity : AppCompatActivity(),
8990
UNDERLINE +
9091
STRIKETHROUGH +
9192
ORDERED +
93+
LINE +
9294
UNORDERED +
9395
QUOTE +
9496
LINK +

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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@
1616
* limitations under the License.
1717
*/
1818

19+
import android.content.Context;
20+
import android.content.res.ColorStateList;
21+
import android.content.res.Resources;
22+
import android.graphics.Color;
23+
import android.graphics.drawable.Drawable;
24+
import android.text.Editable;
25+
import android.text.Spannable;
26+
import android.text.SpannableStringBuilder;
27+
import android.text.Spanned;
28+
import android.text.TextUtils;
29+
import android.text.style.ForegroundColorSpan;
30+
import android.text.style.ParagraphStyle;
31+
import android.text.style.TextAppearanceSpan;
32+
import android.text.style.TypefaceSpan;
33+
1934
import org.ccil.cowan.tagsoup.HTMLSchema;
2035
import org.ccil.cowan.tagsoup.Parser;
2136
import org.wordpress.aztec.AztecText.OnMediaTappedListener;
@@ -47,21 +62,6 @@
4762
import org.xml.sax.XMLReader;
4863
import org.xml.sax.ext.LexicalHandler;
4964

50-
import android.content.Context;
51-
import android.content.res.ColorStateList;
52-
import android.content.res.Resources;
53-
import android.graphics.Color;
54-
import android.graphics.drawable.Drawable;
55-
import android.text.Editable;
56-
import android.text.Spannable;
57-
import android.text.SpannableStringBuilder;
58-
import android.text.Spanned;
59-
import android.text.TextUtils;
60-
import android.text.style.ForegroundColorSpan;
61-
import android.text.style.ParagraphStyle;
62-
import android.text.style.TextAppearanceSpan;
63-
import android.text.style.TypefaceSpan;
64-
6565
import java.io.IOException;
6666
import java.io.StringReader;
6767

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

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class AztecParser {
9898

9999
fun addVisualNewlinesToBlockElements(spanned: Editable) {
100100
// add visual newlines at starts
101-
spanned.getSpans(0, spanned.length, AztecBlockSpan::class.java).forEach {
101+
spanned.getSpans(0, spanned.length, AztecSurroundedWithNewlines::class.java).forEach {
102102
val parent = AztecNestable.getParent(spanned, SpanWrapper(spanned, it))
103103
val repelling = (parent?.span is AztecListItemSpan) && (it is AztecListSpan)
104104

@@ -126,14 +126,14 @@ class AztecParser {
126126

127127
// expand all same-start parents to include the new newline
128128
SpanWrapper.getSpans<AztecNestable>(spanned, spanStart + 1, spanStart + 2)
129-
.filter { parent -> parent.span.nestingLevel < it.nestingLevel && parent.start == spanStart + 1}
129+
.filter { parent -> parent.span.nestingLevel < it.nestingLevel && parent.start == spanStart + 1 }
130130
.forEach { parent -> parent.start-- }
131131

132132
markBlockElementLineBreak(spanned, spanStart)
133133
}
134134

135135
// add visual newlines at ends
136-
spanned.getSpans(0, spanned.length, AztecBlockSpan::class.java).forEach {
136+
spanned.getSpans(0, spanned.length, AztecSurroundedWithNewlines::class.java).forEach {
137137
val spanEnd = spanned.getSpanEnd(it)
138138

139139
// no need for newline if at text end
@@ -144,17 +144,22 @@ class AztecParser {
144144
// no need for newline if there's one and marked as visual
145145
if (spanned[spanEnd] == '\n'
146146
&& spanned.getSpans(spanEnd, spanEnd, BlockElementLinebreak::class.java).isNotEmpty()) {
147-
// but still, expand the span to include the newline
148-
spanned.setSpan(it, spanned.getSpanStart(it), spanEnd + 1, spanned.getSpanFlags(it))
147+
148+
// but still, expand the span to include the newline for block spans, because they are paragraphs
149+
if (it is AztecBlockSpan) {
150+
spanned.setSpan(it, spanned.getSpanStart(it), spanEnd + 1, spanned.getSpanFlags(it))
151+
}
149152

150153
return@forEach
151154
}
152155

153156
// well, it seems we need a visual newline so, add one and mark it as such
154157
spanned.insert(spanEnd, "\n")
155158

156-
// expand the span to include the new newline
157-
spanned.setSpan(it, spanned.getSpanStart(it), spanEnd + 1, spanned.getSpanFlags(it))
159+
// expand the span to include the new newline for block spans, because they are paragraphs
160+
if (it is AztecBlockSpan) {
161+
spanned.setSpan(it, spanned.getSpanStart(it), spanEnd + 1, spanned.getSpanFlags(it))
162+
}
158163

159164
markBlockElementLineBreak(spanned, spanEnd)
160165
}
@@ -168,24 +173,27 @@ class AztecParser {
168173
}
169174

170175
// add visual newlines at ends
171-
spanned.getSpans(0, spanned.length, AztecBlockSpan::class.java).forEach {
176+
spanned.getSpans(0, spanned.length, AztecSurroundedWithNewlines::class.java).forEach {
172177
val spanEnd = spanned.getSpanEnd(it)
173178

179+
// block spans include a newline at the end, we need to account for that
180+
val newlineExpected = if (it is AztecBlockSpan) spanEnd - 1 else spanEnd
181+
174182
if (spanEnd == spanned.length) {
175183
// no visual newline if at text end
176184
return@forEach
177185
}
178186

179-
if (spanned[spanEnd - 1] != '\n') {
187+
if (spanned[newlineExpected] != '\n') {
180188
// no newline inside the end of the span so, nothing to mark as visual newline
181189
return@forEach
182190
}
183191

184192
// at last, all checks passed so, let's mark the newline as visual!
185-
markBlockElementLineBreak(spanned, spanEnd - 1)
193+
markBlockElementLineBreak(spanned, newlineExpected)
186194
}
187195

188-
spanned.getSpans(0, spanned.length, AztecBlockSpan::class.java).forEach {
196+
spanned.getSpans(0, spanned.length, AztecSurroundedWithNewlines::class.java).forEach {
189197
val parent = AztecNestable.getParent(spanned, SpanWrapper(spanned, it))
190198
val repelling = (parent?.span is AztecListItemSpan) && (it is AztecListSpan)
191199

@@ -207,13 +215,13 @@ class AztecParser {
207215
return@forEach
208216
}
209217

210-
if (spanned.getSpans(spanStart, spanStart, AztecBlockSpan::class.java).any { before ->
218+
if (spanned.getSpans(spanStart, spanStart, AztecSurroundedWithNewlines::class.java).any { before ->
211219
spanned.getSpanEnd(before) == spanStart }) {
212220
// the newline before us is the end of a previous block element so, return
213221
return@forEach
214222
}
215223

216-
if (!repelling && spanned[spanStart - 2] == '\n') {
224+
if (!repelling && spanned[spanStart - 2] == '\n' && it is AztecBlockSpan) {
217225
// there's another newline before and we're not repelling a parent so, the adjacent one is not a visual one so, return
218226
return@forEach
219227
}
@@ -278,6 +286,9 @@ class AztecParser {
278286

279287
do {
280288
val paragraphs = text.getSpans(i, end, AztecNestable::class.java)
289+
.filter{ it !is AztecHorizontalLineSpan}
290+
.toTypedArray()
291+
281292
paragraphs.sortWith(Comparator { a, b ->
282293
val startComparison = text.getSpanStart(a).compareTo(text.getSpanStart(b))
283294
if (startComparison == 0) {
@@ -393,6 +404,11 @@ class AztecParser {
393404
out.append("<!--")
394405
}
395406

407+
if (span is AztecHorizontalLineSpan) {
408+
out.append("<${span.getStartTag()}>")
409+
i = next
410+
}
411+
396412
if (span is AztecMediaSpan) {
397413
out.append(span.getHtml())
398414
i = next

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ class AztecTagHandler : Html.TagHandler {
8383
handleElement(output, opening, ParagraphSpan(nestingLevel, attributeString))
8484
return true
8585
}
86+
LINE -> {
87+
if (opening) {
88+
// Add an extra newline above the line to prevent weird typing on the line above
89+
start(output, AztecHorizontalLineSpan(context, ContextCompat.getDrawable(context, R.drawable.img_hr), nestingLevel))
90+
91+
// the placeholder text ~must~ contain at least 2 characters, otherwise extra newline is appended to the HTML
92+
output.append("HR")
93+
} else {
94+
end(output, AztecHorizontalLineSpan::class.java)
95+
}
96+
return true
97+
}
8698
else -> {
8799
if (tag.length == 2 && Character.toLowerCase(tag[0]) == 'h' && tag[1] >= '1' && tag[1] <= '6') {
88100
handleElement(output, opening, AztecHeadingSpan(nestingLevel, tag, attributeString))
@@ -156,6 +168,7 @@ class AztecTagHandler : Html.TagHandler {
156168
private val BLOCKQUOTE = "blockquote"
157169
private val PARAGRAPH = "p"
158170
private val IMAGE = "img"
171+
private val LINE = "hr"
159172

160173
private fun getLast(text: Editable, kind: Class<*>): Any? {
161174
val spans = text.getSpans(0, text.length, kind)

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ class AztecText : EditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlClickListe
247247

248248
TextDeleter.install(this)
249249

250+
FullWidthImageElementWatcher.install(this)
251+
250252
EndOfBufferMarkerAdder.install(this)
251253

252254
}
@@ -373,8 +375,7 @@ class AztecText : EditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlClickListe
373375
internal class SavedState : BaseSavedState {
374376
var state: Bundle = Bundle()
375377

376-
constructor(superState: Parcelable) : super(superState) {
377-
}
378+
constructor(superState: Parcelable) : super(superState)
378379

379380
constructor(parcel: Parcel) : super(parcel) {
380381
state = parcel.readBundle(javaClass.classLoader)
@@ -425,7 +426,7 @@ class AztecText : EditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlClickListe
425426
}
426427

427428
override fun onKeyPreIme(keyCode: Int, event: KeyEvent): Boolean {
428-
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
429+
if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
429430
onImeBackListener?.onImeBack()
430431
}
431432
return super.onKeyPreIme(keyCode, event)
@@ -487,7 +488,7 @@ class AztecText : EditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlClickListe
487488

488489
if (newSelStart == 0 && newSelEnd == 0) {
489490
newSelEnd++
490-
} else if (newSelStart == newSelEnd && editableText.length > selectionStart && editableText[selectionStart - 1] == '\n') {
491+
} else if (newSelStart == newSelEnd && editableText.length > selectionStart && editableText[selectionStart - 1] == Constants.NEWLINE) {
491492
newSelEnd++
492493
} else if (newSelStart > 0 && !isTextSelected()) {
493494
newSelStart--
@@ -592,7 +593,6 @@ class AztecText : EditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlClickListe
592593
return
593594
}
594595

595-
596596
isMediaAdded = text.getSpans(0, text.length, AztecMediaSpan::class.java).isNotEmpty()
597597

598598
history.handleHistory(this)
@@ -627,7 +627,7 @@ class AztecText : EditText, TextWatcher, UnknownHtmlSpan.OnUnknownHtmlClickListe
627627
switchToAztecStyle(builder, 0, builder.length)
628628
disableTextChangedListener()
629629

630-
builder.getSpans(0, builder.length, AztecMediaSpan::class.java).forEach {
630+
builder.getSpans(0, builder.length, AztecDynamicImageSpan::class.java).forEach {
631631
it.textView = this
632632
}
633633

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ object Constants {
88
val IMG_CHAR = '\uFFFC'
99
val IMG_STRING = "" + IMG_CHAR
1010
val NEWLINE = '\n'
11+
val NEWLINE_STRING = "" + NEWLINE
1112
val END_OF_BUFFER_MARKER = ZWJ_CHAR
1213
val END_OF_BUFFER_MARKER_STRING = "" + ZWJ_CHAR
1314
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import android.text.Spanned
55
import android.text.style.StyleSpan
66
import org.wordpress.aztec.AztecPart
77
import org.wordpress.aztec.AztecText
8-
import org.wordpress.aztec.watchers.TextChangedEvent
98
import org.wordpress.aztec.TextFormat
109
import org.wordpress.aztec.spans.*
10+
import org.wordpress.aztec.watchers.TextChangedEvent
1111
import java.util.*
1212

1313

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import android.support.v4.content.ContextCompat
55
import android.text.SpannableStringBuilder
66
import android.text.Spanned
77
import android.text.TextUtils
8-
import org.wordpress.aztec.*
8+
import org.wordpress.aztec.AztecText
99
import org.wordpress.aztec.AztecText.OnMediaTappedListener
10+
import org.wordpress.aztec.Constants
11+
import org.wordpress.aztec.R
12+
import org.wordpress.aztec.TextFormat
1013
import org.wordpress.aztec.spans.*
1114
import org.wordpress.aztec.watchers.EndOfBufferMarkerAdder
1215
import org.xml.sax.Attributes

aztec/src/main/kotlin/org/wordpress/aztec/handlers/ListItemHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import org.wordpress.aztec.spans.AztecListItemSpan
55
import org.wordpress.aztec.spans.AztecNestable
66
import org.wordpress.aztec.watchers.TextDeleter
77

8-
class ListItemHandler() : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class.java) {
8+
class ListItemHandler : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class.java) {
99

1010
override fun handleNewlineAtStartOfBlock() {
1111
// newline added at start of bullet so, add a new bullet

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"
10+
private val block = "div|br|blockquote|ul|ol|li|p|h1|h2|h3|h4|h5|h6|iframe|hr"
1111

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

0 commit comments

Comments
 (0)