[components] Closes https://github.com/mozilla-mobile/android-components/issues/2077: Toolbar: Allow returning Boolean from "URL commit listener" to control switching to display mode.

This commit is contained in:
Sebastian Kaspari
2019-02-15 10:57:47 +01:00
parent 69ff6c67ca
commit 67a1814a26
9 changed files with 59 additions and 25 deletions

View File

@@ -50,6 +50,7 @@ private const val AUTOCOMPLETE_QUERY_THREADS = 3
* URL and controls for navigation. In edit mode the current URL can be edited. Those two modes are * URL and controls for navigation. In edit mode the current URL can be edited. Those two modes are
* implemented by the DisplayToolbar and EditToolbar classes. * implemented by the DisplayToolbar and EditToolbar classes.
* *
* ```
* +----------------+ * +----------------+
* | BrowserToolbar | * | BrowserToolbar |
* +--------+-------+ * +--------+-------+
@@ -59,7 +60,7 @@ private const val AUTOCOMPLETE_QUERY_THREADS = 3
* +---------v------+ +-------v--------+ * +---------v------+ +-------v--------+
* | DisplayToolbar | | EditToolbar | * | DisplayToolbar | | EditToolbar |
* +----------------+ +----------------+ * +----------------+ +----------------+
* * ```
*/ */
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
class BrowserToolbar @JvmOverloads constructor( class BrowserToolbar @JvmOverloads constructor(
@@ -253,7 +254,7 @@ class BrowserToolbar @JvmOverloads constructor(
private var state: State = State.DISPLAY private var state: State = State.DISPLAY
private var searchTerms: String = "" private var searchTerms: String = ""
private var urlCommitListener: ((String) -> Unit)? = null private var urlCommitListener: ((String) -> Boolean)? = null
override var url: String = "" override var url: String = ""
set(value) { set(value) {
@@ -322,10 +323,10 @@ class BrowserToolbar @JvmOverloads constructor(
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
forEach { child -> forEach { child ->
child.layout( child.layout(
0 + paddingLeft, 0 + paddingLeft,
0 + paddingTop, 0 + paddingTop,
paddingLeft + child.measuredWidth, paddingLeft + child.measuredWidth,
paddingTop + child.measuredHeight) paddingTop + child.measuredHeight)
} }
} }
@@ -368,7 +369,7 @@ class BrowserToolbar @JvmOverloads constructor(
displayToolbar.updateProgress(progress) displayToolbar.updateProgress(progress)
} }
override fun setOnUrlCommitListener(listener: (String) -> Unit) { override fun setOnUrlCommitListener(listener: (String) -> Boolean) {
this.urlCommitListener = listener this.urlCommitListener = listener
} }
@@ -444,9 +445,11 @@ class BrowserToolbar @JvmOverloads constructor(
} }
internal fun onUrlEntered(url: String) { internal fun onUrlEntered(url: String) {
displayMode() if (urlCommitListener?.invoke(url) != false) {
// Return to display mode if there's no urlCommitListener or if it returned true. This lets
urlCommitListener?.invoke(url) // the app control whether we should switch to display mode automatically.
displayMode()
}
} }
private fun updateState(state: State) { private fun updateState(state: State) {

View File

@@ -21,6 +21,7 @@ import mozilla.components.browser.toolbar.edit.EditToolbar
import mozilla.components.concept.toolbar.Toolbar import mozilla.components.concept.toolbar.Toolbar
import mozilla.components.concept.toolbar.Toolbar.SiteSecurity import mozilla.components.concept.toolbar.Toolbar.SiteSecurity
import mozilla.components.support.base.android.Padding import mozilla.components.support.base.android.Padding
import mozilla.components.support.ktx.android.view.isGone
import mozilla.components.support.ktx.android.view.isVisible import mozilla.components.support.ktx.android.view.isVisible
import mozilla.components.support.test.mock import mozilla.components.support.test.mock
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@@ -161,9 +162,10 @@ class BrowserToolbarTest {
var called = false var called = false
var url: String? = null var url: String? = null
fun invoke(url: String) { fun invoke(url: String): Boolean {
this.called = true this.called = true
this.url = url this.url = url
return true
} }
} }
@@ -234,6 +236,36 @@ class BrowserToolbarTest {
assertTrue(toolbar.editToolbar.visibility == View.GONE) assertTrue(toolbar.editToolbar.visibility == View.GONE)
} }
@Test
fun `toolbar will switch back to display mode if URL commit listener returns true`() {
val toolbar = BrowserToolbar(context)
toolbar.setOnUrlCommitListener { true }
toolbar.editMode()
assertTrue(toolbar.displayToolbar.isGone())
assertTrue(toolbar.editToolbar.isVisible())
toolbar.onUrlEntered("https://www.mozilla.org")
assertTrue(toolbar.displayToolbar.isVisible())
assertTrue(toolbar.editToolbar.isGone())
}
@Test
fun `toolbar will stay in edit mode if URL commit listener returns false`() {
val toolbar = BrowserToolbar(context)
toolbar.setOnUrlCommitListener { false }
toolbar.editMode()
assertTrue(toolbar.displayToolbar.isGone())
assertTrue(toolbar.editToolbar.isVisible())
toolbar.onUrlEntered("https://www.mozilla.org")
assertTrue(toolbar.displayToolbar.isGone())
assertTrue(toolbar.editToolbar.isVisible())
}
@Test @Test
fun `display and edit toolbar will be laid out at the exact same position`() { fun `display and edit toolbar will be laid out at the exact same position`() {
val toolbar = BrowserToolbar(context) val toolbar = BrowserToolbar(context)

View File

@@ -62,9 +62,12 @@ interface Toolbar {
* Registers the given function to be invoked when the user selected a new URL i.e. is done * Registers the given function to be invoked when the user selected a new URL i.e. is done
* editing. * editing.
* *
* If the function returns `true` then the toolbar will automatically switch to "display mode". Otherwise it
* remains in "edit mode".
*
* @param listener the listener function * @param listener the listener function
*/ */
fun setOnUrlCommitListener(listener: (String) -> Unit) fun setOnUrlCommitListener(listener: (String) -> Boolean)
/** /**
* Registers the given function to be invoked when users changes text in the toolbar. * Registers the given function to be invoked when users changes text in the toolbar.
@@ -223,9 +226,9 @@ interface Toolbar {
if (background == 0) { if (background == 0) {
val outValue = TypedValue() val outValue = TypedValue()
parent.context.theme.resolveAttribute( parent.context.theme.resolveAttribute(
android.R.attr.selectableItemBackgroundBorderless, android.R.attr.selectableItemBackgroundBorderless,
outValue, outValue,
true) true)
imageButton.setBackgroundResource(outValue.resourceId) imageButton.setBackgroundResource(outValue.resourceId)
} else { } else {

View File

@@ -50,7 +50,6 @@ class ToolbarFeature(
* Stop feature: App is in the background. * Stop feature: App is in the background.
*/ */
override fun stop() { override fun stop() {
interactor.stop()
presenter.stop() presenter.stop()
} }
} }

View File

@@ -30,13 +30,7 @@ class ToolbarInteractor(
} else { } else {
searchUseCase?.invoke(text) ?: loadUrlUseCase.invoke(text) searchUseCase?.invoke(text) ?: loadUrlUseCase.invoke(text)
} }
true
} }
} }
/**
* Stops this interactor.
*/
fun stop() {
toolbar.setOnUrlCommitListener { }
}
} }

View File

@@ -49,7 +49,7 @@ class ToolbarAutocompleteFeatureTest {
return false return false
} }
override fun setOnUrlCommitListener(listener: (String) -> Unit) { override fun setOnUrlCommitListener(listener: (String) -> Boolean) {
fail() fail()
} }

View File

@@ -37,7 +37,7 @@ class ToolbarInteractorTest {
return false return false
} }
override fun setOnUrlCommitListener(listener: (String) -> Unit) { override fun setOnUrlCommitListener(listener: (String) -> Boolean) {
listener("https://mozilla.org") listener("https://mozilla.org")
} }

View File

@@ -89,6 +89,7 @@ permalink: /changelog/
* If there is an active bundle then the bundle will be removed instead of updated with the empty snapshot. * If there is an active bundle then the bundle will be removed instead of updated with the empty snapshot.
* **browser-toolbar**, **concept-toolbar** * **browser-toolbar**, **concept-toolbar**
* ⚠️ **This is a breaking API change**: The interface of the "URL commit listener" changed from `(String) -> Unit` to `(String) -> Boolean`. If the function returns `true` then the toolbar will automatically switch to "display mode". If no function is set or if the function returns false the toolbar remains in "edit mode".
* Added `private` field (`Boolean`): Enables/Disables private mode. In private mode the IME should not update any personalized data such as typing history and personalized language model based on what the user typed. * Added `private` field (`Boolean`): Enables/Disables private mode. In private mode the IME should not update any personalized data such as typing history and personalized language model based on what the user typed.
* The background and foreground color of the autocomplete suggestion can now be styled: * The background and foreground color of the autocomplete suggestion can now be styled:

View File

@@ -406,6 +406,8 @@ class ToolbarActivity : AppCompatActivity() {
if (url.isNotEmpty()) { if (url.isNotEmpty()) {
toolbar.url = url toolbar.url = url
} }
true
} }
} }