@@ -22,6 +22,7 @@ import org.wordpress.aztec.spans.AztecStyleStrongSpan
2222import org.wordpress.aztec.spans.AztecStyleSpan
2323import org.wordpress.aztec.spans.AztecUnderlineSpan
2424import org.wordpress.aztec.spans.HighlightSpan
25+ import org.wordpress.aztec.spans.IAztecExclusiveInlineSpan
2526import org.wordpress.aztec.spans.IAztecInlineSpan
2627import org.wordpress.aztec.spans.MarkSpan
2728import org.wordpress.aztec.watchers.TextChangedEvent
@@ -37,23 +38,43 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
3738
3839 fun toggle (textFormat : ITextFormat ) {
3940 if (! containsInlineStyle(textFormat)) {
41+ val inlineSpan = makeInlineSpan(textFormat)
42+ if (inlineSpan is IAztecExclusiveInlineSpan ) {
43+ // If text format is exclusive, remove all the inclusive text formats already applied
44+ removeAllInclusiveFormats()
45+ } else {
46+ // If text format is inclusive, remove all the exclusive text formats already applied
47+ removeAllExclusiveFormats()
48+ }
4049 applyInlineStyle(textFormat)
4150 } else {
4251 removeInlineStyle(textFormat)
4352 }
4453 }
4554
55+ private fun removeAllInclusiveFormats () {
56+ editableText.getSpans(selectionStart, selectionEnd, IAztecInlineSpan ::class .java).filter {
57+ it !is IAztecExclusiveInlineSpan
58+ }.forEach { removeInlineStyle(it) }
59+ }
60+
4661 /* *
4762 * Removes all formats in the list but if none found, applies the first one
4863 */
4964 fun toggleAny (textFormats : Set <ITextFormat >) {
5065 if (! textFormats
5166 .filter { containsInlineStyle(it) }
52- .fold(false , { found, containedTextFormat -> removeInlineStyle(containedTextFormat); true })) {
67+ .fold(false ) { found, containedTextFormat -> removeInlineStyle(containedTextFormat); true }) {
68+ removeAllExclusiveFormats()
5369 applyInlineStyle(textFormats.first())
5470 }
5571 }
5672
73+ private fun removeAllExclusiveFormats () {
74+ editableText.getSpans(selectionStart, selectionEnd, IAztecExclusiveInlineSpan ::class .java)
75+ .forEach { removeInlineStyle(it) }
76+ }
77+
5778 fun handleInlineStyling (textChangedEvent : TextChangedEvent ) {
5879 if (textChangedEvent.isEndOfBufferMarker()) return
5980
@@ -117,7 +138,7 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
117138 }
118139 }
119140
120- fun applyInlineStyle (textFormat : ITextFormat , start : Int = selectionStart, end : Int = selectionEnd, attrs : AztecAttributes = AztecAttributes ()) {
141+ private fun applyInlineStyle (textFormat : ITextFormat , start : Int = selectionStart, end : Int = selectionEnd, attrs : AztecAttributes = AztecAttributes ()) {
121142 val spanToApply = makeInlineSpan(textFormat)
122143 spanToApply.attributes = attrs
123144
@@ -144,7 +165,7 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
144165 if (spanEnd > start) {
145166 // ensure css style is applied
146167 (precedingSpan as IAztecInlineSpan ).applyInlineStyleAttributes(editableText, start, end)
147- return @applyInlineStyle // we are adding text inside span - no need to do anything special
168+ return // we are adding text inside span - no need to do anything special
148169 } else {
149170 applySpan(precedingSpan as IAztecInlineSpan , spanStart, end, Spanned .SPAN_EXCLUSIVE_EXCLUSIVE )
150171 }
@@ -217,18 +238,18 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
217238 }
218239
219240 fun spanToTextFormat (span : IAztecInlineSpan ): ITextFormat ? {
220- when (span::class .java) {
221- AztecStyleBoldSpan ::class .java -> return AztecTextFormat .FORMAT_BOLD
222- AztecStyleStrongSpan ::class .java -> return AztecTextFormat .FORMAT_STRONG
223- AztecStyleItalicSpan ::class .java -> return AztecTextFormat .FORMAT_ITALIC
224- AztecStyleEmphasisSpan ::class .java -> return AztecTextFormat .FORMAT_EMPHASIS
225- AztecStyleCiteSpan ::class .java -> return AztecTextFormat .FORMAT_CITE
226- AztecStrikethroughSpan ::class .java -> return AztecTextFormat .FORMAT_STRIKETHROUGH
227- AztecUnderlineSpan ::class .java -> return AztecTextFormat .FORMAT_UNDERLINE
228- AztecCodeSpan ::class .java -> return AztecTextFormat .FORMAT_CODE
229- MarkSpan ::class .java -> return AztecTextFormat .FORMAT_MARK
230- HighlightSpan ::class .java -> return AztecTextFormat .FORMAT_HIGHLIGHT
231- else -> return null
241+ return when (span::class .java) {
242+ AztecStyleBoldSpan ::class .java -> AztecTextFormat .FORMAT_BOLD
243+ AztecStyleStrongSpan ::class .java -> AztecTextFormat .FORMAT_STRONG
244+ AztecStyleItalicSpan ::class .java -> AztecTextFormat .FORMAT_ITALIC
245+ AztecStyleEmphasisSpan ::class .java -> AztecTextFormat .FORMAT_EMPHASIS
246+ AztecStyleCiteSpan ::class .java -> AztecTextFormat .FORMAT_CITE
247+ AztecStrikethroughSpan ::class .java -> AztecTextFormat .FORMAT_STRIKETHROUGH
248+ AztecUnderlineSpan ::class .java -> AztecTextFormat .FORMAT_UNDERLINE
249+ AztecCodeSpan ::class .java -> AztecTextFormat .FORMAT_CODE
250+ MarkSpan ::class .java -> AztecTextFormat .FORMAT_MARK
251+ HighlightSpan ::class .java -> AztecTextFormat .FORMAT_HIGHLIGHT
252+ else -> null
232253 }
233254 }
234255
@@ -363,20 +384,20 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
363384 }
364385
365386 fun makeInlineSpan (textFormat : ITextFormat ): IAztecInlineSpan {
366- when (textFormat) {
367- AztecTextFormat .FORMAT_BOLD -> return AztecStyleBoldSpan ()
368- AztecTextFormat .FORMAT_STRONG -> return AztecStyleStrongSpan ()
369- AztecTextFormat .FORMAT_ITALIC -> return AztecStyleItalicSpan ()
370- AztecTextFormat .FORMAT_EMPHASIS -> return AztecStyleEmphasisSpan ()
371- AztecTextFormat .FORMAT_CITE -> return AztecStyleCiteSpan ()
372- AztecTextFormat .FORMAT_STRIKETHROUGH -> return AztecStrikethroughSpan ()
373- AztecTextFormat .FORMAT_UNDERLINE -> return AztecUnderlineSpan ()
374- AztecTextFormat .FORMAT_CODE -> return AztecCodeSpan (codeStyle)
387+ return when (textFormat) {
388+ AztecTextFormat .FORMAT_BOLD -> AztecStyleBoldSpan ()
389+ AztecTextFormat .FORMAT_STRONG -> AztecStyleStrongSpan ()
390+ AztecTextFormat .FORMAT_ITALIC -> AztecStyleItalicSpan ()
391+ AztecTextFormat .FORMAT_EMPHASIS -> AztecStyleEmphasisSpan ()
392+ AztecTextFormat .FORMAT_CITE -> AztecStyleCiteSpan ()
393+ AztecTextFormat .FORMAT_STRIKETHROUGH -> AztecStrikethroughSpan ()
394+ AztecTextFormat .FORMAT_UNDERLINE -> AztecUnderlineSpan ()
395+ AztecTextFormat .FORMAT_CODE -> AztecCodeSpan (codeStyle)
375396 AztecTextFormat .FORMAT_HIGHLIGHT -> {
376- return HighlightSpan (highlightStyle = highlightStyle, context = editor.context)
397+ HighlightSpan (highlightStyle = highlightStyle, context = editor.context)
377398 }
378- AztecTextFormat .FORMAT_MARK -> return MarkSpan ()
379- else -> return AztecStyleSpan (Typeface .NORMAL )
399+ AztecTextFormat .FORMAT_MARK -> MarkSpan ()
400+ else -> AztecStyleSpan (Typeface .NORMAL )
380401 }
381402 }
382403
@@ -392,18 +413,16 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
392413 return false
393414 } else {
394415 val before = editableText.getSpans(start - 1 , start, IAztecInlineSpan ::class .java)
395- .filter { it -> isSameInlineSpanType(it, spanToCheck) }
396- .firstOrNull()
416+ .firstOrNull { isSameInlineSpanType(it, spanToCheck) }
397417 val after = editableText.getSpans(start, start + 1 , IAztecInlineSpan ::class .java)
398- .filter { isSameInlineSpanType(it, spanToCheck) }
399- .firstOrNull()
418+ .firstOrNull { isSameInlineSpanType(it, spanToCheck) }
400419 return before != null && after != null && isSameInlineSpanType(before, after)
401420 }
402421 } else {
403422 val builder = StringBuilder ()
404423
405424 // Make sure no duplicate characters be added
406- for (i in start.. end - 1 ) {
425+ for (i in start until end ) {
407426 val spans = editableText.getSpans(i, i + 1 , IAztecInlineSpan ::class .java)
408427
409428 for (span in spans) {
0 commit comments