mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] For https://github.com/mozilla-mobile/fenix/issues/1667: Screen reader can't reach other UI items when QAB expanded (https://github.com/mozilla-mobile/fenix/pull/4695)
This commit is contained in:
parent
bf76cbe7e6
commit
4987c40d67
@ -19,7 +19,6 @@ import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.component_search.*
|
||||
import kotlinx.android.synthetic.main.fragment_browser.*
|
||||
@ -72,6 +71,7 @@ import org.mozilla.fenix.ext.enterToImmersiveMode
|
||||
import org.mozilla.fenix.ext.nav
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.toTab
|
||||
import org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
@ -173,7 +173,7 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler, SessionManager.Obs
|
||||
it.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
},
|
||||
currentSessionAsTab = session.toTab(context!!),
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(nestedScrollQuickAction)
|
||||
bottomSheetBehavior = QuickActionSheetBehavior.from(nestedScrollQuickAction)
|
||||
)
|
||||
|
||||
browserInteractor =
|
||||
|
@ -26,6 +26,7 @@ import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.nav
|
||||
import org.mozilla.fenix.home.sessioncontrol.Tab
|
||||
import org.mozilla.fenix.lib.Do
|
||||
import org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior
|
||||
|
||||
/**
|
||||
* An interface that handles the view manipulation of the BrowserToolbar, triggered by the Interactor
|
||||
@ -47,7 +48,7 @@ class DefaultBrowserToolbarController(
|
||||
private val getSupportUrl: () -> String,
|
||||
private val openInFenixIntent: Intent,
|
||||
private val currentSessionAsTab: Tab,
|
||||
private val bottomSheetBehavior: BottomSheetBehavior<NestedScrollView>
|
||||
private val bottomSheetBehavior: QuickActionSheetBehavior<NestedScrollView>
|
||||
) : BrowserToolbarController {
|
||||
|
||||
override fun handleToolbarClick() {
|
||||
|
@ -11,17 +11,15 @@ import android.view.View
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import android.widget.LinearLayout
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import mozilla.components.browser.toolbar.BrowserToolbar
|
||||
import org.mozilla.fenix.R
|
||||
import kotlinx.android.synthetic.main.layout_quick_action_sheet.view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
const val POSITION_SNAP_BUFFER = 1f
|
||||
@ -35,7 +33,7 @@ class QuickActionSheet @JvmOverloads constructor(
|
||||
|
||||
private val scope = MainScope()
|
||||
|
||||
private lateinit var quickActionSheetBehavior: QuickActionSheetBehavior
|
||||
private lateinit var quickActionSheetBehavior: QuickActionSheetBehavior<NestedScrollView>
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.layout_quick_action_sheet, this)
|
||||
@ -43,8 +41,8 @@ class QuickActionSheet @JvmOverloads constructor(
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
quickActionSheetBehavior = BottomSheetBehavior.from(quick_action_sheet.parent as View)
|
||||
as QuickActionSheetBehavior
|
||||
quickActionSheetBehavior =
|
||||
QuickActionSheetBehavior.from(quick_action_sheet.parent as NestedScrollView)
|
||||
quickActionSheetBehavior.isHideable = false
|
||||
setupHandle()
|
||||
}
|
||||
@ -76,21 +74,21 @@ class QuickActionSheet @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
class HandleAccessibilityDelegate(
|
||||
private val quickActionSheetBehavior: QuickActionSheetBehavior
|
||||
private val quickActionSheetBehavior: QuickActionSheetBehavior<NestedScrollView>
|
||||
) : View.AccessibilityDelegate() {
|
||||
private var finalState = BottomSheetBehavior.STATE_COLLAPSED
|
||||
get() = when (quickActionSheetBehavior.state) {
|
||||
BottomSheetBehavior.STATE_EXPANDED,
|
||||
BottomSheetBehavior.STATE_HIDDEN,
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> {
|
||||
quickActionSheetBehavior.state
|
||||
get() = when (quickActionSheetBehavior.state) {
|
||||
BottomSheetBehavior.STATE_EXPANDED,
|
||||
BottomSheetBehavior.STATE_HIDDEN,
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> {
|
||||
quickActionSheetBehavior.state
|
||||
}
|
||||
else -> field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
quickActionSheetBehavior.state = value
|
||||
}
|
||||
else -> field
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
quickActionSheetBehavior.state = value
|
||||
}
|
||||
|
||||
override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
|
||||
finalState = when (action) {
|
||||
@ -113,11 +111,13 @@ class QuickActionSheet @JvmOverloads constructor(
|
||||
|
||||
override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfo?) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info)
|
||||
info?.addAction(when (finalState) {
|
||||
BottomSheetBehavior.STATE_COLLAPSED,
|
||||
BottomSheetBehavior.STATE_HIDDEN -> AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND
|
||||
else -> AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE
|
||||
})
|
||||
info?.addAction(
|
||||
when (finalState) {
|
||||
BottomSheetBehavior.STATE_COLLAPSED,
|
||||
BottomSheetBehavior.STATE_HIDDEN -> AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND
|
||||
else -> AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,44 +126,3 @@ class QuickActionSheet @JvmOverloads constructor(
|
||||
const val BOUNCE_ANIMATION_PAUSE_LENGTH = 2000L
|
||||
}
|
||||
}
|
||||
|
||||
class QuickActionSheetBehavior(
|
||||
context: Context,
|
||||
attrs: AttributeSet
|
||||
) : BottomSheetBehavior<NestedScrollView>(context, attrs) {
|
||||
|
||||
override fun layoutDependsOn(parent: CoordinatorLayout, child: NestedScrollView, dependency: View): Boolean {
|
||||
if (dependency is BrowserToolbar) {
|
||||
return true
|
||||
}
|
||||
|
||||
return super.layoutDependsOn(parent, child, dependency)
|
||||
}
|
||||
|
||||
override fun onDependentViewChanged(
|
||||
parent: CoordinatorLayout,
|
||||
child: NestedScrollView,
|
||||
dependency: View
|
||||
): Boolean {
|
||||
return if (dependency is BrowserToolbar) {
|
||||
repositionQuickActionSheet(child, dependency)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun repositionQuickActionSheet(quickActionSheetContainer: NestedScrollView, toolbar: BrowserToolbar) {
|
||||
if (toolbar.translationY >= toolbar.height.toFloat() - POSITION_SNAP_BUFFER) {
|
||||
state = STATE_HIDDEN
|
||||
} else if (state == STATE_HIDDEN || state == STATE_SETTLING) {
|
||||
state = STATE_COLLAPSED
|
||||
}
|
||||
quickActionSheetContainer.translationY = toolbar.translationY + toolbar.height * -1.0f
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun from(view: NestedScrollView) =
|
||||
BottomSheetBehavior.from(view) as QuickActionSheetBehavior
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,6 @@ import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.fragment_browser.*
|
||||
import kotlinx.android.synthetic.main.layout_quick_action_sheet.*
|
||||
@ -31,6 +30,7 @@ interface QuickActionSheetViewInteractor {
|
||||
fun onQuickActionSheetAppearancePressed()
|
||||
fun onQuickActionSheetOpenLinkPressed()
|
||||
}
|
||||
|
||||
/**
|
||||
* View for the quick action sheet that slides out from the toolbar.
|
||||
*/
|
||||
@ -47,13 +47,14 @@ class QuickActionSheetView(
|
||||
private val quickActionSheetBehavior = QuickActionSheetBehavior.from(nestedScrollQuickAction)
|
||||
|
||||
init {
|
||||
quickActionSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onStateChanged(v: View, state: Int) {
|
||||
updateImportantForAccessibility(state)
|
||||
quickActionSheetBehavior.setQuickActionSheetCallback(object :
|
||||
QuickActionSheetBehavior.QuickActionSheetCallback {
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
updateImportantForAccessibility(newState)
|
||||
|
||||
if (state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
if (newState == QuickActionSheetBehavior.STATE_EXPANDED) {
|
||||
interactor.onQuickActionSheetOpened()
|
||||
} else if (state == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
} else if (newState == QuickActionSheetBehavior.STATE_COLLAPSED) {
|
||||
interactor.onQuickActionSheetClosed()
|
||||
}
|
||||
}
|
||||
@ -86,7 +87,7 @@ class QuickActionSheetView(
|
||||
R.id.quick_action_open_app_link -> interactor.onQuickActionSheetOpenLinkPressed()
|
||||
else -> return
|
||||
}
|
||||
quickActionSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
quickActionSheetBehavior.state = QuickActionSheetBehavior.STATE_COLLAPSED
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +103,7 @@ class QuickActionSheetView(
|
||||
*/
|
||||
private fun updateImportantForAccessibility(state: Int) {
|
||||
view.quick_action_buttons_layout.importantForAccessibility = when (state) {
|
||||
BottomSheetBehavior.STATE_COLLAPSED, BottomSheetBehavior.STATE_HIDDEN ->
|
||||
QuickActionSheetBehavior.STATE_COLLAPSED, QuickActionSheetBehavior.STATE_HIDDEN ->
|
||||
View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
|
||||
else ->
|
||||
View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
|
||||
|
@ -26,8 +26,8 @@
|
||||
android:id="@+id/nestedScrollQuickAction"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="12dp"
|
||||
app:mozac_behavior_hideable="true"
|
||||
app:mozac_behavior_peekHeight="12dp"
|
||||
app:layout_behavior="org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior" />
|
||||
|
||||
<ViewStub
|
||||
|
@ -48,4 +48,56 @@
|
||||
<declare-styleable name="OnboardingRadioButton">
|
||||
<attr name="onboardingKey" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="QuickActionSheetBehavior_Layout">
|
||||
<!-- The height of the bottom sheet when it is collapsed. -->
|
||||
<attr format="dimension" name="mozac_behavior_peekHeight">
|
||||
<!-- Peek at the 16:9 ratio keyline of its parent -->
|
||||
<enum name="auto" value="-1"/>
|
||||
</attr>
|
||||
<!-- Whether this bottom sheet can be hidden by dragging it further downwards -->
|
||||
<attr format="boolean" name="mozac_behavior_hideable"/>
|
||||
<!-- Skip the collapsed state once expanded; no effect unless it is hideable -->
|
||||
<attr format="boolean" name="mozac_behavior_skipCollapsed"/>
|
||||
<!-- Whether height of expanded sheet wraps content or not -->
|
||||
<attr format="boolean" name="mozac_behavior_fitToContents"/>
|
||||
<!-- The ratio to be used to set the height of half-expanded state in proportion to parent, when
|
||||
fitToContents is false. Defaults to true half, 0.5, if not explicitly set. Ratio must be a
|
||||
float value between 0 and 1 and produce a half-expanded state height larger than the
|
||||
peek height for the half-expanded state to be operational -->
|
||||
<attr format="reference|float" name="mozac_behavior_halfExpandedRatio"/>
|
||||
<!-- The top offset of the BottomSheet in the expanded-state when fitsToContent is false.
|
||||
The default value is 0, which results in the sheet matching the parent's top. -->
|
||||
<attr format="reference|integer" name="mozac_behavior_expandedOffset"/>
|
||||
<!-- Shape appearance style reference for BottomSheet. Attribute declaration is in the shape
|
||||
package. -->
|
||||
<attr name="shapeAppearance"/>
|
||||
<!-- Shape appearance overlay style reference for BottomSheet. To be used to augment attributes
|
||||
declared in the shapeAppearance. Attribute declaration is in the shape package. -->
|
||||
<attr name="shapeAppearanceOverlay"/>
|
||||
<!-- Background color used by the BottomSheetBehavior background drawable when shape theming is
|
||||
enabled. Accepts a ColorStateList or ColorInt. If shape theming is not enabled,
|
||||
android:background should instead be utilized to set the background resource. -->
|
||||
<attr name="backgroundTint"/>
|
||||
<!-- Behavior properties will be saved and restored by evaluating each flag.
|
||||
usage: app:behavior_saveFlags=”hideable|skipCollapsed” -->
|
||||
<attr name="mozac_behavior_saveFlags">
|
||||
<!-- This flag will preserve the peekHeight on configuration change. -->
|
||||
<flag name="peekHeight" value="0x1"/>
|
||||
<!-- This flag will preserve the fitToContents boolean value on configuration change. -->
|
||||
<flag name="fitToContents" value="0x2"/>
|
||||
<!-- This flag will preserve the hideable boolean value on configuration change. -->
|
||||
<flag name="hideable" value="0x4"/>
|
||||
<!-- This flag will preserve the skipCollapsed boolean value on configuration change. -->
|
||||
<flag name="skipCollapsed" value="0x8"/>
|
||||
<!-- This flag will preserve the all the aforementioned values on configuration change. -->
|
||||
<flag name="all" value="-1"/>
|
||||
<!-- This flag will not preserve the aforementioned values on configuration change. The only
|
||||
value preserved will be the positional state, e.g. collapsed, hidden, expanded, etc.
|
||||
This is the default behavior. -->
|
||||
<flag name="none" value="0"/>
|
||||
</attr>
|
||||
<attr name="android:elevation"/>
|
||||
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
@ -34,6 +34,8 @@
|
||||
<!--Quick Settings-->
|
||||
<dimen name="quicksettings_item_height">46dp</dimen>
|
||||
|
||||
<dimen name="design_quick_action_sheet_peek_height_min">64dp</dimen>
|
||||
|
||||
<dimen name="onboarding_header_icon_height_width">32dp</dimen>
|
||||
|
||||
<!-- Bottom Sheet Fragment card -->
|
||||
|
@ -7,7 +7,6 @@ package org.mozilla.fenix.components.toolbar
|
||||
import android.content.Intent
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.navigation.NavController
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
@ -37,6 +36,7 @@ import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.nav
|
||||
import org.mozilla.fenix.home.sessioncontrol.Tab
|
||||
import org.mozilla.fenix.home.sessioncontrol.TabCollection
|
||||
import org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@ObsoleteCoroutinesApi
|
||||
@ -54,7 +54,7 @@ class DefaultBrowserToolbarControllerTest {
|
||||
private val getSupportUrl: () -> String = { "https://supportUrl.org" }
|
||||
private val openInFenixIntent: Intent = mockk(relaxed = true)
|
||||
private val currentSessionAsTab: Tab = mockk(relaxed = true)
|
||||
private val bottomSheetBehavior: BottomSheetBehavior<NestedScrollView> = mockk(relaxed = true)
|
||||
private val bottomSheetBehavior: QuickActionSheetBehavior<NestedScrollView> = mockk(relaxed = true)
|
||||
private val metrics: MetricController = mockk(relaxed = true)
|
||||
private val sessionUseCases: SessionUseCases = mockk(relaxed = true)
|
||||
|
||||
@ -236,7 +236,7 @@ class DefaultBrowserToolbarControllerTest {
|
||||
|
||||
controller.handleToolbarItemInteraction(item)
|
||||
|
||||
verify { bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED }
|
||||
verify { bottomSheetBehavior.state = QuickActionSheetBehavior.STATE_COLLAPSED }
|
||||
verify { findInPageLauncher() }
|
||||
verify { metrics.track(Event.FindInPageOpened) }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user