Bug 1802584 - Announce "Find in page" edit box when using Talkback
When using talkback, the focus keeps jumping between the dismiss button and the "Find in page" edit text. Seems like giving up the view stub fixes this issue. Considering that the view inflation performance wins are rather small for such added complexity, we have given up the view stub.fenix/114.1.0
parent
900e1169e0
commit
ac4f4ccaca
@ -1,89 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.components
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewStub
|
||||
import androidx.annotation.UiThread
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
import mozilla.components.support.base.feature.UserInteractionHandler
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* A base feature class that enables lazy inflation of a view needed by a feature.
|
||||
*
|
||||
* When a feature needs to be launched (e.g. by user interaction) calling [launch]
|
||||
* will inflate the view only then, start the feature, and then executes [onLaunch]
|
||||
* for any feature-specific startup needs.
|
||||
*/
|
||||
abstract class InflationAwareFeature(
|
||||
private val stub: ViewStub,
|
||||
) : LifecycleAwareFeature, UserInteractionHandler {
|
||||
|
||||
internal lateinit var view: WeakReference<View>
|
||||
internal var feature: LifecycleAwareFeature? = null
|
||||
private val stubListener = ViewStub.OnInflateListener { _, inflated ->
|
||||
view = WeakReference(inflated)
|
||||
feature = onViewInflated(inflated).also {
|
||||
it.start()
|
||||
onLaunch(inflated, it)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a view-dependent feature needs to be started along with the feature itself.
|
||||
*/
|
||||
@UiThread
|
||||
fun launch() {
|
||||
// If we have a feature and view, we can launch immediately.
|
||||
if (feature != null && view.get() != null) {
|
||||
onLaunch(view.get()!!, feature!!)
|
||||
} else {
|
||||
stub.apply {
|
||||
setOnInflateListener(stubListener)
|
||||
inflate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation notes: This implemented method does nothing since we only start the feature
|
||||
* when the view is inflated.
|
||||
*/
|
||||
override fun start() {
|
||||
feature?.start()
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
feature?.stop()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the feature gets the option to handle the user pressing the back key.
|
||||
*
|
||||
* @return true if the feature also implements [UserInteractionHandler] and the feature has
|
||||
* been initiated.
|
||||
*/
|
||||
override fun onBackPressed(): Boolean {
|
||||
return (feature as? UserInteractionHandler)?.onBackPressed() ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the view has been inflated for the feature to be created with it.
|
||||
*
|
||||
* @param view The newly created view.
|
||||
* @return The feature initiated with the view.
|
||||
*/
|
||||
abstract fun onViewInflated(view: View): LifecycleAwareFeature
|
||||
|
||||
/**
|
||||
* Invoked after the feature is instantiated. If the feature already exists,
|
||||
* this is invoked immediately.
|
||||
*
|
||||
* @param view The view that is attached to the feature.
|
||||
* @param feature The feature that was instantiated.
|
||||
*/
|
||||
abstract fun onLaunch(view: View, feature: LifecycleAwareFeature)
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<mozilla.components.feature.findinpage.view.FindInPageBar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/findInPageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?attr/layer1"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:findInPageNoMatchesTextColor="?attr/textWarning"
|
||||
app:findInPageButtonsTint="?attr/textPrimary"
|
||||
app:findInPageResultCountTextColor="?attr/textPrimary" />
|
@ -1,101 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.components
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewStub
|
||||
import io.mockk.mockk
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
import mozilla.components.support.base.feature.UserInteractionHandler
|
||||
import org.junit.Test
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class InflationAwareFeatureTest {
|
||||
@Test
|
||||
fun `stub inflates if no feature or view exists`() {
|
||||
val stub: ViewStub = mockk(relaxed = true)
|
||||
val feature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
|
||||
|
||||
feature.launch()
|
||||
|
||||
verify { stub.setOnInflateListener(any()) }
|
||||
verify { stub.inflate() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `stub immediately launches if the feature is available`() {
|
||||
val stub: ViewStub = mockk()
|
||||
val feature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
|
||||
|
||||
feature.feature = mockk(relaxed = true)
|
||||
feature.view = WeakReference(mockk())
|
||||
|
||||
feature.launch()
|
||||
|
||||
verify(exactly = 0) { stub.setOnInflateListener(any()) }
|
||||
verify(exactly = 0) { stub.inflate() }
|
||||
verify { feature.onLaunch(any(), any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `feature calls stop if created`() {
|
||||
val stub: ViewStub = mockk()
|
||||
val inflationFeature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
|
||||
val innerFeature: LifecycleAwareFeature = mockk(relaxed = true)
|
||||
|
||||
inflationFeature.stop()
|
||||
|
||||
verify(exactly = 0) { innerFeature.stop() }
|
||||
|
||||
inflationFeature.feature = innerFeature
|
||||
|
||||
inflationFeature.stop()
|
||||
|
||||
verify { innerFeature.stop() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `start should be delegated to the inner feature`() {
|
||||
val inflationFeature: InflationAwareFeature = spyk(TestableInflationAwareFeature(mockk()))
|
||||
val innerFeature: LifecycleAwareFeature = mockk(relaxed = true)
|
||||
inflationFeature.feature = innerFeature
|
||||
|
||||
inflationFeature.start()
|
||||
|
||||
verify { innerFeature.start() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `if feature has implemented UserInteractionHandler invoke it`() {
|
||||
val stub: ViewStub = mockk()
|
||||
val inflationFeature: InflationAwareFeature = spyk(TestableInflationAwareFeature(stub))
|
||||
val innerFeature: LifecycleAwareFeature = mockk()
|
||||
val userInteractionHandlerFeature = object : LifecycleAwareFeature, UserInteractionHandler {
|
||||
override fun onBackPressed() = true
|
||||
|
||||
override fun start() {}
|
||||
|
||||
override fun stop() {}
|
||||
}
|
||||
|
||||
assert(!inflationFeature.onBackPressed())
|
||||
|
||||
inflationFeature.feature = innerFeature
|
||||
|
||||
assert(!inflationFeature.onBackPressed())
|
||||
|
||||
inflationFeature.feature = userInteractionHandlerFeature
|
||||
|
||||
assert(inflationFeature.onBackPressed())
|
||||
}
|
||||
}
|
||||
|
||||
class TestableInflationAwareFeature(stub: ViewStub) : InflationAwareFeature(stub) {
|
||||
override fun onViewInflated(view: View): LifecycleAwareFeature = mockk()
|
||||
|
||||
override fun onLaunch(view: View, feature: LifecycleAwareFeature) = Unit
|
||||
}
|
Loading…
Reference in New Issue