[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:
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class ToolbarAutocompleteFeatureTest {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setOnUrlCommitListener(listener: (String) -> Unit) {
|
override fun setOnUrlCommitListener(listener: (String) -> Boolean) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -406,6 +406,8 @@ class ToolbarActivity : AppCompatActivity() {
|
|||||||
if (url.isNotEmpty()) {
|
if (url.isNotEmpty()) {
|
||||||
toolbar.url = url
|
toolbar.url = url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user