Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add content watcher for aztec text #887

Merged
merged 5 commits into from
Jan 2, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.wordpress.aztec

import java.lang.ref.WeakReference

class AztecContentChangeWatcher {
private val observers = mutableListOf<WeakReference<AztecTextChangeObserver>>()
fun registerObserver(observer: AztecTextChangeObserver) {
if (observers.none { it.get() == observer }) {
observers.add(WeakReference(observer))
}
}

fun unregisterObserver(observer: AztecTextChangeObserver) {
observers.removeAll { it.get() == observer }
}

internal fun notifyContentChanged() {
val iterator = observers.iterator()
while (iterator.hasNext()) {
val item = iterator.next()
val foundObserver = item.get()
if (foundObserver == null) {
iterator.remove()
} else {
foundObserver.onContentChanged()
}
}
}

interface AztecTextChangeObserver {
fun onContentChanged()
}
}
12 changes: 12 additions & 0 deletions aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown

private var focusOnVisible = true

val contentChangeWatcher = AztecContentChangeWatcher()

interface OnSelectionChangedListener {
fun onSelectionChanged(selStart: Int, selEnd: Int)
}
Expand Down Expand Up @@ -497,6 +499,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
// use HTML from the new text to set the state of the editText directly
fromHtml(toFormattedHtml(newText), false)

contentChangeWatcher.notifyContentChanged()

// re-enable MediaDeleted listener
enableMediaDeletedListener()
// re-enable this very filter
Expand Down Expand Up @@ -565,6 +569,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
setText("")
enableTextChangedListener()
}
contentChangeWatcher.notifyContentChanged()
}
return wasStyleRemoved
}
Expand Down Expand Up @@ -627,6 +632,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
}

override fun afterTextChanged(text: Editable) {
contentChangeWatcher.notifyContentChanged()
if (isTextChangedListenerDisabled()) {
return
}
Expand Down Expand Up @@ -1024,6 +1030,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
.forEach { it.toggle() }
}
}

contentChangeWatcher.notifyContentChanged()
}

fun contains(format: ITextFormat, selStart: Int = selectionStart, selEnd: Int = selectionEnd): Boolean {
Expand Down Expand Up @@ -1128,10 +1136,12 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown

fun redo() {
history.redo(this)
contentChangeWatcher.notifyContentChanged()
}

fun undo() {
history.undo(this)
contentChangeWatcher.notifyContentChanged()
}

// Helper ======================================================================================
Expand Down Expand Up @@ -1618,6 +1628,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
fromHtml(newHtml, false)
inlineFormatter.joinStyleSpans(0, length())
}
contentChangeWatcher.notifyContentChanged()
}
}

Expand All @@ -1643,6 +1654,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
} else {
linkFormatter.addLink(url, anchor, openInNewWindow, selectionStart, selectionEnd)
}
contentChangeWatcher.notifyContentChanged()
}

fun removeLink() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.wordpress.aztec

import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class AztecContentChangeWatcherTest {
private lateinit var aztecContentChangeWatcher: AztecContentChangeWatcher
@Before
fun setUp() {
aztecContentChangeWatcher = AztecContentChangeWatcher()
}

@Test
fun `notifies registered observer`() {
// Given
var contentChanged = false
setupRegisteredObserver {
contentChanged = true
}

// When
aztecContentChangeWatcher.notifyContentChanged()

// Then
assertTrue(contentChanged)
}

@Test
fun `does not notify unregistered observer`() {
// Given
var contentChanged = false
val observer = setupRegisteredObserver {
contentChanged = true
}

// When
aztecContentChangeWatcher.unregisterObserver(observer)
aztecContentChangeWatcher.notifyContentChanged()

// Then
assertFalse(contentChanged)
}

@Test
fun `observer is garbage collected and reference is lost`() {
// Given
var contentChanged = false
setupRegisteredObserver {
contentChanged = true
}
System.gc()

// When
aztecContentChangeWatcher.notifyContentChanged()

// Then
assertFalse(contentChanged)
}

private fun setupRegisteredObserver(onContentChanged: () -> Unit): AztecContentChangeWatcher.AztecTextChangeObserver {
val observer = object : AztecContentChangeWatcher.AztecTextChangeObserver {
override fun onContentChanged() {
onContentChanged()
}
}
aztecContentChangeWatcher.registerObserver(observer)
return observer
}
}