mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
added typed action clear_focus
c6c010f5eae937b1db19a40ac338aa88c8be003a
This commit is contained in:
@@ -907,6 +907,7 @@
|
||||
"client/android/div/src/main/java/com/yandex/div/core/DivVisibilityChangeListener.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivVisibilityChangeListener.java",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/ScrollDirection.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/ScrollDirection.java",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedArrayMutationHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedArrayMutationHandler.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedClearFocusHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedClearFocusHandler.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedCopyToClipboardHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedCopyToClipboardHandler.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedFocusElementHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedFocusElementHandler.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHandler.kt",
|
||||
@@ -1375,12 +1376,14 @@
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/SuperLineHeightTextViewTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/SuperLineHeightTextViewTest.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TabsSwipeTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TabsSwipeTest.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypeAutoAccessibilityTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypeAutoAccessibilityTest.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypedFocusActionsTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypedFocusActionsTest.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/ActivityParamsTestRule.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/ActivityParamsTestRule.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/Rules.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/Rules.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/ClickHandlingTestSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/ClickHandlingTestSteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/CoordinateSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/CoordinateSteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivCustomSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivCustomSteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusSteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusTypedActionsSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusTypedActionsSteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivGallerySteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivGallerySteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivHistogramsSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivHistogramsSteps.kt",
|
||||
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivInputSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivInputSteps.kt",
|
||||
@@ -14744,6 +14747,7 @@
|
||||
"schema/div-action-array-insert-value.json":"divkit/public/schema/div-action-array-insert-value.json",
|
||||
"schema/div-action-array-remove-value.json":"divkit/public/schema/div-action-array-remove-value.json",
|
||||
"schema/div-action-base.json":"divkit/public/schema/div-action-base.json",
|
||||
"schema/div-action-clear-focus.json":"divkit/public/schema/div-action-clear-focus.json",
|
||||
"schema/div-action-copy-to-clipboard-content.json":"divkit/public/schema/div-action-copy-to-clipboard-content.json",
|
||||
"schema/div-action-copy-to-clipboard.json":"divkit/public/schema/div-action-copy-to-clipboard.json",
|
||||
"schema/div-action-focus-element.json":"divkit/public/schema/div-action-focus-element.json",
|
||||
@@ -16022,6 +16026,7 @@
|
||||
"test_data/ui_test_data/custom/div_custom_several_states_changing.json":"divkit/public/test_data/ui_test_data/custom/div_custom_several_states_changing.json",
|
||||
"test_data/ui_test_data/custom/div_custom_state_changing.json":"divkit/public/test_data/ui_test_data/custom/div_custom_state_changing.json",
|
||||
"test_data/ui_test_data/focus/actions.json":"divkit/public/test_data/ui_test_data/focus/actions.json",
|
||||
"test_data/ui_test_data/focus/focus-element-and-clear-actions.json":"divkit/public/test_data/ui_test_data/focus/focus-element-and-clear-actions.json",
|
||||
"test_data/ui_test_data/focus/snapshot_div_input_selection.json":"divkit/public/test_data/ui_test_data/focus/snapshot_div_input_selection.json",
|
||||
"test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background.json":"divkit/public/test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background.json",
|
||||
"test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background_and_border.json":"divkit/public/test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background_and_border.json",
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.yandex.div.core.actions
|
||||
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.yandex.div.core.view2.Div2View
|
||||
import com.yandex.div2.DivActionTyped
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
internal class DivActionTypedClearFocusHandler @Inject constructor() : DivActionTypedHandler {
|
||||
override fun handleAction(action: DivActionTyped, view: Div2View): Boolean = when (action) {
|
||||
is DivActionTyped.ClearFocus -> {
|
||||
view.clearFocus()
|
||||
closeKeyboard(view)
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun closeKeyboard(view: Div2View) {
|
||||
val imm = ContextCompat.getSystemService(view.getContext(), InputMethodManager::class.java)
|
||||
imm?.hideSoftInputFromWindow(view.windowToken, InputMethodManager.SHOW_IMPLICIT)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.yandex.div.core.dagger
|
||||
|
||||
import com.yandex.div.core.actions.DivActionTypedArrayMutationHandler
|
||||
import com.yandex.div.core.actions.DivActionTypedClearFocusHandler
|
||||
import com.yandex.div.core.actions.DivActionTypedCopyToClipboardHandler
|
||||
import com.yandex.div.core.actions.DivActionTypedSetVariableHandler
|
||||
import com.yandex.div.core.actions.DivActionTypedHandler
|
||||
@@ -8,7 +9,6 @@ import com.yandex.div.core.actions.DivActionTypedFocusElementHandler
|
||||
import com.yandex.yatagan.Binds
|
||||
import com.yandex.yatagan.IntoSet
|
||||
import com.yandex.yatagan.Module
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
internal interface DivActionTypedModule {
|
||||
@@ -36,4 +36,10 @@ internal interface DivActionTypedModule {
|
||||
fun provideCopyToClipboardActionHandler(
|
||||
impl: DivActionTypedCopyToClipboardHandler
|
||||
): DivActionTypedHandler
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
fun provideClearFocusActionHandler(
|
||||
impl: DivActionTypedClearFocusHandler
|
||||
): DivActionTypedHandler
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.yandex.div
|
||||
|
||||
import com.yandex.div.rule.ActivityParamsTestRule
|
||||
import com.yandex.div.rule.uiTestRule
|
||||
import com.yandex.div.steps.divFocusTypedActions
|
||||
import com.yandex.divkit.demo.screenshot.DivScreenshotActivity
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class TypedFocusActionsTest {
|
||||
|
||||
@get:Rule
|
||||
val rule = uiTestRule {
|
||||
ActivityParamsTestRule(
|
||||
DivScreenshotActivity::class.java,
|
||||
DivScreenshotActivity.EXTRA_DIV_ASSET_NAME to "ui_test_data/focus/focus-element-and-clear-actions.json"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun focusViewFocusInput() {
|
||||
divFocusTypedActions {
|
||||
triggerFocusInputAction()
|
||||
assert { checkInputFocused() }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearFocusRemovesFocusFromInput() {
|
||||
divFocusTypedActions {
|
||||
triggerFocusInputAction()
|
||||
waitForClearFocusActionTriggered()
|
||||
|
||||
assert { checkFocusCleared() }
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.yandex.div.steps
|
||||
|
||||
import android.view.View
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isFocused
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isNotFocused
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import com.yandex.div.view.ViewActions
|
||||
import com.yandex.test.util.StepsDsl
|
||||
import org.hamcrest.Matcher
|
||||
import ru.tinkoff.allure.step
|
||||
|
||||
internal fun divFocusTypedActions(f: DivFocusTypedActionsSteps.() -> Unit) = f(DivFocusTypedActionsSteps())
|
||||
|
||||
@StepsDsl
|
||||
internal class DivFocusTypedActionsSteps {
|
||||
|
||||
fun triggerFocusInputAction(): Unit = step("Click on button 'Focus input'") {
|
||||
clickOnView(focusInputMatcher)
|
||||
}
|
||||
|
||||
fun waitForClearFocusActionTriggered(): Unit = step("Wait for until timer clean focus") {
|
||||
ViewActions.waitForView(finishedLabelMatcher, waitingTimeout = 2500)
|
||||
}
|
||||
|
||||
fun assert(f: DivFocusTypedActionsAssertions.() -> Unit) = f(DivFocusTypedActionsAssertions())
|
||||
}
|
||||
|
||||
@StepsDsl
|
||||
internal class DivFocusTypedActionsAssertions {
|
||||
fun checkInputFocused(): Unit = step("Check input has focus") {
|
||||
onView(inputMatcher).check(matches(isFocused()))
|
||||
}
|
||||
|
||||
fun checkFocusCleared(): Unit = step("Check input has no focus") {
|
||||
onView(inputMatcher).check(matches(isNotFocused()))
|
||||
}
|
||||
}
|
||||
|
||||
private fun clickOnView(matcher: Matcher<View>) = onView(matcher).perform(click())
|
||||
|
||||
private val focusInputMatcher = getTextMatcher("Focus input")
|
||||
private val inputMatcher = getTextMatcher("input view")
|
||||
private val finishedLabelMatcher = getTextMatcher("finished")
|
||||
|
||||
private fun getTextMatcher(text: String) = withText(text)
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"type": "object",
|
||||
"$description": "translations.json#/div_action_clear_focus",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"clear_focus"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
}
|
||||
@@ -16,6 +16,12 @@
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"$ref": "div-action-clear-focus.json",
|
||||
"platforms": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
{
|
||||
"$ref": "div-action-copy-to-clipboard.json"
|
||||
}
|
||||
|
||||
@@ -69,7 +69,11 @@
|
||||
},
|
||||
"div_action_copy_to_clipboard": {
|
||||
"en": "Copies data to the clipboard.",
|
||||
"ru": "Копирует данные в буфер обмена"
|
||||
"ru": "Копирует данные в буфер обмена."
|
||||
},
|
||||
"div_action_clear_focus": {
|
||||
"en": "Removes focus from focused item.",
|
||||
"ru": "Снимает фокус со сфокусированного элемента."
|
||||
},
|
||||
"div_action_focus_element": {
|
||||
"en": "Requests focus for an element. May require a user action on the web.",
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"templates": {
|
||||
"button": {
|
||||
"type": "text",
|
||||
"paddings": {
|
||||
"top": 4,
|
||||
"bottom": 4,
|
||||
"left": 8,
|
||||
"right": 8
|
||||
},
|
||||
"margins": {
|
||||
"right": 8,
|
||||
"left": 8
|
||||
},
|
||||
"text_alignment_horizontal": "center",
|
||||
"text_alignment_vertical": "center",
|
||||
"font_size": 12,
|
||||
"text_color": "#ffff",
|
||||
"font_weight": "bold",
|
||||
"height": {
|
||||
"type": "wrap_content"
|
||||
},
|
||||
"width": {
|
||||
"type": "match_parent"
|
||||
},
|
||||
"border": {
|
||||
"corner_radius": 16
|
||||
},
|
||||
"background": [
|
||||
{
|
||||
"type": "solid",
|
||||
"color": "#0000FF"
|
||||
}
|
||||
],
|
||||
"focus": {
|
||||
"background": [
|
||||
{
|
||||
"type": "solid",
|
||||
"color": "#ff5500"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"card": {
|
||||
"log_id": "tests",
|
||||
"variables": [
|
||||
{
|
||||
"name": "input_value_1",
|
||||
"type": "string",
|
||||
"value": "input view"
|
||||
},
|
||||
{
|
||||
"name": "timer_label",
|
||||
"type": "string",
|
||||
"value": "finished"
|
||||
}
|
||||
],
|
||||
"timers": [
|
||||
{
|
||||
"id": "clear_focus",
|
||||
"duration": 2000,
|
||||
"end_actions": [
|
||||
{
|
||||
"log_id": "clear focus",
|
||||
"typed": {
|
||||
"type": "clear_focus"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "div-action://set_variable?name=timer_label&value=finished",
|
||||
"log_id": "timer finished"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"states": [
|
||||
{
|
||||
"state_id": 0,
|
||||
"div": {
|
||||
"type": "container",
|
||||
"orientation": "vertical",
|
||||
"margins": {
|
||||
"top": 24,
|
||||
"bottom": 24
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"type": "container",
|
||||
"orientation": "horizontal",
|
||||
"margins": {
|
||||
"left": 16,
|
||||
"top": 16
|
||||
},
|
||||
"width": {
|
||||
"type": "wrap_content"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Timer for clear focus: ",
|
||||
"font_weight": "bold"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"text": "@{timer_label}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "input",
|
||||
"text_variable": "input_value_1",
|
||||
"type": "input",
|
||||
"width": {
|
||||
"type": "match_parent"
|
||||
},
|
||||
"height": {
|
||||
"type": "wrap_content"
|
||||
},
|
||||
"paddings": {
|
||||
"left": 16,
|
||||
"top": 16,
|
||||
"right": 16,
|
||||
"bottom": 16
|
||||
},
|
||||
"margins": {
|
||||
"left": 16,
|
||||
"top": 16,
|
||||
"right": 16,
|
||||
"bottom": 16
|
||||
},
|
||||
"border": {
|
||||
"corner_radius": 8,
|
||||
"stroke": {
|
||||
"color": "#0000FF"
|
||||
}
|
||||
},
|
||||
"focus": {
|
||||
"background": [
|
||||
{
|
||||
"type": "solid",
|
||||
"color": "#ff5500"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"text": "Focus input",
|
||||
"id": "button_1",
|
||||
"alignment_horizontal": "center",
|
||||
"width": {
|
||||
"type": "wrap_content"
|
||||
},
|
||||
"actions": [
|
||||
{
|
||||
"log_id": "focus_1",
|
||||
"typed": {
|
||||
"type": "focus_element",
|
||||
"element_id": "input"
|
||||
}
|
||||
},
|
||||
{
|
||||
"log_id": "Start timer",
|
||||
"url": "div-action://timer?id=clear_focus&action=start"
|
||||
},
|
||||
{
|
||||
"url": "div-action://set_variable?name=timer_label&value=started",
|
||||
"log_id": "timer started"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user