diff --git a/.mapping.json b/.mapping.json index 7bd6f393b..8c8a47eb2 100644 --- a/.mapping.json +++ b/.mapping.json @@ -557,7 +557,6 @@ "client/android/div-data/src/main/java/com/yandex/div/data/Variable.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/data/Variable.kt", "client/android/div-data/src/main/java/com/yandex/div/data/VariableDeclarationException.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/data/VariableDeclarationException.kt", "client/android/div-data/src/main/java/com/yandex/div/data/VariableMutationException.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/data/VariableMutationException.kt", - "client/android/div-data/src/main/java/com/yandex/div/internal/core/DivItemBuilderResult.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/internal/core/DivItemBuilderResult.kt", "client/android/div-data/src/main/java/com/yandex/div/util/DivDataUtils.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/util/DivDataUtils.kt", "client/android/div-data/src/test/java/com/yandex/div/data/MutableExpressionTest.kt":"divkit/public/client/android/div-data/src/test/java/com/yandex/div/data/MutableExpressionTest.kt", "client/android/div-data/src/test/java/com/yandex/div/data/VariableTest.kt":"divkit/public/client/android/div-data/src/test/java/com/yandex/div/data/VariableTest.kt", @@ -961,11 +960,9 @@ "client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariableController.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariablesParser.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariablesParser.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/GlobalVariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/GlobalVariableController.kt", - "client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/Observers.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/Observers.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/TwoWayVariableBinder.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/TwoWayVariableBinder.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt", - "client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableDeclarationNotifier.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableDeclarationNotifier.kt", "client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableSource.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableSource.kt", "client/android/div/src/main/java/com/yandex/div/core/extension/DivExtensionController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/extension/DivExtensionController.kt", @@ -1033,7 +1030,6 @@ "client/android/div/src/main/java/com/yandex/div/core/util/validator/ValidatorItemData.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/validator/ValidatorItemData.kt", "client/android/div/src/main/java/com/yandex/div/core/view2/AccessibilityDelegateWrapper.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/AccessibilityDelegateWrapper.kt", "client/android/div/src/main/java/com/yandex/div/core/view2/AccessibilityListDelegate.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/AccessibilityListDelegate.kt", - "client/android/div/src/main/java/com/yandex/div/core/view2/BindingContext.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/BindingContext.kt", "client/android/div/src/main/java/com/yandex/div/core/view2/CompositeLogId.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/CompositeLogId.kt", "client/android/div/src/main/java/com/yandex/div/core/view2/Div2Builder.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/Div2Builder.kt", "client/android/div/src/main/java/com/yandex/div/core/view2/Div2View.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/view2/Div2View.kt", @@ -1706,10 +1702,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -2016,9 +2008,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -2520,10 +2509,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -2830,9 +2815,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -3334,10 +3316,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -3644,9 +3622,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -4148,10 +4123,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -4458,9 +4429,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -4962,10 +4930,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -5272,9 +5236,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -5776,10 +5737,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -6086,9 +6043,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -6590,10 +6544,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -6901,9 +6851,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -7405,10 +7352,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -7716,9 +7659,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", @@ -8220,10 +8160,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step5.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step6.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/base-properties/step7.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step0.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step1.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/separators/step2.png", @@ -8530,9 +8466,6 @@ "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-between-separators.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation-with-wrap-content-constrained-children.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/horizontal-orientation.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png", - "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/known-match-parent-cross-axis.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-inside-wrap-content.png", "client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png":"divkit/public/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/match-parent-lesser-than-paddings.png", diff --git a/api_generator/api_generator/generators/kotlin/generator.py b/api_generator/api_generator/generators/kotlin/generator.py index b82dd729c..22282a947 100644 --- a/api_generator/api_generator/generators/kotlin/generator.py +++ b/api_generator/api_generator/generators/kotlin/generator.py @@ -16,6 +16,7 @@ from ...schema.modeling.entities import ( Entity, Object, ObjectFormat, + Array, ) from ...schema.modeling.text import Text, EMPTY @@ -58,24 +59,95 @@ class KotlinGenerator(Generator): result += ' }' result += EMPTY result += entity.value_resolving_declaration.indented(indent_width=4) + else: + prop_names = map(lambda prop_name: prop_name.declaration_name, entity.instance_properties_kotlin) - if not is_template: - additional_fields = entity.declare_additional_fields() - if additional_fields: - result += additional_fields + prop_filter = ['items'] + is_div_state = utils.capitalize_camel_case(entity.name) == 'DivState' - if not is_template: - result += entity.hash_declaration(self._generate_equality) + if is_div_state: + prop_filter.append('states') + + generate_properties = True if len(set(prop_filter).intersection(prop_names)) > 0 else False + + result += EMPTY + if generate_properties: + result += ' private var _propertiesHash: Int? = null ' + result += ' private var _hash: Int? = null ' + if generate_properties: + result += EMPTY + result += ' override fun propertiesHash(): Int {' + result += ' _propertiesHash?.let {' + result += ' return it' + result += ' }' + if len(entity.instance_properties_kotlin) > 1: + result += ' val propertiesHash = ' + result += self._generate_hash(list(filter(lambda it: it.declaration_name not in prop_filter, + entity.instance_properties_kotlin))).indented(indent_width=12) + else: + result += ' val propertiesHash = javaClass.hashCode()' + result += ' _propertiesHash = propertiesHash' + result += ' return propertiesHash' + result += ' }' + result += EMPTY + result += ' override fun hash(): Int {' + result += ' _hash?.let {' + result += ' return it' + result += ' }' + + if entity.instance_properties_kotlin: + result += ' val hash = ' + if generate_properties: + hash_text = Text() + hash_text += 'propertiesHash() +' + hash_text += self._generate_hash( + list(filter(lambda it: it.declaration_name in prop_filter, entity.instance_properties_kotlin))) + + result += hash_text.indented(indent_width=12) + else: + result += self._generate_hash(list(filter( + lambda it: it.declaration_name not in prop_filter, + entity.instance_properties_kotlin)) + ).indented(indent_width=12) + else: + result += ' val hash = javaClass.hashCode()' + + result += ' _hash = hash' + result += ' return hash' + result += ' }' + if self._generate_equality: + result += EMPTY + result += ' fun isHashCalculated() = _hash != null' if self.generate_serialization: result += EMPTY result += entity.serialization_declaration.indented(indent_width=4) - if not is_template: - result += entity.copy_declaration - if not is_template and self._generate_equality: - result += entity.equality_declaration + result += EMPTY + if entity.instance_properties: + result += ' override fun equals(other: Any?): Boolean {' + result += ' if (this === other) { return true }' + class_name = utils.capitalize_camel_case(entity.name) + result += f' if (other !is {class_name} || (this.isHashCalculated() && other.isHashCalculated()' + result += ' && this.hash() != other.hash())) {' + result += ' return false' + result += ' }' + result += EMPTY + for prop in entity.instance_properties_kotlin: + prefix = "return " if prop == entity.instance_properties_kotlin[0] else " " + postfix = "&&" if prop != entity.instance_properties_kotlin[-1] else "" + result += f' {prefix}this.{prop.declaration_name} == other.{prop.declaration_name} {postfix}' + result += ' }' + result += EMPTY + result += ' override fun hashCode() = hash()' + else: + result += self.__manual_equals_hash_code_declaration.indented(indent_width=4) + + if not is_template: + patch = entity.copy_with_new_properties_declaration + if patch: + result += patch static_declarations = entity.static_declarations(self.generate_serialization) if static_declarations.lines: @@ -95,6 +167,29 @@ class KotlinGenerator(Generator): return result + @staticmethod + def _generate_hash(props: List[KotlinProperty]) -> Text: + hash_text = Text() + for prop in props: + hash_type = 'hash()' if prop.use_custom_hash else 'hashCode()' + + prop_hash = '' + if prop.should_be_optional: + prop_hash += '(' + prop_hash += prop.declaration_name + if prop.should_be_optional: + prop_hash += '?' + prop_hash += '.' + if isinstance(prop.property_type, Array) and prop.use_custom_hash: + prop_hash += f'sumOf {{ it.{hash_type} }}' + else: + prop_hash += hash_type + if prop.should_be_optional: + prop_hash += ' ?: 0)' + prop_hash += " +" if prop != props[-1] else "" + hash_text += prop_hash + return hash_text + @staticmethod def __declaration_as_interface(entity: KotlinEntity) -> Text: result = Text(f'interface {utils.capitalize_camel_case(entity.name)} {{') @@ -103,9 +198,6 @@ class KotlinGenerator(Generator): in_interface=True, with_comma=False, with_default=False).indented(indent_width=4) - additional_fields = entity.declare_additional_fields() - if additional_fields: - result += additional_fields result += '}' return result @@ -171,6 +263,13 @@ class KotlinGenerator(Generator): return result + @property + def __manual_equals_hash_code_declaration(self) -> Text: + result = Text('override fun equals(other: Any?) = javaClass == other?.javaClass') + result += EMPTY + result += 'override fun hashCode() = javaClass.hashCode()' + return result + def _entity_enumeration_declaration(self, entity_enumeration: EntityEnumeration) -> Text: entity_enumeration: KotlinEntityEnumeration = cast(KotlinEntityEnumeration, entity_enumeration) entity_enumeration.__class__ = KotlinEntityEnumeration diff --git a/api_generator/api_generator/generators/kotlin/kotlin_entities.py b/api_generator/api_generator/generators/kotlin/kotlin_entities.py index f6a1833b3..6dbfe3037 100644 --- a/api_generator/api_generator/generators/kotlin/kotlin_entities.py +++ b/api_generator/api_generator/generators/kotlin/kotlin_entities.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import reduce import dataclasses -from typing import List, Optional, cast, Dict, Any +from typing import List, Optional, cast, Dict from ..base import declaration_comment from ...schema.modeling.entities import ( @@ -253,177 +253,50 @@ class KotlinEntity(Entity): return static_decl @property - def copy_declaration(self) -> Text: + def copy_with_new_properties_declaration(self) -> Optional[Text]: + generator_properties = self.generator_properties + if not generator_properties: + return None + + general_properties = generator_properties.general_properties + if not general_properties: + return None + + kotlin_generator_properties = general_properties.get('kotlin') + if not isinstance(kotlin_generator_properties, Dict): + return None + + new_properties = kotlin_generator_properties.get('properties_to_patch') + if not isinstance(new_properties, list): + return None + result = EMPTY - decl = ' fun copy(' + result += ' fun copyWithNewProperties(' method_params: List[str] = [] constructor_params: List[str] = [] + def append_arg(name: str): + constructor_params.append(f' {name},') + for p in sorted(filter(lambda prop: not isinstance(prop.property_type, StaticString), - self.properties_kotlin), key=lambda prop: prop.name): - property_name = p.declaration_name - property_class = p.type_declaration - method_params.append(f'\n {property_name}: {property_class} = this.{property_name},') - constructor_params.append(f'\n {property_name} = {property_name},') - - decl += ''.join(method_params) - if len(method_params) > 0: - decl += '\n ' - decl += f') = {utils.capitalize_camel_case(self.name)}(' - decl += ''.join(constructor_params) - if len(constructor_params) > 0: - decl += '\n ' - decl += ')' - result += decl - return result - - @property - def equality_declaration(self) -> Text: - result = EMPTY - if self.instance_properties: - result += ' override fun equals(other: Any?): Boolean {' - result += ' if (this === other) { return true }' - class_name = utils.capitalize_camel_case(self.name) - result += f' if (other !is {class_name} || (this.isHashCalculated() && other.isHashCalculated()' - result += ' && this.hash() != other.hash())) {' - result += ' return false' - result += ' }' - result += EMPTY - for prop in self.instance_properties_kotlin: - prefix = "return " if prop == self.instance_properties_kotlin[0] else " " - postfix = "&&" if prop != self.instance_properties_kotlin[-1] else "" - result += f' {prefix}this.{prop.declaration_name} == other.{prop.declaration_name} {postfix}' - result += ' }' - result += EMPTY - result += ' override fun hashCode() = hash()' - else: - result += self.__manual_equals_hash_code_declaration.indented(indent_width=4) - return result - - @property - def __manual_equals_hash_code_declaration(self) -> Text: - result = Text('override fun equals(other: Any?) = javaClass == other?.javaClass') - result += EMPTY - result += 'override fun hashCode() = javaClass.hashCode()' - return result - - def hash_declaration(self, with_calculation_flag: bool = False) -> Text: - prop_names = map(lambda prop_name: prop_name.declaration_name, self.instance_properties_kotlin) - - prop_filter = ['items'] - is_div_state = utils.capitalize_camel_case(self.name) == 'DivState' - - if is_div_state: - prop_filter.append('states') - - generate_properties = True if len(set(prop_filter).intersection(prop_names)) > 0 else False - - result = EMPTY - if generate_properties: - result += ' private var _propertiesHash: Int? = null ' - result += ' private var _hash: Int? = null ' - if generate_properties: - result += EMPTY - result += ' override fun propertiesHash(): Int {' - result += ' _propertiesHash?.let {' - result += ' return it' - result += ' }' - if len(self.instance_properties_kotlin) > 1: - result += ' val propertiesHash = ' - result += self.__generate_hash(list(filter(lambda it: it.declaration_name not in prop_filter, - self.instance_properties_kotlin))).indented(indent_width=12) - else: - result += ' val propertiesHash = javaClass.hashCode()' - result += ' _propertiesHash = propertiesHash' - result += ' return propertiesHash' - result += ' }' - result += EMPTY - result += ' override fun hash(): Int {' - result += ' _hash?.let {' - result += ' return it' - result += ' }' - - if self.instance_properties_kotlin: - result += ' val hash = ' - if generate_properties: - hash_text = Text() - hash_text += 'propertiesHash() +' - hash_text += self.__generate_hash( - list(filter(lambda it: it.declaration_name in prop_filter, self.instance_properties_kotlin))) - - result += hash_text.indented(indent_width=12) - else: - result += self.__generate_hash(list(filter( - lambda it: it.declaration_name not in prop_filter, - self.instance_properties_kotlin)) - ).indented(indent_width=12) - else: - result += ' val hash = javaClass.hashCode()' - - result += ' _hash = hash' - result += ' return hash' - result += ' }' - if with_calculation_flag: - result += EMPTY - result += ' fun isHashCalculated() = _hash != null' - return result - - @staticmethod - def __generate_hash(props: List[KotlinProperty]) -> Text: - hash_text = Text() - for prop in props: - hash_type = 'hash()' if prop.use_custom_hash else 'hashCode()' - - prop_hash = '' - if prop.should_be_optional: - prop_hash += '(' - prop_hash += prop.declaration_name - if prop.should_be_optional: - prop_hash += '?' - prop_hash += '.' - if isinstance(prop.property_type, Array) and prop.use_custom_hash: - prop_hash += f'sumOf {{ it.{hash_type} }}' - else: - prop_hash += hash_type - if prop.should_be_optional: - prop_hash += ' ?: 0)' - prop_hash += " +" if prop != props[-1] else "" - hash_text += prop_hash - return hash_text - - def declare_additional_fields(self) -> Optional[Text]: - if not isinstance(self.generator_properties, KotlinGeneratorProperties): - return None - - additional_fields = self.generator_properties.additional_fields - if not isinstance(additional_fields, list) or len(additional_fields) == 0: - return None - - result = EMPTY - for field in filter(lambda f: isinstance(f, Dict), additional_fields): - field_name = field.get('name') - field_type = field.get('type') - if field_name is None or len(field_name) == 0 or field_type is None or len(field_type) == 0: + self.properties), key=lambda prop: prop.name): + property_name = utils.lower_camel_case(p.name) + if p.name not in new_properties: + append_arg(property_name) continue - decl = f'var {field_name}: {field_type}' - field_override = field.get('protocol_name') - if field_override and len(field_override) != 0: - if field_override != self.name: - decl = f'override {decl}' - decl += self.__add_default_value_to_additional_field(field) - else: - decl += self.__add_default_value_to_additional_field(field) + item = p.property_type.property_type.object + item_class = utils.capitalize_camel_case(item.prefixed_declaration) + method_params.append(f' {property_name}: List<{item_class}>,') + constructor_params.append(f' {property_name},') - result += Text(decl).indented(indent_width=4) + result += '\n'.join(method_params) + result += f' ) = {utils.capitalize_camel_case(self.name)}(' + result += '\n'.join(constructor_params) + result += ' )' return result - @staticmethod - def __add_default_value_to_additional_field(field: Dict[str, Any]) -> str: - default_value = field.get("default_value") - return f' = {default_value}' if default_value else '' - class KotlinProperty(Property): @property @@ -740,9 +613,7 @@ class KotlinPropertyType(PropertyType): if len(values) != len(declarations): return None joined = ', '.join(declarations) - return 'listOf<' +\ - item_type.declaration(GenerationMode.NORMAL_WITHOUT_TEMPLATES, supports_expressions_flag) +\ - f'>({joined})' + return f'listOf<{item_type.declaration(GenerationMode.NORMAL_WITHOUT_TEMPLATES)}>({joined})' elif isinstance(self, Object): if self.object is None: return None diff --git a/api_generator/api_generator/schema/modeling/entities.py b/api_generator/api_generator/schema/modeling/entities.py index 8f289c422..d1e21ce0b 100644 --- a/api_generator/api_generator/schema/modeling/entities.py +++ b/api_generator/api_generator/schema/modeling/entities.py @@ -982,7 +982,6 @@ class KotlinGeneratorProperties(GeneratorProperties): ): super().__init__(general_properties, lang, mode) self.public_default_values: bool = specific_properties.get('public_default_values', False) - self.additional_fields: list[dict] = specific_properties.get('additional_fields') class DocumentationGeneratorProperties(GeneratorProperties): diff --git a/api_generator/tests/references/kotlin/EntityWithArray.kt b/api_generator/tests/references/kotlin/EntityWithArray.kt index 6fdedea3a..88fca46dd 100644 --- a/api_generator/tests/references/kotlin/EntityWithArray.kt +++ b/api_generator/tests/references/kotlin/EntityWithArray.kt @@ -40,10 +40,10 @@ class EntityWithArray( return json } - fun copy( - array: List = this.array, + fun copyWithNewProperties( + array: List, ) = EntityWithArray( - array = array, + array, ) companion object { diff --git a/api_generator/tests/references/kotlin/EntityWithArrayOfEnums.kt b/api_generator/tests/references/kotlin/EntityWithArrayOfEnums.kt index c6373c350..9fdce23d0 100644 --- a/api_generator/tests/references/kotlin/EntityWithArrayOfEnums.kt +++ b/api_generator/tests/references/kotlin/EntityWithArrayOfEnums.kt @@ -51,10 +51,10 @@ class EntityWithArrayOfEnums( return json } - fun copy( - items: List = this.items, + fun copyWithNewProperties( + items: List, ) = EntityWithArrayOfEnums( - items = items, + items, ) companion object { diff --git a/api_generator/tests/references/kotlin/EntityWithArrayOfExpressions.kt b/api_generator/tests/references/kotlin/EntityWithArrayOfExpressions.kt index 434727fef..828e6a008 100644 --- a/api_generator/tests/references/kotlin/EntityWithArrayOfExpressions.kt +++ b/api_generator/tests/references/kotlin/EntityWithArrayOfExpressions.kt @@ -51,12 +51,6 @@ class EntityWithArrayOfExpressions( return json } - fun copy( - items: ExpressionList = this.items, - ) = EntityWithArrayOfExpressions( - items = items, - ) - companion object { const val TYPE = "entity_with_array_of_expressions" diff --git a/api_generator/tests/references/kotlin/EntityWithArrayOfNestedItems.kt b/api_generator/tests/references/kotlin/EntityWithArrayOfNestedItems.kt index c9e99da70..90166b19e 100644 --- a/api_generator/tests/references/kotlin/EntityWithArrayOfNestedItems.kt +++ b/api_generator/tests/references/kotlin/EntityWithArrayOfNestedItems.kt @@ -51,10 +51,10 @@ class EntityWithArrayOfNestedItems( return json } - fun copy( - items: List = this.items, + fun copyWithNewProperties( + items: List, ) = EntityWithArrayOfNestedItems( - items = items, + items, ) companion object { @@ -101,14 +101,6 @@ class EntityWithArrayOfNestedItems( return json } - fun copy( - entity: Entity = this.entity, - property: Expression = this.property, - ) = Item( - entity = entity, - property = property, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/kotlin/EntityWithArrayWithTransform.kt b/api_generator/tests/references/kotlin/EntityWithArrayWithTransform.kt index eeb1ccd7a..3b356ee40 100644 --- a/api_generator/tests/references/kotlin/EntityWithArrayWithTransform.kt +++ b/api_generator/tests/references/kotlin/EntityWithArrayWithTransform.kt @@ -40,12 +40,6 @@ class EntityWithArrayWithTransform( return json } - fun copy( - array: ExpressionList = this.array, - ) = EntityWithArrayWithTransform( - array = array, - ) - companion object { const val TYPE = "entity_with_array_with_transform" diff --git a/api_generator/tests/references/kotlin/EntityWithComplexProperty.kt b/api_generator/tests/references/kotlin/EntityWithComplexProperty.kt index 5f2077f35..eda3ef8b9 100644 --- a/api_generator/tests/references/kotlin/EntityWithComplexProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithComplexProperty.kt @@ -40,12 +40,6 @@ class EntityWithComplexProperty( return json } - fun copy( - property: Property = this.property, - ) = EntityWithComplexProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_complex_property" @@ -85,12 +79,6 @@ class EntityWithComplexProperty( return json } - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/kotlin/EntityWithComplexPropertyWithDefaultValue.kt b/api_generator/tests/references/kotlin/EntityWithComplexPropertyWithDefaultValue.kt index f2948b8a0..95c1282c0 100644 --- a/api_generator/tests/references/kotlin/EntityWithComplexPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/kotlin/EntityWithComplexPropertyWithDefaultValue.kt @@ -40,12 +40,6 @@ class EntityWithComplexPropertyWithDefaultValue( return json } - fun copy( - property: Property = this.property, - ) = EntityWithComplexPropertyWithDefaultValue( - property = property, - ) - companion object { const val TYPE = "entity_with_complex_property_with_default_value" @@ -87,12 +81,6 @@ class EntityWithComplexPropertyWithDefaultValue( return json } - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/kotlin/EntityWithEntityProperty.kt b/api_generator/tests/references/kotlin/EntityWithEntityProperty.kt index 95b4035d6..bac65bd08 100644 --- a/api_generator/tests/references/kotlin/EntityWithEntityProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithEntityProperty.kt @@ -40,12 +40,6 @@ class EntityWithEntityProperty( return json } - fun copy( - entity: Entity = this.entity, - ) = EntityWithEntityProperty( - entity = entity, - ) - companion object { const val TYPE = "entity_with_entity_property" diff --git a/api_generator/tests/references/kotlin/EntityWithJsonProperty.kt b/api_generator/tests/references/kotlin/EntityWithJsonProperty.kt index d92c532e5..886f6f5c0 100644 --- a/api_generator/tests/references/kotlin/EntityWithJsonProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithJsonProperty.kt @@ -40,12 +40,6 @@ class EntityWithJsonProperty( return json } - fun copy( - jsonProperty: JSONObject = this.jsonProperty, - ) = EntityWithJsonProperty( - jsonProperty = jsonProperty, - ) - companion object { const val TYPE = "entity_with_json_property" diff --git a/api_generator/tests/references/kotlin/EntityWithOptionalComplexProperty.kt b/api_generator/tests/references/kotlin/EntityWithOptionalComplexProperty.kt index eaa2d78be..6696d7136 100644 --- a/api_generator/tests/references/kotlin/EntityWithOptionalComplexProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithOptionalComplexProperty.kt @@ -40,12 +40,6 @@ class EntityWithOptionalComplexProperty( return json } - fun copy( - property: Property? = this.property, - ) = EntityWithOptionalComplexProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_complex_property" @@ -85,12 +79,6 @@ class EntityWithOptionalComplexProperty( return json } - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/kotlin/EntityWithOptionalProperty.kt b/api_generator/tests/references/kotlin/EntityWithOptionalProperty.kt index a6804e395..cd58245ff 100644 --- a/api_generator/tests/references/kotlin/EntityWithOptionalProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithOptionalProperty.kt @@ -40,12 +40,6 @@ class EntityWithOptionalProperty( return json } - fun copy( - property: Expression? = this.property, - ) = EntityWithOptionalProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_property" diff --git a/api_generator/tests/references/kotlin/EntityWithOptionalStringEnumProperty.kt b/api_generator/tests/references/kotlin/EntityWithOptionalStringEnumProperty.kt index c6c441805..5794e138f 100644 --- a/api_generator/tests/references/kotlin/EntityWithOptionalStringEnumProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithOptionalStringEnumProperty.kt @@ -40,12 +40,6 @@ class EntityWithOptionalStringEnumProperty( return json } - fun copy( - property: Expression? = this.property, - ) = EntityWithOptionalStringEnumProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_string_enum_property" diff --git a/api_generator/tests/references/kotlin/EntityWithPropertyWithDefaultValue.kt b/api_generator/tests/references/kotlin/EntityWithPropertyWithDefaultValue.kt index 87de1e658..3df6481e1 100644 --- a/api_generator/tests/references/kotlin/EntityWithPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/kotlin/EntityWithPropertyWithDefaultValue.kt @@ -46,16 +46,6 @@ class EntityWithPropertyWithDefaultValue( return json } - fun copy( - int: Expression = this.int, - nested: Nested? = this.nested, - url: Expression = this.url, - ) = EntityWithPropertyWithDefaultValue( - int = int, - nested = nested, - url = url, - ) - companion object { const val TYPE = "entity_with_property_with_default_value" @@ -109,16 +99,6 @@ class EntityWithPropertyWithDefaultValue( return json } - fun copy( - int: Expression = this.int, - nonOptional: Expression = this.nonOptional, - url: Expression = this.url, - ) = Nested( - int = int, - nonOptional = nonOptional, - url = url, - ) - companion object { private val INT_DEFAULT_VALUE = Expression.constant(0L) private val URL_DEFAULT_VALUE = Expression.constant(Uri.parse("https://yandex.ru")) diff --git a/api_generator/tests/references/kotlin/EntityWithRawArray.kt b/api_generator/tests/references/kotlin/EntityWithRawArray.kt index 79967c57d..fdce48b30 100644 --- a/api_generator/tests/references/kotlin/EntityWithRawArray.kt +++ b/api_generator/tests/references/kotlin/EntityWithRawArray.kt @@ -40,12 +40,6 @@ class EntityWithRawArray( return json } - fun copy( - array: Expression = this.array, - ) = EntityWithRawArray( - array = array, - ) - companion object { const val TYPE = "entity_with_raw_array" diff --git a/api_generator/tests/references/kotlin/EntityWithRequiredProperty.kt b/api_generator/tests/references/kotlin/EntityWithRequiredProperty.kt index be407886b..309004140 100644 --- a/api_generator/tests/references/kotlin/EntityWithRequiredProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithRequiredProperty.kt @@ -40,12 +40,6 @@ class EntityWithRequiredProperty( return json } - fun copy( - property: Expression = this.property, - ) = EntityWithRequiredProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_required_property" diff --git a/api_generator/tests/references/kotlin/EntityWithSimpleProperties.kt b/api_generator/tests/references/kotlin/EntityWithSimpleProperties.kt index c39c40891..60d2a9ac0 100644 --- a/api_generator/tests/references/kotlin/EntityWithSimpleProperties.kt +++ b/api_generator/tests/references/kotlin/EntityWithSimpleProperties.kt @@ -64,28 +64,6 @@ class EntityWithSimpleProperties( return json } - fun copy( - boolean: Expression? = this.boolean, - booleanInt: Expression? = this.booleanInt, - color: Expression? = this.color, - double: Expression? = this.double, - id: Long = this.id, - integer: Expression = this.integer, - positiveInteger: Expression? = this.positiveInteger, - string: Expression? = this.string, - url: Expression? = this.url, - ) = EntityWithSimpleProperties( - boolean = boolean, - booleanInt = booleanInt, - color = color, - double = double, - id = id, - integer = integer, - positiveInteger = positiveInteger, - string = string, - url = url, - ) - companion object { const val TYPE = "entity_with_simple_properties" diff --git a/api_generator/tests/references/kotlin/EntityWithStringArrayProperty.kt b/api_generator/tests/references/kotlin/EntityWithStringArrayProperty.kt index 847ce7ace..109f19701 100644 --- a/api_generator/tests/references/kotlin/EntityWithStringArrayProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithStringArrayProperty.kt @@ -40,12 +40,6 @@ class EntityWithStringArrayProperty( return json } - fun copy( - array: ExpressionList = this.array, - ) = EntityWithStringArrayProperty( - array = array, - ) - companion object { const val TYPE = "entity_with_string_array_property" diff --git a/api_generator/tests/references/kotlin/EntityWithStringEnumProperty.kt b/api_generator/tests/references/kotlin/EntityWithStringEnumProperty.kt index b9ec3a85d..203db5f27 100644 --- a/api_generator/tests/references/kotlin/EntityWithStringEnumProperty.kt +++ b/api_generator/tests/references/kotlin/EntityWithStringEnumProperty.kt @@ -40,12 +40,6 @@ class EntityWithStringEnumProperty( return json } - fun copy( - property: Expression = this.property, - ) = EntityWithStringEnumProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_string_enum_property" diff --git a/api_generator/tests/references/kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt b/api_generator/tests/references/kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt index b996e3075..dda9f97b8 100644 --- a/api_generator/tests/references/kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt @@ -40,12 +40,6 @@ class EntityWithStringEnumPropertyWithDefaultValue( return json } - fun copy( - value: Expression = this.value, - ) = EntityWithStringEnumPropertyWithDefaultValue( - value = value, - ) - companion object { const val TYPE = "entity_with_string_enum_property_with_default_value" diff --git a/api_generator/tests/references/kotlin/EntityWithoutProperties.kt b/api_generator/tests/references/kotlin/EntityWithoutProperties.kt index 9af0277e7..5751afd24 100644 --- a/api_generator/tests/references/kotlin/EntityWithoutProperties.kt +++ b/api_generator/tests/references/kotlin/EntityWithoutProperties.kt @@ -36,8 +36,6 @@ class EntityWithoutProperties() : JSONSerializable, Hashable { return json } - fun copy() = EntityWithoutProperties() - companion object { const val TYPE = "entity_without_properties" diff --git a/api_generator/tests/references/kotlin/WithDefault.kt b/api_generator/tests/references/kotlin/WithDefault.kt index 2a7950738..a8c42016e 100644 --- a/api_generator/tests/references/kotlin/WithDefault.kt +++ b/api_generator/tests/references/kotlin/WithDefault.kt @@ -36,8 +36,6 @@ class WithDefault() : JSONSerializable, Hashable { return json } - fun copy() = WithDefault() - companion object { const val TYPE = "default" diff --git a/api_generator/tests/references/kotlin/WithoutDefault.kt b/api_generator/tests/references/kotlin/WithoutDefault.kt index 454cdfad3..a24dbbc8d 100644 --- a/api_generator/tests/references/kotlin/WithoutDefault.kt +++ b/api_generator/tests/references/kotlin/WithoutDefault.kt @@ -36,8 +36,6 @@ class WithoutDefault() : JSONSerializable, Hashable { return json } - fun copy() = WithoutDefault() - companion object { const val TYPE = "non_default" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithArray.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithArray.kt index 6fdedea3a..88fca46dd 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithArray.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithArray.kt @@ -40,10 +40,10 @@ class EntityWithArray( return json } - fun copy( - array: List = this.array, + fun copyWithNewProperties( + array: List, ) = EntityWithArray( - array = array, + array, ) companion object { diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfEnums.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfEnums.kt index c6373c350..9fdce23d0 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfEnums.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfEnums.kt @@ -51,10 +51,10 @@ class EntityWithArrayOfEnums( return json } - fun copy( - items: List = this.items, + fun copyWithNewProperties( + items: List, ) = EntityWithArrayOfEnums( - items = items, + items, ) companion object { diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfExpressions.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfExpressions.kt index 434727fef..828e6a008 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfExpressions.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfExpressions.kt @@ -51,12 +51,6 @@ class EntityWithArrayOfExpressions( return json } - fun copy( - items: ExpressionList = this.items, - ) = EntityWithArrayOfExpressions( - items = items, - ) - companion object { const val TYPE = "entity_with_array_of_expressions" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfNestedItems.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfNestedItems.kt index c9e99da70..90166b19e 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfNestedItems.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayOfNestedItems.kt @@ -51,10 +51,10 @@ class EntityWithArrayOfNestedItems( return json } - fun copy( - items: List = this.items, + fun copyWithNewProperties( + items: List, ) = EntityWithArrayOfNestedItems( - items = items, + items, ) companion object { @@ -101,14 +101,6 @@ class EntityWithArrayOfNestedItems( return json } - fun copy( - entity: Entity = this.entity, - property: Expression = this.property, - ) = Item( - entity = entity, - property = property, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayWithTransform.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayWithTransform.kt index eeb1ccd7a..3b356ee40 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithArrayWithTransform.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithArrayWithTransform.kt @@ -40,12 +40,6 @@ class EntityWithArrayWithTransform( return json } - fun copy( - array: ExpressionList = this.array, - ) = EntityWithArrayWithTransform( - array = array, - ) - companion object { const val TYPE = "entity_with_array_with_transform" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithComplexProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithComplexProperty.kt index 5f2077f35..eda3ef8b9 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithComplexProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithComplexProperty.kt @@ -40,12 +40,6 @@ class EntityWithComplexProperty( return json } - fun copy( - property: Property = this.property, - ) = EntityWithComplexProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_complex_property" @@ -85,12 +79,6 @@ class EntityWithComplexProperty( return json } - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithComplexPropertyWithDefaultValue.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithComplexPropertyWithDefaultValue.kt index f2948b8a0..95c1282c0 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithComplexPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithComplexPropertyWithDefaultValue.kt @@ -40,12 +40,6 @@ class EntityWithComplexPropertyWithDefaultValue( return json } - fun copy( - property: Property = this.property, - ) = EntityWithComplexPropertyWithDefaultValue( - property = property, - ) - companion object { const val TYPE = "entity_with_complex_property_with_default_value" @@ -87,12 +81,6 @@ class EntityWithComplexPropertyWithDefaultValue( return json } - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithEntityProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithEntityProperty.kt index 95b4035d6..bac65bd08 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithEntityProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithEntityProperty.kt @@ -40,12 +40,6 @@ class EntityWithEntityProperty( return json } - fun copy( - entity: Entity = this.entity, - ) = EntityWithEntityProperty( - entity = entity, - ) - companion object { const val TYPE = "entity_with_entity_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithJsonProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithJsonProperty.kt index d92c532e5..886f6f5c0 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithJsonProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithJsonProperty.kt @@ -40,12 +40,6 @@ class EntityWithJsonProperty( return json } - fun copy( - jsonProperty: JSONObject = this.jsonProperty, - ) = EntityWithJsonProperty( - jsonProperty = jsonProperty, - ) - companion object { const val TYPE = "entity_with_json_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalComplexProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalComplexProperty.kt index eaa2d78be..6696d7136 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalComplexProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalComplexProperty.kt @@ -40,12 +40,6 @@ class EntityWithOptionalComplexProperty( return json } - fun copy( - property: Property? = this.property, - ) = EntityWithOptionalComplexProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_complex_property" @@ -85,12 +79,6 @@ class EntityWithOptionalComplexProperty( return json } - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) - companion object { @JvmStatic @JvmName("fromJson") diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalProperty.kt index a6804e395..cd58245ff 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalProperty.kt @@ -40,12 +40,6 @@ class EntityWithOptionalProperty( return json } - fun copy( - property: Expression? = this.property, - ) = EntityWithOptionalProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalStringEnumProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalStringEnumProperty.kt index c6c441805..5794e138f 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalStringEnumProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithOptionalStringEnumProperty.kt @@ -40,12 +40,6 @@ class EntityWithOptionalStringEnumProperty( return json } - fun copy( - property: Expression? = this.property, - ) = EntityWithOptionalStringEnumProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_string_enum_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithPropertyWithDefaultValue.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithPropertyWithDefaultValue.kt index 87de1e658..3df6481e1 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithPropertyWithDefaultValue.kt @@ -46,16 +46,6 @@ class EntityWithPropertyWithDefaultValue( return json } - fun copy( - int: Expression = this.int, - nested: Nested? = this.nested, - url: Expression = this.url, - ) = EntityWithPropertyWithDefaultValue( - int = int, - nested = nested, - url = url, - ) - companion object { const val TYPE = "entity_with_property_with_default_value" @@ -109,16 +99,6 @@ class EntityWithPropertyWithDefaultValue( return json } - fun copy( - int: Expression = this.int, - nonOptional: Expression = this.nonOptional, - url: Expression = this.url, - ) = Nested( - int = int, - nonOptional = nonOptional, - url = url, - ) - companion object { private val INT_DEFAULT_VALUE = Expression.constant(0L) private val URL_DEFAULT_VALUE = Expression.constant(Uri.parse("https://yandex.ru")) diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithRawArray.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithRawArray.kt index 79967c57d..fdce48b30 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithRawArray.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithRawArray.kt @@ -40,12 +40,6 @@ class EntityWithRawArray( return json } - fun copy( - array: Expression = this.array, - ) = EntityWithRawArray( - array = array, - ) - companion object { const val TYPE = "entity_with_raw_array" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithRequiredProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithRequiredProperty.kt index be407886b..309004140 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithRequiredProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithRequiredProperty.kt @@ -40,12 +40,6 @@ class EntityWithRequiredProperty( return json } - fun copy( - property: Expression = this.property, - ) = EntityWithRequiredProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_required_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithSimpleProperties.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithSimpleProperties.kt index c39c40891..60d2a9ac0 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithSimpleProperties.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithSimpleProperties.kt @@ -64,28 +64,6 @@ class EntityWithSimpleProperties( return json } - fun copy( - boolean: Expression? = this.boolean, - booleanInt: Expression? = this.booleanInt, - color: Expression? = this.color, - double: Expression? = this.double, - id: Long = this.id, - integer: Expression = this.integer, - positiveInteger: Expression? = this.positiveInteger, - string: Expression? = this.string, - url: Expression? = this.url, - ) = EntityWithSimpleProperties( - boolean = boolean, - booleanInt = booleanInt, - color = color, - double = double, - id = id, - integer = integer, - positiveInteger = positiveInteger, - string = string, - url = url, - ) - companion object { const val TYPE = "entity_with_simple_properties" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithStringArrayProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithStringArrayProperty.kt index 847ce7ace..109f19701 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithStringArrayProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithStringArrayProperty.kt @@ -40,12 +40,6 @@ class EntityWithStringArrayProperty( return json } - fun copy( - array: ExpressionList = this.array, - ) = EntityWithStringArrayProperty( - array = array, - ) - companion object { const val TYPE = "entity_with_string_array_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumProperty.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumProperty.kt index b9ec3a85d..203db5f27 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumProperty.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumProperty.kt @@ -40,12 +40,6 @@ class EntityWithStringEnumProperty( return json } - fun copy( - property: Expression = this.property, - ) = EntityWithStringEnumProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_string_enum_property" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt index b996e3075..dda9f97b8 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt @@ -40,12 +40,6 @@ class EntityWithStringEnumPropertyWithDefaultValue( return json } - fun copy( - value: Expression = this.value, - ) = EntityWithStringEnumPropertyWithDefaultValue( - value = value, - ) - companion object { const val TYPE = "entity_with_string_enum_property_with_default_value" diff --git a/api_generator/tests/references/not_templates_kotlin/EntityWithoutProperties.kt b/api_generator/tests/references/not_templates_kotlin/EntityWithoutProperties.kt index 9af0277e7..5751afd24 100644 --- a/api_generator/tests/references/not_templates_kotlin/EntityWithoutProperties.kt +++ b/api_generator/tests/references/not_templates_kotlin/EntityWithoutProperties.kt @@ -36,8 +36,6 @@ class EntityWithoutProperties() : JSONSerializable, Hashable { return json } - fun copy() = EntityWithoutProperties() - companion object { const val TYPE = "entity_without_properties" diff --git a/api_generator/tests/references/not_templates_kotlin/WithDefault.kt b/api_generator/tests/references/not_templates_kotlin/WithDefault.kt index 2a7950738..a8c42016e 100644 --- a/api_generator/tests/references/not_templates_kotlin/WithDefault.kt +++ b/api_generator/tests/references/not_templates_kotlin/WithDefault.kt @@ -36,8 +36,6 @@ class WithDefault() : JSONSerializable, Hashable { return json } - fun copy() = WithDefault() - companion object { const val TYPE = "default" diff --git a/api_generator/tests/references/not_templates_kotlin/WithoutDefault.kt b/api_generator/tests/references/not_templates_kotlin/WithoutDefault.kt index 454cdfad3..a24dbbc8d 100644 --- a/api_generator/tests/references/not_templates_kotlin/WithoutDefault.kt +++ b/api_generator/tests/references/not_templates_kotlin/WithoutDefault.kt @@ -36,8 +36,6 @@ class WithoutDefault() : JSONSerializable, Hashable { return json } - fun copy() = WithoutDefault() - companion object { const val TYPE = "non_default" diff --git a/api_generator/tests/references/reference_clean_unused_definitions.json b/api_generator/tests/references/reference_clean_unused_definitions.json index 8b21f143e..6c333d874 100644 --- a/api_generator/tests/references/reference_clean_unused_definitions.json +++ b/api_generator/tests/references/reference_clean_unused_definitions.json @@ -162,6 +162,13 @@ "ios", "web" ], + "codegen": { + "kotlin": { + "properties_to_patch": [ + "array" + ] + } + }, "properties": { "type": { "type": "string", @@ -195,6 +202,13 @@ { "entity_with_array_of_enums.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "properties": { "type": { "type": "string", @@ -247,6 +261,13 @@ { "entity_with_array_of_nested_items.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "definitions": {}, "properties": { "type": { diff --git a/api_generator/tests/references/reference_merge_allOfs.json b/api_generator/tests/references/reference_merge_allOfs.json index e0e24bcc8..a3b190761 100644 --- a/api_generator/tests/references/reference_merge_allOfs.json +++ b/api_generator/tests/references/reference_merge_allOfs.json @@ -105,6 +105,13 @@ "ios", "web" ], + "codegen": { + "kotlin": { + "properties_to_patch": [ + "array" + ] + } + }, "properties": { "type": { "type": "string", @@ -135,6 +142,13 @@ { "entity_with_array_of_enums.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "properties": { "type": { "type": "string", @@ -187,6 +201,13 @@ { "entity_with_array_of_nested_items.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "definitions": { "item": { "type": "object", diff --git a/api_generator/tests/references/reference_resolve_references.json b/api_generator/tests/references/reference_resolve_references.json index 9f0769f2c..0ddcc862b 100644 --- a/api_generator/tests/references/reference_resolve_references.json +++ b/api_generator/tests/references/reference_resolve_references.json @@ -162,6 +162,13 @@ "ios", "web" ], + "codegen": { + "kotlin": { + "properties_to_patch": [ + "array" + ] + } + }, "properties": { "type": { "type": "string", @@ -195,6 +202,13 @@ { "entity_with_array_of_enums.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "properties": { "type": { "type": "string", @@ -247,6 +261,13 @@ { "entity_with_array_of_nested_items.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "definitions": { "item": { "type": "object", diff --git a/api_generator/tests/references/reference_resolve_structure.json b/api_generator/tests/references/reference_resolve_structure.json index e0e24bcc8..a3b190761 100644 --- a/api_generator/tests/references/reference_resolve_structure.json +++ b/api_generator/tests/references/reference_resolve_structure.json @@ -105,6 +105,13 @@ "ios", "web" ], + "codegen": { + "kotlin": { + "properties_to_patch": [ + "array" + ] + } + }, "properties": { "type": { "type": "string", @@ -135,6 +142,13 @@ { "entity_with_array_of_enums.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "properties": { "type": { "type": "string", @@ -187,6 +201,13 @@ { "entity_with_array_of_nested_items.json": { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "definitions": { "item": { "type": "object", diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithArray.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithArray.kt index 27ddb5319..711d3dd49 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithArray.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithArray.kt @@ -20,10 +20,10 @@ class EntityWithArray( return hash } - fun copy( - array: List = this.array, + fun copyWithNewProperties( + array: List, ) = EntityWithArray( - array = array, + array, ) companion object { diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfEnums.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfEnums.kt index 9b518f1bf..71cc9741a 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfEnums.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfEnums.kt @@ -31,10 +31,10 @@ class EntityWithArrayOfEnums( return hash } - fun copy( - items: List = this.items, + fun copyWithNewProperties( + items: List, ) = EntityWithArrayOfEnums( - items = items, + items, ) companion object { diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfExpressions.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfExpressions.kt index 7aac543b4..1e39762ab 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfExpressions.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfExpressions.kt @@ -31,12 +31,6 @@ class EntityWithArrayOfExpressions( return hash } - fun copy( - items: ExpressionList = this.items, - ) = EntityWithArrayOfExpressions( - items = items, - ) - companion object { const val TYPE = "entity_with_array_of_expressions" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfNestedItems.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfNestedItems.kt index a171dab92..c69e49ab6 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfNestedItems.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayOfNestedItems.kt @@ -31,10 +31,10 @@ class EntityWithArrayOfNestedItems( return hash } - fun copy( - items: List = this.items, + fun copyWithNewProperties( + items: List, ) = EntityWithArrayOfNestedItems( - items = items, + items, ) companion object { @@ -61,13 +61,5 @@ class EntityWithArrayOfNestedItems( _hash = hash return hash } - - fun copy( - entity: Entity = this.entity, - property: Expression = this.property, - ) = Item( - entity = entity, - property = property, - ) } } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayWithTransform.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayWithTransform.kt index e90a2468b..557ed8233 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithArrayWithTransform.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithArrayWithTransform.kt @@ -20,12 +20,6 @@ class EntityWithArrayWithTransform( return hash } - fun copy( - array: ExpressionList = this.array, - ) = EntityWithArrayWithTransform( - array = array, - ) - companion object { const val TYPE = "entity_with_array_with_transform" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithComplexProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithComplexProperty.kt index dc8e479e2..f7aca653d 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithComplexProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithComplexProperty.kt @@ -20,12 +20,6 @@ class EntityWithComplexProperty( return hash } - fun copy( - property: Property = this.property, - ) = EntityWithComplexProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_complex_property" } @@ -46,11 +40,5 @@ class EntityWithComplexProperty( _hash = hash return hash } - - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) } } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithComplexPropertyWithDefaultValue.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithComplexPropertyWithDefaultValue.kt index 56f3aa1b1..395286f3f 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithComplexPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithComplexPropertyWithDefaultValue.kt @@ -20,12 +20,6 @@ class EntityWithComplexPropertyWithDefaultValue( return hash } - fun copy( - property: Property = this.property, - ) = EntityWithComplexPropertyWithDefaultValue( - property = property, - ) - companion object { const val TYPE = "entity_with_complex_property_with_default_value" @@ -48,11 +42,5 @@ class EntityWithComplexPropertyWithDefaultValue( _hash = hash return hash } - - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) } } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithEntityProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithEntityProperty.kt index 5937af481..68edd043b 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithEntityProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithEntityProperty.kt @@ -20,12 +20,6 @@ class EntityWithEntityProperty( return hash } - fun copy( - entity: Entity = this.entity, - ) = EntityWithEntityProperty( - entity = entity, - ) - companion object { const val TYPE = "entity_with_entity_property" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithJsonProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithJsonProperty.kt index 882d58416..ceaf61f90 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithJsonProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithJsonProperty.kt @@ -20,12 +20,6 @@ class EntityWithJsonProperty( return hash } - fun copy( - jsonProperty: JSONObject = this.jsonProperty, - ) = EntityWithJsonProperty( - jsonProperty = jsonProperty, - ) - companion object { const val TYPE = "entity_with_json_property" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalComplexProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalComplexProperty.kt index 731e490d3..2b327e686 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalComplexProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalComplexProperty.kt @@ -20,12 +20,6 @@ class EntityWithOptionalComplexProperty( return hash } - fun copy( - property: Property? = this.property, - ) = EntityWithOptionalComplexProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_complex_property" } @@ -46,11 +40,5 @@ class EntityWithOptionalComplexProperty( _hash = hash return hash } - - fun copy( - value: Expression = this.value, - ) = Property( - value = value, - ) } } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalProperty.kt index 79114aaa3..070888e1d 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalProperty.kt @@ -20,12 +20,6 @@ class EntityWithOptionalProperty( return hash } - fun copy( - property: Expression? = this.property, - ) = EntityWithOptionalProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_property" } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalStringEnumProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalStringEnumProperty.kt index b18fe36ea..b5ddb6ac4 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalStringEnumProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithOptionalStringEnumProperty.kt @@ -20,12 +20,6 @@ class EntityWithOptionalStringEnumProperty( return hash } - fun copy( - property: Expression? = this.property, - ) = EntityWithOptionalStringEnumProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_optional_string_enum_property" } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithPropertyWithDefaultValue.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithPropertyWithDefaultValue.kt index edd875b5b..76a9d3cc1 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithPropertyWithDefaultValue.kt @@ -24,16 +24,6 @@ class EntityWithPropertyWithDefaultValue( return hash } - fun copy( - int: Expression = this.int, - nested: Nested? = this.nested, - url: Expression = this.url, - ) = EntityWithPropertyWithDefaultValue( - int = int, - nested = nested, - url = url, - ) - companion object { const val TYPE = "entity_with_property_with_default_value" @@ -65,16 +55,6 @@ class EntityWithPropertyWithDefaultValue( return hash } - fun copy( - int: Expression = this.int, - nonOptional: Expression = this.nonOptional, - url: Expression = this.url, - ) = Nested( - int = int, - nonOptional = nonOptional, - url = url, - ) - companion object { private val INT_DEFAULT_VALUE = Expression.constant(0L) private val URL_DEFAULT_VALUE = Expression.constant(Uri.parse("https://yandex.ru")) diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithRawArray.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithRawArray.kt index 6cdbef757..2b2cb6ea1 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithRawArray.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithRawArray.kt @@ -20,12 +20,6 @@ class EntityWithRawArray( return hash } - fun copy( - array: Expression = this.array, - ) = EntityWithRawArray( - array = array, - ) - companion object { const val TYPE = "entity_with_raw_array" } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithRequiredProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithRequiredProperty.kt index e94c2d8dc..398c708d1 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithRequiredProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithRequiredProperty.kt @@ -20,12 +20,6 @@ class EntityWithRequiredProperty( return hash } - fun copy( - property: Expression = this.property, - ) = EntityWithRequiredProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_required_property" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithSimpleProperties.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithSimpleProperties.kt index 8de679948..1840b606b 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithSimpleProperties.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithSimpleProperties.kt @@ -36,28 +36,6 @@ class EntityWithSimpleProperties( return hash } - fun copy( - boolean: Expression? = this.boolean, - booleanInt: Expression? = this.booleanInt, - color: Expression? = this.color, - double: Expression? = this.double, - id: Long = this.id, - integer: Expression = this.integer, - positiveInteger: Expression? = this.positiveInteger, - string: Expression? = this.string, - url: Expression? = this.url, - ) = EntityWithSimpleProperties( - boolean = boolean, - booleanInt = booleanInt, - color = color, - double = double, - id = id, - integer = integer, - positiveInteger = positiveInteger, - string = string, - url = url, - ) - companion object { const val TYPE = "entity_with_simple_properties" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithStringArrayProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithStringArrayProperty.kt index c433b2ddf..19b49702d 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithStringArrayProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithStringArrayProperty.kt @@ -20,12 +20,6 @@ class EntityWithStringArrayProperty( return hash } - fun copy( - array: ExpressionList = this.array, - ) = EntityWithStringArrayProperty( - array = array, - ) - companion object { const val TYPE = "entity_with_string_array_property" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumProperty.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumProperty.kt index 99babbb34..8e4afbaac 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumProperty.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumProperty.kt @@ -20,12 +20,6 @@ class EntityWithStringEnumProperty( return hash } - fun copy( - property: Expression = this.property, - ) = EntityWithStringEnumProperty( - property = property, - ) - companion object { const val TYPE = "entity_with_string_enum_property" } diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt index bd1340e53..45c83553e 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithStringEnumPropertyWithDefaultValue.kt @@ -20,12 +20,6 @@ class EntityWithStringEnumPropertyWithDefaultValue( return hash } - fun copy( - value: Expression = this.value, - ) = EntityWithStringEnumPropertyWithDefaultValue( - value = value, - ) - companion object { const val TYPE = "entity_with_string_enum_property_with_default_value" diff --git a/api_generator/tests/references/shared_data_kotlin/EntityWithoutProperties.kt b/api_generator/tests/references/shared_data_kotlin/EntityWithoutProperties.kt index 8de5b8604..f0a45bd45 100644 --- a/api_generator/tests/references/shared_data_kotlin/EntityWithoutProperties.kt +++ b/api_generator/tests/references/shared_data_kotlin/EntityWithoutProperties.kt @@ -17,8 +17,6 @@ class EntityWithoutProperties() : Hashable { return hash } - fun copy() = EntityWithoutProperties() - companion object { const val TYPE = "entity_without_properties" } diff --git a/api_generator/tests/references/shared_data_kotlin/WithDefault.kt b/api_generator/tests/references/shared_data_kotlin/WithDefault.kt index dc47783d1..ef76de76e 100644 --- a/api_generator/tests/references/shared_data_kotlin/WithDefault.kt +++ b/api_generator/tests/references/shared_data_kotlin/WithDefault.kt @@ -17,8 +17,6 @@ class WithDefault() : Hashable { return hash } - fun copy() = WithDefault() - companion object { const val TYPE = "default" } diff --git a/api_generator/tests/references/shared_data_kotlin/WithoutDefault.kt b/api_generator/tests/references/shared_data_kotlin/WithoutDefault.kt index 9870422a5..198575946 100644 --- a/api_generator/tests/references/shared_data_kotlin/WithoutDefault.kt +++ b/api_generator/tests/references/shared_data_kotlin/WithoutDefault.kt @@ -17,8 +17,6 @@ class WithoutDefault() : Hashable { return hash } - fun copy() = WithoutDefault() - companion object { const val TYPE = "non_default" } diff --git a/client/android/api-generator-test/testing-generator-config.json b/client/android/api-generator-test/testing-generator-config.json index bcfd80aa5..10d96f658 100644 --- a/client/android/api-generator-test/testing-generator-config.json +++ b/client/android/api-generator-test/testing-generator-config.json @@ -1,5 +1,5 @@ { "lang": "kotlin", - "header": "// Generated code. Do not modify.\n\npackage com.yandex.testing\n\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.annotation.ColorInt\nimport com.yandex.div.data.Hashable\nimport com.yandex.div.internal.core.*\nimport com.yandex.div.internal.parser.*\nimport com.yandex.div.internal.template.*\nimport com.yandex.div.internal.util.*\nimport com.yandex.div.json.*\nimport com.yandex.div.json.expressions.*\nimport com.yandex.div.core.annotations.Mockable\nimport java.io.IOException\nimport java.util.BitSet\nimport org.json.JSONObject\nimport org.json.JSONArray\n", + "header": "// Generated code. Do not modify.\n\npackage com.yandex.testing\n\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.annotation.ColorInt\nimport com.yandex.div.data.Hashable\nimport com.yandex.div.internal.parser.*\nimport com.yandex.div.internal.template.*\nimport com.yandex.div.internal.util.*\nimport com.yandex.div.json.*\nimport com.yandex.div.json.expressions.*\nimport com.yandex.div.core.annotations.Mockable\nimport java.io.IOException\nimport java.util.BitSet\nimport org.json.JSONObject\nimport org.json.JSONArray\n", "generateEquality": true } diff --git a/client/android/div-data/div2-generator-config.json b/client/android/div-data/div2-generator-config.json index 7f7ba057f..b4fba2826 100644 --- a/client/android/div-data/div2-generator-config.json +++ b/client/android/div-data/div2-generator-config.json @@ -1,6 +1,6 @@ { "lang": "kotlin", - "header": "// Generated code. Do not modify.\n\npackage com.yandex.div2\n\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.annotation.ColorInt\nimport com.yandex.div.internal.core.*\nimport com.yandex.div.internal.parser.*\nimport com.yandex.div.internal.template.*\nimport com.yandex.div.internal.util.*\nimport com.yandex.div.json.*\nimport com.yandex.div.json.expressions.*\nimport com.yandex.div.core.annotations.Mockable\nimport java.io.IOException\nimport java.util.BitSet\nimport org.json.JSONObject\nimport com.yandex.div.data.*\nimport org.json.JSONArray\n", + "header": "// Generated code. Do not modify.\n\npackage com.yandex.div2\n\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.annotation.ColorInt\nimport com.yandex.div.internal.parser.*\nimport com.yandex.div.internal.template.*\nimport com.yandex.div.internal.util.*\nimport com.yandex.div.json.*\nimport com.yandex.div.json.expressions.*\nimport com.yandex.div.core.annotations.Mockable\nimport java.io.IOException\nimport java.util.BitSet\nimport org.json.JSONObject\nimport com.yandex.div.data.*\nimport org.json.JSONArray\n", "kotlinAnnotations": { "classes": ["@Mockable"], "constructors": ["@DivModelInternalApi"] diff --git a/client/android/div-data/div2-shared-data-generator-config.json b/client/android/div-data/div2-shared-data-generator-config.json index 93e0d0434..b1d6fba9d 100644 --- a/client/android/div-data/div2-shared-data-generator-config.json +++ b/client/android/div-data/div2-shared-data-generator-config.json @@ -1,6 +1,6 @@ { "lang": "kotlin", - "header": "// Generated code. Do not modify.\n\npackage com.yandex.div2\n\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.annotation.ColorInt\nimport com.yandex.div.internal.core.*\nimport com.yandex.div.internal.parser.*\nimport com.yandex.div.internal.template.*\nimport com.yandex.div.internal.util.*\nimport com.yandex.div.json.*\nimport com.yandex.div.json.expressions.*\nimport com.yandex.div.core.annotations.Mockable\nimport java.io.IOException\nimport java.util.BitSet\nimport org.json.JSONObject\nimport com.yandex.div.data.*\nimport org.json.JSONArray\n", + "header": "// Generated code. Do not modify.\n\npackage com.yandex.div2\n\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.annotation.ColorInt\nimport com.yandex.div.internal.parser.*\nimport com.yandex.div.internal.template.*\nimport com.yandex.div.internal.util.*\nimport com.yandex.div.json.*\nimport com.yandex.div.json.expressions.*\nimport com.yandex.div.core.annotations.Mockable\nimport java.io.IOException\nimport java.util.BitSet\nimport org.json.JSONObject\nimport com.yandex.div.data.*\nimport org.json.JSONArray\n", "kotlinAnnotations": { "classes": ["@Mockable"], "constructors": ["@DivModelInternalApi"] diff --git a/client/android/div-data/src/main/java/com/yandex/div/internal/core/DivItemBuilderResult.kt b/client/android/div-data/src/main/java/com/yandex/div/internal/core/DivItemBuilderResult.kt deleted file mode 100644 index 421538f99..000000000 --- a/client/android/div-data/src/main/java/com/yandex/div/internal/core/DivItemBuilderResult.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.yandex.div.internal.core - -import com.yandex.div.json.expressions.ExpressionResolver -import com.yandex.div2.Div - -class DivItemBuilderResult( - val div: Div, - val expressionResolver: ExpressionResolver, -) { - - operator fun component1() = div - operator fun component2() = expressionResolver -} diff --git a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/Evaluator.kt b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/Evaluator.kt index 9a38d13e6..12b681b13 100644 --- a/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/Evaluator.kt +++ b/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/Evaluator.kt @@ -6,7 +6,7 @@ import com.yandex.div.evaluable.types.DateTime import kotlin.math.abs @Mockable -class Evaluator(val evaluationContext: EvaluationContext) { +class Evaluator(private val evaluationContext: EvaluationContext) { @Throws(EvaluableException::class) @Suppress("UNCHECKED_CAST") diff --git a/client/android/div-shimmer/src/main/java/com/yandex/div/shimmer/DivShimmerExtensionHandler.kt b/client/android/div-shimmer/src/main/java/com/yandex/div/shimmer/DivShimmerExtensionHandler.kt index 37293f236..f2cab31ff 100644 --- a/client/android/div-shimmer/src/main/java/com/yandex/div/shimmer/DivShimmerExtensionHandler.kt +++ b/client/android/div-shimmer/src/main/java/com/yandex/div/shimmer/DivShimmerExtensionHandler.kt @@ -48,12 +48,11 @@ open class DivShimmerExtensionHandler( if (animationStartTime == 0L) { animationStartTime = SystemClock.uptimeMillis() } - val resolver = divView.getExpressionResolver(div) val drawable = ShimmerDrawable( - data.createShimmer(resolver), + data.createShimmer(divView.expressionResolver), animationStartTime ) - data.observeTo(drawable, resolver) + data.observeTo(drawable, divView.expressionResolver) imageView.setImage(drawable) view.setTag(R.id.div_shimmer_drawable, drawable) } diff --git a/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandler.kt b/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandler.kt index bad0a2ab6..904c712a4 100644 --- a/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandler.kt +++ b/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandler.kt @@ -41,7 +41,7 @@ class DivSizeProviderExtensionHandler( val data = divView.divData ?: return val variablesHolder = variablesHolders[data] ?: DivSizeProviderVariablesHolder() - .apply { observeDivData(data, divView.getExpressionResolver(div)) } + .apply { observeDivData(data, divView.expressionResolver) } .also { variablesHolders[data] = it } divDataCounters[data] = (divDataCounters[data] ?: 0) + 1 view.setTag(R.id.div_size_provider_data, data) diff --git a/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt b/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt index df22e2241..cd19075d5 100644 --- a/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt +++ b/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt @@ -28,7 +28,7 @@ class DivSizeProviderVariablesHolder : DivVisitor(), ExpressionSubscriber override fun visit(data: Div.Container, resolver: ExpressionResolver) { defaultVisit(data, resolver) - data.value.buildItems(resolver).forEach { visit(it.div, it.expressionResolver) } + data.value.buildItems(resolver).forEach { visit(it, resolver) } } override fun visit(data: Div.Grid, resolver: ExpressionResolver) { @@ -65,7 +65,7 @@ class DivSizeProviderVariablesHolder : DivVisitor(), ExpressionSubscriber private fun DivSize.observe(resolver: ExpressionResolver) { val size = value() as? DivFixedSize ?: return - val sizeExpr = size.value as? Expression.MutableExpression<*, Long> ?: return + val sizeExpr = size.value as? Expression.MutableExpression<*, Int> ?: return addSubscription(sizeExpr.observe(resolver) { changedVariables.addAll(sizeExpr.getVariablesName()) }) diff --git a/client/android/div-size-provider/src/test/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandlerTest.kt b/client/android/div-size-provider/src/test/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandlerTest.kt index 3bb419a8b..9b220fe96 100644 --- a/client/android/div-size-provider/src/test/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandlerTest.kt +++ b/client/android/div-size-provider/src/test/java/com/yandex/div/sizeprovider/DivSizeProviderExtensionHandlerTest.kt @@ -47,7 +47,7 @@ class DivSizeProviderExtensionHandlerTest { } private val divView = mock { on { divData } doReturn data - on { getExpressionResolver(any()) } doReturn mock() + on { expressionResolver } doReturn mock() on { viewTreeObserver } doReturn viewTreeObserver } private val underTest = DivSizeProviderExtensionHandler() diff --git a/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt b/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt index 0e8eb87a0..95276c59e 100644 --- a/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt +++ b/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt @@ -5,7 +5,7 @@ import android.util.AttributeSet import android.view.View import android.view.ViewGroup import android.view.ViewGroup.MarginLayoutParams -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.gallery.DivGalleryBinder import com.yandex.div.core.view2.divs.gallery.DivGalleryItemHelper import com.yandex.div.core.view2.divs.gallery.ScrollPosition @@ -14,7 +14,7 @@ import com.yandex.div.internal.widget.DivLayoutParams import com.yandex.div2.DivGallery internal class DivLinearLayoutManager( - override val bindingContext: BindingContext, + override val divView: Div2View, override val view: RecyclerView, override val div: DivGallery, @RecyclerView.Orientation orientation: Int = RecyclerView.HORIZONTAL diff --git a/client/android/div/src/main/java/com/yandex/div/core/DivCustomContainerChildFactory.kt b/client/android/div/src/main/java/com/yandex/div/core/DivCustomContainerChildFactory.kt index d49fdd5cb..2b8ba8525 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/DivCustomContainerChildFactory.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/DivCustomContainerChildFactory.kt @@ -20,7 +20,7 @@ class DivCustomContainerChildFactory @Inject internal constructor (){ divStatePath: DivStatePath, divView: Div2View ): View { - return divView.div2Component.div2Builder.buildView(div, divView.bindingContext, divStatePath) + return divView.div2Component.div2Builder.buildView(div, divView, divStatePath) } /** @@ -32,7 +32,7 @@ class DivCustomContainerChildFactory @Inject internal constructor (){ divStatePath: DivStatePath, divView: Div2View ): View { - return divView.div2Component.div2Builder.createView(div, divView.bindingContext, divStatePath) + return divView.div2Component.div2Builder.createView(div, divView, divStatePath) } /** @@ -44,7 +44,7 @@ class DivCustomContainerChildFactory @Inject internal constructor (){ divStatePath: DivStatePath, divView: Div2View ) { - divView.div2Component.divBinder.bind(divView.bindingContext, childView, div, divStatePath) + divView.div2Component.divBinder.bind(childView, div, divView, divStatePath) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt b/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt index c5894d185..938ce19a3 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt @@ -81,7 +81,7 @@ class DivPreloader internal constructor( } override fun visit(data: Div.Container, resolver: ExpressionResolver) { - data.value.buildItems(resolver).forEach { (item, newResolver) -> visit(item, newResolver) } + data.value.buildItems(resolver).forEach { visit(it, resolver) } defaultVisit(data, resolver) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt index 6a2e81086..c7b1489cf 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt @@ -9,6 +9,7 @@ import com.yandex.div.core.view2.divs.widgets.DivPagerView import com.yandex.div.core.view2.divs.widgets.DivRecyclerView import com.yandex.div.internal.KAssert import com.yandex.div.internal.KLog +import com.yandex.div.internal.core.buildItems import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div @@ -75,23 +76,23 @@ internal class DivPatchApply(private val patch: DivPatchMap) { } private fun applyPatch(div: DivContainer, resolver: ExpressionResolver) = Div.Container( - div.copy(items = applyPatchForListOfDivs(div.items, resolver)) + div.copyWithNewProperties(applyPatchForListOfDivs(div.items, resolver)) ) private fun applyPatch(div: DivGrid, resolver: ExpressionResolver): Div.Grid = Div.Grid( - div.copy(items = applyPatchForListOfDivs(div.items, resolver)) + div.copyWithNewProperties(applyPatchForListOfDivs(div.items, resolver)) ) private fun applyPatch(div: DivGallery, resolver: ExpressionResolver) = Div.Gallery( - div.copy(items = applyPatchForListOfDivs(div.items, resolver)) + div.copyWithNewProperties(applyPatchForListOfDivs(div.items, resolver)) ) private fun applyPatch(div: DivPager, resolver: ExpressionResolver) = Div.Pager( - div.copy(items = applyPatchForListOfDivs(div.items, resolver)) + div.copyWithNewProperties(applyPatchForListOfDivs(div.items, resolver)) ) private fun applyPatch(div: DivState, resolver: ExpressionResolver) = Div.State( - div.copy(states = applyPatchForListStates(div.states, resolver)) + div.copyWithNewProperties(applyPatchForListStates(div.states, resolver)) ) private fun applyPatchForListStates(states: List, @@ -159,7 +160,7 @@ internal class DivPatchApply(private val patch: DivPatchMap) { } } return Div.Tabs( - div.copy(items = newTabItems) + div.copyWithNewProperties(newTabItems) ) } @@ -196,21 +197,24 @@ internal class DivPatchApply(private val patch: DivPatchMap) { ): List
{ currentPath.add(currentDiv) return when (val currentDivValue = currentDiv.value()) { - is DivContainer -> - currentDivValue.nonNullItems - .pathToChildWithId(idToFind, resolver, currentPath) + is DivContainer -> currentDivValue.buildItems(resolver).pathToChildWithId( + idToFind, + resolver, + currentPath, + builtByBuilder = currentDivValue.items == null + ) is DivGrid -> currentDivValue.nonNullItems - .pathToChildWithId(idToFind, resolver, currentPath) + .pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) is DivGallery -> currentDivValue.nonNullItems - .pathToChildWithId(idToFind, resolver, currentPath) + .pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) is DivPager -> currentDivValue.nonNullItems - .pathToChildWithId(idToFind, resolver, currentPath) + .pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) is DivTabs -> { if (currentDivValue.items.any { it.div.value().id == idToFind }) { @@ -244,8 +248,14 @@ internal class DivPatchApply(private val patch: DivPatchMap) { idToFind: String, resolver: ExpressionResolver, currentPath: MutableList
= mutableListOf(), + builtByBuilder: Boolean ): List
{ - if (any { it.value().id == idToFind }) return currentPath + if (any { it.value().id == idToFind }) { + if (!builtByBuilder) return currentPath + + KAssert.fail { "Unable to patch container which has items built by items_builder." } + return emptyList() + } forEach { val newPath = pathToChildWithId(it, idToFind, resolver, currentPath) @@ -261,12 +271,8 @@ internal class DivPatchApply(private val patch: DivPatchMap) { ): Div { return when (val currentDivValue = currentDiv.value()) { is DivContainer -> { - getPatchedDivCollection( - currentDiv, - currentDivValue.nonNullItems, - pathIterator, - resolver, - { Div.Container(currentDivValue.copy(items = it)) }, + getPatchedDivCollection(currentDiv, currentDivValue.buildItems(resolver), pathIterator, resolver, + { Div.Container(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) } @@ -277,7 +283,7 @@ internal class DivPatchApply(private val patch: DivPatchMap) { currentDivValue.nonNullItems, pathIterator, resolver, - { Div.Grid(currentDivValue.copy(items = it)) }, + { Div.Grid(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) } @@ -288,7 +294,7 @@ internal class DivPatchApply(private val patch: DivPatchMap) { currentDivValue.nonNullItems, pathIterator, resolver, - { Div.Gallery(currentDivValue.copy(items = it)) }, + { Div.Gallery(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) } @@ -299,7 +305,7 @@ internal class DivPatchApply(private val patch: DivPatchMap) { currentDivValue.nonNullItems, pathIterator, resolver, - { Div.Pager(currentDivValue.copy(items = it)) }, + { Div.Pager(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) } @@ -319,7 +325,7 @@ internal class DivPatchApply(private val patch: DivPatchMap) { itemToReplace.title, itemToReplace.titleClickAction ) - Div.Tabs(currentDivValue.copy(items = newItems)) + Div.Tabs(currentDivValue.copyWithNewProperties(newItems)) } else { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } @@ -345,7 +351,7 @@ internal class DivPatchApply(private val patch: DivPatchMap) { itemToReplace.swipeOutActions ) - Div.State(currentDivValue.copy(states = newItems)) + Div.State(currentDivValue.copyWithNewProperties(newItems)) } else { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchManager.kt b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchManager.kt index e8edf9f22..2bbb40645 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchManager.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchManager.kt @@ -5,8 +5,8 @@ import com.yandex.div.DivDataTag import com.yandex.div.core.annotations.Mockable import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.state.DivStatePath -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2Builder +import com.yandex.div.core.view2.Div2View import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.DivData import com.yandex.div2.DivPatch @@ -24,15 +24,11 @@ internal class DivPatchManager @Inject constructor( return divPatchCache.putPatch(tag, patch) } - fun createViewsForId(context: BindingContext, id: String): List? { - val patchDivs = divPatchCache.getPatchDivListById(context.divView.dataTag, id) ?: return null + fun createViewsForId(rootView: Div2View, id: String): List? { + val patchDivs = divPatchCache.getPatchDivListById(rootView.dataTag, id) ?: return null val listViews = mutableListOf() patchDivs.forEach { - val view = divViewCreator.get().buildView( - it, - context, - DivStatePath.fromState(context.divView.currentStateId) - ) + val view = divViewCreator.get().buildView(it, rootView, DivStatePath.fromState(rootView.currentStateId)) listViews.add(view) } return listViews diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionResolverImpl.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionResolverImpl.kt index 3a3f42226..506eda554 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionResolverImpl.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionResolverImpl.kt @@ -2,13 +2,10 @@ package com.yandex.div.core.expression import com.yandex.div.core.Disposable import com.yandex.div.core.ObserverList -import com.yandex.div.core.expression.variables.LocalVariableController import com.yandex.div.core.expression.variables.VariableController -import com.yandex.div.core.expression.variables.VariableSource import com.yandex.div.core.view2.errors.ErrorCollector import com.yandex.div.evaluable.Evaluable import com.yandex.div.evaluable.EvaluableException -import com.yandex.div.evaluable.EvaluationContext import com.yandex.div.evaluable.Evaluator import com.yandex.div.evaluable.MissingVariableException import com.yandex.div.internal.parser.Converter @@ -24,11 +21,10 @@ import com.yandex.div.json.resolveFailed import com.yandex.div.json.typeMismatch internal class ExpressionResolverImpl( - private val variableController: VariableController, + variableController: VariableController, private val evaluator: Evaluator, private val errorCollector: ErrorCollector, ) : ExpressionResolver { - private val evaluationsCache = mutableMapOf() private val varToExpressions = mutableMapOf>() @@ -213,20 +209,4 @@ internal class ExpressionResolverImpl( observers.addObserver(callback) return Disposable { expressionObservers[rawExpression]?.removeObserver(callback) } } - - operator fun plus(variableSource: VariableSource): ExpressionResolverImpl { - val localVariableController = LocalVariableController(variableController, variableSource) - return ExpressionResolverImpl( - variableController = localVariableController, - evaluator = Evaluator( - evaluationContext = EvaluationContext( - variableProvider = localVariableController, - storedValueProvider = evaluator.evaluationContext.storedValueProvider, - functionProvider = evaluator.evaluationContext.functionProvider, - warningSender = evaluator.evaluationContext.warningSender - ) - ), - errorCollector = errorCollector - ) - } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntime.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntime.kt index d359bcbd2..7bcfbb0fa 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntime.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntime.kt @@ -2,12 +2,12 @@ package com.yandex.div.core.expression import com.yandex.div.core.DivViewFacade import com.yandex.div.core.expression.triggers.TriggersController -import com.yandex.div.core.expression.variables.VariableControllerImpl +import com.yandex.div.core.expression.variables.VariableController import com.yandex.div.json.expressions.ExpressionResolver internal class ExpressionsRuntime( val expressionResolver: ExpressionResolver, - val variableController: VariableControllerImpl, + val variableController: VariableController, val triggersController: TriggersController, ) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntimeProvider.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntimeProvider.kt index a1f9823d5..6d24fc339 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntimeProvider.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntimeProvider.kt @@ -9,7 +9,6 @@ import com.yandex.div.core.expression.triggers.TriggersController import com.yandex.div.core.expression.variables.DivVariableController import com.yandex.div.core.expression.variables.GlobalVariableController import com.yandex.div.core.expression.variables.VariableController -import com.yandex.div.core.expression.variables.VariableControllerImpl import com.yandex.div.core.expression.variables.toVariable import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.DivActionBinder @@ -112,7 +111,7 @@ internal class ExpressionsRuntimeProvider @Inject constructor( private fun createRuntimeFor(data: DivData, tag: DivDataTag): ExpressionsRuntime { val errorCollector = errorCollectors.getOrCreate(tag, data) - val variableController = VariableControllerImpl().apply { + val variableController = VariableController().apply { data.variables?.forEach { divVariable: DivVariable -> try { declare(divVariable.toVariable()) @@ -126,7 +125,9 @@ internal class ExpressionsRuntimeProvider @Inject constructor( } val evaluationContext = EvaluationContext( - variableProvider = variableController, + variableProvider = { variableName -> + variableController.getMutableVariable(variableName)?.getValue() + }, storedValueProvider = { storedValueName -> storedValuesController.getStoredValue(storedValueName, errorCollector)?.getValue() }, diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/triggers/TriggersController.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/triggers/TriggersController.kt index 711a0852a..b1d0f968c 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/triggers/TriggersController.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/triggers/TriggersController.kt @@ -155,7 +155,7 @@ private class TriggerExecutor( logger.logTrigger(div2View, it) } } - divActionBinder.handleActions(viewFacade, viewFacade.expressionResolver, actions, DivActionReason.TRIGGER) + divActionBinder.handleActions(viewFacade, actions, DivActionReason.TRIGGER) } private fun conditionSatisfied(): Boolean { diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt deleted file mode 100644 index af3d308d6..000000000 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.yandex.div.core.expression.variables - -import com.yandex.div.core.view2.errors.ErrorCollector -import com.yandex.div.data.Variable - -internal class LocalVariableController( - private val delegate: VariableController, - private val localVariables: VariableSource -) : VariableController { - - override fun subscribeToVariablesChange( - names: List, - invokeOnSubscription: Boolean, - observer: (Variable) -> Unit - ) = delegate.subscribeToVariablesChange(names, invokeOnSubscription, observer) - - override fun subscribeToVariableChange( - name: String, - errorCollector: ErrorCollector?, - invokeOnSubscription: Boolean, - observer: (Variable) -> Unit - ) = delegate.subscribeToVariableChange(name, errorCollector, invokeOnSubscription, observer) - - override fun addSource(source: VariableSource) = delegate.addSource(source) - - override fun getMutableVariable(name: String) = - localVariables.getMutableVariable(name) ?: delegate.getMutableVariable(name) - - override fun declare(variable: Variable) = delegate.declare(variable) - - override fun setOnAnyVariableChangeCallback(callback: (Variable) -> Unit) = - delegate.setOnAnyVariableChangeCallback(callback) -} diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt index 13e5001b6..a17b5300f 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt @@ -1,32 +1,141 @@ package com.yandex.div.core.expression.variables import com.yandex.div.core.Disposable +import com.yandex.div.core.ObserverList +import com.yandex.div.core.annotations.Mockable import com.yandex.div.core.view2.errors.ErrorCollector import com.yandex.div.data.Variable -import com.yandex.div.evaluable.VariableProvider +import com.yandex.div.data.VariableDeclarationException +import com.yandex.div.internal.Assert -internal interface VariableController : VariableProvider { +import com.yandex.div.json.missingVariable + +@Mockable +internal class VariableController { + private val variables = mutableMapOf() + private val extraVariablesSources = mutableListOf() + private val onChangeObservers = mutableMapOf Unit>>() + + private var onAnyVariableChangeCallback: ((Variable) -> Unit)? = null + private val notifyVariableChangedCallback = { v : Variable -> notifyVariableChanged(v) } + private val declarationObserver = { v : Variable -> onVariableDeclared(v) } + + private fun addObserver(name: String, observer: (Variable) -> Unit) { + val observers = onChangeObservers.getOrPut(name) { + ObserverList() + } + observers.addObserver(observer) + } - override fun get(name: String) = getMutableVariable(name)?.getValue() fun subscribeToVariablesChange( names: List, invokeOnSubscription: Boolean = false, observer: (Variable) -> Unit - ): Disposable + ): Disposable { + names.forEach { name -> + subscribeToVariableChangeImpl(name, null, invokeOnSubscription, observer) + } + return Disposable { + names.forEach { name -> + removeChangeObserver(name, observer) + } + } + } fun subscribeToVariableChange( name: String, errorCollector: ErrorCollector? = null, invokeOnSubscription: Boolean = false, observer: (Variable) -> Unit - ): Disposable + ): Disposable { + subscribeToVariableChangeImpl(name, errorCollector, invokeOnSubscription, observer) + return Disposable { + removeChangeObserver(name, observer) + } + } - fun addSource(source: VariableSource) + private fun subscribeToVariableChangeImpl( + name: String, + errorCollector: ErrorCollector? = null, + invokeOnSubscription: Boolean = false, + observer: (Variable) -> Unit + ) { + val variable = getMutableVariable(name) + ?: run { + errorCollector?.logError(missingVariable(name)) + addObserver(name, observer) + return + } - fun getMutableVariable(name: String): Variable? + if (invokeOnSubscription) { + // Any on variable changed notify should be executed on main thread. + Assert.assertMainThread() + observer.invoke(variable) + } + addObserver(name, observer) + return + } - fun declare(variable: Variable) + private fun removeChangeObserver(name: String, observer: (Variable) -> Unit) { + onChangeObservers[name]?.removeObserver(observer) + } - fun setOnAnyVariableChangeCallback(callback: (Variable) -> Unit) + private fun notifyVariableChanged(v: Variable) { + Assert.assertMainThread() + onAnyVariableChangeCallback?.invoke(v) + onChangeObservers[v.name]?.forEach { it.invoke(v) } + } + + + /** + * aka "adding references to global variables" + */ + fun addSource(source: VariableSource) { + source.observeVariables(notifyVariableChangedCallback) + source.observeDeclaration(declarationObserver) + extraVariablesSources.add(source) + } + + private fun onVariableDeclared(variable: Variable) { + variable.addObserver(notifyVariableChangedCallback) + notifyVariableChanged(variable) + } + + fun getMutableVariable(name: String): Variable? { + variables[name]?.let { + return it + } + + extraVariablesSources.forEach { source: VariableSource -> + source.getMutableVariable(name)?.let { + return it + } + } + + return null + } + + internal fun cleanup() { + extraVariablesSources.forEach { variableSource -> + variableSource.removeVariablesObserver(notifyVariableChangedCallback) + variableSource.removeDeclarationObserver(declarationObserver) + } + onAnyVariableChangeCallback = null + } + + @Throws(VariableDeclarationException::class) + fun declare(variable: Variable) { + val prevVariable = variables.put(variable.name, variable) + if (prevVariable != null) { + variables[variable.name] = prevVariable + throw VariableDeclarationException("Variable '${variable.name}' already declared!") + } + onVariableDeclared(variable) + } + + fun setOnAnyVariableChangeCallback(callback: (Variable) -> Unit) { + Assert.assertNull(onAnyVariableChangeCallback) + onAnyVariableChangeCallback = callback + } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt b/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt deleted file mode 100644 index 88fb2d58b..000000000 --- a/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt +++ /dev/null @@ -1,138 +0,0 @@ -package com.yandex.div.core.expression.variables - -import com.yandex.div.core.Disposable -import com.yandex.div.core.ObserverList -import com.yandex.div.core.annotations.Mockable -import com.yandex.div.core.view2.errors.ErrorCollector -import com.yandex.div.data.Variable -import com.yandex.div.data.VariableDeclarationException -import com.yandex.div.internal.Assert -import com.yandex.div.json.missingVariable - -@Mockable -internal class VariableControllerImpl : VariableController { - private val variables = mutableMapOf() - private val extraVariablesSources = mutableListOf() - private val onChangeObservers = mutableMapOf Unit>>() - - private val onAnyVariableChangeObservers = ObserverList<(Variable) -> Unit>() - private val notifyVariableChangedCallback = { v : Variable -> notifyVariableChanged(v) } - private val declarationObserver = { v : Variable -> onVariableDeclared(v) } - - private fun addObserver(name: String, observer: (Variable) -> Unit) { - val observers = onChangeObservers.getOrPut(name) { - ObserverList() - } - observers.addObserver(observer) - } - - override fun subscribeToVariablesChange( - names: List, - invokeOnSubscription: Boolean, - observer: (Variable) -> Unit - ): Disposable { - names.forEach { name -> - subscribeToVariableChangeImpl(name, null, invokeOnSubscription, observer) - } - return Disposable { - names.forEach { name -> - removeChangeObserver(name, observer) - } - } - } - - override fun subscribeToVariableChange( - name: String, - errorCollector: ErrorCollector?, - invokeOnSubscription: Boolean, - observer: (Variable) -> Unit - ): Disposable { - subscribeToVariableChangeImpl(name, errorCollector, invokeOnSubscription, observer) - return Disposable { - removeChangeObserver(name, observer) - } - } - - private fun subscribeToVariableChangeImpl( - name: String, - errorCollector: ErrorCollector? = null, - invokeOnSubscription: Boolean = false, - observer: (Variable) -> Unit - ) { - val variable = getMutableVariable(name) - ?: run { - errorCollector?.logError(missingVariable(name)) - addObserver(name, observer) - return - } - - if (invokeOnSubscription) { - // Any on variable changed notify should be executed on main thread. - Assert.assertMainThread() - observer.invoke(variable) - } - addObserver(name, observer) - return - } - - private fun removeChangeObserver(name: String, observer: (Variable) -> Unit) { - onChangeObservers[name]?.removeObserver(observer) - } - - private fun notifyVariableChanged(v: Variable) { - Assert.assertMainThread() - onAnyVariableChangeObservers.forEach { it.invoke(v) } - onChangeObservers[v.name]?.forEach { it.invoke(v) } - } - - - /** - * aka "adding references to global variables" - */ - override fun addSource(source: VariableSource) { - source.observeVariables(notifyVariableChangedCallback) - source.observeDeclaration(declarationObserver) - extraVariablesSources.add(source) - } - - private fun onVariableDeclared(variable: Variable) { - variable.addObserver(notifyVariableChangedCallback) - notifyVariableChanged(variable) - } - - override fun getMutableVariable(name: String): Variable? { - variables[name]?.let { - return it - } - - extraVariablesSources.forEach { source: VariableSource -> - source.getMutableVariable(name)?.let { - return it - } - } - - return null - } - - internal fun cleanup() { - extraVariablesSources.forEach { variableSource -> - variableSource.removeVariablesObserver(notifyVariableChangedCallback) - variableSource.removeDeclarationObserver(declarationObserver) - } - onAnyVariableChangeObservers.clear() - } - - @Throws(VariableDeclarationException::class) - override fun declare(variable: Variable) { - val prevVariable = variables.put(variable.name, variable) - if (prevVariable != null) { - variables[variable.name] = prevVariable - throw VariableDeclarationException("Variable '${variable.name}' already declared!") - } - onVariableDeclared(variable) - } - - override fun setOnAnyVariableChangeCallback(callback: (Variable) -> Unit) { - onAnyVariableChangeObservers.addObserver(callback) - } -} diff --git a/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt b/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt index 8911cec61..8c538db71 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt @@ -59,8 +59,8 @@ internal class DivVideoActionHandler @Inject constructor( return null } is DivContainer -> { - div.buildItems(resolver).forEach { (item, newResolver) -> - findDivVideoWithId(item.value(), id, newResolver)?.let { + div.buildItems(resolver).forEach { item -> + findDivVideoWithId(item.value(), id, resolver)?.let { return it } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt b/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt index d45b65628..e6d46f659 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt @@ -4,7 +4,6 @@ import android.view.View import android.view.ViewGroup import androidx.core.view.children import com.yandex.div.core.view2.divs.widgets.DivStateLayout -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.buildItems import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver @@ -110,7 +109,7 @@ internal object DivPathUtils { } } is Div.Tabs -> value.items.map { it.div }.findRecursively(divId, resolver) - is Div.Container -> value.buildItems(resolver).findRecursively(divId) + is Div.Container -> value.buildItems(resolver).findRecursively(divId, resolver) is Div.Grid -> value.nonNullItems.findRecursively(divId, resolver) is Div.Gallery -> value.nonNullItems.findRecursively(divId, resolver) is Div.Pager -> value.nonNullItems.findRecursively(divId, resolver) @@ -127,13 +126,6 @@ internal object DivPathUtils { } } - private fun Iterable.findRecursively(divId: String): Div? { - forEach { (div, resolver) -> - div.findByPath(divId, resolver)?.let { return it } - } - return null - } - private fun Iterable
.findRecursively(divId: String, resolver: ExpressionResolver): Div? { forEach { div: Div -> val state = div.findByPath(divId, resolver) diff --git a/client/android/div/src/main/java/com/yandex/div/core/timer/TimerController.kt b/client/android/div/src/main/java/com/yandex/div/core/timer/TimerController.kt index 99c36a0f2..b963ea7e5 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/timer/TimerController.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/timer/TimerController.kt @@ -88,7 +88,7 @@ internal class TimerController( UiThreadHandler.executeOnMainThread { div2View?.let { - divActionBinder.handleActions(it, it.expressionResolver, tickActions, DivActionReason.TIMER) + divActionBinder.handleActions(it, tickActions, DivActionReason.TIMER) } } } @@ -98,7 +98,7 @@ internal class TimerController( UiThreadHandler.executeOnMainThread { div2View?.let { - divActionBinder.handleActions(it, it.expressionResolver, endActions, DivActionReason.TIMER) + divActionBinder.handleActions(it, endActions, DivActionReason.TIMER) } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/tooltip/DivTooltipController.kt b/client/android/div/src/main/java/com/yandex/div/core/tooltip/DivTooltipController.kt index 08459328b..4a465544e 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/tooltip/DivTooltipController.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/tooltip/DivTooltipController.kt @@ -26,7 +26,6 @@ import com.yandex.div.core.util.AccessibilityStateProvider import com.yandex.div.core.util.SafePopupWindow import com.yandex.div.core.util.doOnActualLayout import com.yandex.div.core.util.isActuallyLaidOut -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2Builder import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivVisibilityActionTracker @@ -73,18 +72,18 @@ internal class DivTooltipController @VisibleForTesting constructor( accessibilityStateProvider, { c: View, w: Int, h: Int -> DivTooltipWindow(c, w, h) }) - fun showTooltip(tooltipId: String, context: BindingContext, multiple: Boolean = false) { - findChildWithTooltip(tooltipId, context.divView)?.let { (divTooltip, anchor) -> - showTooltip(divTooltip, anchor, context, multiple) + fun showTooltip(tooltipId: String, div2View: Div2View, multiple: Boolean = false) { + findChildWithTooltip(tooltipId, div2View)?.let { (divTooltip, anchor) -> + showTooltip(divTooltip, anchor, div2View, multiple) } } - private fun showTooltip(divTooltip: DivTooltip, anchor: View, context: BindingContext, multiple: Boolean) { + private fun showTooltip(divTooltip: DivTooltip, anchor: View, div2View: Div2View, multiple: Boolean) { if (tooltips.contains(divTooltip.id)) { return } anchor.doOnActualLayout { - tryShowTooltip(anchor, divTooltip, context, multiple) + tryShowTooltip(anchor, divTooltip, div2View, multiple) } if (!anchor.isActuallyLaidOut && !anchor.isLayoutRequested) { anchor.requestLayout() @@ -95,9 +94,9 @@ internal class DivTooltipController @VisibleForTesting constructor( tooltips[id]?.popupWindow?.dismiss() } - fun cancelTooltips(context: BindingContext) = cancelTooltips(context, context.divView) + fun cancelTooltips(div2View: Div2View) = cancelTooltips(div2View, div2View) - private fun cancelTooltips(context: BindingContext, view: View) { + private fun cancelTooltips(div2View: Div2View, view: View) { @Suppress("UNCHECKED_CAST") (view.getTag(R.id.div_tooltips_tag) as? List)?.let { tooltipList -> tooltipList.forEach { tooltip -> @@ -109,7 +108,7 @@ internal class DivTooltipController @VisibleForTesting constructor( popupWindow.dismiss() } else { forRemove.add(tooltip.id) - stopVisibilityTracking(context, tooltip.div) + stopVisibilityTracking(div2View, tooltip.div) } ticket?.cancel() } @@ -118,7 +117,7 @@ internal class DivTooltipController @VisibleForTesting constructor( } if (view is ViewGroup) { view.children.forEach { child -> - cancelTooltips(context, child) + cancelTooltips(div2View, child) } } } @@ -139,24 +138,23 @@ internal class DivTooltipController @VisibleForTesting constructor( private fun tryShowTooltip( anchor: View, divTooltip: DivTooltip, - context: BindingContext, + div2View: Div2View, multiple: Boolean ) { - val div2View = context.divView if (!tooltipRestrictor.canShowTooltip(div2View, anchor, divTooltip, multiple)) { return } val div = divTooltip.div val divBase = div.value() - val tooltipView = div2Builder.get().buildView(div, context, DivStatePath.fromState(0)) + val tooltipView = div2Builder.get().buildView(div, div2View, DivStatePath.fromState(0)) if (tooltipView == null) { Assert.fail("Broken div in popup") return } - val displayMetrics = context.divView.resources.displayMetrics - val resolver = context.expressionResolver + val displayMetrics = div2View.resources.displayMetrics + val resolver = div2View.expressionResolver val popup = createPopup( tooltipView, @@ -165,23 +163,23 @@ internal class DivTooltipController @VisibleForTesting constructor( ).apply { setOnDismissListener { tooltips.remove(divTooltip.id) - stopVisibilityTracking(context, divTooltip.div) + stopVisibilityTracking(div2View, divTooltip.div) divVisibilityActionTracker.getDivWithWaitingDisappearActions()[tooltipView]?.let { - divVisibilityActionTracker.trackDetachedView(context, tooltipView, it) + divVisibilityActionTracker.trackDetachedView(div2View, tooltipView, it) } tooltipRestrictor.tooltipShownCallback?.onDivTooltipDismissed(div2View, anchor, divTooltip) } setDismissOnTouchOutside() - setupAnimation(divTooltip, resolver) + setupAnimation(divTooltip, div2View.expressionResolver) } val tooltipData = TooltipData(popup, div, null) tooltips[divTooltip.id] = tooltipData - val ticket = divPreloader.preload(div, resolver) { hasFailures -> + val ticket = divPreloader.preload(div, div2View.expressionResolver) { hasFailures -> if (!hasFailures && !tooltipData.dismissed && anchor.isViewAttachedToWindow() && tooltipRestrictor.canShowTooltip(div2View, anchor, divTooltip, multiple)) { tooltipView.doOnActualLayout { val windowFrame = div2View.getWindowFrame() - val location = calcPopupLocation(tooltipView, anchor, divTooltip, resolver) + val location = calcPopupLocation(tooltipView, anchor, divTooltip, div2View.expressionResolver) val finalTooltipWidth = minOf(tooltipView.width, windowFrame.right) val finalTooltipHeight = minOf(tooltipView.height, windowFrame.bottom) @@ -195,7 +193,7 @@ internal class DivTooltipController @VisibleForTesting constructor( } popup.update(location.x, location.y, finalTooltipWidth, finalTooltipHeight) - startVisibilityTracking(context, div, tooltipView) + startVisibilityTracking(div2View, div, tooltipView) tooltipRestrictor.tooltipShownCallback?.onDivTooltipShown(div2View, anchor, divTooltip) } @@ -210,7 +208,7 @@ internal class DivTooltipController @VisibleForTesting constructor( popup.showAtLocation(anchor, Gravity.NO_GRAVITY, 0, 0) if (divTooltip.duration.evaluate(resolver) != 0L) { - mainThreadHandler.postDelayed(divTooltip.duration.evaluate(resolver)) { + mainThreadHandler.postDelayed(divTooltip.duration.evaluate(resolver).toLong()) { hideTooltip(divTooltip.id, div2View) } } @@ -219,18 +217,13 @@ internal class DivTooltipController @VisibleForTesting constructor( tooltips[divTooltip.id]?.ticket = ticket } - private fun startVisibilityTracking(context: BindingContext, div: Div, tooltipView: View) { - stopVisibilityTracking(context, div) - divVisibilityActionTracker.trackVisibilityActionsOf( - context.divView, - context.expressionResolver, - tooltipView, - div - ) + private fun startVisibilityTracking(div2View: Div2View, div: Div, tooltipView: View) { + stopVisibilityTracking(div2View, div) + divVisibilityActionTracker.trackVisibilityActionsOf(div2View, tooltipView, div) } - private fun stopVisibilityTracking(context: BindingContext, div: Div) { - divVisibilityActionTracker.trackVisibilityActionsOf(context.divView, context.expressionResolver, null, div) + private fun stopVisibilityTracking(div2View: Div2View, div: Div) { + divVisibilityActionTracker.trackVisibilityActionsOf(div2View, null, div) } private fun View.getWrappedTooltip(): View = diff --git a/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt b/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt index 726ab86f9..a6c5343a4 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt @@ -1,6 +1,5 @@ package com.yandex.div.core.util -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.buildItems import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver @@ -19,11 +18,11 @@ internal class DivTreeWalk private constructor( private val onEnter: ((Div) -> Boolean)?, private val onLeave: ((Div) -> Unit)?, private val maxDepth: Int = Int.MAX_VALUE -) : Sequence { +) : Sequence
{ internal constructor(root: Div, resolver: ExpressionResolver) : this(root, resolver, null, null) - override fun iterator(): Iterator = DivTreeWalkIterator(root, resolver) + override fun iterator(): Iterator
= DivTreeWalkIterator(root, resolver) /** * Sets a [predicate], that is called on any entered container div (div-container, div-gallery, etc.) @@ -62,103 +61,106 @@ internal class DivTreeWalk private constructor( private inner class DivTreeWalkIterator( private val root: Div, private val resolver: ExpressionResolver - ) : AbstractIterator() { + ) : AbstractIterator
() { private val stack = ArrayDeque().apply { - addLast(node(DivItemBuilderResult(root, resolver))) + addLast(node(root, resolver)) } override fun computeNext() { - val nextItem = nextItem() - if (nextItem != null) { - setNext(nextItem) + val nextDiv = nextDiv() + if (nextDiv != null) { + setNext(nextDiv) } else { done() } } - private fun nextItem(): DivItemBuilderResult? { + private fun nextDiv(): Div? { val node = stack.lastOrNull() ?: return null - val item = node.step() - return if (item == null) { + val div = node.step() + return if (div == null) { stack.removeLast() - nextItem() - } else if (item === node.item || item.div.isLeaf || stack.size >= maxDepth) { - item + nextDiv() + } else if (div === node.div || div.isLeaf || stack.size >= maxDepth) { + div } else { - stack.addLast(node(item)) - nextItem() + stack.addLast(node(div, resolver)) + nextDiv() } } - private fun node(item: DivItemBuilderResult): Node { - return if (item.div.isBranch) { - BranchNode(item, onEnter, onLeave) + private fun node(div: Div, resolver: ExpressionResolver): Node { + return if (div.isBranch) { + BranchNode(div, resolver, onEnter, onLeave) } else { - LeafNode(item) + LeafNode(div, resolver) } } } private interface Node { - val item: DivItemBuilderResult + val div: Div + val resolver: ExpressionResolver - fun step(): DivItemBuilderResult? + fun step(): Div? } private class LeafNode( - override val item: DivItemBuilderResult, + override val div: Div, + override val resolver: ExpressionResolver ) : Node { private var visited = false - override fun step(): DivItemBuilderResult? { + override fun step(): Div? { if (visited) { return null } visited = true - return item + return div } } private class BranchNode( - override val item: DivItemBuilderResult, + override val div: Div, + override val resolver: ExpressionResolver, private val onEnter: ((Div) -> Boolean)?, private val onLeave: ((Div) -> Unit)? ) : Node { private var rootVisited = false - private var children: List? = null + private var children: List
? = null private var childIndex = 0 - override fun step(): DivItemBuilderResult? { + override fun step(): Div? { if (!rootVisited) { - if (onEnter?.invoke(item.div) == false) { + if (onEnter?.invoke(div) == false) { return null } rootVisited = true - return item + return div } var children = this.children if (children == null) { - children = item.div.getItems(item.expressionResolver) + children = div.getItems(resolver) this.children = children } return if (childIndex < children.size) { children[childIndex++] } else { - onLeave?.invoke(item.div) + onLeave?.invoke(div) null } } } } -private fun Div.getItems(resolver: ExpressionResolver): List { +private fun Div.getItems(resolver: ExpressionResolver): List
{ return when (this) { is Div.Text -> emptyList() is Div.Image -> emptyList() @@ -171,10 +173,10 @@ private fun Div.getItems(resolver: ExpressionResolver): List emptyList() is Div.Video -> emptyList() is Div.Container -> value.buildItems(resolver) - is Div.Grid -> value.nonNullItems.map { DivItemBuilderResult(it, resolver) } - is Div.Gallery -> value.nonNullItems.map { DivItemBuilderResult(it, resolver) } - is Div.Pager -> value.nonNullItems.map { DivItemBuilderResult(it, resolver) } - is Div.Tabs -> value.items.map { DivItemBuilderResult(it.div, resolver) } - is Div.State -> value.states.mapNotNull { state -> state.div?.let { DivItemBuilderResult(it, resolver) } } + is Div.Grid -> value.nonNullItems + is Div.Gallery -> value.nonNullItems + is Div.Pager -> value.nonNullItems + is Div.Tabs -> value.items.map { tab -> tab.div } + is Div.State -> value.states.mapNotNull { state -> state.div } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt b/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt index e5e98626b..36fa1d50f 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt @@ -131,7 +131,7 @@ internal fun Div.containsStateInnerTransitions(resolver: ExpressionResolver): Bo } return when (this) { is Div.Container -> value.buildItems(resolver) - .map { it.div.containsStateInnerTransitions(it.expressionResolver) } + .map { it.containsStateInnerTransitions(resolver) } .contains(true) is Div.Grid -> value.nonNullItems .map { it.containsStateInnerTransitions(resolver) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/BindingContext.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/BindingContext.kt deleted file mode 100644 index 36477aeb7..000000000 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/BindingContext.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.yandex.div.core.view2 - -import com.yandex.div.json.expressions.ExpressionResolver - -internal data class BindingContext( - val divView: Div2View, - val expressionResolver: ExpressionResolver -) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/Div2Builder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/Div2Builder.kt index 7e6f886df..b7fa37f73 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/Div2Builder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/Div2Builder.kt @@ -20,18 +20,18 @@ internal class Div2Builder @Inject constructor( private val viewBinder: DivBinder ) { - fun buildView(data: Div, context: BindingContext, path: DivStatePath): View { - val view = createView(data, context, path) + fun buildView(data: Div, divView: Div2View, path: DivStatePath): View { + val view = createView(data, divView, path) suppressExpressionErrors { - viewBinder.bind(context, view, data, path) + viewBinder.bind(view, data, divView, path) } return view } - fun createView(data: Div, context: BindingContext, path: DivStatePath): View { - val resolver = context.expressionResolver + fun createView(data: Div, divView: Div2View, path: DivStatePath): View { + val resolver = divView.expressionResolver val view = viewCreator.create(data, resolver).apply { layoutParams = DivLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/Div2View.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/Div2View.kt index c65686796..9066c2089 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/Div2View.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/Div2View.kt @@ -27,8 +27,8 @@ import com.yandex.div.core.DivViewFacade import com.yandex.div.core.annotations.Mockable import com.yandex.div.core.dagger.Div2Component import com.yandex.div.core.dagger.Div2ViewComponent -import com.yandex.div.core.downloader.PersistentDivDataObserver import com.yandex.div.core.downloader.DivDataChangedObserver +import com.yandex.div.core.downloader.PersistentDivDataObserver import com.yandex.div.core.expression.ExpressionsRuntime import com.yandex.div.core.expression.suppressExpressionErrors import com.yandex.div.core.expression.variables.VariableController @@ -59,7 +59,6 @@ import com.yandex.div.histogram.Div2ViewHistogramReporter import com.yandex.div.histogram.HistogramCallType import com.yandex.div.internal.Assert import com.yandex.div.internal.KAssert -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.util.hasScrollableChildUnder import com.yandex.div.internal.util.immutableCopy import com.yandex.div.internal.widget.FrameContainerLayout @@ -70,7 +69,6 @@ import com.yandex.div.util.getInitialStateId import com.yandex.div2.Div import com.yandex.div2.DivAccessibility import com.yandex.div2.DivAction -import com.yandex.div2.DivBase import com.yandex.div2.DivData import com.yandex.div2.DivPatch import com.yandex.div2.DivTransitionSelector @@ -108,7 +106,6 @@ class Div2View private constructor( private val divDataChangedObservers = mutableListOf() private val persistentDivDataObservers = mutableListOf() private val viewToDivBindings = WeakHashMap() - private val divToBindingContextBindings = WeakHashMap() private val propagatedAccessibilityModes = WeakHashMap() private val bulkActionsHandler = BulkActionHandler() private val divVideoActionHandler: DivVideoActionHandler @@ -124,8 +121,6 @@ class Div2View private constructor( internal val oldExpressionResolver: ExpressionResolver get() = oldExpressionsRuntime?.expressionResolver ?: ExpressionResolver.EMPTY - internal var bindingContext: BindingContext = BindingContext(this, expressionResolver) - internal var divTimerEventDispatcher: DivTimerEventDispatcher? = null private val monitor = Any() @@ -187,7 +182,6 @@ class Div2View private constructor( if (oldExpressionsRuntime != _expressionsRuntime) { oldExpressionsRuntime?.clearBinding() } - bindingContext = BindingContext(this, expressionResolver) } private fun attachVariableTriggers() { @@ -404,33 +398,18 @@ class Div2View private constructor( } private fun trackStateVisibility(state: DivData.State) { - div2Component.visibilityActionTracker.trackVisibilityActionsOf( - this, - getExpressionResolver(state.div.value()), - view, - state.div - ) + div2Component.visibilityActionTracker.trackVisibilityActionsOf(this, view, state.div) } private fun discardStateVisibility(state: DivData.State) { - div2Component.visibilityActionTracker.trackVisibilityActionsOf( - scope = this, - resolver = getExpressionResolver(state.div.value()), - view = null, - div = state.div - ) + div2Component.visibilityActionTracker.trackVisibilityActionsOf(this, null, state.div) } fun trackChildrenVisibility() { val visibilityActionTracker = div2Component.visibilityActionTracker viewToDivBindings.forEach { (view, div) -> if (ViewCompat.isAttachedToWindow(view)) { - visibilityActionTracker.trackVisibilityActionsOf( - this, - getExpressionResolver(div.value()), - view, - div - ) + visibilityActionTracker.trackVisibilityActionsOf(this, view, div) } } } @@ -733,7 +712,7 @@ class Div2View private constructor( } if (bindBeforeViewAdded) { - div2Component.divBinder.bind(bindingContext, newStateView, newState.div, DivStatePath.fromState(newState.stateId)) + div2Component.divBinder.bind(newStateView, newState.div, this, DivStatePath.fromState(newState.stateId)) } if (transition != null) { @@ -762,7 +741,7 @@ class Div2View private constructor( isUpdateTemporary: Boolean = true ): View { div2Component.stateManager.updateState(dataTag, stateId, isUpdateTemporary) - return divBuilder.buildView(newState.div, bindingContext, DivStatePath.fromState(newState.stateId)).also { + return divBuilder.buildView(newState.div, this, DivStatePath.fromState(newState.stateId)).also { div2Component.divBinder.attachIndicators() } } @@ -774,16 +753,16 @@ class Div2View private constructor( ): View { div2Component.stateManager.updateState(dataTag, stateId, isUpdateTemporary) val path = DivStatePath.fromState(newState.stateId) - val view = divBuilder.createView(newState.div, bindingContext, path) + val view = divBuilder.createView(newState.div, this, path) if (bindOnAttachEnabled) { bindOnAttachRunnable = SingleTimeOnAttachCallback(this) { suppressExpressionErrors { - div2Component.divBinder.bind(bindingContext, view, newState.div, path) + div2Component.divBinder.bind(view, newState.div, this, path) } div2Component.divBinder.attachIndicators() } } else { - div2Component.divBinder.bind(bindingContext, view, newState.div, path) + div2Component.divBinder.bind(view, newState.div, this, path) doOnAttach { div2Component.divBinder.attachIndicators() } @@ -797,8 +776,8 @@ class Div2View private constructor( } val transition = viewComponent.transitionBuilder.buildTransitions( - from = oldDiv?.let { itemSequenceForTransition(oldData, it, oldExpressionResolver) }, - to = newDiv?.let { itemSequenceForTransition(newData, it, expressionResolver) }, + from = oldDiv?.let { divSequenceForTransition(oldData, it, oldExpressionResolver) }, + to = newDiv?.let { divSequenceForTransition(newData, it, expressionResolver) }, fromResolver = oldExpressionResolver, toResolver = expressionResolver ) @@ -816,11 +795,7 @@ class Div2View private constructor( return transition } - private fun itemSequenceForTransition( - divData: DivData?, - div: Div, - resolver: ExpressionResolver - ): Sequence { + private fun divSequenceForTransition(divData: DivData?, div: Div, resolver: ExpressionResolver): Sequence
{ val selectors = ArrayDeque().apply { addLast(divData?.transitionAnimationSelector?.evaluate(resolver) ?: DivTransitionSelector.NONE) } @@ -833,8 +808,8 @@ class Div2View private constructor( .onLeave { div -> if (div is Div.State) selectors.removeLast() } - .filter { item -> - item.div.value().transitionTriggers?.allowsTransitionsOnDataChange() + .filter { div -> + div.value().transitionTriggers?.allowsTransitionsOnDataChange() ?: selectors.lastOrNull()?.allowsTransitionsOnDataChange() ?: false } @@ -849,28 +824,18 @@ class Div2View private constructor( } @JvmOverloads - fun handleAction( - action: DivAction, - reason: String = DivActionReason.EXTERNAL, - expressionResolver: ExpressionResolver = getExpressionResolver(), - ) { - handleActionWithResult(action, reason, expressionResolver) + fun handleAction(action: DivAction, reason: String = DivActionReason.EXTERNAL) { + handleActionWithResult(action, reason) } @JvmOverloads - fun handleActionWithResult( - action: DivAction, - reason: String = DivActionReason.EXTERNAL, - expressionResolver: ExpressionResolver = getExpressionResolver(), - ): Boolean { + fun handleActionWithResult(action: DivAction, reason: String = DivActionReason.EXTERNAL): Boolean { return div2Component.actionBinder.handleAction( divView = this, - expressionResolver, action = action, reason = reason, actionUid = null, - viewActionHandler = actionHandler - ) + viewActionHandler = actionHandler) } override fun handleUri(uri: Uri) { @@ -928,18 +893,12 @@ class Div2View private constructor( return _expressionsRuntime?.expressionResolver ?: ExpressionResolver.EMPTY } - fun getExpressionResolver(div: DivBase?): ExpressionResolver { - return divToBindingContextBindings[div]?.expressionResolver ?: expressionResolver - } - - internal fun getBindingContext(div: DivBase?) = divToBindingContextBindings[div] ?: bindingContext - override fun showTooltip(tooltipId: String) { - tooltipController.showTooltip(tooltipId, bindingContext) + tooltipController.showTooltip(tooltipId, this) } override fun showTooltip(tooltipId: String, multiple: Boolean) { - tooltipController.showTooltip(tooltipId, bindingContext, multiple) + tooltipController.showTooltip(tooltipId, this, multiple) } override fun hideTooltip(tooltipId: String) { @@ -947,7 +906,7 @@ class Div2View private constructor( } override fun cancelTooltips() { - tooltipController.cancelTooltips(bindingContext) + tooltipController.cancelTooltips(this) } override fun dispatchDraw(canvas: Canvas) { @@ -968,10 +927,6 @@ class Div2View private constructor( viewToDivBindings[view] = div } - internal fun bindDivToBindingContext(div: DivBase?, context: BindingContext) { - divToBindingContextBindings[div] = context - } - internal fun takeBindingDiv(view: View) = viewToDivBindings[view] internal fun setPropagatedAccessibilityMode(view: View, mode: DivAccessibility.Mode) { @@ -1040,8 +995,6 @@ class Div2View private constructor( internal fun unbindViewFromDiv(view: View): Div? = viewToDivBindings.remove(view) - internal fun unbindDivFromBindingContext(div: DivBase?) = divToBindingContextBindings.remove(div) - private fun rebind(newData: DivData, isAutoanimations: Boolean) { try { if (childCount == 0) { @@ -1057,7 +1010,7 @@ class Div2View private constructor( } divData = newData div2Component.stateManager.updateState(dataTag, state.stateId, true) - div2Component.divBinder.bind(bindingContext, rootDivView, state.div, DivStatePath.fromState(stateId)) + div2Component.divBinder.bind(rootDivView, state.div, this, DivStatePath.fromState(stateId)) requestLayout() if (isAutoanimations) { div2Component.divStateChangeListener.onDivAnimatedStateChanged(this) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt index f56e6eaa8..bc8717390 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt @@ -87,17 +87,16 @@ internal class DivBinder @Inject constructor( private val pagerIndicatorConnector: PagerIndicatorConnector ) { @MainThread - fun bind(context: BindingContext, view: View, div: Div, path: DivStatePath) = suppressExpressionErrors { - context.divView.currentRebindReusableList?.pop(div)?.let { + fun bind(view: View, div: Div, divView: Div2View, path: DivStatePath) = suppressExpressionErrors { + divView.currentRebindReusableList?.pop(div)?.let { return@suppressExpressionErrors } - if (!validator.validate(div, context.expressionResolver)) { - bindLayoutParams(view, div.value(), context.expressionResolver) + if (!validator.validate(div, divView.expressionResolver)) { + bindLayoutParams(view, div.value(), divView.expressionResolver) return } - val divView = context.divView extensionController.beforeBindView(divView, view, div.value()) if (div !is Div.Custom) { @@ -105,22 +104,22 @@ internal class DivBinder @Inject constructor( } return when (div) { - is Div.Text -> bindText(context, view, div.value) - is Div.Image -> bindImage(context, view, div.value) - is Div.GifImage -> bindGifImage(context, view, div.value) - is Div.Separator -> bindSeparator(context, view, div.value) - is Div.Container -> bindContainer(context, view, div.value, path) - is Div.Grid -> bindGrid(context, view, div.value, path) - is Div.Gallery -> bindGallery(context, view, div.value, path) - is Div.Pager -> bindPager(context, view, div.value, path) - is Div.Tabs -> bindTabs(context, view, div.value, path) - is Div.State -> bindState(context, view, div.value, path) - is Div.Custom -> bindCustom(context, view, div.value, path) - is Div.Indicator -> bindIndicator(context, view, div.value) - is Div.Slider -> bindSlider(context, view, div.value) - is Div.Input -> bindInput(context, view, div.value) - is Div.Select -> bindSelect(context, view, div.value) - is Div.Video -> bindVideo(context, view, div.value) + is Div.Text -> bindText(view, div.value, divView) + is Div.Image -> bindImage(view, div.value, divView) + is Div.GifImage -> bindGifImage(view, div.value, divView) + is Div.Separator -> bindSeparator(view, div.value, divView) + is Div.Container -> bindContainer(view, div.value, divView, path) + is Div.Grid -> bindGrid(view, div.value, divView, path) + is Div.Gallery -> bindGallery(view, div.value, divView, path) + is Div.Pager -> bindPager(view, div.value, divView, path) + is Div.Tabs -> bindTabs(view, div.value, divView, path) + is Div.State -> bindState(view, div.value, divView, path) + is Div.Custom -> bindCustom(view, div.value, divView, path) + is Div.Indicator -> bindIndicator(view, div.value, divView) + is Div.Slider -> bindSlider(view, div.value, divView) + is Div.Input -> bindInput(view, div.value, divView) + is Div.Select -> bindSelect(view, div.value, divView) + is Div.Video -> bindVideo(view, div.value, divView) }.also { // extensionController bound new CustomView in DivCustomBinder after replacing in parent if (div !is Div.Custom) { @@ -134,68 +133,68 @@ internal class DivBinder @Inject constructor( pagerIndicatorConnector.attach() } - private fun bindText(context: BindingContext, view: View, data: DivText) { - textBinder.bindView(context, view as DivLineHeightTextView, data) + private fun bindText(view: View, data: DivText, divView: Div2View) { + textBinder.bindView(view as DivLineHeightTextView, data, divView) } - private fun bindImage(context: BindingContext, view: View, data: DivImage) { - imageBinder.bindView(context, view as DivImageView, data) + private fun bindImage(view: View, data: DivImage, divView: Div2View) { + imageBinder.bindView(view as DivImageView, data, divView) } - private fun bindGifImage(context: BindingContext, view: View, data: DivGifImage) { - gifImageBinder.bindView(context, view as DivGifImageView, data) + private fun bindGifImage(view: View, data: DivGifImage, divView: Div2View) { + gifImageBinder.bindView(view as DivGifImageView, data, divView) } - private fun bindSeparator(context: BindingContext, view: View, data: DivSeparator) { - separatorBinder.bindView(context, view as DivSeparatorView, data) + private fun bindSeparator(view: View, data: DivSeparator, divView: Div2View) { + separatorBinder.bindView(view as DivSeparatorView, data, divView) } - private fun bindContainer(context: BindingContext, view: View, data: DivContainer, path: DivStatePath) { - containerBinder.bindView(context, view as ViewGroup, data, path) + private fun bindContainer(view: View, data: DivContainer, divView: Div2View, path: DivStatePath) { + containerBinder.bindView(view as ViewGroup, data, divView, path) } - private fun bindGrid(context: BindingContext, view: View, data: DivGrid, path: DivStatePath) { - gridBinder.bindView(context, view as DivGridLayout, data, path) + private fun bindGrid(view: View, data: DivGrid, divView: Div2View, path: DivStatePath) { + gridBinder.bindView(view as DivGridLayout, data, divView, path) } - private fun bindGallery(context: BindingContext, view: View, data: DivGallery, path: DivStatePath) { - galleryBinder.bindView(context, view as DivRecyclerView, data, path) + private fun bindGallery(view: View, data: DivGallery, divView: Div2View, path: DivStatePath) { + galleryBinder.bindView(view as DivRecyclerView, data, divView, path) } - private fun bindPager(context: BindingContext, view: View, data: DivPager, path: DivStatePath) { - pagerBinder.bindView(context, view as DivPagerView, data, path) + private fun bindPager(view: View, data: DivPager, divView: Div2View, path: DivStatePath) { + pagerBinder.bindView(view as DivPagerView, data, divView, path) } - private fun bindTabs(context: BindingContext, view: View, data: DivTabs, path: DivStatePath) { - tabsBinder.bindView(context, view as DivTabsLayout, data, this, path) + private fun bindTabs(view: View, data: DivTabs, divView: Div2View, path: DivStatePath) { + tabsBinder.bindView(view as DivTabsLayout, data, divView, this, path) } - private fun bindState(context: BindingContext, view: View, data: DivState, path: DivStatePath) { - stateBinder.bindView(context, view as DivStateLayout, data, path) + private fun bindState(view: View, data: DivState, divView: Div2View, path: DivStatePath) { + stateBinder.bindView(view as DivStateLayout, data, divView, path) } - private fun bindCustom(context: BindingContext, view: View, data: DivCustom, path: DivStatePath) { - customBinder.bindView(context, view as DivCustomWrapper, data, path) + private fun bindCustom(view: View, data: DivCustom, divView: Div2View, path: DivStatePath) { + customBinder.bindView(view as DivCustomWrapper, data, divView, path) } - private fun bindIndicator(context: BindingContext, view: View, data: DivIndicator) { - indicatorBinder.bindView(context, view as DivPagerIndicatorView, data) + private fun bindIndicator(view: View, data: DivIndicator, divView: Div2View) { + indicatorBinder.bindView(view as DivPagerIndicatorView, data, divView) } - private fun bindSlider(context: BindingContext, view: View, data: DivSlider) { - sliderBinder.bindView(context, view as DivSliderView, data) + private fun bindSlider(view: View, data: DivSlider, divView: Div2View) { + sliderBinder.bindView(view as DivSliderView, data, divView) } - private fun bindInput(context: BindingContext, view: View, data: DivInput) { - inputBinder.bindView(context, view as DivInputView, data) + private fun bindInput(view: View, data: DivInput, divView: Div2View) { + inputBinder.bindView(view as DivInputView, data, divView) } - private fun bindSelect(context: BindingContext, view: View, data: DivSelect) { - selectBinder.bindView(context, view as DivSelectView, data) + private fun bindSelect(view: View, data: DivSelect, divView: Div2View) { + selectBinder.bindView(view as DivSelectView, data, divView) } - private fun bindVideo(context: BindingContext, view: View, data: DivVideo) { - videoBinder.bindView(context, view as DivVideoView, data) + private fun bindVideo(view: View, data: DivVideo, divView: Div2View) { + videoBinder.bindView(view as DivVideoView, data, divView) } private fun bindLayoutParams(view: View, data: DivBase, resolver: ExpressionResolver) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt index 16199a741..f7ef70506 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt @@ -88,7 +88,7 @@ class DivImagePreloader @Inject constructor( override fun visit(data: Div.Container, resolver: ExpressionResolver) { defaultVisit(data, resolver) if (visitContainers) { - data.value.buildItems(resolver).forEach { visit(it.div, it.expressionResolver) } + data.value.buildItems(resolver).forEach { visit(it, resolver) } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivTransitionBuilder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivTransitionBuilder.kt index 7063847cc..4d5a5af7a 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivTransitionBuilder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivTransitionBuilder.kt @@ -17,7 +17,6 @@ import com.yandex.div.core.view2.animations.Scale import com.yandex.div.core.view2.animations.Slide import com.yandex.div.core.view2.animations.plusAssign import com.yandex.div.core.view2.divs.toPx -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivAppearanceTransition @@ -52,8 +51,8 @@ internal class DivTransitionBuilder @Inject constructor( } fun buildTransitions( - from: Sequence?, - to: Sequence?, + from: Sequence
?, + to: Sequence
?, fromResolver: ExpressionResolver, toResolver: ExpressionResolver, ): TransitionSet { @@ -77,14 +76,14 @@ internal class DivTransitionBuilder @Inject constructor( } private fun buildOutgoingTransitions( - itemSequence: Sequence, + divSequence: Sequence
, resolver: ExpressionResolver ): List { val transitions = mutableListOf() - itemSequence.forEach { item -> - val id = item.div.value().id - val outgoingTransition = item.div.value().transitionOut + divSequence.forEach { div -> + val id = div.value().id + val outgoingTransition = div.value().transitionOut if (id != null && outgoingTransition != null) { val transition = outgoingTransition.toAndroidTransition(Visibility.MODE_OUT, resolver).apply { addTarget(viewIdProvider.getViewId(id)) @@ -97,14 +96,14 @@ internal class DivTransitionBuilder @Inject constructor( } private fun buildChangeTransitions( - itemSequence: Sequence, + divSequence: Sequence
, resolver: ExpressionResolver ): List { val transitions = mutableListOf() - itemSequence.forEach { item -> - val id = item.div.value().id - val changeTransition = item.div.value().transitionChange + divSequence.forEach { div -> + val id = div.value().id + val changeTransition = div.value().transitionChange if (id != null && changeTransition != null) { val transition = changeTransition.toAndroidTransition(resolver).apply { addTarget(viewIdProvider.getViewId(id)) @@ -117,14 +116,14 @@ internal class DivTransitionBuilder @Inject constructor( } private fun buildIncomingTransitions( - itemSequence: Sequence, + divSequence: Sequence
, resolver: ExpressionResolver ): List { val transitions = mutableListOf() - itemSequence.forEach { item -> - val id = item.div.value().id - val incomingTransition = item.div.value().transitionIn + divSequence.forEach { div -> + val id = div.value().id + val incomingTransition = div.value().transitionIn if (id != null && incomingTransition != null) { val transition = incomingTransition.toAndroidTransition(Visibility.MODE_IN, resolver).apply { addTarget(viewIdProvider.getViewId(id)) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewBinder.kt index d12668ea2..2e75d24b4 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewBinder.kt @@ -13,9 +13,9 @@ internal interface DivViewBinder { /** * Binds div's data to templated view */ - fun bindView(context: BindingContext, view: TView, div: TData) = Unit + fun bindView(view: TView, div: TData, divView: Div2View) = Unit - fun bindView(context: BindingContext, view: TView, div: TData, path: DivStatePath) { - bindView(context, view, div) + fun bindView(view: TView, div: TData, divView: Div2View, path: DivStatePath) { + bindView(view, div, divView) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt index 058fbfa8f..4e7529f46 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt @@ -118,8 +118,8 @@ internal class DivViewCreator @Inject constructor( override fun visit(data: Div.Container, resolver: ExpressionResolver): View { val view = defaultVisit(data, resolver) as ViewGroup - data.value.buildItems(resolver).forEach { item -> - view.addView(create(item.div, item.expressionResolver)) + data.value.buildItems(resolver).forEach { childData -> + view.addView(create(childData, resolver)) } return view } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionDispatcher.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionDispatcher.kt index e26ba6b9d..83da89b45 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionDispatcher.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionDispatcher.kt @@ -10,7 +10,6 @@ import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.view2.divs.DivActionBeaconSender import com.yandex.div.internal.KLog import com.yandex.div.internal.util.arrayMap -import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivDisappearAction import com.yandex.div2.DivSightAction @@ -29,34 +28,34 @@ internal class DivVisibilityActionDispatcher @Inject constructor( private val actionLogCounters = arrayMap() - fun dispatchActions(scope: Div2View, resolver: ExpressionResolver, view: View, actions: Array) { + fun dispatchActions(scope: Div2View, view: View, actions: Array) { scope.bulkActions { actions.forEach { - dispatchAction(scope, resolver, view, it) + dispatchAction(scope, view, it) } } } - fun dispatchAction(scope: Div2View, resolver: ExpressionResolver, view: View, action: DivSightAction) { + fun dispatchAction(scope: Div2View, view: View, action: DivSightAction) { val compositeLogId = compositeLogIdOf(scope, action) val counter = actionLogCounters.getOrPut(compositeLogId) { 0 } KLog.d(TAG) { "visibility action dispatched: id=$compositeLogId, counter=$counter" } - val logLimit = action.logLimit.evaluate(resolver) + val logLimit = action.logLimit.evaluate(scope.expressionResolver) if (logLimit == LIMITLESS_LOG || counter < logLimit) { - if (divActionHandler.useActionUid) { + if (divActionHandler.useActionUid == true) { val uuid = UUID.randomUUID().toString() // try to handle scheme if it is known, otherwise log val handled = scope.actionHandler?.handleAction(action, scope, uuid) ?: false if (!handled && !divActionHandler.handleAction(action, scope, uuid)) { - logAction(scope, resolver, view, action, uuid) + logAction(scope, view, action, uuid) } } else { // try to handle scheme if it is known, otherwise log val handled = scope.actionHandler?.handleAction(action, scope) ?: false if (!handled && !divActionHandler.handleAction(action, scope)) { - logAction(scope, resolver, view, action) + logAction(scope, view, action) } } @@ -65,28 +64,22 @@ internal class DivVisibilityActionDispatcher @Inject constructor( } } - private fun logAction(scope: Div2View, resolver: ExpressionResolver, view: View, action: DivSightAction) { + private fun logAction(scope: Div2View, view: View, action: DivSightAction) { if (action is DivVisibilityAction) { logger.logViewShown(scope, view, action) } else { logger.logViewDisappeared(scope, view, action as DivDisappearAction) } - divActionBeaconSender.sendVisibilityActionBeacon(action, resolver) + divActionBeaconSender.sendVisibilityActionBeacon(action, scope.expressionResolver) } - private fun logAction( - scope: Div2View, - resolver: ExpressionResolver, - view: View, - action: DivSightAction, - actionUid: String - ) { + private fun logAction(scope: Div2View, view: View, action: DivSightAction, actionUid: String) { if (action is DivVisibilityAction) { logger.logViewShown(scope, view, action, actionUid) } else { logger.logViewDisappeared(scope, view, action as DivDisappearAction, actionUid) } - divActionBeaconSender.sendVisibilityActionBeacon(action, resolver) + divActionBeaconSender.sendVisibilityActionBeacon(action, scope.expressionResolver) } fun dispatchVisibleViewsChanged(visibleViews: Map) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt index 3083036c6..9a6870a7b 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivVisibilityActionTracker.kt @@ -15,7 +15,6 @@ import com.yandex.div.core.view2.divs.duration import com.yandex.div.internal.Assert import com.yandex.div.internal.KAssert import com.yandex.div.internal.KLog -import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivDisappearAction import com.yandex.div2.DivSightAction @@ -35,11 +34,11 @@ internal class DivVisibilityActionTracker @Inject constructor( private val trackedTokens = DivVisibilityTokenHolder() private val isEnabledObserver = SightActionIsEnabledObserver( - onEnable = { scope, resolver, view, div, action -> - trackVisibilityActions(scope, resolver, view, div, listOf(action)) + onEnable = { scope, view, div, action -> + trackVisibilityActions(scope, view, div, listOf(action)) }, - onDisable = { scope, resolver, _, div, action -> - shouldTrackVisibilityAction(scope, resolver, null, action, 0) + onDisable = { scope, _, div, action -> + shouldTrackVisibilityAction(scope, null, action, 0) } ) @@ -75,7 +74,6 @@ internal class DivVisibilityActionTracker @Inject constructor( @AnyThread fun trackVisibilityActionsOf( scope: Div2View, - resolver: ExpressionResolver, view: View?, div: Div, visibilityActions: List = div.value().allSightActions @@ -90,9 +88,9 @@ internal class DivVisibilityActionTracker @Inject constructor( action = { // Prevent visibility tracking when data has changed if (scope.divData === originalDivData) { - isEnabledObserver.observe(view, scope, resolver, div, visibilityActions) - trackVisibilityActions(scope, resolver, view, div, visibilityActions.filter { - it.isEnabled.evaluate(resolver) + isEnabledObserver.observe(view, scope, div, visibilityActions) + trackVisibilityActions(scope, view, div, visibilityActions.filter { + it.isEnabled.evaluate(scope.expressionResolver) }) } @@ -106,47 +104,45 @@ internal class DivVisibilityActionTracker @Inject constructor( // Canceling tracking isEnabledObserver.cancelObserving(visibilityActions) visibilityActions.forEach { action -> - shouldTrackVisibilityAction(scope, resolver, view, action, 0) + shouldTrackVisibilityAction(scope, view, action, 0) } } } fun trackDetachedView( - context: BindingContext, + scope: Div2View, view: View, div: Div ) { val actions = div.value().disappearActions ?: return - trackVisibilityActions(context.divView, context.expressionResolver, view, div, actions.filter { - it.isEnabled.evaluate(context.expressionResolver) + trackVisibilityActions(scope, view, div, actions.filter { + it.isEnabled.evaluate(scope.expressionResolver) }) } - fun startTrackingViewsHierarchy(context: BindingContext, root: View, rootDiv: Div?) { - trackViewsHierarchy(context, root, rootDiv) { currentView, currentDiv -> + fun startTrackingViewsHierarchy(scope: Div2View, root: View, rootDiv: Div?) { + trackViewsHierarchy(scope, root, rootDiv) { currentView, currentDiv -> val isViewFullyVisible = viewVisibilityCalculator.isViewFullyVisible(currentView) if (isViewFullyVisible && previousVisibilityIsFull[currentView] == true) { false } else { previousVisibilityIsFull[currentView] = isViewFullyVisible - currentDiv?.let { - trackVisibilityActionsOf(context.divView, context.expressionResolver, currentView, it) - } + currentDiv?.let { trackVisibilityActionsOf(scope, currentView, it) } true } } } - fun cancelTrackingViewsHierarchy(context: BindingContext, root: View, div: Div?) { - trackViewsHierarchy(context, root, div) { currentView, currentDiv -> + fun cancelTrackingViewsHierarchy(scope: Div2View, root: View, div: Div?) { + trackViewsHierarchy(scope, root, div) { currentView, currentDiv -> previousVisibilityIsFull.remove(currentView) - currentDiv?.let { trackVisibilityActionsOf(context.divView, context.expressionResolver, null, it) } + currentDiv?.let { trackVisibilityActionsOf(scope, null, it) } true } } private fun trackViewsHierarchy( - context: BindingContext, + scope: Div2View, view: View, div: Div?, trackAction: (View, Div?) -> Boolean @@ -155,14 +151,13 @@ internal class DivVisibilityActionTracker @Inject constructor( return } view.children.forEach { - val childDiv = context.divView.takeBindingDiv(it) - trackViewsHierarchy(context, it, childDiv, trackAction) + val childDiv = scope.takeBindingDiv(it) + trackViewsHierarchy(scope, it, childDiv, trackAction) } } private fun trackVisibilityActions( scope: Div2View, - resolver: ExpressionResolver, view: View, div: Div, visibilityActions: List @@ -176,13 +171,13 @@ internal class DivVisibilityActionTracker @Inject constructor( } visibilityActions.groupBy { action: DivSightAction -> - action.duration.evaluate(resolver) + action.duration.evaluate(scope.expressionResolver) }.forEach { entry: Map.Entry> -> val (delayMs, actions) = entry var haveWaitingDisappearActions = false actions.filterIsInstance().forEach { - val actionPercentage = it.visibilityPercentage.evaluate(resolver) + val actionPercentage = it.visibilityPercentage.evaluate(scope.expressionResolver) val needWaiting = visibilityPercentage > actionPercentage haveWaitingDisappearActions = haveWaitingDisappearActions || needWaiting if (needWaiting) { @@ -194,10 +189,10 @@ internal class DivVisibilityActionTracker @Inject constructor( } val actionsToBeTracked = actions.filterTo(ArrayList(actions.size)) { action -> - shouldTrackVisibilityAction(scope, resolver, view, action, visibilityPercentage) + shouldTrackVisibilityAction(scope, view, action, visibilityPercentage) } if (actionsToBeTracked.isNotEmpty()) { - startTracking(scope, resolver, view, actionsToBeTracked, delayMs) + startTracking(scope, view, actionsToBeTracked, delayMs) } } } @@ -207,18 +202,17 @@ internal class DivVisibilityActionTracker @Inject constructor( */ private fun shouldTrackVisibilityAction( scope: Div2View, - resolver: ExpressionResolver, view: View?, action: DivSightAction, visibilityPercentage: Int ): Boolean { val trackable = when (action) { is DivVisibilityAction -> { - visibilityPercentage >= action.visibilityPercentage.evaluate(resolver) + visibilityPercentage >= action.visibilityPercentage.evaluate(scope.expressionResolver) } is DivDisappearAction -> { (appearedForDisappearActions[view]?.contains(action) ?: false) && - visibilityPercentage <= action.visibilityPercentage.evaluate(resolver) + visibilityPercentage <= action.visibilityPercentage.evaluate(scope.expressionResolver) } else -> { KAssert.fail { "Trying to check visibility for class without known visibility range" } @@ -244,7 +238,6 @@ internal class DivVisibilityActionTracker @Inject constructor( private fun startTracking( scope: Div2View, - resolver: ExpressionResolver, view: View, actions: List, delayMs: Long @@ -266,7 +259,7 @@ internal class DivVisibilityActionTracker @Inject constructor( divWithWaitingDisappearActions.remove(view) } } - visibilityActionDispatcher.dispatchActions(scope, resolver, view, logIds.values.toTypedArray()) + visibilityActionDispatcher.dispatchActions(scope, view, logIds.values.toTypedArray()) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/SightActionIsEnabledObserver.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/SightActionIsEnabledObserver.kt index c978f71b0..94bbf9a47 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/SightActionIsEnabledObserver.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/SightActionIsEnabledObserver.kt @@ -4,15 +4,14 @@ import android.view.View import com.yandex.div.core.Disposable import com.yandex.div.core.view2.divs.allSightActions import com.yandex.div.internal.core.ExpressionSubscriber -import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivSightAction import java.lang.ref.WeakReference import java.util.WeakHashMap internal class SightActionIsEnabledObserver( - private val onEnable: (Div2View, ExpressionResolver, View, Div, DivSightAction) -> Unit, - private val onDisable: (Div2View, ExpressionResolver, View, Div, DivSightAction) -> Unit + private val onEnable: (Div2View, View, Div, DivSightAction) -> Unit, + private val onDisable: (Div2View, View, Div, DivSightAction) -> Unit ) { private val boundedActions = WeakHashMap>() @@ -23,7 +22,6 @@ internal class SightActionIsEnabledObserver( fun observe( view: View, div2View: Div2View, - resolver: ExpressionResolver, div: Div, actions: List = div.value().allSightActions ) { @@ -36,12 +34,13 @@ internal class SightActionIsEnabledObserver( }, onAdd = { action -> cancelObserving(action) + val resolver = div2View.expressionResolver subscriptions[action] = Subscription( disposable = action.isEnabled.observe(resolver) { isEnabled -> if (isEnabled) { - onEnable(div2View, resolver, view, div, action) + onEnable(div2View, view, div, action) } else { - onDisable(div2View, resolver, view, div, action) + onDisable(div2View, view, div, action) } }, owner = view diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt index 57471cfa9..38c7445bf 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt @@ -1,7 +1,6 @@ package com.yandex.div.core.view2.animations import com.yandex.div.core.view2.divs.isWrapContainer -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.buildItems import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver @@ -44,6 +43,8 @@ internal object DivComparator { return areValuesReplaceable(old.value(), new.value(), oldResolver, newResolver) && areChildrenReplaceable( extractChildren(old, oldResolver), extractChildren(new, newResolver), + oldResolver, + newResolver ) } @@ -71,22 +72,24 @@ internal object DivComparator { } fun areChildrenReplaceable( - oldChildren: List, - newChildren: List, + oldChildren: List
, + newChildren: List
, + oldResolver: ExpressionResolver, + newResolver: ExpressionResolver, ): Boolean { if (oldChildren.size != newChildren.size) { return false } return oldChildren.zip(newChildren).all { - areDivsReplaceable(it.first.div, it.second.div, it.first.expressionResolver, it.second.expressionResolver) + areDivsReplaceable(it.first, it.second, oldResolver, newResolver) } } - private fun extractChildren(div: Div, resolver: ExpressionResolver): List { + private fun extractChildren(div: Div, resolver: ExpressionResolver): List
{ return when (div) { is Div.Container -> div.value.buildItems(resolver) - is Div.Grid -> div.value.nonNullItems.map { DivItemBuilderResult(it, resolver) } + is Div.Grid -> div.value.nonNullItems is Div.Image -> emptyList() is Div.GifImage -> emptyList() is Div.Text -> emptyList() diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt index bc70a39dd..64f63a6d4 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/BaseDivViewExtensions.kt @@ -26,7 +26,6 @@ import com.yandex.div.core.state.DivStatePath import com.yandex.div.core.util.doOnActualLayout import com.yandex.div.core.util.isLayoutRtl import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivGestureListener @@ -38,7 +37,6 @@ import com.yandex.div.core.widget.AspectView import com.yandex.div.core.widget.FixedLineHeightView import com.yandex.div.core.widget.FixedLineHeightView.Companion.UNDEFINED_LINE_HEIGHT import com.yandex.div.internal.Log -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.ExpressionSubscriber import com.yandex.div.internal.drawable.CircleDrawable import com.yandex.div.internal.drawable.RoundedRectDrawable @@ -509,7 +507,7 @@ internal fun DivBlendMode.toPorterDuffMode(): PorterDuff.Mode { } internal fun View.applyDivActions( - context: BindingContext, + divView: Div2View, action: DivAction?, actions: List?, longTapActions: List?, @@ -517,27 +515,27 @@ internal fun View.applyDivActions( actionAnimation: DivAnimation, accessibility: DivAccessibility?, ) { - val actionBinder = context.divView.div2Component.actionBinder + val actionBinder = divView.div2Component.actionBinder val tapActions = if (actions.isNullOrEmpty()) { action?.let { listOf(it) } } else { actions } - actionBinder.bindDivActions(context, this, tapActions, longTapActions, doubleTapActions, + actionBinder.bindDivActions(divView, this, tapActions, longTapActions, doubleTapActions, actionAnimation, accessibility) } internal fun View.setAnimatedTouchListener( - context: BindingContext, + divView: Div2View, divAnimation: DivAnimation?, divGestureListener: DivGestureListener? ) { - val animations = divAnimation?.asTouchListener(context.expressionResolver, this) + val animations = divAnimation?.asTouchListener(divView.expressionResolver, this) // Avoid creating GestureDetector if unnecessary cause it's expensive. val gestureDetector = divGestureListener ?.takeUnless { it.onSingleTapListener == null && it.onDoubleTapListener == null } - ?.let { GestureDetectorCompat(context.divView.context, divGestureListener) } + ?.let { GestureDetectorCompat(divView.context, divGestureListener) } if (animations != null || gestureDetector != null) { //noinspection ClickableViewAccessibility @@ -602,7 +600,7 @@ internal fun View.bindLayoutParams(div: DivBase, resolver: ExpressionResolver) = */ internal fun View.bindStates( div: Div?, - context: BindingContext, + divView: Div2View, resolver: ExpressionResolver, binder: DivBinder, ) { @@ -621,7 +619,7 @@ internal fun View.bindStates( val divByPath = div.findDivState(path, resolver) if (divByPath != null) { val parentState = path.parentState() - binder.bind(context, layout, divByPath, parentState) + binder.bind(layout, divByPath, divView, parentState) } } } @@ -645,36 +643,21 @@ internal fun DivImageScale.toImageScale(): AspectImageView.Scale { } @MainThread -internal fun ViewGroup.trackVisibilityActions( - newItems: List, - oldItems: List?, - divView: Div2View -) { +internal fun ViewGroup.trackVisibilityActions(newDivs: List
, oldDivs: List
?, divView: Div2View) { val visibilityActionTracker = divView.div2Component.visibilityActionTracker - if (!oldItems.isNullOrEmpty()) { - val newLogIds = newItems.flatMap { it.div.value().allSightActions }.mapTo(HashSet()) { it.logId } + if (!oldDivs.isNullOrEmpty()) { + val newLogIds = newDivs.flatMap {it.value().allSightActions }.mapTo(HashSet()) { it.logId } - for (oldDiv in oldItems) { - val actionsToRemove = oldDiv.div.value().allSightActions.filter { it.logId !in newLogIds } - visibilityActionTracker.trackVisibilityActionsOf( - divView, - oldDiv.expressionResolver, - null, - oldDiv.div, - actionsToRemove - ) + for (oldDiv in oldDivs) { + val actionsToRemove = oldDiv.value().allSightActions.filter { it.logId !in newLogIds } + visibilityActionTracker.trackVisibilityActionsOf(divView, null, oldDiv, actionsToRemove) } } - if (newItems.isNotEmpty()) { + if (newDivs.isNotEmpty()) { doOnNextLayout { // Shortcut to check children are laid out at once - for ((view, item) in children zip newItems.asSequence()) { - visibilityActionTracker.trackVisibilityActionsOf( - divView, - item.expressionResolver, - view, - item.div - ) + for ((view, div) in children zip newDivs.asSequence()) { + visibilityActionTracker.trackVisibilityActionsOf(divView, view, div) } } } @@ -832,7 +815,7 @@ internal fun View.bindAspectRatio(newAspect: DivAspect?, oldAspect: DivAspect?, } internal fun View.applyBitmapFilters( - context: BindingContext, + divView: Div2View, bitmap: Bitmap, filters: List?, actionAfterFilters: (Bitmap) -> Unit @@ -842,8 +825,8 @@ internal fun View.applyBitmapFilters( return } - val resolver = context.expressionResolver - val bitmapEffectHelper = context.divView.div2Component.bitmapEffectHelper + val resolver = divView.expressionResolver + val bitmapEffectHelper = divView.div2Component.bitmapEffectHelper doOnActualLayout { val scale = max(height / bitmap.height.toFloat(), width / bitmap.width.toFloat()) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt index 9cc0f291c..b5316ca95 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivActionBinder.kt @@ -20,7 +20,6 @@ import com.yandex.div.core.experiments.Experiment.ACCESSIBILITY_ENABLED import com.yandex.div.core.experiments.Experiment.IGNORE_ACTION_MENU_ITEMS_ENABLED import com.yandex.div.core.experiments.Experiment.LONGTAP_ACTIONS_PASS_TO_CHILD_ENABLED import com.yandex.div.core.view2.AccessibilityDelegateWrapper -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivGestureListener import com.yandex.div.core.view2.divs.DivActionBinder.LogType.Companion.LOG_BLUR @@ -63,7 +62,7 @@ internal class DivActionBinder @Inject constructor( } fun bindDivActions( - context: BindingContext, + divView: Div2View, target: View, actions: List?, longTapActions: List?, @@ -71,18 +70,18 @@ internal class DivActionBinder @Inject constructor( actionAnimation: DivAnimation, accessibility: DivAccessibility?, ) { - val resolver = context.expressionResolver val onApply = { applyDivActions( - context = context, + divView = divView, target = target, - actions = actions.onlyEnabled(resolver), - doubleTapActions = doubleTapActions.onlyEnabled(resolver), - longTapActions = longTapActions.onlyEnabled(resolver), + actions = actions.onlyEnabled(divView.expressionResolver), + doubleTapActions = doubleTapActions.onlyEnabled(divView.expressionResolver), + longTapActions = longTapActions.onlyEnabled(divView.expressionResolver), actionAnimation = actionAnimation, accessibility = accessibility, ) } + val resolver = divView.expressionResolver with(target) { observe(actions, resolver) { onApply() } observe(longTapActions, resolver) { onApply() } @@ -92,7 +91,7 @@ internal class DivActionBinder @Inject constructor( } private fun applyDivActions( - context: BindingContext, + divView: Div2View, target: View, actions: List, longTapActions: List, @@ -106,20 +105,20 @@ internal class DivActionBinder @Inject constructor( val divGestureListener = DivGestureListener( awaitLongClick = longTapActions.isNotEmpty() || target.parentIsLongClickable() ) - bindLongTapActions(context, target, longTapActions, actions.isEmpty()) - bindDoubleTapActions(context, target, divGestureListener, doubleTapActions) + bindLongTapActions(divView, target, longTapActions, actions.isEmpty()) + bindDoubleTapActions(divView, target, divGestureListener, doubleTapActions) // Order is urgent: tap actions depend on double tap actions - bindTapActions(context, target, divGestureListener, actions, shouldIgnoreActionMenuItems) + bindTapActions(divView, target, divGestureListener, actions, shouldIgnoreActionMenuItems) target.setAnimatedTouchListener( - context, + divView, actionAnimation.takeUnless { allIsNullOrEmpty(actions, longTapActions, doubleTapActions) }, divGestureListener ) if (accessibilityEnabled) { - if (DivAccessibility.Mode.MERGE == context.divView.getPropagatedAccessibilityMode(target) && - context.divView.isDescendantAccessibilityMode(target)) { + if (DivAccessibility.Mode.MERGE == divView.getPropagatedAccessibilityMode(target) && + divView.isDescendantAccessibilityMode(target)) { target.isClickable = clickableState target.isLongClickable = longClickableState } @@ -167,7 +166,7 @@ internal class DivActionBinder @Inject constructor( } private fun bindTapActions( - context: BindingContext, + divView: Div2View, target: View, divGestureListener: DivGestureListener, actions: List, @@ -195,23 +194,24 @@ internal class DivActionBinder @Inject constructor( } if (menuAction != null) { - prepareMenu(target, context, menuAction) { overflowMenuWrapper -> + prepareMenu(target, divView, menuAction) { overflowMenuWrapper -> setTapListener { - logger.logClick(context.divView, target, menuAction) - divActionBeaconSender.sendTapActionBeacon(menuAction, context.expressionResolver) + logger.logClick(divView, target, menuAction) + divActionBeaconSender.sendTapActionBeacon(menuAction, + divView.expressionResolver) overflowMenuWrapper.onMenuClickListener.onClick(target) } } } else { setTapListener { - handleBulkActions(context, target, actions) + handleBulkActions(divView, target, actions) } } } private fun bindLongTapActions( - context: BindingContext, + divView: Div2View, target: View, actions: List, noClickAction: Boolean @@ -225,20 +225,21 @@ internal class DivActionBinder @Inject constructor( !action.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems } if (menuAction != null) { - prepareMenu(target, context, menuAction) { overflowMenuWrapper -> + prepareMenu(target, divView, menuAction) { overflowMenuWrapper -> target.setOnLongClickListener { val uuid = UUID.randomUUID().toString() - divActionBeaconSender.sendTapActionBeacon(menuAction, context.expressionResolver) + divActionBeaconSender.sendTapActionBeacon(menuAction, + divView.expressionResolver) overflowMenuWrapper.onMenuClickListener.onClick(target) - actions.forEach { action -> logger.logLongClick(context.divView, target, action, uuid) } + actions.forEach { action -> logger.logLongClick(divView, target, action, uuid) } return@setOnLongClickListener true } } } else { target.setOnLongClickListener { - handleBulkActions(context, target, actions, actionLogType = LOG_LONG_CLICK) + handleBulkActions(divView, target, actions, actionLogType = LOG_LONG_CLICK) return@setOnLongClickListener true } @@ -270,7 +271,7 @@ internal class DivActionBinder @Inject constructor( } private fun bindDoubleTapActions( - context: BindingContext, + divView: Div2View, target: View, divGestureListener: DivGestureListener, actions: List @@ -284,32 +285,31 @@ internal class DivActionBinder @Inject constructor( !action.menuItems.isNullOrEmpty() && !shouldIgnoreActionMenuItems } if (menuAction != null) { - prepareMenu(target, context, menuAction) { overflowMenuWrapper -> + prepareMenu(target, divView, menuAction) { overflowMenuWrapper -> divGestureListener.onDoubleTapListener = { - logger.logDoubleClick(context.divView, target, menuAction) - divActionBeaconSender.sendTapActionBeacon(menuAction, context.expressionResolver) + logger.logDoubleClick(divView, target, menuAction) + divActionBeaconSender.sendTapActionBeacon(menuAction, + divView.expressionResolver) overflowMenuWrapper.onMenuClickListener.onClick(target) } } } else { divGestureListener.onDoubleTapListener = { - handleBulkActions(context, target, actions, actionLogType = LOG_DOUBLE_CLICK) + handleBulkActions(divView, target, actions, actionLogType = LOG_DOUBLE_CLICK) } } } internal fun handleBulkActions( - context: BindingContext, + divView: Div2View, target: View, actions: List, @LogType actionLogType: String = LOG_CLICK ) { - val divView = context.divView - val resolver = context.expressionResolver divView.bulkActions { val uuid = UUID.randomUUID().toString() - actions.onlyEnabled(resolver).forEach { action -> + actions.onlyEnabled(divView.expressionResolver).forEach { action -> when(actionLogType) { LOG_CLICK -> logger.logClick(divView, target, action, uuid) LOG_LONG_CLICK -> logger.logLongClick(divView, target, action, uuid) @@ -318,8 +318,9 @@ internal class DivActionBinder @Inject constructor( LOG_BLUR -> logger.logFocusChanged(divView, target, action, false) else -> Assert.fail("Please, add new logType") } - divActionBeaconSender.sendTapActionBeacon(action, resolver) - handleAction(divView, resolver, action, actionLogType.toDivActionReason(), uuid) + divActionBeaconSender.sendTapActionBeacon(action, + divView.expressionResolver) + handleAction(divView, action, actionLogType.toDivActionReason(), uuid) } } } @@ -333,26 +334,20 @@ internal class DivActionBinder @Inject constructor( else -> DivActionReason.EXTERNAL } - internal fun handleActions( - divView: DivViewFacade, - resolver: ExpressionResolver, - actions: List?, - reason: String - ) { + internal fun handleActions(divView: DivViewFacade, actions: List?, reason: String) { if (actions == null) return val viewActionHandler = (divView as? Div2View)?.actionHandler - actions.forEach { handleAction(divView, resolver, it, reason, null, viewActionHandler) } + actions.forEach { handleAction(divView, it, reason, null, viewActionHandler) } } internal fun handleAction( divView: DivViewFacade, - resolver: ExpressionResolver, action: DivAction, reason: String, actionUid: String? = null, viewActionHandler: DivActionHandler? = (divView as? Div2View)?.actionHandler, ): Boolean { - if (!action.isEnabled.evaluate(resolver)) return false + if (!action.isEnabled.evaluate(divView.expressionResolver)) return false if (actionHandler.useActionUid && actionUid != null) { if (viewActionHandler?.handleActionWithReason( action, divView, actionUid, reason) == true) { @@ -367,23 +362,24 @@ internal class DivActionBinder @Inject constructor( } } - internal fun handleTapClick(context: BindingContext, target: View, actions: List) { - val enabledActions = actions.onlyEnabled(context.expressionResolver) + internal fun handleTapClick(divView: Div2View, target: View, actions: List) { + val enabledActions = actions.onlyEnabled(divView.expressionResolver) val menuAction = enabledActions.firstOrNull { action -> !action.menuItems.isNullOrEmpty() } if (menuAction != null) { - prepareMenu(target, context, menuAction) { overflowMenuWrapper -> - logger.logClick(context.divView, target, menuAction) - divActionBeaconSender.sendTapActionBeacon(menuAction, context.expressionResolver) + prepareMenu(target, divView, menuAction) { overflowMenuWrapper -> + logger.logClick(divView, target, menuAction) + divActionBeaconSender.sendTapActionBeacon(menuAction, + divView.expressionResolver) overflowMenuWrapper.onMenuClickListener.onClick(target) } } else { - handleBulkActions(context, target, enabledActions) + handleBulkActions(divView, target, enabledActions) } } private inline fun prepareMenu( target: View, - context: BindingContext, + divView: Div2View, action: DivAction, onPrepared: (OverflowMenuWrapper) -> Unit ) { @@ -396,11 +392,11 @@ internal class DivActionBinder @Inject constructor( val overflowMenuWrapper = OverflowMenuWrapper( target.context, target, - context.divView + divView ) - .listener(MenuWrapperListener(context, menuItems)) + .listener(MenuWrapperListener(divView, menuItems)) .overflowGravity(Gravity.RIGHT or Gravity.TOP) - with(context.divView) { + with(divView) { clearSubscriptions() subscribe { overflowMenuWrapper.dismiss() } } @@ -408,13 +404,12 @@ internal class DivActionBinder @Inject constructor( } private inner class MenuWrapperListener( - private val context: BindingContext, + private val divView: Div2View, private val items: List ) : OverflowMenuWrapper.Listener.Simple() { override fun onMenuCreated(popupMenu: PopupMenu) { - val divView = context.divView - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver val menu = popupMenu.menu for (itemData in items) { val itemPosition = menu.size() @@ -428,15 +423,16 @@ internal class DivActionBinder @Inject constructor( KAssert.fail { "Menu item does not have any action" } return@bulkActions } - actions.onlyEnabled(expressionResolver).forEach { action -> + actions.onlyEnabled(divView.expressionResolver).forEach { action -> logger.logPopupMenuItemClick( divView, itemPosition, itemData.text.evaluate(expressionResolver), action ) - divActionBeaconSender.sendTapActionBeacon(action, expressionResolver) - handleAction(divView, expressionResolver, action, DivActionReason.MENU) + divActionBeaconSender.sendTapActionBeacon(action, + divView.expressionResolver) + handleAction(divView, action, DivActionReason.MENU) } actionsHandled = true } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBackgroundBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBackgroundBinder.kt index 2482618d9..cdad5eec5 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBackgroundBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBackgroundBinder.kt @@ -19,7 +19,6 @@ import com.yandex.div.core.images.CachedBitmap import com.yandex.div.core.images.DivImageLoader import com.yandex.div.core.util.observeBackground import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.internal.core.ExpressionSubscriber import com.yandex.div.internal.drawable.LinearGradientDrawable @@ -46,14 +45,14 @@ internal class DivBackgroundBinder @Inject constructor( @Suppress("UNCHECKED_CAST") fun bindBackground( view: View, - context: BindingContext, + divView: Div2View, defaultBackgroundList: List?, focusedBackgroundList: List?, + resolver: ExpressionResolver, subscriber: ExpressionSubscriber, additionalLayer: Drawable? = null ): Unit = view.run { val metrics = resources.displayMetrics - val resolver = context.expressionResolver if (focusedBackgroundList == null) { val callback = { _: Any -> @@ -69,7 +68,7 @@ internal class DivBackgroundBinder @Inject constructor( (currentAdditionalLayer != additionalLayer) if (backgroundChanged) { - updateBackground(newDefaultDivBackground.toDrawable(this, context, additionalLayer)) + updateBackground(newDefaultDivBackground.toDrawable(this, divView, additionalLayer)) setTag(R.id.div_default_background_list_tag, newDefaultDivBackground) setTag(R.id.div_focused_background_list_tag, null) @@ -101,13 +100,13 @@ internal class DivBackgroundBinder @Inject constructor( stateList.addState( intArrayOf(android.R.attr.state_focused), - newFocusedDivBackground.toDrawable(this, context, additionalLayer) + newFocusedDivBackground.toDrawable(this, divView, additionalLayer) ) if (defaultBackgroundList != null || additionalLayer != null) { stateList.addState( StateSet.WILD_CARD, - newDefaultDivBackground.toDrawable(this, context, additionalLayer)) + newDefaultDivBackground.toDrawable(this, divView, additionalLayer)) } updateBackground(stateList) @@ -160,7 +159,7 @@ internal class DivBackgroundBinder @Inject constructor( private fun List?.toDrawable( view: View, - context: BindingContext, + divView: Div2View, additionalLayer: Drawable? ): Drawable? { additionalLayer?.mutate() @@ -168,7 +167,7 @@ internal class DivBackgroundBinder @Inject constructor( this ?: return additionalLayer?.let { LayerDrawable(arrayOf(it)) } val listDrawable = mapNotNull { - it.toDrawable(context, view, imageLoader).mutate() + it.toDrawable(divView, view, imageLoader).mutate() }.toMutableList() additionalLayer?.let { listDrawable.add(it) } @@ -305,30 +304,28 @@ internal class DivBackgroundBinder @Inject constructor( } fun getDivImageBackground( - context: BindingContext, + divView: Div2View, target: View, imageLoader: DivImageLoader ): Drawable { val scaleDrawable = ScalingDrawable() val url = imageUrl.toString() - val loadReference = imageLoader.loadImage( - url, - object : DivIdLoggingImageDownloadCallback(context.divView) { - @UiThread - override fun onSuccess(cachedBitmap: CachedBitmap) { - target.applyBitmapFilters( - context, - cachedBitmap.bitmap, - filters?.map { it.toDiv() }, - ) { scaleDrawable.setBitmap(it) } - scaleDrawable.alpha = (alpha * 255).toInt() - scaleDrawable.customScaleType = scale.toScaleType() - scaleDrawable.alignmentHorizontal = contentAlignmentHorizontal.toHorizontalAlignment() - scaleDrawable.alignmentVertical = contentAlignmentVertical.toVerticalAlignment() - } - }) - context.divView.addLoadReference(loadReference, target) + val loadReference = imageLoader.loadImage(url, object : DivIdLoggingImageDownloadCallback(divView) { + @UiThread + override fun onSuccess(cachedBitmap: CachedBitmap) { + target.applyBitmapFilters( + divView, + cachedBitmap.bitmap, + filters?.map { it.toDiv() }, + ) { scaleDrawable.setBitmap(it) } + scaleDrawable.alpha = (alpha * 255).toInt() + scaleDrawable.customScaleType = scale.toScaleType() + scaleDrawable.alignmentHorizontal = contentAlignmentHorizontal.toHorizontalAlignment() + scaleDrawable.alignmentVertical = contentAlignmentVertical.toVerticalAlignment() + } + }) + divView.addLoadReference(loadReference, target) return scaleDrawable } @@ -369,12 +366,12 @@ internal class DivBackgroundBinder @Inject constructor( } fun toDrawable( - context: BindingContext, + divView: Div2View, target: View, imageLoader: DivImageLoader ): Drawable = when (this) { - is Image -> getDivImageBackground(context, target, imageLoader) - is NinePatch -> getNinePatchDrawable(context.divView, target, imageLoader) + is Image -> getDivImageBackground(divView, target, imageLoader) + is NinePatch -> getNinePatchDrawable(divView, target, imageLoader) is Solid -> ColorDrawable(color) is LinearGradient -> LinearGradientDrawable( angle = angle.toFloat(), diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBaseBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBaseBinder.kt index 2f125d495..09a120678 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBaseBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivBaseBinder.kt @@ -17,7 +17,6 @@ import com.yandex.div.core.util.isConstant import com.yandex.div.core.util.observeEdgeInsets import com.yandex.div.core.util.observeSize import com.yandex.div.core.util.observeTransform -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivAccessibilityBinder import com.yandex.div.core.view2.animations.DivTransitionHandler.ChangeType @@ -45,35 +44,31 @@ internal class DivBaseBinder @Inject constructor( private val divFocusBinder: DivFocusBinder, private val divAccessibilityBinder: DivAccessibilityBinder, ) { - fun bindView(context: BindingContext, view: View, div: DivBase, oldDiv: DivBase?) { + fun bindView(view: View, div: DivBase, oldDiv: DivBase?, divView: Div2View) { @Suppress("UNCHECKED_CAST") (view as DivHolderView).let { it.closeAllSubscription() it.div = div } - val divView = context.divView - val resolver = context.expressionResolver + val resolver = divView.expressionResolver val subscriber = view.expressionSubscriber if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { view.defaultFocusHighlightEnabled = false } - divView.bindDivToBindingContext(div, context) - divView.unbindDivFromBindingContext(oldDiv) - view.bindId(divView, div, oldDiv) view.bindLayoutParams(div, oldDiv, resolver, subscriber) view.bindAccessibility(divView, div, oldDiv, resolver, subscriber) view.bindAlpha(div, oldDiv, resolver, subscriber) - view.bindBackground(context, div, subscriber) - view.bindBorder(context, div) + view.bindBackground(divView, div, resolver, subscriber) + view.bindBorder(divView, div, resolver) view.bindPaddings(div, oldDiv, resolver, subscriber) view.bindNextFocus(divView, div, oldDiv, resolver, subscriber) - view.bindFocusActions(context, div.focus?.onFocus, div.focus?.onBlur) + view.bindFocusActions(divView, resolver, div.focus?.onFocus, div.focus?.onBlur) view.bindVisibility(divView, div, oldDiv, resolver, subscriber) view.bindTransform(div, oldDiv, resolver, subscriber) @@ -424,10 +419,11 @@ internal class DivBaseBinder @Inject constructor( //region Border private fun View.bindBorder( - context: BindingContext, + divView: Div2View, newDiv: DivBase, + resolver: ExpressionResolver ) { - divFocusBinder.bindDivBorder(this, context, newDiv.focus?.border, newDiv.border) + divFocusBinder.bindDivBorder(this, divView, resolver, newDiv.focus?.border, newDiv.border) } //endregion @@ -435,28 +431,31 @@ internal class DivBaseBinder @Inject constructor( //region Background internal fun bindBackground( - context: BindingContext, + divView: Div2View, target: View, newDiv: DivBase, oldDiv: DivBase?, + resolver: ExpressionResolver, subscriber: ExpressionSubscriber, additionalLayer: Drawable? = null ) { - target.bindBackground(context, newDiv, subscriber, additionalLayer) - target.bindPaddings(newDiv, oldDiv, context.expressionResolver, subscriber) + target.bindBackground(divView, newDiv, resolver, subscriber, additionalLayer) + target.bindPaddings(newDiv, oldDiv, resolver, subscriber) } private fun View.bindBackground( - context: BindingContext, + divView: Div2View, newDiv: DivBase, + resolver: ExpressionResolver, subscriber: ExpressionSubscriber, additionalLayer: Drawable? = null ) { divBackgroundBinder.bindBackground( this, - context, + divView, newDiv.background, newDiv.focus?.background, + resolver, subscriber, additionalLayer ) @@ -514,11 +513,12 @@ internal class DivBaseBinder @Inject constructor( } private fun View.bindFocusActions( - context: BindingContext, + divView: Div2View, + resolver: ExpressionResolver, onFocus: List?, onBlur: List? ) { - divFocusBinder.bindDivFocusActions(this, context, onFocus, onBlur) + divFocusBinder.bindDivFocusActions(this, divView, resolver, onFocus, onBlur) } //endregion diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivContainerBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivContainerBinder.kt index b6043c9b2..67ab7f789 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivContainerBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivContainerBinder.kt @@ -17,7 +17,6 @@ import com.yandex.div.core.util.isBranch import com.yandex.div.core.util.isConstant import com.yandex.div.core.util.observeDrawable import com.yandex.div.core.util.type -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewBinder @@ -33,7 +32,6 @@ import com.yandex.div.core.view2.reuse.util.tryRebindPlainContainerChildren import com.yandex.div.core.widget.AspectView import com.yandex.div.core.widget.ShowSeparatorsMode import com.yandex.div.core.widget.wraplayout.WrapDirection -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.ExpressionSubscriber import com.yandex.div.internal.core.buildItems import com.yandex.div.json.expressions.ExpressionResolver @@ -71,25 +69,18 @@ internal class DivContainerBinder @Inject constructor( private val tempRect = Rect() - override fun bindView(context: BindingContext, view: ViewGroup, div: DivContainer, path: DivStatePath) { + override fun bindView(view: ViewGroup, div: DivContainer, divView: Div2View, path: DivStatePath) { @Suppress("UNCHECKED_CAST") val divHolderView = view as DivHolderView val oldDiv = divHolderView.div - val divView = context.divView - val oldResolver = oldDiv?.let { divView.getExpressionResolver(it) } ?: divView.oldExpressionResolver - baseBinder.bindView(context, view, div, oldDiv) - view.applyDivActions( - context, - div.action, - div.actions, - div.longtapActions, - div.doubletapActions, - div.actionAnimation, - div.accessibility, - ) + baseBinder.bindView(view, div, oldDiv, divView) + view.applyDivActions(divView, div.action, div.actions, div.longtapActions, + div.doubletapActions, div.actionAnimation, div.accessibility) - val resolver = context.expressionResolver + val resolver = divView.expressionResolver + val oldResolver = divView.oldExpressionResolver + val errorCollector = errorCollectors.getOrCreate(divView.dataTag, divView.divData) view.bindAspectRatio(div.aspect, oldDiv?.aspect, resolver) @@ -104,97 +95,49 @@ internal class DivContainerBinder @Inject constructor( divView.unbindViewFromDiv(childView) } - view.bindItems(context, div, oldDiv, oldResolver, path) - } + view.tryRebindPlainContainerChildren( + divView, + div.buildItems(resolver), + divViewCreator + ) - private fun ViewGroup.bindItems( - context: BindingContext, - div: DivContainer, - oldDiv: DivContainer?, - oldResolver: ExpressionResolver, - path: DivStatePath, - ) { - val divView = context.divView - val resolver = context.expressionResolver val items = div.buildItems(resolver) - val oldItems = oldDiv?.buildItems(oldResolver)?.let { when { div === oldDiv -> it divView.complexRebindInProgress -> null - DivComparator.areValuesReplaceable(oldDiv, div, oldResolver, context.expressionResolver) && - DivComparator.areChildrenReplaceable(it, items) -> it + DivComparator.areValuesReplaceable(oldDiv, div, oldResolver, resolver) && + DivComparator.areChildrenReplaceable(it, items, oldResolver, resolver) -> it else -> { - replaceWithReuse(it, items, divView) + view.replaceWithReuse(it, items, divView) null } } } - bindItemBuilder(context, div, items, path) - applyItems(context, div, oldDiv, items, oldItems, path) - } - private fun ViewGroup.bindItemBuilder( - context: BindingContext, - div: DivContainer, - items: List, - path: DivStatePath, - ) { - val builder = div.itemBuilder ?: return - - val callback = { _: Any -> - val cachedItems = builder.result ?: emptyList() - builder.result = null - val newItems = div.buildItems(context.expressionResolver) - replaceWithReuse(cachedItems, newItems, context.divView) - applyItems(context, div, div, newItems, cachedItems, path) - } - builder.data.observe(context.expressionResolver, callback) - - if (items.isEmpty()) return - - builder.prototypes.forEach { - it.selector.observe(items[0].expressionResolver, callback) - } - } - - private fun ViewGroup.applyItems( - context: BindingContext, - div: DivContainer, - oldDiv: DivContainer?, - items: List, - oldItems: List?, - path: DivStatePath, - ) { - div.itemBuilder?.result = items - - val divView = context.divView - val errorCollector = errorCollectors.getOrCreate(divView.dataTag, divView.divData) - tryRebindPlainContainerChildren(divView, items, divViewCreator) - - validateChildren(div, items, context.expressionResolver, errorCollector) - dispatchBinding(context, div, oldDiv, items, path, expressionSubscriber) + view.validateChildren(div, resolver, errorCollector) + view.dispatchBinding(divView, div, oldDiv, path, resolver) items.forEachIndexed { i, item -> - if (item.div.value().hasSightActions) { - divView.bindViewToDiv(getChildAt(i), item.div) + if (item.value().hasSightActions) { + divView.bindViewToDiv(view.getChildAt(i), item) } } - trackVisibilityActions(items, oldItems, divView) + view.trackVisibilityActions(items, oldItems, divView) } private fun ViewGroup.validateChildren( div: DivContainer, - items: List, resolver: ExpressionResolver, errorCollector: ErrorCollector ) { + val items = div.buildItems(resolver) var childrenWithIncorrectWidth = 0 var childrenWithIncorrectHeight = 0 items.forEach { item -> - val childDivValue = item.div.value() + val childDivValue = item.value() if (this is DivWrapLayout) { div.checkCrossAxisSize(childDivValue, resolver, errorCollector) @@ -221,73 +164,47 @@ internal class DivContainerBinder @Inject constructor( } private fun ViewGroup.dispatchBinding( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivContainer, oldDiv: DivContainer?, - items: List, path: DivStatePath, - subscriber: ExpressionSubscriber + resolver: ExpressionResolver ) { val binder = divBinder.get() + val items = newDiv.buildItems(resolver) var shift = 0 + val subscriber = expressionSubscriber items.forEachIndexed { index, item -> val childView = getChildAt(index + shift) val oldChildDiv = (childView as? DivHolderView<*>)?.div - val patchShift = newDiv.itemBuilder?.let { NO_PATCH_SHIFT } ?: applyPatchToChild( - bindingContext, - newDiv, - oldDiv, - item.div.value(), - index + shift, - subscriber - ) - + val patchShift = applyPatchToChild(divView, newDiv, oldDiv, item.value(), index + shift, resolver, subscriber) if (patchShift > NO_PATCH_SHIFT) { shift += patchShift } else { - val childBindingContext = BindingContext(bindingContext.divView, item.expressionResolver) - binder.bind(childBindingContext, childView, item.div, path) - childView.bindChildAlignment( - newDiv, - oldDiv, - item.div.value(), - oldChildDiv, - bindingContext.expressionResolver, - item.expressionResolver, - subscriber, - bindingContext.divView - ) + binder.bind(childView, item, divView, path) + childView.bindChildAlignment(newDiv, oldDiv, item.value(), oldChildDiv, resolver, subscriber, divView) } } } private fun ViewGroup.applyPatchToChild( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivContainer, oldDiv: DivContainer?, childDiv: DivBase, childIndex: Int, + resolver: ExpressionResolver, subscriber: ExpressionSubscriber ): Int { - val divView = bindingContext.divView childDiv.id?.let { id -> - val patchViewsToAdd = divPatchManager.createViewsForId(bindingContext, id) ?: return NO_PATCH_SHIFT + val patchViewsToAdd = divPatchManager.createViewsForId(divView, id) ?: return NO_PATCH_SHIFT val patchDivs = divPatchCache.getPatchDivListById(divView.dataTag, id) ?: return NO_PATCH_SHIFT removeViewAt(childIndex) patchViewsToAdd.forEachIndexed { patchIndex, patchView -> val patchDivValue = patchDivs[patchIndex].value() addView(patchView, childIndex + patchIndex) - patchView.bindChildAlignment( - newDiv = newDiv, - oldDiv = oldDiv, - newChildDiv = patchDivValue, - oldChildDiv = null, - resolver = bindingContext.expressionResolver, - childResolver = bindingContext.expressionResolver, - subscriber = subscriber, - divView = divView - ) + patchView.bindChildAlignment(newDiv, oldDiv, patchDivValue, null, resolver, subscriber, divView) if (patchDivValue.hasSightActions) { divView.bindViewToDiv(patchView, patchDivs[patchIndex]) } @@ -297,14 +214,12 @@ internal class DivContainerBinder @Inject constructor( return NO_PATCH_SHIFT } - private fun ViewGroup.replaceWithReuse( - oldItems: List, - newItems: List, - divView: Div2View - ) { + private fun ViewGroup.replaceWithReuse(oldItems: List
, newItems: List
, divView: Div2View) { + val resolver = divView.expressionResolver + val oldChildren = mutableMapOf() oldItems.zip(children.toList()) { childDiv, child -> - oldChildren[childDiv.div] = child + oldChildren[childDiv] = child } removeAllViews() @@ -314,9 +229,9 @@ internal class DivContainerBinder @Inject constructor( newItems.forEachIndexed { index, newChild -> val oldViewIndex = oldChildren.keys.firstOrNull { oldChildDiv -> if (oldChildDiv.isBranch) { - newChild.div.type == oldChildDiv.type + newChild.type == oldChildDiv.type } else { - oldChildDiv.canBeReused(newChild.div, newChild.expressionResolver) + oldChildDiv.canBeReused(newChild, resolver) } } @@ -330,15 +245,15 @@ internal class DivContainerBinder @Inject constructor( } createViewIndices.forEach { index -> - val newChild = newItems[index] + val newChildDiv = newItems[index] val oldViewIndex = oldChildren.keys.firstOrNull { oldChildDiv -> - oldChildDiv.type == newChild.div.type + oldChildDiv.type == newChildDiv.type } val childView = oldChildren .remove(oldViewIndex) - ?: divViewCreator.get().create(newChild.div, newChild.expressionResolver) + ?: divViewCreator.get().create(newChildDiv, divView.expressionResolver) addView(childView, index) } @@ -586,7 +501,6 @@ internal class DivContainerBinder @Inject constructor( newChildDiv: DivBase, oldChildDiv: DivBase?, resolver: ExpressionResolver, - childResolver: ExpressionResolver, subscriber: ExpressionSubscriber, divView: Div2View, ) { @@ -598,7 +512,7 @@ internal class DivContainerBinder @Inject constructor( return } - applyChildAlignment(newDiv, newChildDiv, resolver, childResolver) + applyChildAlignment(newDiv, newChildDiv, resolver) if (newDiv.contentAlignmentHorizontal.isConstant() && newDiv.contentAlignmentVertical.isConstant() @@ -607,29 +521,28 @@ internal class DivContainerBinder @Inject constructor( return } - val callback = { _: Any -> applyChildAlignment(newDiv, newChildDiv, resolver, childResolver) } + val callback = { _: Any -> applyChildAlignment(newDiv, newChildDiv, resolver) } subscriber.addSubscription(newDiv.contentAlignmentHorizontal.observe(resolver, callback)) subscriber.addSubscription(newDiv.contentAlignmentVertical.observe(resolver, callback)) - subscriber.addSubscription(newChildDiv.alignmentHorizontal?.observe(childResolver, callback)) - subscriber.addSubscription(newChildDiv.alignmentVertical?.observe(childResolver, callback)) + subscriber.addSubscription(newChildDiv.alignmentHorizontal?.observe(resolver, callback)) + subscriber.addSubscription(newChildDiv.alignmentVertical?.observe(resolver, callback)) } private fun View.applyChildAlignment( div: DivContainer, childDiv: DivBase, resolver: ExpressionResolver, - childResolver: ExpressionResolver, ) { val childAlignmentHorizontal = childDiv.alignmentHorizontal val alignmentHorizontal = when { - childAlignmentHorizontal != null -> childAlignmentHorizontal.evaluate(childResolver) + childAlignmentHorizontal != null -> childAlignmentHorizontal.evaluate(resolver) div.isWrapContainer(resolver) -> null else -> div.contentAlignmentHorizontal.evaluate(resolver).toAlignmentHorizontal() } val childAlignmentVertical = childDiv.alignmentVertical val alignmentVertical = when { - childAlignmentVertical != null -> childAlignmentVertical.evaluate(childResolver) + childAlignmentVertical != null -> childAlignmentVertical.evaluate(resolver) div.isWrapContainer(resolver) -> null else -> div.contentAlignmentVertical.evaluate(resolver).toAlignmentVertical() } @@ -679,7 +592,7 @@ internal class DivContainerBinder @Inject constructor( (view as DivHolderView).div = div val binder = divBinder.get() div.buildItems(resolver).forEachIndexed { index, item -> - binder.setDataWithoutBinding(view.getChildAt(index), item.div, item.expressionResolver) + binder.setDataWithoutBinding(view.getChildAt(index), item, resolver) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivCustomBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivCustomBinder.kt index e33fe0e81..4788fd3b1 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivCustomBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivCustomBinder.kt @@ -10,7 +10,6 @@ import com.yandex.div.core.DivCustomViewAdapter import com.yandex.div.core.DivCustomViewFactory import com.yandex.div.core.extension.DivExtensionController import com.yandex.div.core.state.DivStatePath -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewBinder @@ -29,13 +28,12 @@ internal class DivCustomBinder @Inject constructor( private val divBinder: Provider, ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivCustomWrapper, div: DivCustom, path: DivStatePath) { + override fun bindView(view: DivCustomWrapper, div: DivCustom, divView: Div2View, path: DivStatePath) { val customView = view.customView val oldDiv = view.div - val divView = context.divView if (oldDiv === div) { - view.bindStates(divView.rootDiv(), context, context.expressionResolver, divBinder.get()) + view.bindStates(divView.rootDiv(), divView, divView.expressionResolver, divBinder.get()) return } @@ -43,16 +41,16 @@ internal class DivCustomBinder @Inject constructor( extensionController.unbindView(divView, customView, oldDiv) } - baseBinder.bindView(context, view, div, null) + baseBinder.bindView(view, div, null, divView) baseBinder.bindId(divView, view, null) if (divCustomContainerViewAdapter.isCustomTypeSupported(div.customType)) { - bind(view, customView, div, context, + bind(view, customView, div, divView, { divCustomContainerViewAdapter.createView(div, divView, path) }, { divCustomContainerViewAdapter.bindView(it, div, divView, path) } ) } else if (divCustomViewAdapter.isCustomTypeSupported(div.customType)) { - bind(view, customView, div, context, + bind(view, customView, div, divView, { divCustomViewAdapter.createView(div, divView) }, { divCustomViewAdapter.bindView(it, div, divView) } ) @@ -65,7 +63,7 @@ internal class DivCustomBinder @Inject constructor( previousWrapper: DivCustomWrapper, oldCustomView: View?, div: DivCustom, - context: BindingContext, + divView: Div2View, createView: () -> View, bindView: (View) -> Unit ) { @@ -77,10 +75,8 @@ internal class DivCustomBinder @Inject constructor( } } - val divView = context.divView - baseBinder.bindId(divView, customView, div.id) - divView.bindDivToBindingContext(div, context) bindView(customView) + baseBinder.bindId(divView, customView, div.id) if (oldCustomView != customView) { replaceInParent(previousWrapper, customView, divView) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivFocusBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivFocusBinder.kt index 919b26a33..c440d341d 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivFocusBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivFocusBinder.kt @@ -4,7 +4,7 @@ import android.view.View import com.yandex.div.R import com.yandex.div.core.annotations.Mockable import com.yandex.div.core.dagger.DivScope -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.widgets.DivBorderDrawer import com.yandex.div.core.view2.divs.widgets.DivBorderSupports import com.yandex.div.internal.util.allIsNullOrEmpty @@ -19,7 +19,8 @@ internal class DivFocusBinder @Inject constructor(private val actionBinder: DivA fun bindDivBorder( view: View, - context: BindingContext, + divView: Div2View, + resolver: ExpressionResolver, focusedBorder: DivBorder?, blurredBorder: DivBorder? ): Unit = view.run { @@ -29,7 +30,7 @@ internal class DivFocusBinder @Inject constructor(private val actionBinder: DivA isFocused -> focusedBorder else -> blurredBorder } - applyBorder(border, context.expressionResolver) + applyBorder(border, resolver) val focusListener = onFocusChangeListener as? FocusChangeListener if (focusListener == null && focusedBorder.isConstantlyEmpty()) { @@ -45,7 +46,7 @@ internal class DivFocusBinder @Inject constructor(private val actionBinder: DivA return } - onFocusChangeListener = FocusChangeListener(context).apply { + onFocusChangeListener = FocusChangeListener(divView, resolver).apply { setBorders(focusedBorder, blurredBorder) focusListener?.let { setActions(it.focusActions, it.blurActions) } } @@ -68,7 +69,8 @@ internal class DivFocusBinder @Inject constructor(private val actionBinder: DivA fun bindDivFocusActions( target: View, - context: BindingContext, + divView: Div2View, + resolver: ExpressionResolver, onFocusActions: List?, onBlurActions: List? ) = target.run { @@ -86,14 +88,15 @@ internal class DivFocusBinder @Inject constructor(private val actionBinder: DivA return } - onFocusChangeListener = FocusChangeListener(context).apply { + onFocusChangeListener = FocusChangeListener(divView, resolver).apply { focusListener?.let { setBorders(it.focusedBorder, it.blurredBorder) } setActions(onFocusActions, onBlurActions) } } private inner class FocusChangeListener( - private val context: BindingContext, + private val divView: Div2View, + private val resolver: ExpressionResolver ): View.OnFocusChangeListener { var focusedBorder: DivBorder? = null @@ -126,9 +129,9 @@ internal class DivFocusBinder @Inject constructor(private val actionBinder: DivA } } - private fun DivBorder.applyToView(v: View) = v.applyBorder(this, context.expressionResolver) + private fun DivBorder.applyToView(v: View) = v.applyBorder(this, resolver) private fun List.handle(target: View, actionLogType: String) = - actionBinder.handleBulkActions(context, target, this, actionLogType) + actionBinder.handleBulkActions(divView, target, this, actionLogType) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGifImageBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGifImageBinder.kt index 93c90f17c..144fd2773 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGifImageBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGifImageBinder.kt @@ -4,6 +4,8 @@ import android.content.Context import android.graphics.ImageDecoder import android.graphics.drawable.AnimatedImageDrawable import android.graphics.drawable.Drawable +import android.graphics.drawable.PictureDrawable +import android.graphics.drawable.ScaleDrawable import android.os.AsyncTask import android.os.Build import androidx.annotation.RequiresApi @@ -11,7 +13,6 @@ import com.yandex.div.core.DivIdLoggingImageDownloadCallback import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.images.CachedBitmap import com.yandex.div.core.images.DivImageLoader -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivPlaceholderLoader import com.yandex.div.core.view2.DivViewBinder @@ -41,26 +42,18 @@ internal class DivGifImageBinder @Inject constructor( private val errorCollectors: ErrorCollectors, ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivGifImageView, div: DivGifImage) { + override fun bindView(view: DivGifImageView, div: DivGifImage, divView: Div2View) { val oldDiv = view.div if (div === oldDiv) return - val divView = context.divView val errorCollector = errorCollectors.getOrCreate(divView.dataTag, divView.divData) - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) - view.applyDivActions( - context, - div.action, - div.actions, - div.longtapActions, - div.doubletapActions, - div.actionAnimation, - div.accessibility, - ) + view.applyDivActions(divView, div.action, div.actions, div.longtapActions, + div.doubletapActions, div.actionAnimation, div.accessibility) view.bindAspectRatio(div.aspect, oldDiv?.aspect, expressionResolver) @@ -69,9 +62,7 @@ internal class DivGifImageBinder @Inject constructor( ) view.observeContentAlignment(expressionResolver, div.contentAlignmentHorizontal, div.contentAlignmentVertical) view.addSubscription( - div.gifUrl.observeAndGet(expressionResolver) { - view.applyGifImage(divView, expressionResolver, div, errorCollector) - } + div.gifUrl.observeAndGet(expressionResolver) { view.applyGifImage(divView, expressionResolver, div, errorCollector) } ) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt index 78fdf8ef0..4ff07c63b 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt @@ -8,19 +8,17 @@ import com.yandex.div.core.downloader.DivPatchManager import com.yandex.div.core.state.DivStatePath import com.yandex.div.core.util.expressionSubscriber import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.DivViewCreator import com.yandex.div.core.view2.divs.widgets.DivGridLayout import com.yandex.div.core.view2.reuse.util.tryRebindPlainContainerChildren -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.ExpressionSubscriber import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.widget.DivLayoutParams import com.yandex.div.json.expressions.Expression import com.yandex.div.json.expressions.ExpressionResolver -import com.yandex.div2.Div import com.yandex.div2.DivAlignmentHorizontal import com.yandex.div2.DivAlignmentVertical import com.yandex.div2.DivBase @@ -37,28 +35,20 @@ internal class DivGridBinder @Inject constructor( private val divViewCreator: Provider, ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivGridLayout, div: DivGrid, path: DivStatePath) { + override fun bindView(view: DivGridLayout, div: DivGrid, divView: Div2View, path: DivStatePath) { val oldDiv = view.div if (div === oldDiv) { // todo MORDAANDROID-636 // return } - val divView = context.divView - val resolver = context.expressionResolver + val resolver = divView.expressionResolver view.releaseViewVisitor = divView.releaseViewVisitor - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) - view.applyDivActions( - context, - div.action, - div.actions, - div.longtapActions, - div.doubletapActions, - div.actionAnimation, - div.accessibility, - ) + view.applyDivActions(divView, div.action, div.actions, div.longtapActions, + div.doubletapActions, div.actionAnimation, div.accessibility) view.addSubscription( div.columnCount.observeAndGet(resolver) { columnCount -> view.columnCount = columnCount.toIntSafely() } @@ -69,7 +59,7 @@ internal class DivGridBinder @Inject constructor( view.tryRebindPlainContainerChildren( divView, - items.toDivItemBuilderResults(resolver), + items, divViewCreator ) @@ -80,7 +70,7 @@ internal class DivGridBinder @Inject constructor( val childDivId = childDivValue.id // applying div patch if (childDivId != null && !divView.complexRebindInProgress) { - val patchViewsToAdd = divPatchManager.createViewsForId(context, childDivId) + val patchViewsToAdd = divPatchManager.createViewsForId(divView, childDivId) val patchDivs = divPatchCache.getPatchDivListById(divView.dataTag, childDivId) if (patchViewsToAdd != null && patchDivs != null) { view.removeViewAt(gridIndex + viewsPositionDiff) @@ -99,7 +89,7 @@ internal class DivGridBinder @Inject constructor( } } childView.layoutParams = DivLayoutParams(WRAP_CONTENT, WRAP_CONTENT) - divBinder.get().bind(context, childView, items[gridIndex], path) + divBinder.get().bind(childView, items[gridIndex], divView, path) bindLayoutParams(childView, childDivValue, resolver) if (childDivValue.hasSightActions) { divView.bindViewToDiv(childView, items[gridIndex]) @@ -108,11 +98,7 @@ internal class DivGridBinder @Inject constructor( } } - view.trackVisibilityActions( - items.toDivItemBuilderResults(resolver), - oldDiv?.items?.toDivItemBuilderResults(resolver), - divView - ) + view.trackVisibilityActions(items, oldDiv?.items, divView) } private fun DivGridLayout.observeContentAlignment( @@ -174,7 +160,4 @@ internal class DivGridBinder @Inject constructor( ) } } - - private fun List
.toDivItemBuilderResults(resolver: ExpressionResolver) = - map { DivItemBuilderResult(it, resolver) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivImageBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivImageBinder.kt index 4c20900ea..a8d787a2f 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivImageBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivImageBinder.kt @@ -9,7 +9,7 @@ import com.yandex.div.core.images.DivImageLoader import com.yandex.div.core.util.androidInterpolator import com.yandex.div.core.util.equalsToConstant import com.yandex.div.core.util.isConstant -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivPlaceholderLoader import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivImageView @@ -37,32 +37,24 @@ internal class DivImageBinder @Inject constructor( private val errorCollectors: ErrorCollectors, ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivImageView, div: DivImage) { + override fun bindView(view: DivImageView, div: DivImage, divView: Div2View) { val oldDiv = view.div if (div === oldDiv) return - baseBinder.bindView(context, view, div, oldDiv) - view.applyDivActions( - context, - div.action, - div.actions, - div.longtapActions, - div.doubletapActions, - div.actionAnimation, - div.accessibility, - ) + baseBinder.bindView(view, div, oldDiv, divView) + view.applyDivActions(divView, div.action, div.actions, div.longtapActions, + div.doubletapActions, div.actionAnimation, div.accessibility) - val divView = context.divView - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver val errorCollector = errorCollectors.getOrCreate(divView.dataTag, divView.divData) view.bindAspectRatio(div.aspect, oldDiv?.aspect, expressionResolver) view.bindImageScale(div, oldDiv, expressionResolver) view.bindContentAlignment(div, oldDiv, expressionResolver) - view.bindPreview(context, div, oldDiv, errorCollector) - view.bindImage(context, div, oldDiv, errorCollector) + view.bindPreview(divView, div, oldDiv, expressionResolver, errorCollector) + view.bindImage(divView, div, oldDiv, expressionResolver, errorCollector) view.bindTint(div, oldDiv, expressionResolver) - view.bindFilters(context, div, oldDiv) + view.bindFilters(divView, div, oldDiv, expressionResolver) } //region Image Scale @@ -136,9 +128,10 @@ internal class DivImageBinder @Inject constructor( //region Filters private fun DivImageView.bindFilters( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivImage, oldDiv: DivImage?, + resolver: ExpressionResolver, ) { if (newDiv.filters?.size == oldDiv?.filters?.size) { val filtersAreTheSame = newDiv.filters?.foldIndexed(initial = true) { index, result, newFilter -> @@ -149,32 +142,31 @@ internal class DivImageBinder @Inject constructor( } } - applyFiltersAndSetBitmap(bindingContext, newDiv.filters) + applyFiltersAndSetBitmap(divView, newDiv.filters) val allFiltersAreConstant = newDiv.filters?.all { filter -> filter.isConstant() } if (allFiltersAreConstant != false) { return } - val callback = { _: Any -> applyFiltersAndSetBitmap(bindingContext, newDiv.filters) } + val callback = { _: Any -> applyFiltersAndSetBitmap(divView, newDiv.filters) } newDiv.filters?.forEach { filter -> when (filter) { - is DivFilter.Blur -> - addSubscription(filter.value.radius.observe(bindingContext.expressionResolver, callback)) + is DivFilter.Blur -> { addSubscription(filter.value.radius.observe(resolver, callback)) } else -> Unit } } } private fun DivImageView.applyFiltersAndSetBitmap( - bindingContext: BindingContext, + divView: Div2View, filters: List? ) { val bitmap = currentBitmapWithoutFilters if (bitmap == null) { setImageBitmap(null) } else { - applyBitmapFilters(bindingContext, bitmap, filters) { + applyBitmapFilters(divView, bitmap, filters) { setImageBitmap(it) } } @@ -185,9 +177,10 @@ internal class DivImageBinder @Inject constructor( //region Preview private fun DivImageView.bindPreview( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivImage, oldDiv: DivImage?, + resolver: ExpressionResolver, errorCollector: ErrorCollector ) { if (isImageLoaded) { @@ -206,15 +199,16 @@ internal class DivImageBinder @Inject constructor( } addSubscription( - newDiv.preview?.observe(bindingContext.expressionResolver) { newPreview -> + newDiv.preview?.observe(resolver) { newPreview -> if (isImageLoaded || newPreview == preview) { return@observe } resetImageLoaded() applyPreview( - bindingContext, + divView, newDiv, - isHighPriorityShow(bindingContext.expressionResolver, this, newDiv), + isHighPriorityShow(resolver, this, newDiv), + resolver, errorCollector ) } @@ -222,12 +216,12 @@ internal class DivImageBinder @Inject constructor( } private fun DivImageView.applyPreview( - bindingContext: BindingContext, + divView: Div2View, div: DivImage, synchronous: Boolean, + resolver: ExpressionResolver, errorCollector: ErrorCollector ) { - val resolver = bindingContext.expressionResolver placeholderLoader.applyPlaceholder( this, errorCollector, @@ -242,7 +236,7 @@ internal class DivImageBinder @Inject constructor( onSetPreview = { if (!isImageLoaded) { currentBitmapWithoutFilters = it - applyFiltersAndSetBitmap(bindingContext, div.filters) + applyFiltersAndSetBitmap(divView, div.filters) previewLoaded() applyTint(div.tintColor?.evaluate(resolver), div.tintMode.evaluate(resolver)) } @@ -255,34 +249,45 @@ internal class DivImageBinder @Inject constructor( //region Image private fun DivImageView.bindImage( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivImage, oldDiv: DivImage?, + resolver: ExpressionResolver, errorCollector: ErrorCollector ) { if (newDiv.imageUrl.equalsToConstant(oldDiv?.imageUrl)) { return } - applyImage(bindingContext, newDiv, errorCollector) + applyImage( + divView = divView, + div = newDiv, + resolver = resolver, + errorCollector = errorCollector + ) if (newDiv.imageUrl.isConstantOrNull()) { return } addSubscription( - newDiv.imageUrl.observe(bindingContext.expressionResolver) { - applyImage(bindingContext, newDiv, errorCollector) + newDiv.imageUrl.observe(resolver) { + applyImage( + divView = divView, + div = newDiv, + resolver = resolver, + errorCollector = errorCollector + ) } ) } private fun DivImageView.applyImage( - bindingContext: BindingContext, + divView: Div2View, div: DivImage, + resolver: ExpressionResolver, errorCollector: ErrorCollector ) { - val resolver = bindingContext.expressionResolver val imageUrl = div.imageUrl.evaluate(resolver) if (imageUrl == this.imageUrl) { return @@ -295,16 +300,16 @@ internal class DivImageBinder @Inject constructor( clearTint() loadReference?.cancel() - applyPreview(bindingContext, div, isHighPriorityShowPreview, errorCollector) + applyPreview(divView, div, isHighPriorityShowPreview, resolver, errorCollector) this.imageUrl = imageUrl val reference = imageLoader.loadImage( imageUrl.toString(), - object : DivIdLoggingImageDownloadCallback(bindingContext.divView) { + object : DivIdLoggingImageDownloadCallback(divView) { override fun onSuccess(cachedBitmap: CachedBitmap) { super.onSuccess(cachedBitmap) currentBitmapWithoutFilters = cachedBitmap.bitmap - applyFiltersAndSetBitmap(bindingContext, div.filters) + applyFiltersAndSetBitmap(divView, div.filters) applyLoadingFade(div, resolver, cachedBitmap.from) imageLoaded() applyTint(div.tintColor?.evaluate(resolver), div.tintMode.evaluate(resolver)) @@ -318,7 +323,7 @@ internal class DivImageBinder @Inject constructor( } ) - bindingContext.divView.addLoadReference(reference, this) + divView.addLoadReference(reference, this) loadReference = reference } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivIndicatorBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivIndicatorBinder.kt index 085a10bf7..4b1a0b6da 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivIndicatorBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivIndicatorBinder.kt @@ -5,7 +5,7 @@ import com.yandex.div.core.util.observeFixedSize import com.yandex.div.core.util.observeRoundedRectangleShape import com.yandex.div.core.util.observeShape import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivPagerIndicatorView import com.yandex.div.internal.widget.indicator.IndicatorParams @@ -24,7 +24,7 @@ internal class DivIndicatorBinder @Inject constructor( private val baseBinder: DivBaseBinder, private val pagerIndicatorConnector: PagerIndicatorConnector ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivPagerIndicatorView, div: DivIndicator) { + override fun bindView(view: DivPagerIndicatorView, div: DivIndicator, divView: Div2View) { div.pagerId?.let { pagerIndicatorConnector.submitIndicator(it, view) } @@ -32,9 +32,9 @@ internal class DivIndicatorBinder @Inject constructor( val oldDiv = view.div if (div === oldDiv) return - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) view.observeStyle(expressionResolver, div) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt index 8ac86201d..5b3664f3a 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivInputBinder.kt @@ -21,7 +21,6 @@ import com.yandex.div.core.util.toIntSafely import com.yandex.div.core.util.validator.ExpressionValidator import com.yandex.div.core.util.validator.RegexValidator import com.yandex.div.core.util.validator.ValidatorItemData -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivTypefaceResolver import com.yandex.div.core.view2.DivViewBinder @@ -53,13 +52,13 @@ internal class DivInputBinder @Inject constructor( private val errorCollectors: ErrorCollectors ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivInputView, div: DivInput) { + override fun bindView(view: DivInputView, div: DivInput, divView: Div2View) { val oldDiv = view.div if (div === oldDiv) return - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) view.apply { isFocusable = true @@ -67,7 +66,7 @@ internal class DivInputBinder @Inject constructor( textAlignment = TextView.TEXT_ALIGNMENT_VIEW_START accessibilityEnabled = accessibilityStateProvider.isAccessibilityEnabled(view.context) - observeBackground(context, div, oldDiv, expressionResolver) + observeBackground(divView, div, oldDiv, expressionResolver) observeFontSize(div, expressionResolver) observeTypeface(div, expressionResolver) @@ -83,9 +82,9 @@ internal class DivInputBinder @Inject constructor( observeKeyboardType(div, expressionResolver) observeSelectAllOnFocus(div, expressionResolver) - observeText(div, expressionResolver, context.divView) + observeText(div, expressionResolver, divView) - focusTracker = context.divView.inputFocusTracker + focusTracker = divView.inputFocusTracker focusTracker?.requestFocusIfNeeded(view) } } @@ -120,7 +119,7 @@ internal class DivInputBinder @Inject constructor( } private fun DivInputView.observeBackground( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivInput, oldDiv: DivInput?, resolver: ExpressionResolver @@ -129,7 +128,7 @@ internal class DivInputBinder @Inject constructor( val drawable = nativeBackground ?: return val callback = { color: Int -> - applyNativeBackgroundColor(color, newDiv, oldDiv, bindingContext, drawable) + applyNativeBackgroundColor(color, newDiv, oldDiv, divView, resolver, drawable) } addSubscription(nativeBackgroundColorVariable.observeAndGet(resolver, callback)) } @@ -138,11 +137,12 @@ internal class DivInputBinder @Inject constructor( color: Int, newDiv: DivInput, oldDiv: DivInput?, - bindingContext: BindingContext, + divView: Div2View, + resolver: ExpressionResolver, nativeBackground: Drawable ) { nativeBackground.setTint(color) - baseBinder.bindBackground(bindingContext, this, newDiv, oldDiv, expressionSubscriber, nativeBackground) + baseBinder.bindBackground(divView, this, newDiv, oldDiv, resolver, expressionSubscriber, nativeBackground) } private fun DivInputView.observeFontSize(div: DivInput, resolver: ExpressionResolver) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt index 76b511c6b..08d47a2b4 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt @@ -25,7 +25,7 @@ import com.yandex.div.core.util.doOnEveryDetach import com.yandex.div.core.util.isLayoutRtl import com.yandex.div.core.util.makeFocusable import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.DivViewCreator @@ -62,26 +62,25 @@ internal class DivPagerBinder @Inject constructor( ) : DivViewBinder { override fun bindView( - context: BindingContext, view: DivPagerView, div: DivPager, + divView: Div2View, path: DivStatePath ) { div.id?.let { pagerIndicatorConnector.submitPager(it, view) } - val divView = context.divView - val resolver = context.expressionResolver + val resolver = divView.expressionResolver val oldDiv = view.div if (div === oldDiv) { val adapter = view.viewPager.adapter as PagerAdapter - if (!adapter.applyPatch(view.getRecyclerView(), divPatchCache)) { + if (!adapter.applyPatch(view.getRecyclerView(), divPatchCache, divView)) { adapter.notifyItemRangeChanged(0, adapter.itemCount) } return } - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) val pageTranslations = SparseArray() val a11yEnabled = accessibilityStateProvider.isAccessibilityEnabled(view.context) @@ -103,7 +102,7 @@ internal class DivPagerBinder @Inject constructor( } view.viewPager.adapter = PagerAdapter( divs = divItems, - bindingContext = context, + div2View = divView, divBinder = divBinder.get(), translationBinder = { holder: PagerViewHolder, position: Int -> pageTranslations[position]?.let { @@ -155,13 +154,14 @@ internal class DivPagerBinder @Inject constructor( }) view.pagerSelectedActionsDispatcher = PagerSelectedActionsDispatcher( - bindingContext = context, + divView = divView, + div = div, divs = divItems, divActionBinder = divActionBinder, ) view.changePageCallbackForLogger = PageChangeCallback( - bindingContext = context, + divView = divView, divPager = div, divs = divItems, recyclerView = view.viewPager.getChildAt(0) as RecyclerView @@ -435,12 +435,11 @@ internal class DivPagerBinder @Inject constructor( class PageChangeCallback( private val divPager: DivPager, private val divs: List
, - private val bindingContext: BindingContext, + private val divView: Div2View, private val recyclerView: RecyclerView ) : ViewPager2.OnPageChangeCallback() { private var prevPosition = RecyclerView.NO_POSITION - private val divView = bindingContext.divView private val minimumSignificantDx = divView.config.logCardScrollSignificantThreshold private var totalDelta = 0 @@ -508,39 +507,38 @@ internal class DivPagerBinder @Inject constructor( } val childDiv = divs[childPosition] - divView.div2Component.visibilityActionTracker - .startTrackingViewsHierarchy(bindingContext, child, childDiv) + divView.div2Component.visibilityActionTracker.startTrackingViewsHierarchy(divView, child, childDiv) } } } private class PagerAdapter( divs: List
, - private val bindingContext: BindingContext, + private val div2View: Div2View, private val divBinder: DivBinder, private val translationBinder: (holder: PagerViewHolder, position: Int) -> Unit, private val viewCreator: DivViewCreator, private val path: DivStatePath, private val accessibilityEnabled: Boolean, - ) : DivPatchableAdapter(divs, bindingContext) { + ) : DivPatchableAdapter(divs, div2View) { override val subscriptions = mutableListOf() var orientation = ViewPager2.ORIENTATION_HORIZONTAL override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagerViewHolder { - val view = PageLayout(bindingContext.divView.context) { orientation } + val view = PageLayout(div2View.context) { orientation } view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) - return PagerViewHolder(bindingContext, view, divBinder, viewCreator, accessibilityEnabled) + return PagerViewHolder(div2View, view, divBinder, viewCreator, accessibilityEnabled) } override fun getItemCount() = items.size override fun onBindViewHolder(holder: PagerViewHolder, position: Int) { val div = items[position] - holder.bind(bindingContext, div, path, position) + holder.bind(div2View, div, path, position) translationBinder.invoke(holder, position) } @@ -578,7 +576,7 @@ internal class DivPagerBinder @Inject constructor( } private class PagerViewHolder( - bindingContext: BindingContext, + divView: Div2View, val frameLayout: PageLayout, private val divBinder: DivBinder, private val viewCreator: DivViewCreator, @@ -588,29 +586,23 @@ internal class DivPagerBinder @Inject constructor( init { itemView.doOnEveryDetach { view -> val div = oldDiv ?: return@doOnEveryDetach - bindingContext.divView.div2Component.visibilityActionTracker - .startTrackingViewsHierarchy(bindingContext, view, div) + divView.div2Component.visibilityActionTracker.startTrackingViewsHierarchy(divView, view, div) } } private var oldDiv: Div? = null - fun bind(bindingContext: BindingContext, div: Div, path: DivStatePath, position: Int) { - val div2View = bindingContext.divView - val resolver = bindingContext.expressionResolver + fun bind(div2View: Div2View, div: Div, path: DivStatePath, position: Int) { + val resolver = div2View.expressionResolver - if (frameLayout.tryRebindRecycleContainerChildren(bindingContext.divView, div)) { + if (frameLayout.tryRebindRecycleContainerChildren(div2View, div)) { oldDiv = div return } - val divView = if (oldDiv != null && frameLayout.isNotEmpty() && - DivComparator.areDivsReplaceable( - oldDiv, - div, - div2View.getExpressionResolver(oldDiv?.value()), - resolver - )) { + val divView = if (oldDiv != null + && frameLayout.isNotEmpty() + && DivComparator.areDivsReplaceable(oldDiv, div, div2View.oldExpressionResolver, resolver)) { frameLayout[0] } else { val newDivView = viewCreator.create(div, resolver) @@ -623,7 +615,11 @@ internal class DivPagerBinder @Inject constructor( frameLayout.setTag(R.id.div_pager_item_clip_id, position) } oldDiv = div - divBinder.bind(bindingContext, divView, div, path) + divBinder.bind(divView, div, div2View, path) + } + + private fun getPagerView(): DivPagerView { + return ((frameLayout.parent as ViewGroup).parent as ViewGroup).parent as DivPagerView } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPatchableAdapter.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPatchableAdapter.kt index 502b8c9a5..b25d82dfc 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPatchableAdapter.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPatchableAdapter.kt @@ -3,15 +3,14 @@ package com.yandex.div.core.view2.divs import androidx.recyclerview.widget.RecyclerView import com.yandex.div.core.downloader.DivPatchApply import com.yandex.div.core.downloader.DivPatchCache -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.internal.core.ExpressionSubscriber -import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivVisibility internal abstract class DivPatchableAdapter( divs: List
, - private val bindingContext: BindingContext, + private val div2View: Div2View, ) : RecyclerView.Adapter(), ExpressionSubscriber { private val _items = divs.toMutableList() val items: List
@@ -31,7 +30,7 @@ internal abstract class DivPatchableAdapter( activityMap.clear() indexedItems.forEach { - val isActive = it.value.isActive(bindingContext.expressionResolver) + val isActive = it.value.isActive(div2View) activityMap[it.value] = isActive if (isActive) { @@ -43,7 +42,7 @@ internal abstract class DivPatchableAdapter( fun subscribeOnElements() { indexedItems.forEach { item -> val div = item.value - val subscription = div.value().visibility.observe(bindingContext.expressionResolver) { + val subscription = div.value().visibility.observe(div2View.expressionResolver) { item.updateVisibility(it) } @@ -73,8 +72,9 @@ internal abstract class DivPatchableAdapter( fun applyPatch( recyclerView: RecyclerView?, divPatchCache: DivPatchCache, + divView: Div2View ): Boolean { - val patch = divPatchCache.getPatch(bindingContext.divView.dataTag) ?: return false + val patch = divPatchCache.getPatch(div2View.dataTag) ?: return false val divPatchApply = DivPatchApply(patch) val appliedToListPatchIds = mutableSetOf() @@ -85,7 +85,7 @@ internal abstract class DivPatchableAdapter( val childDiv = _items[index] val patchId = childDiv.value().id val patchDivs = patchId?.let { - divPatchCache.getPatchDivListById(bindingContext.divView.dataTag, it) + divPatchCache.getPatchDivListById(div2View.dataTag, it) } val isActive = activityMap[childDiv] == true @@ -98,7 +98,7 @@ internal abstract class DivPatchableAdapter( _items.addAll(index, patchDivs) - val activeItemsInserted = patchDivs.count { it.isActive(bindingContext.expressionResolver) } + val activeItemsInserted = patchDivs.count { it.isActive(div2View) } notifyItemRangeInserted(activeIndex, activeItemsInserted) index += patchDivs.size - 1 @@ -118,10 +118,10 @@ internal abstract class DivPatchableAdapter( for (i in 0 until _items.size) { val childDiv = _items[i] divPatchApply.patchDivChild( - parentView = recyclerView ?: bindingContext.divView, + parentView = recyclerView ?: divView, childDiv, idToFind, - bindingContext.expressionResolver + divView.expressionResolver )?.let { newDiv -> _items[i] = newDiv return@forEach @@ -135,8 +135,8 @@ internal abstract class DivPatchableAdapter( } companion object { - private fun Div.isActive(resolver: ExpressionResolver): Boolean = - value().visibility.evaluate(resolver).isActive() + private fun Div.isActive(div2View: Div2View): Boolean = + value().visibility.evaluate(div2View.expressionResolver).isActive() private fun DivVisibility?.isActive() = this != DivVisibility.GONE diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSelectBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSelectBinder.kt index 3057e36a3..e3b4d6989 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSelectBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSelectBinder.kt @@ -4,7 +4,7 @@ import android.widget.TextView import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.expression.variables.TwoWayStringVariableBinder import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivTypefaceResolver import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.animations.DEFAULT_CLICK_ANIMATION @@ -22,22 +22,21 @@ internal class DivSelectBinder @Inject constructor( private val variableBinder: TwoWayStringVariableBinder, private val errorCollectors: ErrorCollectors ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivSelectView, div: DivSelect) { + override fun bindView(view: DivSelectView, div: DivSelect, divView: Div2View) { val oldDiv = view.div if (div === oldDiv) return - val divView = context.divView - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver val errorCollector = errorCollectors.getOrCreate(divView.dataTag, divView.divData) - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) view.apply { textAlignment = TextView.TEXT_ALIGNMENT_VIEW_START - applyOptions(div, context) - observeVariable(div, context, errorCollector) + applyOptions(div, divView) + observeVariable(div, divView, errorCollector) observeFontSize(div, expressionResolver) observeTypeface(div, expressionResolver) @@ -49,16 +48,18 @@ internal class DivSelectBinder @Inject constructor( } } - private fun DivSelectView.applyOptions(div: DivSelect, bindingContext: BindingContext) { - setAnimatedTouchListener(bindingContext, DEFAULT_CLICK_ANIMATION, null) + private fun DivSelectView.applyOptions(div: DivSelect, divView: Div2View) { + val resolver = divView.expressionResolver - val itemList = createObservedItemList(div, bindingContext.expressionResolver) + setAnimatedTouchListener(divView, DEFAULT_CLICK_ANIMATION, null) + + val itemList = createObservedItemList(div, divView.expressionResolver) setItems(itemList) onItemSelectedListener = { position -> text = itemList[position] - valueUpdater?.invoke(div.options[position].value.evaluate(bindingContext.expressionResolver)) + valueUpdater?.invoke(div.options[position].value.evaluate(resolver)) } } @@ -79,15 +80,11 @@ internal class DivSelectBinder @Inject constructor( return itemList } - private fun DivSelectView.observeVariable( - div: DivSelect, - bindingContext: BindingContext, - errorCollector: ErrorCollector - ) { - val resolver = bindingContext.expressionResolver + private fun DivSelectView.observeVariable(div: DivSelect, divView: Div2View, errorCollector: ErrorCollector) { + val resolver = divView.expressionResolver val subscription = variableBinder.bindVariable( - bindingContext.divView, + divView, div.valueVariable, callbacks = object : TwoWayStringVariableBinder.Callbacks { override fun onVariableChanged(value: String?) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSeparatorBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSeparatorBinder.kt index 085690bf3..27f3c8aee 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSeparatorBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSeparatorBinder.kt @@ -3,7 +3,7 @@ package com.yandex.div.core.view2.divs import android.view.Gravity import com.yandex.div.R import com.yandex.div.core.dagger.DivScope -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivSeparatorView import com.yandex.div.json.expressions.ExpressionResolver @@ -17,22 +17,15 @@ internal class DivSeparatorBinder @Inject constructor( private val baseBinder: DivBaseBinder ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivSeparatorView, div: DivSeparator) { + override fun bindView(view: DivSeparatorView, div: DivSeparator, divView: Div2View) { val oldDiv = view.div if (div === oldDiv) return - baseBinder.bindView(context, view, div, oldDiv) - view.applyDivActions( - context, - div.action, - div.actions, - div.longtapActions, - div.doubletapActions, - div.actionAnimation, - div.accessibility, - ) + baseBinder.bindView(view, div, oldDiv, divView) + view.applyDivActions(divView, div.action, div.actions, div.longtapActions, + div.doubletapActions, div.actionAnimation, div.accessibility) - view.bindStyle(div.delimiterStyle, oldDiv?.delimiterStyle, context.expressionResolver) + view.bindStyle(div.delimiterStyle, oldDiv?.delimiterStyle, divView.expressionResolver) view.setDividerHeightResource(R.dimen.div_separator_delimiter_height) view.dividerGravity = Gravity.CENTER diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSliderBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSliderBinder.kt index 569adb513..92c7983fb 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSliderBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivSliderBinder.kt @@ -9,7 +9,6 @@ import com.yandex.div.core.expression.variables.TwoWayIntegerVariableBinder import com.yandex.div.core.font.DivTypefaceProvider import com.yandex.div.core.util.observeDrawable import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivSliderView @@ -41,15 +40,14 @@ internal class DivSliderBinder @Inject constructor( private var errorCollector: ErrorCollector? = null - override fun bindView(context: BindingContext, view: DivSliderView, div: DivSlider) { + override fun bindView(view: DivSliderView, div: DivSlider, divView: Div2View) { val oldDiv = view.div - val divView = context.divView errorCollector = errorCollectors.getOrCreate(divView.dataTag, divView.divData) if (div === oldDiv) return - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) view.interceptionAngle = horizontalInterceptionAngle diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivStateBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivStateBinder.kt index 0357e366e..bdf617cf9 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivStateBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivStateBinder.kt @@ -22,7 +22,6 @@ import com.yandex.div.core.util.androidInterpolator import com.yandex.div.core.util.containsStateInnerTransitions import com.yandex.div.core.util.getDefaultState import com.yandex.div.core.util.walk -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivTransitionBuilder @@ -67,26 +66,24 @@ internal class DivStateBinder @Inject constructor( /** * For example, to bind state to path 0/content/expanded/comments/expanded/comment_03/collapsed you should have: - * @param context includes Div2View and ExpressionResolver for current Div. * @param layout layout with path 0/content/expanded/comments/expanded/comment_03/{any_state_here}. * @param div [DivState], corresponding to path 0/content/expanded/comments/expanded/comment_03, * Exact stateId will be set via [DivStateCache] or [TemporaryDivStateCache], and this class will * handle receiving corresponding to the state [Div] by itself. + * @param divView papa-view, it always the same. * @param divStatePath path 0/content/expanded/comments/expanded, so to previous [DivStateLayout]. */ fun bindView( - context: BindingContext, layout: DivStateLayout, div: DivState, + divView: Div2View, divStatePath: DivStatePath ) { val oldDivState = layout.div val oldDiv = layout.activeStateDiv - val divView = context.divView - val oldResolver = divView.getExpressionResolver(oldDiv?.value()) - baseBinder.bindView(context, layout, div, oldDivState) + baseBinder.bindView(layout, div, oldDivState, divView) - val resolver = context.expressionResolver + val resolver = divView.expressionResolver layout.fixAlignment(div, oldDivState, resolver) val cardId = divView.divTag.id val id = div.getId { @@ -120,7 +117,7 @@ internal class DivStateBinder @Inject constructor( } else { null } - val transition = replaceViewsAnimated(context, div, newState, oldState, incoming, outgoing) + val transition = replaceViewsAnimated(divView, div, newState, oldState, incoming, outgoing) if (transition != null) { TransitionManager.endTransitions(layout) @@ -130,19 +127,15 @@ internal class DivStateBinder @Inject constructor( if (incoming != null) { layout.addView(incoming) if (newStateDiv != null) { - viewBinder.get().bind(context, incoming, newStateDiv, currentPath) + viewBinder.get().bind(incoming, newStateDiv, divView, currentPath) } } if (outgoing != null) { divView.divTransitionHandler.runTransitions(root = layout, endTransitions = false) } } else if (newStateDivValue != null) { - val areDivsReplaceable = outgoing != null && DivComparator.areDivsReplaceable( - oldDiv, - newStateDiv, - oldResolver, - resolver - ) + val areDivsReplaceable = outgoing != null && + DivComparator.areDivsReplaceable(oldDiv, newStateDiv, divView.oldExpressionResolver, resolver) incoming = if (areDivsReplaceable) { outgoing } else { @@ -153,7 +146,7 @@ internal class DivStateBinder @Inject constructor( layout.addView(incoming) } if (incoming != null) { - viewBinder.get().bind(context, incoming, newStateDiv, currentPath) + viewBinder.get().bind(incoming, newStateDiv, divView, currentPath) } } else { layout.releaseAndRemoveChildren(divView) @@ -168,8 +161,8 @@ internal class DivStateBinder @Inject constructor( divView.unbindViewFromDiv(outgoing) if (oldDiv != null) { // We pass null instead of outgoing view to mark previous state as invisible - divVisibilityActionTracker.trackVisibilityActionsOf(divView, oldResolver, null, oldDiv) - untrackRecursively(outgoing, divView, divView.getExpressionResolver(oldDiv.value())) + divVisibilityActionTracker.trackVisibilityActionsOf(divView, null, oldDiv) + untrackRecursively(outgoing, divView) } } } @@ -177,7 +170,7 @@ internal class DivStateBinder @Inject constructor( if (newStateDivValue.visibilityAction != null || newStateDivValue.visibilityActions != null) { divView.bindViewToDiv(incoming, newStateDiv) incoming.doOnNextLayout { - divVisibilityActionTracker.trackVisibilityActionsOf(divView, resolver, incoming, newStateDiv) + divVisibilityActionTracker.trackVisibilityActionsOf(divView, incoming, newStateDiv) } } } @@ -187,7 +180,7 @@ internal class DivStateBinder @Inject constructor( // applying div patch if (childDivId != null) { - val patchView = divPatchManager.createViewsForId(context, childDivId)?.let { views -> + val patchView = divPatchManager.createViewsForId(divView, childDivId)?.let { views -> if (views.size > 1) { KLog.e(TAG) { "Unable to patch state because there is more than 1 div in the patch" } null @@ -202,7 +195,7 @@ internal class DivStateBinder @Inject constructor( if (patchDiv.value().hasSightActions) { divView.bindViewToDiv(patchView, patchDiv) } - viewBinder.get().bind(context, patchView, patchDiv, currentPath) + viewBinder.get().bind(patchView, patchDiv, divView, currentPath) } } @@ -211,7 +204,7 @@ internal class DivStateBinder @Inject constructor( layout.swipeOutCallback = { divView.bulkActions { actions.forEach { - divActionBinder.handleAction(divView, resolver, it, DivActionReason.STATE_SWIPE_OUT) + divActionBinder.handleAction(divView, it, DivActionReason.STATE_SWIPE_OUT) div2Logger.logSwipedAway(divView, layout, it) divActionBeaconSender.sendSwipeOutActionBeacon(it, resolver) } @@ -266,21 +259,21 @@ internal class DivStateBinder @Inject constructor( addSubscription(subscription) } - private fun untrackRecursively(outgoing: View?, divView: Div2View, resolver: ExpressionResolver) { + private fun untrackRecursively(outgoing: View?, divView: Div2View) { if (outgoing is ViewGroup) { // Also, unbind every child outgoing.children.forEach { childView: View -> val childDiv: Div? = divView.unbindViewFromDiv(childView) if (childDiv != null) { - divVisibilityActionTracker.trackVisibilityActionsOf(divView, resolver, null, childDiv) + divVisibilityActionTracker.trackVisibilityActionsOf(divView, null, childDiv) } - untrackRecursively(childView, divView, resolver) + untrackRecursively(childView, divView) } } } private fun replaceViewsAnimated( - context: BindingContext, + divView: Div2View, divState: DivState, incomingState: DivState.State, outgoingState: DivState.State?, @@ -289,11 +282,9 @@ internal class DivStateBinder @Inject constructor( ): Transition? { val outgoingDiv = outgoingState?.div val incomingDiv = incomingState.div - val divView = context.divView - val resolver = context.expressionResolver - val oldResolver = divView.getExpressionResolver(outgoingDiv?.value()) + val resolver = divView.expressionResolver val transition = if (divState.allowsTransitionsOnStateChange(resolver) - && (outgoingDiv?.containsStateInnerTransitions(oldResolver) == true + && (outgoingDiv?.containsStateInnerTransitions(resolver) == true || incomingDiv?.containsStateInnerTransitions(resolver) == true)) { setupTransitions( divView.viewComponent.transitionBuilder, @@ -301,10 +292,10 @@ internal class DivStateBinder @Inject constructor( incomingState, outgoingState, resolver, - oldResolver + divView.oldExpressionResolver ) } else { - setupAnimation(context, incomingState, outgoingState, incoming, outgoing) + setupAnimation(divView, incomingState, outgoingState, incoming, outgoing) } return transition } @@ -331,13 +322,13 @@ internal class DivStateBinder @Inject constructor( val transition = transitionBuilder.buildTransitions( from = outgoingState?.div?.walk(outgoingResolver) ?.onEnter { div -> div !is Div.State } - ?.filter { item -> - item.div.value().transitionTriggers?.allowsTransitionsOnStateChange() ?: true + ?.filter { div -> + div.value().transitionTriggers?.allowsTransitionsOnStateChange() ?: true }, to = incomingState.div?.walk(incomingResolver) ?.onEnter { div -> div !is Div.State } - ?.filter { item -> - item.div.value().transitionTriggers?.allowsTransitionsOnStateChange() ?: true + ?.filter { div -> + div.value().transitionTriggers?.allowsTransitionsOnStateChange() ?: true }, fromResolver = outgoingResolver, toResolver = incomingResolver @@ -348,13 +339,13 @@ internal class DivStateBinder @Inject constructor( } private fun setupAnimation( - context: BindingContext, + divView: Div2View, incomingState: DivState.State, outgoingState: DivState.State?, incoming: View?, outgoing: View? ): Transition? { - val resolver = context.expressionResolver + val resolver = divView.expressionResolver val animationIn = incomingState.animationIn val animationOut = outgoingState?.animationOut if (animationIn != null || animationOut != null ) { @@ -378,21 +369,20 @@ internal class DivStateBinder @Inject constructor( } } - val outResolver = context.divView.getExpressionResolver(outgoingState?.div?.value()) if (animationOut != null && outgoing != null) { - val animationsOut = if (animationOut.name.evaluate(outResolver) != DivAnimation.Name.SET) { + val animationsOut = if (animationOut.name.evaluate(resolver) != DivAnimation.Name.SET) { listOf(animationOut) } else { animationOut.items.orEmpty() } for (animation in animationsOut) { - animation.toTransition(incoming = false, outResolver)?.let { + animation.toTransition(incoming = false, resolver)?.let { transition.addTransition(it .addTarget(outgoing) - .setDuration(animation.duration.evaluate(outResolver)) - .setStartDelay(animation.startDelay.evaluate(outResolver)) - .setInterpolator(animation.interpolator.evaluate(outResolver).androidInterpolator) + .setDuration(animation.duration.evaluate(resolver)) + .setStartDelay(animation.startDelay.evaluate(resolver)) + .setInterpolator(animation.interpolator.evaluate(resolver).androidInterpolator) ) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivTextBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivTextBinder.kt index 68769c039..aefbfbd58 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivTextBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivTextBinder.kt @@ -29,7 +29,7 @@ import com.yandex.div.core.util.doOnActualLayout import com.yandex.div.core.util.text.DivBackgroundSpan import com.yandex.div.core.util.text.DivTextRangesBackgroundHelper import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivTypefaceResolver import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivLineHeightTextView @@ -86,22 +86,15 @@ internal class DivTextBinder @Inject constructor( @ExperimentFlag(HYPHENATION_SUPPORT_ENABLED) private val isHyphenationEnabled: Boolean ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivLineHeightTextView, div: DivText) { + override fun bindView(view: DivLineHeightTextView, div: DivText, divView: Div2View) { val oldDiv = view.div if (div === oldDiv) return - baseBinder.bindView(context, view, div, oldDiv) - view.applyDivActions( - context, - div.action, - div.actions, - div.longtapActions, - div.doubletapActions, - div.actionAnimation, - div.accessibility, - ) + baseBinder.bindView(view, div, oldDiv, divView) + view.applyDivActions(divView, div.action, div.actions, div.longtapActions, + div.doubletapActions, div.actionAnimation, div.accessibility) - val expressionResolver = context.expressionResolver + val expressionResolver = divView.expressionResolver view.bindTypeface(div, oldDiv, expressionResolver) view.bindTextAlignment(div, oldDiv, expressionResolver) view.bindFontSize(div, oldDiv, expressionResolver) @@ -110,8 +103,8 @@ internal class DivTextBinder @Inject constructor( view.bindUnderline(div, oldDiv, expressionResolver) view.bindStrikethrough(div, oldDiv, expressionResolver) view.bindMaxLines(div, oldDiv, expressionResolver) - view.bindText(context, div, oldDiv) - view.bindEllipsis(context, div, oldDiv) + view.bindText(divView, div, oldDiv, expressionResolver) + view.bindEllipsis(divView, div, oldDiv, expressionResolver) view.bindAutoEllipsize(div, oldDiv, expressionResolver) view.bindTextGradient(div, oldDiv, expressionResolver) view.bindTextShadow(div, oldDiv, expressionResolver) @@ -612,33 +605,34 @@ internal class DivTextBinder @Inject constructor( //region Text private fun DivLineHeightTextView.bindText( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivText, oldDiv: DivText?, + resolver: ExpressionResolver ) { if (newDiv.ranges == null && newDiv.images == null) { - bindPlainText(newDiv, oldDiv, bindingContext.expressionResolver) + bindPlainText(newDiv, oldDiv, resolver) } else { - bindRichText(bindingContext, newDiv) + bindRichText(divView, newDiv, resolver) } } private fun DivLineHeightTextView.bindRichText( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivText, + resolver: ExpressionResolver ) { - val resolver = bindingContext.expressionResolver - applyRichText(bindingContext, newDiv) + applyRichText(divView, resolver, newDiv) applyHyphenation(newDiv.text.evaluate(resolver)) addSubscription( newDiv.text.observe(resolver) { text -> - applyRichText(bindingContext, newDiv) + applyRichText(divView, resolver, newDiv) applyHyphenation(text) } ) - val callback = { _: Any -> applyRichText(bindingContext, newDiv) } + val callback = { _: Any -> applyRichText(divView, resolver, newDiv) } newDiv.ranges?.forEach { range -> addSubscription(range.start.observe(resolver, callback)) addSubscription(range.end.observe(resolver, callback)) @@ -662,13 +656,14 @@ internal class DivTextBinder @Inject constructor( } private fun TextView.applyRichText( - bindingContext: BindingContext, + divView: Div2View, + resolver: ExpressionResolver, div: DivText ) { - val resolver = bindingContext.expressionResolver val ranger = DivTextRanger( - bindingContext, + divView, this, + resolver, div.text.evaluate(resolver), div.fontSize.evaluate(resolver), div.fontFamily?.evaluate(resolver), @@ -744,15 +739,16 @@ internal class DivTextBinder @Inject constructor( //region Ellipsis private fun DivLineHeightTextView.bindEllipsis( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivText, oldDiv: DivText?, + resolver: ExpressionResolver ) { val ellipsis = newDiv.ellipsis if (ellipsis?.ranges == null && ellipsis?.images == null && ellipsis?.actions == null) { - bindPlainEllipsis(newDiv.ellipsis, oldDiv?.ellipsis, bindingContext.expressionResolver) + bindPlainEllipsis(newDiv.ellipsis, oldDiv?.ellipsis, resolver) } else { - bindRichEllipsis(bindingContext, newDiv) + bindRichEllipsis(divView, newDiv, resolver) } } @@ -781,15 +777,15 @@ internal class DivTextBinder @Inject constructor( } private fun DivLineHeightTextView.bindRichEllipsis( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivText, + resolver: ExpressionResolver ) { - applyRichEllipsis(bindingContext, newDiv) + applyRichEllipsis(divView, newDiv, resolver) val ellipsis = newDiv.ellipsis ?: return - val resolver = bindingContext.expressionResolver - val callback = { _: Any -> applyRichEllipsis(bindingContext, newDiv) } + val callback = { _: Any -> applyRichEllipsis(divView, newDiv, resolver) } addSubscription(ellipsis.text.observe(resolver, callback)) ellipsis.ranges?.forEach { range -> addSubscription(range.start.observe(resolver, callback)) @@ -819,8 +815,9 @@ internal class DivTextBinder @Inject constructor( } private fun EllipsizedTextView.applyRichEllipsis( - bindingContext: BindingContext, + divView: Div2View, newDiv: DivText, + resolver: ExpressionResolver ) { val ellipsis = newDiv.ellipsis if (ellipsis == null) { @@ -828,10 +825,10 @@ internal class DivTextBinder @Inject constructor( return } - val resolver = bindingContext.expressionResolver val ranger = DivTextRanger( - bindingContext, + divView, this, + resolver, ellipsis.text.evaluate(resolver), newDiv.fontSize.evaluate(resolver), newDiv.fontFamily?.evaluate(resolver), @@ -935,8 +932,9 @@ internal class DivTextBinder @Inject constructor( // TODO: refactor to SpannedTextBuilder scoped by div context. private inner class DivTextRanger( - private val bindingContext: BindingContext, + private val divView: Div2View, private val textView: TextView, + private val resolver: ExpressionResolver, private val text: String, private val fontSize: Long, private val fontFamily: String?, @@ -945,8 +943,6 @@ internal class DivTextBinder @Inject constructor( images: List? ) { - private val divView = bindingContext.divView - private val resolver = bindingContext.expressionResolver private val context = divView.context private val metrics = divView.resources.displayMetrics private val sb: SpannableStringBuilder = SpannableStringBuilder(text) @@ -1146,7 +1142,7 @@ internal class DivTextBinder @Inject constructor( private inner class DivClickableSpan(private val actions: List) : ClickableSpan() { override fun onClick(p0: View) { val actionBinder = divView.div2Component.actionBinder - actionBinder.handleTapClick(bindingContext, p0, actions) + actionBinder.handleTapClick(divView, p0, actions) } override fun updateDrawState(ds: TextPaint) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivVideoBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivVideoBinder.kt index e7913837d..4b0a63812 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivVideoBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivVideoBinder.kt @@ -17,7 +17,6 @@ import com.yandex.div.core.player.DivPlayerView import com.yandex.div.core.player.DivVideoResolution import com.yandex.div.core.player.DivVideoSource import com.yandex.div.core.player.DivVideoViewMapper -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivVideoView @@ -32,12 +31,11 @@ internal class DivVideoBinder @Inject constructor( private val divActionBinder: DivActionBinder, private val videoViewMapper: DivVideoViewMapper, ) : DivViewBinder { - override fun bindView(context: BindingContext, view: DivVideoView, div: DivVideo) { + override fun bindView(view: DivVideoView, div: DivVideo, divView: Div2View) { val oldDiv = view.div - val divView = context.divView - val resolver = context.expressionResolver + val resolver = divView.expressionResolver - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) val source = div.createSource(resolver) val config = DivPlayerPlaybackConfig( @@ -90,23 +88,23 @@ internal class DivVideoBinder @Inject constructor( val playerListener = object : DivPlayer.Observer { override fun onPlay() { - divActionBinder.handleActions(divView, resolver, div.resumeActions, DivActionReason.VIDEO) + divActionBinder.handleActions(divView, div.resumeActions, DivActionReason.VIDEO) } override fun onPause() { - divActionBinder.handleActions(divView, resolver, div.pauseActions, DivActionReason.VIDEO) + divActionBinder.handleActions(divView, div.pauseActions, DivActionReason.VIDEO) } override fun onBuffering() { - divActionBinder.handleActions(divView, resolver, div.bufferingActions, DivActionReason.VIDEO) + divActionBinder.handleActions(divView, div.bufferingActions, DivActionReason.VIDEO) } override fun onEnd() { - divActionBinder.handleActions(divView, resolver, div.endActions, DivActionReason.VIDEO) + divActionBinder.handleActions(divView, div.endActions, DivActionReason.VIDEO) } override fun onFatal() { - divActionBinder.handleActions(divView, resolver, div.fatalActions, DivActionReason.VIDEO) + divActionBinder.handleActions(divView, div.fatalActions, DivActionReason.VIDEO) } override fun onReady() { @@ -119,14 +117,14 @@ internal class DivVideoBinder @Inject constructor( if (div === oldDiv) { view.observeElapsedTime(div, divView, player) - view.observeMuted(div, resolver, player) - view.observeScale(div, resolver, playerView) + view.observeMuted(div, divView, player) + view.observeScale(div, divView, playerView) return } view.observeElapsedTime(div, divView, player) - view.observeMuted(div, resolver, player) - view.observeScale(div, resolver, playerView) + view.observeMuted(div, divView, player) + view.observeScale(div, divView, playerView) if (currentPreviewView == null && currentPlayerView == null) { view.removeAllViews() @@ -167,11 +165,11 @@ internal class DivVideoBinder @Inject constructor( private fun DivVideoView.observeMuted( div: DivVideo, - resolver: ExpressionResolver, + divView: Div2View, player: DivPlayer ) { addSubscription( - div.muted.observeAndGet(resolver) { + div.muted.observeAndGet(divView.expressionResolver) { player.setMuted(it) } ) @@ -179,11 +177,11 @@ internal class DivVideoBinder @Inject constructor( private fun DivVideoView.observeScale( div: DivVideo, - resolver: ExpressionResolver, + divView: Div2View, playerView: DivPlayerView ) { addSubscription( - div.scale.observeAndGet(resolver) { + div.scale.observeAndGet(divView.expressionResolver) { playerView.setScale(it) } ) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcher.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcher.kt index fe9652da6..979f36443 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcher.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcher.kt @@ -4,7 +4,7 @@ import androidx.annotation.VisibleForTesting import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import com.yandex.div.core.DivActionHandler.DivActionReason -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.internal.KLog import com.yandex.div2.Div import com.yandex.div2.DivPager @@ -15,7 +15,8 @@ private const val TAG = "Ya:PagerSelectedActionsTracker" * Responsible to dispatch item's `selected_actions` for [DivPager]. */ internal class PagerSelectedActionsDispatcher( - private val bindingContext: BindingContext, + private val divView: Div2View, + private val div: DivPager, private val divs: List
, private val divActionBinder: DivActionBinder ) { @@ -67,14 +68,9 @@ internal class PagerSelectedActionsDispatcher( private fun dispatchSelectedActions(div: Div) { div.value().selectedActions?.let { actions -> - bindingContext.divView.bulkActions { + divView.bulkActions { actions.forEach { action -> - divActionBinder.handleAction( - bindingContext.divView, - bindingContext.expressionResolver, - action, - DivActionReason.SELECTION - ) + divActionBinder.handleAction(divView, action, DivActionReason.SELECTION) } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt index a926bd21d..a6bcb324a 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt @@ -16,7 +16,7 @@ import com.yandex.div.core.state.GalleryState import com.yandex.div.core.state.UpdateStateScrollListener import com.yandex.div.core.util.doOnActualLayout import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.DivViewCreator @@ -34,6 +34,7 @@ import com.yandex.div.core.view2.reuse.util.tryRebindRecycleContainerChildren import com.yandex.div.core.widget.DivViewWrapper import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.widget.PaddingItemDecoration +import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivGallery import java.util.WeakHashMap @@ -51,24 +52,23 @@ internal class DivGalleryBinder @Inject constructor( ) : DivViewBinder { @SuppressLint("ClickableViewAccessibility") - override fun bindView(context: BindingContext, view: DivRecyclerView, div: DivGallery, path: DivStatePath) { - val divView = context.divView - val resolver = context.expressionResolver + override fun bindView(view: DivRecyclerView, div: DivGallery, divView: Div2View, path: DivStatePath) { + val resolver = divView.expressionResolver val oldDiv = (view as? DivRecyclerView)?.div if (div === oldDiv) { val adapter = view.adapter as GalleryAdapter - adapter.applyPatch(view, divPatchCache) + adapter.applyPatch(view, divPatchCache, divView) adapter.closeAllSubscription() adapter.subscribeOnElements() - view.bindStates(divView.rootDiv(), context, resolver, divBinder.get()) + view.bindStates(divView.rootDiv(), divView, resolver, divBinder.get()) return } - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) val reusableObserver = { _: Any -> - updateDecorations(view, div, context) + updateDecorations(view, div, divView, resolver) } view.addSubscription(div.orientation.observe(resolver, reusableObserver)) view.addSubscription(div.scrollbar.observe(resolver, reusableObserver)) @@ -86,22 +86,22 @@ internal class DivGalleryBinder @Inject constructor( view.overScrollMode = RecyclerView.OVER_SCROLL_NEVER val itemStateBinder = { itemView: View, _: Div -> - itemView.bindStates(divView.rootDiv(), context, resolver, divBinder.get()) + itemView.bindStates(divView.rootDiv(), divView, resolver, divBinder.get()) } view.adapter = - GalleryAdapter(div.nonNullItems, context, divBinder.get(), viewCreator, itemStateBinder, path) + GalleryAdapter(div.nonNullItems, divView, divBinder.get(), viewCreator, itemStateBinder, path) view.resetAnimatorAndRestoreOnLayout() - updateDecorations(view, div, context) + updateDecorations(view, div, divView, resolver) } private fun updateDecorations( view: DivRecyclerView, div: DivGallery, - context: BindingContext, + divView: Div2View, + resolver: ExpressionResolver, ) { val metrics = view.resources.displayMetrics - val resolver = context.expressionResolver val divOrientation = div.orientation.evaluate(resolver) val orientation = if (divOrientation == DivGallery.Orientation.HORIZONTAL) { RecyclerView.HORIZONTAL @@ -153,15 +153,15 @@ internal class DivGalleryBinder @Inject constructor( // DivGalleryItemHelper type with DivGridLayoutManager, resulting in // casting DivLinearLayoutManager to DivGridLayoutManager exception. val itemHelper: DivGalleryItemHelper = if (columnCount == 1L) { - DivLinearLayoutManager(context, view, div, orientation) + DivLinearLayoutManager(divView, view, div, orientation) } else { - DivGridLayoutManager(context, view, div, orientation) + DivGridLayoutManager(divView, view, div, orientation) } view.layoutManager = itemHelper.toLayoutManager() view.scrollInterceptionAngle = scrollInterceptionAngle view.clearOnScrollListeners() - context.divView.currentState?.let { state -> + divView.currentState?.let { state -> val id = div.id ?: div.hashCode().toString() val galleryState = state.getBlockState(id) as GalleryState? val position = galleryState?.visibleItemIndex @@ -170,7 +170,7 @@ internal class DivGalleryBinder @Inject constructor( view.scrollToPositionInternal(position, offset, scrollMode.toScrollPosition()) view.addOnScrollListener(UpdateStateScrollListener(id, state, itemHelper)) } - view.addOnScrollListener(ScrollListener(context, view, itemHelper, div)) + view.addOnScrollListener(ScrollListener(divView, view, itemHelper, div)) view.onInterceptTouchEventListener = if (div.restrictParentScroll.evaluate(resolver)) { ParentScrollRestrictor } else { @@ -218,13 +218,12 @@ internal class DivGalleryBinder @Inject constructor( } private class ScrollListener( - private val bindingContext: BindingContext, + private val divView: Div2View, private val recycler: DivRecyclerView, private val galleryItemHelper: DivGalleryItemHelper, private val galleryDiv: DivGallery, ) : RecyclerView.OnScrollListener() { - private val divView = bindingContext.divView private val minimumSignificantDx = divView.config.logCardScrollSignificantThreshold var totalDelta = 0 @@ -273,13 +272,13 @@ internal class DivGalleryBinder @Inject constructor( if (position == RecyclerView.NO_POSITION) return@forEach val div = (recycler.adapter as GalleryAdapter).items[position] - visibilityActionTracker.startTrackingViewsHierarchy(bindingContext, child, div) + visibilityActionTracker.startTrackingViewsHierarchy(divView, child, div) } // Find and track recycled views containing DisappearActions that are waiting for disappear with(visibilityActionTracker) { getDivWithWaitingDisappearActions().filter { it.key !in recycler.children }.forEach { (view, div) -> - trackDetachedView(bindingContext, view, div) + trackDetachedView(divView, view, div) } } } @@ -287,12 +286,12 @@ internal class DivGalleryBinder @Inject constructor( internal class GalleryAdapter( divs: List
, - private val bindingContext: BindingContext, + private val div2View: Div2View, private val divBinder: DivBinder, private val viewCreator: DivViewCreator, private val itemStateBinder: (itemView: View, div: Div) -> Unit, private val path: DivStatePath - ) : DivPatchableAdapter(divs, bindingContext) { + ) : DivPatchableAdapter(divs, div2View) { private val ids = WeakHashMap() private var lastItemId = 0L @@ -312,7 +311,7 @@ internal class DivGalleryBinder @Inject constructor( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GalleryViewHolder { - val view = DivViewWrapper(bindingContext.divView.context) + val view = DivViewWrapper(div2View.context) return GalleryViewHolder(view, divBinder, viewCreator) } @@ -324,7 +323,7 @@ internal class DivGalleryBinder @Inject constructor( override fun getItemCount() = activeItems.size override fun onBindViewHolder(holder: GalleryViewHolder, position: Int) { - holder.bind(bindingContext, activeItems[position], path) + holder.bind(div2View, activeItems[position], path) holder.rootView.setTag(R.id.div_gallery_item_index, position) divBinder.attachIndicators() } @@ -338,22 +337,17 @@ internal class DivGalleryBinder @Inject constructor( var oldDiv: Div? = null - fun bind(context: BindingContext, div: Div, path: DivStatePath) { - val div2View = context.divView - val resolver = context.expressionResolver + fun bind(div2View: Div2View, div: Div, path: DivStatePath) { + val resolver = div2View.expressionResolver if (rootView.tryRebindRecycleContainerChildren(div2View, div)) { oldDiv = div return } - val divView = if (oldDiv != null && rootView.child != null && - DivComparator.areDivsReplaceable( - oldDiv, - div, - div2View.getExpressionResolver(oldDiv?.value()), - resolver - )) { + val divView = if (oldDiv != null + && rootView.child != null + && DivComparator.areDivsReplaceable(oldDiv, div, div2View.oldExpressionResolver, resolver)) { rootView.child!! } else { val newDivView = viewCreator.create(div, resolver) @@ -363,7 +357,7 @@ internal class DivGalleryBinder @Inject constructor( } oldDiv = div - divBinder.bind(context, divView, div, path) + divBinder.bind(divView, div, div2View, path) } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryItemHelper.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryItemHelper.kt index 688bc9e55..16f8148d7 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryItemHelper.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryItemHelper.kt @@ -10,7 +10,7 @@ import androidx.recyclerview.widget.OrientationHelper import androidx.recyclerview.widget.RecyclerView import com.yandex.div.R import com.yandex.div.core.util.doOnActualLayout -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.widget.makeAtMostSpec import com.yandex.div.core.widget.makeExactSpec import com.yandex.div.core.widget.makeUnspecifiedSpec @@ -24,7 +24,7 @@ import com.yandex.div2.DivGallery import kotlin.math.min internal interface DivGalleryItemHelper { - val bindingContext: BindingContext + val divView: Div2View val view: RecyclerView val div: DivGallery val divItems: List
@@ -55,7 +55,7 @@ internal interface DivGalleryItemHelper { ) { val childDiv = runCatching { divItems[child.getTag(R.id.div_gallery_item_index) as Int].value() }.getOrNull() - val resolver = bindingContext.expressionResolver + val resolver = divView.expressionResolver val parentAlignment = div.crossContentAlignment val orientation = getLayoutManagerOrientation() @@ -226,12 +226,11 @@ internal interface DivGalleryItemHelper { val itemView = container.children.firstOrNull() ?: return val div = divItems[position] - val divView = bindingContext.divView if (clear) { - divView.div2Component.visibilityActionTracker.cancelTrackingViewsHierarchy(bindingContext, itemView, div) + divView.div2Component.visibilityActionTracker.cancelTrackingViewsHierarchy(divView, itemView, div) divView.unbindViewFromDiv(itemView) } else { - divView.div2Component.visibilityActionTracker.startTrackingViewsHierarchy(bindingContext, itemView, div) + divView.div2Component.visibilityActionTracker.startTrackingViewsHierarchy(divView, itemView, div) divView.bindViewToDiv(itemView, div) } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt index d4098d00c..1f33dbf46 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt @@ -4,19 +4,19 @@ import android.view.View import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.dpToPx import com.yandex.div.internal.core.nonNullItems import com.yandex.div2.DivGallery import com.yandex.div2.DivSize internal class DivGridLayoutManager( - override val bindingContext: BindingContext, + override val divView: Div2View, override val view: RecyclerView, override val div: DivGallery, @RecyclerView.Orientation orientation: Int = RecyclerView.HORIZONTAL ) : StaggeredGridLayoutManager ( - div.columnCount?.evaluate(bindingContext.expressionResolver)?.toIntSafely() ?: 1, + div.columnCount?.evaluate(divView.expressionResolver)?.toIntSafely() ?: 1, orientation ), DivGalleryItemHelper { @@ -26,7 +26,7 @@ internal class DivGridLayoutManager( get() = (view.adapter as? DivGalleryBinder.GalleryAdapter)?.items ?: div.nonNullItems private val midPadding - get() = div.itemSpacing.evaluate(bindingContext.expressionResolver).dpToPx(view.resources.displayMetrics) + get() = div.itemSpacing.evaluate(divView.expressionResolver).dpToPx(view.resources.displayMetrics) override fun toLayoutManager() = this diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsAdapter.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsAdapter.kt index 6c069e875..8d8b78b47 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsAdapter.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsAdapter.kt @@ -7,7 +7,7 @@ import com.yandex.div.core.downloader.DivPatchApply import com.yandex.div.core.downloader.DivPatchCache import com.yandex.div.core.state.DivStatePath import com.yandex.div.core.util.expressionSubscriber -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewCreator import com.yandex.div.core.view2.divs.toLayoutParamsSize @@ -29,7 +29,7 @@ internal class DivTabsAdapter( tabbedCardConfig: TabbedCardConfig, heightCalculatorFactory: HeightCalculatorFactory, val isDynamicHeight: Boolean, - private val bindingContext: BindingContext, + private val div2View: Div2View, textStyleProvider: TabTextStyleProvider, private val viewCreator: DivViewCreator, private val divBinder: DivBinder, @@ -49,7 +49,7 @@ internal class DivTabsAdapter( private val tabModels = mutableMapOf() fun setData(data: Input, selectedTab: Int) { - super.setData(data, bindingContext.expressionResolver, bindingContext.divView.expressionSubscriber) + super.setData(data, div2View.expressionResolver, div2View.expressionSubscriber) tabModels.clear() mPager.setCurrentItem(selectedTab, true) } @@ -59,10 +59,10 @@ internal class DivTabsAdapter( tab: DivSimpleTab, tabNumber: Int ): ViewGroup { - tabView.releaseAndRemoveChildren(bindingContext.divView) + tabView.releaseAndRemoveChildren(div2View) val itemDiv = tab.item.div - val itemView = createItemView(itemDiv, bindingContext.expressionResolver) + val itemView = createItemView(itemDiv, div2View.expressionResolver) tabModels[tabView] = TabModel(tabNumber, itemDiv, itemView) tabView.addView(itemView) @@ -71,12 +71,12 @@ internal class DivTabsAdapter( override fun unbindTabData(tabView: ViewGroup) { tabModels.remove(tabView) - tabView.releaseAndRemoveChildren(bindingContext.divView) + tabView.releaseAndRemoveChildren(div2View) } override fun fillMeasuringTab(tabView: ViewGroup, tab: DivSimpleTab, tabNumber: Int) { - tabView.releaseAndRemoveChildren(bindingContext.divView) - val itemView = createItemView(tab.item.div, bindingContext.expressionResolver) + tabView.releaseAndRemoveChildren(div2View) + val itemView = createItemView(tab.item.div, div2View.expressionResolver) tabView.addView(itemView) } @@ -87,23 +87,23 @@ internal class DivTabsAdapter( ViewGroup.LayoutParams.MATCH_PARENT ) } - divBinder.bind(bindingContext, itemView, div, path) + divBinder.bind(itemView, div, div2View, path) return itemView } fun notifyStateChanged() { tabModels.forEach { (tabView, tabModel) -> - divBinder.bind(bindingContext, tabModel.view, tabModel.div, path) + divBinder.bind(tabModel.view, tabModel.div, div2View, path) // ... and a little bit of a magic tabView.requestLayout() } } fun applyPatch(resolver: ExpressionResolver, div: DivTabs): DivTabs? { - val patchMap = divPatchCache.getPatch(bindingContext.divView.dataTag) ?: return null + val patchMap = divPatchCache.getPatch(div2View.dataTag) ?: return null val newTabs = DivPatchApply(patchMap).applyPatchForDiv(Div.Tabs(div), resolver)[0].value() as DivTabs - val displayMetrics = bindingContext.divView.resources.displayMetrics + val displayMetrics = div2View.resources.displayMetrics val list = newTabs.items.map { DivSimpleTab(it, displayMetrics, resolver) } setData ({ list }, mPager.currentItem) return newTabs diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsBinder.kt index 68a28be0d..52ae534f5 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsBinder.kt @@ -14,7 +14,7 @@ import com.yandex.div.core.font.DivTypefaceType import com.yandex.div.core.state.DivStatePath import com.yandex.div.core.util.expressionSubscriber import com.yandex.div.core.util.toIntSafely -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewCreator import com.yandex.div.core.view2.DivVisibilityActionTracker @@ -69,9 +69,9 @@ internal class DivTabsBinder @Inject constructor( viewPool.register(TAG_TAB_ITEM, { TabItemLayout(context) }, 2) } - fun bindView(context: BindingContext, view: DivTabsLayout, div: DivTabs, divBinder: DivBinder, path: DivStatePath) { + fun bindView(view: DivTabsLayout, div: DivTabs, divView: Div2View, divBinder: DivBinder, path: DivStatePath) { val oldDiv = view.div - val resolver = context.expressionResolver + val resolver = divView.expressionResolver if (oldDiv === div) { view.divTabsAdapter?.applyPatch(resolver, div)?.let { view.div = it @@ -79,8 +79,7 @@ internal class DivTabsBinder @Inject constructor( } } - val divView = context.divView - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) view.clipToPadding = false @@ -107,7 +106,7 @@ internal class DivTabsBinder @Inject constructor( }) view.titleLayout.setOnScrollChangedListener { div2Logger.logTabTitlesScroll(divView) } - bindAdapter(path, context, view, oldDiv, div, divBinder, view) + bindAdapter(path, divView, view, oldDiv, div, divBinder, resolver, view) view.addSubscription(div.restrictParentScroll.observeAndGet(resolver) { restrictScroll -> view.viewPager.onInterceptTouchEventListener = if (restrictScroll) { @@ -120,18 +119,18 @@ internal class DivTabsBinder @Inject constructor( private fun bindAdapter( path: DivStatePath, - bindingContext: BindingContext, + divView: Div2View, view: DivTabsLayout, oldDiv: DivTabs?, div: DivTabs, divBinder: DivBinder, + resolver: ExpressionResolver, subscriber: ExpressionSubscriber ) { - val resolver = bindingContext.expressionResolver val list = div.items.map { DivSimpleTab(it, view.resources.displayMetrics, resolver) } fun setupNewAdapter(selectedTab: Int) { - val divTabsUi = createAdapter(bindingContext, div, view, divBinder, path) + val divTabsUi = createAdapter(divView, div, resolver, view, divBinder, path) divTabsUi.setData({ list }, selectedTab) view.divTabsAdapter = divTabsUi } @@ -179,7 +178,6 @@ internal class DivTabsBinder @Inject constructor( subscriber.addSubscription(div.selectedTab.observe(resolver, selectTab)) - val divView = bindingContext.divView val isDataTagTheSame = divView.prevDataTag == DivDataTag.INVALID || divView.dataTag == divView.prevDataTag @@ -200,16 +198,15 @@ internal class DivTabsBinder @Inject constructor( }) } - private fun createAdapter( - bindingContext: BindingContext, - div: DivTabs, - view: DivTabsLayout, - divBinder: DivBinder, - path: DivStatePath, + private fun createAdapter(divView: Div2View, + div: DivTabs, + resolver: ExpressionResolver, + view: DivTabsLayout, + divBinder: DivBinder, + path: DivStatePath, ): DivTabsAdapter { - val eventManager = - DivTabsEventManager(bindingContext, actionBinder, div2Logger, visibilityActionTracker, view, div) - val isDynamicHeight = div.dynamicHeight.evaluate(bindingContext.expressionResolver) + val eventManager = DivTabsEventManager(divView, actionBinder, div2Logger, visibilityActionTracker, view, div) + val isDynamicHeight = div.dynamicHeight.evaluate(resolver) val heightCalculatorFactory = if (isDynamicHeight) { HeightCalculatorFactory(::DynamicCardHeightCalculator) } else { @@ -225,7 +222,7 @@ internal class DivTabsBinder @Inject constructor( } return DivTabsAdapter( viewPool, view, getTabbedCardLayoutIds(), heightCalculatorFactory, isDynamicHeight, - bindingContext, textStyleProvider, viewCreator, divBinder, + divView, textStyleProvider, viewCreator, divBinder, eventManager, path, divPatchCache ) @@ -238,10 +235,10 @@ internal class DivTabsBinder @Inject constructor( private fun TabTitlesLayoutView<*>.observeHeight(div: DivTabs, resolver: ExpressionResolver) { val applyHeight = { _: Any? -> val tabTitleStyle = div.tabTitleStyle ?: DEFAULT_TAB_TITLE_STYLE - val textPaddings = tabTitleStyle.paddings + val textPaddings = tabTitleStyle?.paddings val layoutPaddings = div.titlePaddings val lineHeight = tabTitleStyle.lineHeight?.evaluate(resolver) - ?: (tabTitleStyle.fontSize.evaluate(resolver) * DEFAULT_LINE_HEIGHT_COEFFICIENT).toLong() + ?: (tabTitleStyle?.fontSize?.evaluate(resolver) * DEFAULT_LINE_HEIGHT_COEFFICIENT).toLong() val height = lineHeight + textPaddings.top.evaluate(resolver) + textPaddings.bottom.evaluate(resolver) + layoutPaddings.top.evaluate(resolver) + layoutPaddings.bottom.evaluate(resolver) val metrics = resources.displayMetrics diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsEventManager.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsEventManager.kt index 6c7bfd688..eb3ac088c 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsEventManager.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/tabs/DivTabsEventManager.kt @@ -3,7 +3,7 @@ package com.yandex.div.core.view2.divs.tabs import androidx.viewpager.widget.ViewPager import com.yandex.div.core.Div2Logger import com.yandex.div.core.DivActionHandler.DivActionReason -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivVisibilityActionTracker import com.yandex.div.core.view2.divs.DivActionBinder import com.yandex.div.internal.KLog @@ -13,7 +13,7 @@ import com.yandex.div2.DivAction import com.yandex.div2.DivTabs internal class DivTabsEventManager( - private val context: BindingContext, + private val div2View: Div2View, private val actionBinder: DivActionBinder, private val div2Logger: Div2Logger, private val visibilityActionTracker: DivVisibilityActionTracker, @@ -30,7 +30,7 @@ internal class DivTabsEventManager( override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) = Unit override fun onPageSelected(position: Int) { - div2Logger.logTabPageChanged(context.divView, position) + div2Logger.logTabPageChanged(div2View, position) onPageDisplayed(position) } @@ -44,13 +44,13 @@ internal class DivTabsEventManager( // This assumption is safe as long as we display only one page in ViewPager. if (currentPagePosition != NO_POSITION) { val previousTab = div.items[currentPagePosition] - visibilityActionTracker.cancelTrackingViewsHierarchy(context, viewPager, previousTab.div) - context.divView.unbindViewFromDiv(viewPager) + visibilityActionTracker.cancelTrackingViewsHierarchy(div2View, viewPager, previousTab.div) + div2View.unbindViewFromDiv(viewPager) } val selectedTab = div.items[position] - visibilityActionTracker.startTrackingViewsHierarchy(context, viewPager, selectedTab.div) - context.divView.bindViewToDiv(viewPager, selectedTab.div) + visibilityActionTracker.startTrackingViewsHierarchy(div2View, viewPager, selectedTab.div) + div2View.bindViewToDiv(viewPager, selectedTab.div) currentPagePosition = position } @@ -60,8 +60,8 @@ internal class DivTabsEventManager( // TODO(MORDAANDROID-90): handle case with menuItems != null KLog.w(TAG) { "non-null menuItems ignored in title click action" } } - div2Logger.logActiveTabTitleClick(context.divView, tabPosition, action) - actionBinder.handleAction(context.divView, context.expressionResolver, action, DivActionReason.CLICK) + div2Logger.logActiveTabTitleClick(div2View, tabPosition, action) + actionBinder.handleAction(div2View, action, DivActionReason.CLICK) } private companion object { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt index 1acc597c0..71bb32cdc 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt @@ -6,7 +6,6 @@ import com.yandex.div.core.view2.divs.DivPatchableAdapter import com.yandex.div.core.view2.divs.widgets.DivPagerView import com.yandex.div.core.view2.divs.widgets.DivRecyclerView import com.yandex.div.core.view2.divs.widgets.DivStateLayout -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.buildItems import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver @@ -17,14 +16,14 @@ import com.yandex.div2.DivGrid import com.yandex.div2.DivPager internal class ExistingToken( - item: DivItemBuilderResult, + div: Div, val view: View, override val parentToken: ExistingToken?, childIndex: Int, -) : Token(item, parentToken, childIndex) { +) : Token(div, parentToken, childIndex) { - override fun getChildrenTokens(): List { - return when (val div = item.div) { + override fun getChildrenTokens(resolver: ExpressionResolver): List { + return when (this.div) { is Div.Text -> emptyList() is Div.Image -> emptyList() is Div.GifImage -> emptyList() @@ -35,12 +34,12 @@ internal class ExistingToken( is Div.Custom -> emptyList() is Div.Select -> emptyList() is Div.Video -> emptyList() - is Div.Container -> itemsToExistingTokenList(div.value, item.expressionResolver) - is Div.Grid -> itemsToExistingTokenList(div.value, item.expressionResolver) - is Div.Gallery -> itemsToExistingTokenList(div.value, item.expressionResolver) - is Div.Pager -> itemsToExistingTokenList(div.value, item.expressionResolver) + is Div.Container -> itemsToExistingTokenList(this.div.value, resolver) + is Div.Grid -> itemsToExistingTokenList(this.div.value) + is Div.Gallery -> itemsToExistingTokenList(this.div.value) + is Div.Pager -> itemsToExistingTokenList(this.div.value) is Div.Tabs -> emptyList() // Not supported yet. Only full rebind - is Div.State -> itemsToExistingTokenList(item.expressionResolver) + is Div.State -> itemsToExistingTokenList() } } @@ -51,16 +50,16 @@ internal class ExistingToken( return simpleItemsToExistingTokenList(div.buildItems(resolver)) } - private fun itemsToExistingTokenList(div: DivGrid, resolver: ExpressionResolver): List { - return simpleItemsToExistingTokenList(div.nonNullItems.map { DivItemBuilderResult(it, resolver) }) + private fun itemsToExistingTokenList(div: DivGrid): List { + return simpleItemsToExistingTokenList(div.nonNullItems) } - private fun itemsToExistingTokenList(resolver: ExpressionResolver): List { + private fun itemsToExistingTokenList(): List { val stateDiv = (view as? DivStateLayout)?.activeStateDiv ?: return emptyList() - return simpleItemsToExistingTokenList(listOf(stateDiv).map { DivItemBuilderResult(it, resolver) }) + return simpleItemsToExistingTokenList(listOf(stateDiv)) } - private fun itemsToExistingTokenList(div: DivPager, resolver: ExpressionResolver): List { + private fun itemsToExistingTokenList(div: DivPager): List { val tokens = mutableListOf() val pager = (view as? DivPagerView)?.viewPager ?: return emptyList() val adapter = (pager.adapter as? DivPatchableAdapter) ?: return emptyList() @@ -72,7 +71,7 @@ internal class ExistingToken( val childViewIndex = activeHashes.indexOf(newItem.hash()) val targetView = view.getPageView(childViewIndex) ?: return@forEachIndexed val token = ExistingToken( - item = DivItemBuilderResult(newItem, resolver), + div = newItem, view = targetView, childIndex = index, parentToken = this, @@ -84,7 +83,7 @@ internal class ExistingToken( return tokens } - private fun itemsToExistingTokenList(div: DivGallery, resolver: ExpressionResolver): List { + private fun itemsToExistingTokenList(div: DivGallery): List { val tokens = mutableListOf() val adapter = ((view as? DivRecyclerView)?.adapter as? DivPatchableAdapter) ?: return emptyList() val activeItems = adapter.activeItems @@ -94,7 +93,7 @@ internal class ExistingToken( if (newItem.hash() in activeHashes) { val targetView = view.getItemView(index) ?: return@forEachIndexed val token = ExistingToken( - item = DivItemBuilderResult(newItem, resolver), + div = newItem, view = targetView, childIndex = index, parentToken = this, @@ -106,11 +105,11 @@ internal class ExistingToken( return tokens } - private fun simpleItemsToExistingTokenList(items: List): List { + private fun simpleItemsToExistingTokenList(items: List
): List { val tokens = mutableListOf() items.forEachIndexed { index, item -> val token = ExistingToken( - item = item, + div = item, view = (view as? ViewGroup)?.getChildAt(index) ?: return emptyList(), childIndex = index, parentToken = this, diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt index 3662dfe60..6bf8869d2 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt @@ -1,20 +1,20 @@ package com.yandex.div.core.view2.reuse import com.yandex.div.core.util.getDefaultState -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.internal.core.buildItems import com.yandex.div.internal.core.nonNullItems +import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div internal class NewToken( - item: DivItemBuilderResult, + div: Div, override val parentToken: NewToken?, childIndex: Int, var lastExistingParent: ExistingToken?, -) : Token(item, parentToken, childIndex) { +) : Token(div, parentToken, childIndex) { - override fun getChildrenTokens(): List { - return when (val div = item.div) { + override fun getChildrenTokens(resolver: ExpressionResolver): List { + return when (this.div) { is Div.Text -> listOf() is Div.Image -> listOf() is Div.GifImage -> listOf() @@ -25,27 +25,23 @@ internal class NewToken( is Div.Custom -> listOf() is Div.Select -> listOf() is Div.Video -> listOf() - is Div.Container -> itemsToNewTokenList(div.value.buildItems(item.expressionResolver)) - is Div.Grid -> - itemsToNewTokenList(div.value.nonNullItems.map { DivItemBuilderResult(it, item.expressionResolver) }) - is Div.Gallery -> - itemsToNewTokenList(div.value.nonNullItems.map { DivItemBuilderResult(it, item.expressionResolver) }) - is Div.Pager -> - itemsToNewTokenList(div.value.nonNullItems.map { DivItemBuilderResult(it, item.expressionResolver) }) - is Div.Tabs -> - itemsToNewTokenList(div.value.items.map { DivItemBuilderResult(it.div, item.expressionResolver) }) + is Div.Container -> itemsToNewTokenList(this.div.value.buildItems(resolver)) + is Div.Grid -> itemsToNewTokenList(this.div.value.nonNullItems) + is Div.Gallery -> itemsToNewTokenList(this.div.value.nonNullItems) + is Div.Pager -> itemsToNewTokenList(this.div.value.nonNullItems) + is Div.Tabs -> itemsToNewTokenList(this.div.value.items.map { it.div }) is Div.State -> { - val stateToBindDiv = div.value.getDefaultState(item.expressionResolver)?.div ?: return listOf() - itemsToNewTokenList(listOf(stateToBindDiv).map { DivItemBuilderResult(it, item.expressionResolver) }) + val stateToBindDiv = this.div.value.getDefaultState(resolver)?.div ?: return listOf() + itemsToNewTokenList(listOf(stateToBindDiv)) } } } - private fun itemsToNewTokenList(items: List): List { + private fun itemsToNewTokenList(items: List
): List { val tokens = mutableListOf() items.forEachIndexed { index, item -> val token = NewToken( - item = item, + div = item, childIndex = index, parentToken = this, lastExistingParent = this.lastExistingParent, diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/RebindTask.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/RebindTask.kt index 9af120a0c..b0040b4d0 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/RebindTask.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/RebindTask.kt @@ -8,7 +8,6 @@ import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.reuse.util.combineTokens import com.yandex.div.core.view2.reuse.util.logRebindDiff import com.yandex.div.internal.Log -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.DivData @@ -56,16 +55,14 @@ internal class RebindTask( newDivData: DivData, rootView: ViewGroup, ): Boolean { - val existingItem = div2View.stateToBind(oldDivData)?.div ?: return false val existingToken = ExistingToken( - item = DivItemBuilderResult(existingItem, resolver), + div = div2View.stateToBind(oldDivData)?.div ?: return false, view = rootView, childIndex = 0, parentToken = null, ) - val newItem = div2View.stateToBind(newDivData)?.div ?: return false val newToken = NewToken( - item = DivItemBuilderResult(newItem, newResolver), + div = div2View.stateToBind(newDivData)?.div ?: return false, childIndex = 0, parentToken = null, lastExistingParent = null, @@ -95,10 +92,10 @@ internal class RebindTask( val combinedToken = combineTokens(existingToken, newToken) newToken.lastExistingParent = combinedToken - val aloneNewChild = newToken.getChildrenTokens().toMutableList() + val aloneNewChild = newToken.getChildrenTokens(newResolver).toMutableList() val aloneExistingChild = mutableListOf() - existingToken.getChildrenTokens().forEach { existingChild -> + existingToken.getChildrenTokens(resolver).forEach { existingChild -> val newChildWithSameHash = aloneNewChild.find { it.divHash == existingChild.divHash } if (newChildWithSameHash != null) { @@ -126,7 +123,7 @@ internal class RebindTask( private fun doNodeInExistingMode(token: ExistingToken) { aloneExisting.add(token) - token.getChildrenTokens().forEach { + token.getChildrenTokens(resolver).forEach { doNodeInExistingMode(it) } } @@ -139,7 +136,7 @@ internal class RebindTask( doNodeInSameMode(existingWithSameHash, token) } else { aloneNew.add(token) - token.getChildrenTokens().forEach { + token.getChildrenTokens(newResolver).forEach { doNodeInNewMode(it) } } @@ -159,7 +156,7 @@ internal class RebindTask( bindingPoints.forEach { if (bindingPoints.contains(it.parentToken)) return@forEach - divBinder.bind(div2View.getBindingContext(it.item.div.value()), it.view, it.item.div, path) + divBinder.bind(it.view, it.div, div2View, path) } clear() diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/Token.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/Token.kt index dd49c3015..976d421ec 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/Token.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/Token.kt @@ -1,13 +1,14 @@ package com.yandex.div.core.view2.reuse -import com.yandex.div.internal.core.DivItemBuilderResult +import com.yandex.div.json.expressions.ExpressionResolver +import com.yandex.div2.Div internal abstract class Token( - val item: DivItemBuilderResult, + val div: Div, open val parentToken: Token?, val childIndex: Int, ) { - val divHash: Int = item.div.propertiesHash() + val divHash: Int = div.propertiesHash() - abstract fun getChildrenTokens(): List + abstract fun getChildrenTokens(resolver: ExpressionResolver): List } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindLogUtils.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindLogUtils.kt index b9ccbe4dc..90ab76674 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindLogUtils.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindLogUtils.kt @@ -23,22 +23,22 @@ internal fun logRebindDiff( """.trimIndent() ) bindingPoints.forEach { - it.item.div.printSelf(reusableList, bindingPoints, log) + it.div.printSelf(reusableList, bindingPoints, log) } log.appendLine("\nreuse [${reusableList.count()}]: ") reusableList.asList().forEach { - it.item.div.printSelf(reusableList, bindingPoints, log) + it.div.printSelf(reusableList, bindingPoints, log) } log.appendLine("\nremoved [${aloneExisting.count()}]: ") aloneExisting.forEach { - it.item.div.printSelf(reusableList, bindingPoints, log) + it.div.printSelf(reusableList, bindingPoints, log) } log.appendLine("\nnew [${aloneNew.count()}]: ") aloneNew.forEach { - it.item.div.printSelf(reusableList, bindingPoints, log) + it.div.printSelf(reusableList, bindingPoints, log) } log.appendLine("-----------") diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindTokenUtils.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindTokenUtils.kt index 689127d46..da3459758 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindTokenUtils.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindTokenUtils.kt @@ -7,7 +7,7 @@ internal fun combineTokens( existingToken: ExistingToken, newToken: NewToken, ) = ExistingToken( - item = newToken.item, + div = newToken.div, view = existingToken.view, parentToken = existingToken.parentToken, childIndex = newToken.childIndex, diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindUtils.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindUtils.kt index 5e43c4509..0eeb34769 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindUtils.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/util/RebindUtils.kt @@ -3,7 +3,6 @@ package com.yandex.div.core.view2.reuse.util import android.view.ViewGroup import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivViewCreator -import com.yandex.div.internal.core.DivItemBuilderResult import com.yandex.div2.Div import javax.inject.Provider @@ -19,15 +18,15 @@ internal fun ViewGroup.tryRebindRecycleContainerChildren( internal fun ViewGroup.tryRebindPlainContainerChildren( div2View: Div2View, - items: List, + items: List
, divViewCreator: Provider ): Boolean { val reusableList = div2View.currentRebindReusableList ?: return false removeAllViews() for(item in items) { - val foundReusable = reusableList.getUniqueViewForDiv(item.div) - val viewToAdd = foundReusable ?: divViewCreator.get().create(item.div, item.expressionResolver) + val foundReusable = reusableList.getUniqueViewForDiv(item) + val viewToAdd = foundReusable ?: divViewCreator.get().create(item, div2View.expressionResolver) addView(viewToAdd) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcher.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcher.kt index 8a8fd99c6..da31a2315 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcher.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcher.kt @@ -37,7 +37,7 @@ internal class DivJoinedStateSwitcher @Inject constructor( path = commonPath } } - divBinder.bind(divView.getBindingContext(div.value()), view, div, path.parentState()) + divBinder.bind(view, div, divView, path.parentState()) divBinder.attachIndicators() } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcher.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcher.kt index d4681c182..cf401562d 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcher.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcher.kt @@ -28,12 +28,12 @@ internal class DivMultipleStateSwitcher @Inject constructor( rootView.tryFindStateDivAndLayout(state, path, resolver) ?: return if (viewByPath != null && viewByPath !in boundLayouts) { - divBinder.bind(divView.getBindingContext(divByPath.value()), viewByPath, divByPath, path.parentState()) + divBinder.bind(viewByPath, divByPath, divView, path.parentState()) boundLayouts += viewByPath } } if (boundLayouts.isEmpty()) { - divBinder.bind(divView.bindingContext, rootView, rootDiv, DivStatePath.fromState(state.stateId)) + divBinder.bind(rootView, rootDiv, divView, DivStatePath.fromState(state.stateId)) } divBinder.attachIndicators() diff --git a/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt b/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt index 7af63eada..72f924135 100644 --- a/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt +++ b/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt @@ -1,72 +1,13 @@ package com.yandex.div.internal.core -import com.yandex.div.core.expression.ExpressionResolverImpl -import com.yandex.div.core.expression.variables.VariableSource -import com.yandex.div.data.Variable -import com.yandex.div.internal.util.forEach import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div -import com.yandex.div2.DivCollectionItemBuilder import com.yandex.div2.DivContainer import com.yandex.div2.DivGallery import com.yandex.div2.DivGrid import com.yandex.div2.DivPager -import org.json.JSONObject -fun DivContainer.buildItems(resolver: ExpressionResolver): List = - items?.map { DivItemBuilderResult(it, resolver) } ?: itemBuilder?.build(resolver) ?: emptyList() - -private fun DivCollectionItemBuilder.build( - resolver: ExpressionResolver -): List { - result?.let { return it } - - val result = mutableListOf() - data.evaluate(resolver).forEach { _, json: JSONObject -> - buildItem(json, resolver)?.let { result.add(it) } - } - return result -} - -internal fun DivCollectionItemBuilder.buildItem( - data: JSONObject, - resolver: ExpressionResolver, -): DivItemBuilderResult? { - val localVariableSource = VariableSource( - mapOf(dataElementName to Variable.DictVariable(dataElementName, data)), - {}, - mutableListOf() - ) - val newResolver = (resolver as? ExpressionResolverImpl)?.plus(localVariableSource) ?: resolver - val prototype = prototypes.find { it.selector.evaluate(newResolver) }?.div ?: return null - return DivItemBuilderResult(prototype.copy(), newResolver) -} - -private fun Div.copy(): Div { - return when (this) { - is Div.Image -> Div.Image(value.copy()) - is Div.GifImage -> Div.GifImage(value.copy()) - is Div.Text -> Div.Text(value.copy()) - is Div.Separator -> Div.Separator(value.copy()) - is Div.Container -> Div.Container(value.copy( - itemBuilder = value.itemBuilder?.copy(), - items = value.items?.map { it.copy() }, - )) - is Div.Grid -> Div.Grid(value.copy(items = value.items?.map { it.copy() })) - is Div.Gallery -> Div.Gallery(value.copy(items = value.items?.map { it.copy() })) - is Div.Pager -> Div.Pager(value.copy(items = value.items?.map { it.copy() })) - is Div.Tabs -> Div.Tabs(value.copy(items = value.items.map { it.copy(div = it.div.copy()) })) - is Div.State -> Div.State(value.copy(states = value.states.map { it.copy(div = it.div?.copy()) })) - is Div.Custom -> Div.Custom(value.copy()) - is Div.Indicator -> Div.Indicator(value.copy()) - is Div.Slider -> Div.Slider(value.copy()) - is Div.Input -> Div.Input(value.copy()) - is Div.Select -> Div.Select(value.copy()) - is Div.Video -> Div.Video(value.copy()) - } -} - -val DivContainer.nonNullItems: List
get() = items ?: emptyList() +fun DivContainer.buildItems(resolver: ExpressionResolver) = items ?: emptyList() val DivGallery.nonNullItems: List
get() = items ?: emptyList() diff --git a/client/android/div/src/test/java/com/yandex/div/core/expression/ExpressionResolverImplTest.kt b/client/android/div/src/test/java/com/yandex/div/core/expression/ExpressionResolverImplTest.kt index dc22481e3..6df0e101d 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/expression/ExpressionResolverImplTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/expression/ExpressionResolverImplTest.kt @@ -1,7 +1,7 @@ package com.yandex.div.core.expression import com.yandex.div.core.expression.variables.GlobalVariableController -import com.yandex.div.core.expression.variables.VariableControllerImpl +import com.yandex.div.core.expression.variables.VariableController import com.yandex.div.core.util.EnableAssertsRule import com.yandex.div.data.Variable import com.yandex.div.evaluable.EvaluationContext @@ -56,7 +56,7 @@ class ExpressionResolverImplTest { private val globalVariableController = GlobalVariableController().apply { declare(*globalVariables.values.toTypedArray()) } - private val externalVariables = VariableControllerImpl().apply { + private val externalVariables = VariableController().apply { variables.values.forEach { declare(it) } @@ -78,7 +78,7 @@ class ExpressionResolverImplTest { private val withFuncGetCallback = { callback: () -> Unit -> ExpressionResolverImpl( - VariableControllerImpl(), + VariableController(), Evaluator( EvaluationContext( variableProvider = evaluationContext.variableProvider, diff --git a/client/android/div/src/test/java/com/yandex/div/core/expression/triggers/TriggersControllerTest.kt b/client/android/div/src/test/java/com/yandex/div/core/expression/triggers/TriggersControllerTest.kt index ae6b98343..c83b43cdd 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/expression/triggers/TriggersControllerTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/expression/triggers/TriggersControllerTest.kt @@ -41,9 +41,7 @@ class TriggersControllerTest { } private val errorCollector = mock() private val logger = mock() - private val view = mock { - on { expressionResolver } doReturn mock() - } + private val view = mock() private val env = object : ParsingEnvironment { override val templates: TemplateProvider> = TemplateProvider.empty() @@ -110,7 +108,7 @@ class TriggersControllerTest { private fun verifyActionTriggered(logId: String, times: Int = 1) { val actions = argumentCaptor>() - verify(divActionBinder, atLeastOnce()).handleActions(any(), any(), actions.capture(), any()) + verify(divActionBinder, atLeastOnce()).handleActions(any(), actions.capture(), any()) val actionsWithLogId = actions.allValues.flatten().filter { it.logId == logId } Assert.assertEquals(times, actionsWithLogId.size) diff --git a/client/android/div/src/test/java/com/yandex/div/core/expression/variables/TwoWayVariableBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/expression/variables/TwoWayVariableBinderTest.kt index 8c683f379..72588cc8a 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/expression/variables/TwoWayVariableBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/expression/variables/TwoWayVariableBinderTest.kt @@ -31,7 +31,7 @@ class TwoWayVariableBinderTest { on { getOrCreate(any(), any()) } doReturn errorCollector } private val variable = Variable.StringVariable(VARIABLE_NAME, INITIAL_VALUE) - private val variableController = VariableControllerImpl().apply { + private val variableController = VariableController().apply { declare(variable) } private val expressionsRuntime = ExpressionsRuntime(mock(), variableController, mock()) diff --git a/client/android/div/src/test/java/com/yandex/div/core/expression/variables/VariableControllerTest.kt b/client/android/div/src/test/java/com/yandex/div/core/expression/variables/VariableControllerTest.kt index fbd12853d..1a2c5f246 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/expression/variables/VariableControllerTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/expression/variables/VariableControllerTest.kt @@ -34,7 +34,7 @@ class VariableControllerTest { @Before fun initVariableController() { divVariableController = DivVariableController() - variableController = VariableControllerImpl().apply { + variableController = VariableController().apply { localVariables.forEach { declare(it) } diff --git a/client/android/div/src/test/java/com/yandex/div/core/tooltip/DivTooltipControllerTest.kt b/client/android/div/src/test/java/com/yandex/div/core/tooltip/DivTooltipControllerTest.kt index 27b456826..822f26a0e 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/tooltip/DivTooltipControllerTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/tooltip/DivTooltipControllerTest.kt @@ -13,7 +13,6 @@ import com.yandex.div.core.DivTooltipRestrictor import com.yandex.div.core.asExpression import com.yandex.div.core.util.AccessibilityStateProvider import com.yandex.div.core.util.SafePopupWindow -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2Builder import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivVisibilityActionTracker @@ -22,6 +21,7 @@ import com.yandex.div.core.view2.errors.ErrorCollectors import com.yandex.div.internal.Assert import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div +import com.yandex.div2.DivDimension import com.yandex.div2.DivPoint import com.yandex.div2.DivText import com.yandex.div2.DivTooltip @@ -86,8 +86,8 @@ class DivTooltipControllerTest { } on { getChildAt(0) } doReturn anchor on { childCount } doReturn 1 + on { expressionResolver } doReturn expressionResolver } - private val bindingContext = BindingContext(div2View, expressionResolver) private val tooltipView = mock { on { width } doReturn 100 @@ -142,7 +142,7 @@ class DivTooltipControllerTest { fun `tooltip is shown`() { prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) verify(popupWindow).showAtLocation(anchor, Gravity.NO_GRAVITY, 0, 0) verify(popupWindow).update(400, 225, 100, 50) @@ -153,9 +153,9 @@ class DivTooltipControllerTest { fun `visibility tracking is started on show`() { prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) - verify(visibilityActionTracker).trackVisibilityActionsOf(div2View, expressionResolver, tooltipView, div) + verify(visibilityActionTracker).trackVisibilityActionsOf(div2View, tooltipView, div) } @Test @@ -164,7 +164,7 @@ class DivTooltipControllerTest { whenever(tooltipView.height).doReturn(div2ViewHeight.inc()) prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) verify(tooltipShownCallback, times(1)).onDivTooltipShown(div2View, anchor, tooltips[0]) verify(errorCollector, times(2)).logWarning(any()) @@ -173,7 +173,7 @@ class DivTooltipControllerTest { @Test fun `tooltip is dismissed after timeout`() { prepareDiv(duration = 1000) - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) verify(tooltipShownCallback, never()).onDivTooltipDismissed(div2View, anchor, tooltips[0]) ShadowLooper.runUiThreadTasksIncludingDelayedTasks() @@ -184,7 +184,7 @@ class DivTooltipControllerTest { @Test fun `tooltip is dismissed on hideTooltip`() { prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) verify(tooltipShownCallback, never()).onDivTooltipDismissed(div2View, anchor, tooltips[0]) underTest.hideTooltip("tooltip_id", div2View) @@ -195,18 +195,18 @@ class DivTooltipControllerTest { @Test fun `visibility tracking is stopped on dismiss`() { prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) reset(visibilityActionTracker) underTest.hideTooltip("tooltip_id", div2View) - verify(visibilityActionTracker).trackVisibilityActionsOf(div2View, expressionResolver, null, div) + verify(visibilityActionTracker).trackVisibilityActionsOf(div2View, null, div) } @Test fun `tooltip is dismissed on cleanup`() { prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) verify(tooltipShownCallback, never()).onDivTooltipDismissed(div2View, anchor, tooltips[0]) underTest.clear() @@ -217,7 +217,7 @@ class DivTooltipControllerTest { @Test fun `dismiss is canceled on cleanup`() { prepareDiv() - underTest.showTooltip("tooltip_id", bindingContext) + underTest.showTooltip("tooltip_id", div2View) underTest.clear() reset(tooltipRestrictor.tooltipShownCallback) @@ -268,3 +268,6 @@ class DivTooltipControllerTest { Assert.assertEquals(expected.second, actual.y) } } + +@Suppress("SameParameterValue") +private fun divPoint(x: Int, y: Int) = DivPoint(DivDimension(value = x.toDouble().asExpression()), DivDimension(value = y.toDouble().asExpression())) diff --git a/client/android/div/src/test/java/com/yandex/div/core/util/DivWalkTreeTest.kt b/client/android/div/src/test/java/com/yandex/div/core/util/DivWalkTreeTest.kt index d8b2443cd..ca98d5421 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/util/DivWalkTreeTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/util/DivWalkTreeTest.kt @@ -24,7 +24,7 @@ class DivWalkTreeTest { val rootDiv = divText("lorem ipsum") val divWalk = rootDiv.walk(resolver) - .map { item -> item.div.type } + .map { div -> div.type } assertEquals(listOf("text"), divWalk.toList()) } @@ -39,7 +39,7 @@ class DivWalkTreeTest { ) val divWalk = rootDiv.walk(resolver) - .map { item -> item.div.type } + .map { div -> div.type } assertEquals(listOf("container", "text", "image"), divWalk.toList()) } @@ -59,7 +59,7 @@ class DivWalkTreeTest { ) val divWalk = rootDiv.walk(resolver) - .map { item -> item.div.type } + .map { div -> div.type } assertEquals(listOf("container", "container", "text", "image", "text"), divWalk.toList()) } @@ -80,7 +80,7 @@ class DivWalkTreeTest { val divWalk = rootDiv.walk(resolver) .onEnter { div -> div !is Div.Gallery } - .map { item -> item.div.type } + .map { div -> div.type } assertEquals(listOf("container", "text"), divWalk.toList()) } @@ -101,7 +101,7 @@ class DivWalkTreeTest { val divWalk = rootDiv.walk(resolver) .maxDepth(1) - .map { item -> item.div.type } + .map { div -> div.type } assertEquals(listOf("container", "text", "container"), divWalk.toList()) } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionDispatcherTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionDispatcherTest.kt index d378121ce..dac8ad3a5 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionDispatcherTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionDispatcherTest.kt @@ -40,6 +40,7 @@ class DivVisibilityActionDispatcherTest { private val divView = mock { on { logId } doReturn "card" on { dataTag } doReturn DivDataTag("tag") + on { expressionResolver } doReturn resolver } private val dispatcher = DivVisibilityActionDispatcher( @@ -53,7 +54,7 @@ class DivVisibilityActionDispatcherTest { fun `action dispatched to handler`() { val action = DivVisibilityAction(logId = "action") - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(contextActionHandler).handleAction(eq(action as DivSightAction), eq(divView)) } @@ -63,7 +64,7 @@ class DivVisibilityActionDispatcherTest { val action = DivVisibilityAction(logId = "action", logLimit = 2L.asExpression()) repeat(4) { - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) } verify(contextActionHandler, times(2)).handleAction(eq(action as DivSightAction), eq(divView)) @@ -74,10 +75,10 @@ class DivVisibilityActionDispatcherTest { val action = DivVisibilityAction(logId = "action", logLimit = 2L.asExpression()) repeat(4) { - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) } dispatcher.reset(emptyList()) - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(contextActionHandler, times(3)).handleAction(eq(action) as DivSightAction, eq(divView)) } @@ -87,7 +88,7 @@ class DivVisibilityActionDispatcherTest { val action = DivVisibilityAction(logId = "action", logLimit = 0L.asExpression()) repeat(10) { - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) } verify(contextActionHandler, times(10)).handleAction(eq(action as DivSightAction), eq(divView)) @@ -98,7 +99,7 @@ class DivVisibilityActionDispatcherTest { val action = DivVisibilityAction(logId = "action") whenever(divView.actionHandler) doReturn viewActionHandler - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(contextActionHandler, never()).handleAction(eq(action), eq(divView)) } @@ -109,7 +110,7 @@ class DivVisibilityActionDispatcherTest { whenever(divView.actionHandler) doReturn viewActionHandler whenever(viewActionHandler.handleAction(eq(action as DivSightAction), eq(divView))) doReturn false - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(contextActionHandler).handleAction(eq(action as DivSightAction), eq(divView)) } @@ -118,7 +119,7 @@ class DivVisibilityActionDispatcherTest { fun `action doesn't dispatched to logger when handler intercepts it`() { val action = DivVisibilityAction(logId = "action") - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(logger, never()).logViewShown(eq(divView), any(), eq(action)) } @@ -127,7 +128,7 @@ class DivVisibilityActionDispatcherTest { fun `action doesn't dispatched to beacon sender when handler intercepts it`() { val action = DivVisibilityAction(logId = "action") - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(beaconSender, never()).sendVisibilityActionBeacon(any(), any()) } @@ -137,7 +138,7 @@ class DivVisibilityActionDispatcherTest { val action = DivVisibilityAction(logId = "action") whenever(contextActionHandler.handleAction(eq(action) as DivSightAction, eq(divView))) doReturn false - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(logger).logViewShown(eq(divView), any(), eq(action)) } @@ -147,7 +148,7 @@ class DivVisibilityActionDispatcherTest { val action = DivVisibilityAction(logId = "action") whenever(contextActionHandler.handleAction(eq(action as DivSightAction), eq(divView))) doReturn false - dispatcher.dispatchAction(divView, resolver, mock(), action) + dispatcher.dispatchAction(divView, mock(), action) verify(beaconSender).sendVisibilityActionBeacon(action, resolver) } @@ -155,7 +156,7 @@ class DivVisibilityActionDispatcherTest { @Test fun `dispatch actions runs as a bulk`() { val actionArray: Array = arrayOf(DivVisibilityAction(logId = "action"), DivVisibilityAction(logId = "action2")) - dispatcher.dispatchActions(divView, resolver, mock(), actionArray) + dispatcher.dispatchActions(divView, mock(), actionArray) verify(divView, times(1)).bulkActions(any()) } } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionTrackerTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionTrackerTest.kt index ebb9ecf2a..ddb448c0e 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionTrackerTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/DivVisibilityActionTrackerTest.kt @@ -40,6 +40,7 @@ class DivVisibilityActionTrackerTest { private val scope = mock { on { logId } doReturn "div" on { dataTag } doReturn DivDataTag("test") + on { expressionResolver } doReturn resolver } private val view1 = mockView() @@ -79,7 +80,6 @@ class DivVisibilityActionTrackerTest { verify(visibilityActionDispatcher, never()).dispatchActions( eq(scope), - eq(resolver), eq(view1), argThat { this.contains(action1) && this.size == 1 } ) @@ -92,7 +92,6 @@ class DivVisibilityActionTrackerTest { verify(visibilityActionDispatcher).dispatchActions( eq(scope), - eq(resolver), eq(view1), argThat { this.contains(action1) && this.size == 1 } ) @@ -106,7 +105,6 @@ class DivVisibilityActionTrackerTest { verify(visibilityActionDispatcher, never()).dispatchActions( eq(scope), - eq(resolver), eq(view1), argThat { this.contains(action1) && this.size == 1 } ) @@ -116,12 +114,11 @@ class DivVisibilityActionTrackerTest { fun `visibility action is not dispatched when view become null before deadline`() { trackVisibilityAction(view1, div1, 100) updateViewVisibility(view1, visibilityPercentage = 40) - visibilityActionTracker.trackVisibilityActionsOf(scope, resolver, null, div1) + visibilityActionTracker.trackVisibilityActionsOf(scope, null, div1) Robolectric.flushForegroundThreadScheduler() verify(visibilityActionDispatcher, never()).dispatchActions( eq(scope), - eq(resolver), eq(view1), argThat { this.contains(action1) && this.size == 1 } ) @@ -135,7 +132,6 @@ class DivVisibilityActionTrackerTest { verify(visibilityActionDispatcher, times(1)).dispatchActions( eq(scope), - eq(resolver), eq(view1), argThat { this.contains(action1) && this.size == 1 } ) @@ -150,7 +146,6 @@ class DivVisibilityActionTrackerTest { Robolectric.flushForegroundThreadScheduler() verify(visibilityActionDispatcher, times(1)).dispatchActions( eq(scope), - eq(resolver), eq(view1), argThat { this.contains(action1) && this.size == 1 } ) @@ -167,12 +162,7 @@ class DivVisibilityActionTrackerTest { trackVisibilityAction(view1, div1, 100) Robolectric.flushForegroundThreadScheduler() - verify(visibilityActionDispatcher, times(2)).dispatchActions( - eq(scope), - eq(resolver), - eq(view1), - any() - ) + verify(visibilityActionDispatcher, times(2)).dispatchActions(eq(scope), eq(view1), any()) } @Test @@ -230,7 +220,6 @@ class DivVisibilityActionTrackerTest { verify(visibilityActionDispatcher, times(1)).dispatchActions( eq(scope), - eq(resolver), eq(view3), argThat { this.toList().containsAll(lottaActions) && this.size == lottaActions.size } ) @@ -245,7 +234,6 @@ class DivVisibilityActionTrackerTest { Robolectric.flushForegroundThreadScheduler() verify(visibilityActionDispatcher, times(1)).dispatchActions( eq(scope), - eq(resolver), eq(view3), argThat { this.toList().containsAll(lottaActions) && this.size == lottaActions.size } ) @@ -257,21 +245,18 @@ class DivVisibilityActionTrackerTest { Robolectric.getForegroundThreadScheduler().advanceBy(101L, TimeUnit.MILLISECONDS) verify(visibilityActionDispatcher, times(1)).dispatchActions( eq(scope), - eq(resolver), eq(view4), argThat { this.size == 2 } ) Robolectric.getForegroundThreadScheduler().advanceBy(101L, TimeUnit.MILLISECONDS) verify(visibilityActionDispatcher, times(2)).dispatchActions( eq(scope), - eq(resolver), eq(view4), argThat { this.size == 2 } ) Robolectric.getForegroundThreadScheduler().advanceBy(101L, TimeUnit.MILLISECONDS) verify(visibilityActionDispatcher, times(3)).dispatchActions( eq(scope), - eq(resolver), eq(view4), argThat { this.size == 2 } ) @@ -283,23 +268,17 @@ class DivVisibilityActionTrackerTest { Robolectric.getForegroundThreadScheduler().advanceBy(101L, TimeUnit.MILLISECONDS) verify(visibilityActionDispatcher, times(1)).dispatchActions( eq(scope), - eq(resolver), eq(view4), argThat { this.size == 2 } ) trackVisibilityAction(view4, div4, 0) Robolectric.flushForegroundThreadScheduler() - verify(visibilityActionDispatcher, times(1)).dispatchActions( - eq(scope), - eq(resolver), - eq(view4), - any() - ) + verify(visibilityActionDispatcher, times(1)).dispatchActions(eq(scope), eq(view4), any()) } private fun trackVisibilityAction(view: View, div: Div, visibilityPercentage: Int) { updateViewVisibility(view, visibilityPercentage) - visibilityActionTracker.trackVisibilityActionsOf(scope, resolver, view, div) + visibilityActionTracker.trackVisibilityActionsOf(scope, view, div) } private fun updateViewVisibility(view: View, visibilityPercentage: Int) { diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/Assertions.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/Assertions.kt index 5da292afe..7643c0223 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/Assertions.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/Assertions.kt @@ -2,7 +2,7 @@ package com.yandex.div.core.view2.divs import android.net.Uri import android.view.View -import com.yandex.div.core.view2.BindingContext +import com.yandex.div.core.view2.Div2View import com.yandex.div2.DivAction import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue @@ -12,10 +12,10 @@ import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.eq import org.mockito.kotlin.verify -internal fun assertActionApplied(context: BindingContext, target: View, actionUri: Uri) { +internal fun assertActionApplied(divView: Div2View, target: View, actionUri: Uri) { val actionCaptor = argumentCaptor>() - verify(context.divView.div2Component.actionBinder).bindDivActions( - context = eq(context), + verify(divView.div2Component.actionBinder).bindDivActions( + divView = eq(divView), target = eq(target), actions = actionCaptor.capture(), longTapActions = anyOrNull(), @@ -25,7 +25,7 @@ internal fun assertActionApplied(context: BindingContext, target: View, actionUr ) val action = actionCaptor.firstValue.find { - action -> action.url?.evaluate(context.expressionResolver) == actionUri + action -> action.url?.evaluate(divView.expressionResolver) == actionUri } assertNotNull(action) assertTrue(target.hasOnClickListeners()) diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBaseBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBaseBinderTest.kt index c36ac3e48..1881cb587 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBaseBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBaseBinderTest.kt @@ -2,7 +2,6 @@ package com.yandex.div.core.view2.divs import com.yandex.div.core.asExpression import com.yandex.div.core.dagger.Div2ViewComponent -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.animations.DivTransitionHandler import com.yandex.div.core.view2.divs.widgets.DivLineHeightTextView @@ -38,20 +37,20 @@ class DivBaseBinderTest { private val expressionResolver = mock() private val viewComponent = mock() private val divView = mock { + on { expressionResolver } doReturn expressionResolver on { divTransitionHandler } doReturn DivTransitionHandler(mock) on { viewComponent } doReturn viewComponent } - private val context = BindingContext(divView, expressionResolver) @Test fun `do not apply paddings when same`() { val div = DivText(text = "text".asExpression(), paddings = paddingsBottom1) val oldDiv = DivText(text = "text".asExpression(), paddings = paddingsBottom1) - baseBinder.bindView(context, view, oldDiv, null) + baseBinder.bindView(view, oldDiv, null, divView) clearInvocations(view) - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) verify(view, never()).setPadding(any(), any(), any(), any()) verify(view, never()).requestLayout() @@ -62,10 +61,10 @@ class DivBaseBinderTest { val div = DivText(text = "text".asExpression(), paddings = paddingsBottom1) val oldDiv = DivText(text = "text".asExpression(), paddings = paddingsBottom2) - baseBinder.bindView(context, view, oldDiv, null) + baseBinder.bindView(view, oldDiv, null, divView) clearInvocations(view) - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) verify(view, never()).setPadding(any(), any(), any(), any()) verify(view, never()).requestLayout() @@ -76,7 +75,7 @@ class DivBaseBinderTest { val div = DivText(text = "text".asExpression(), paddings = paddingsBottom1) val oldDiv = DivText(text = "text".asExpression(), paddings = paddingsTop) - baseBinder.bindView(context, view, div, oldDiv) + baseBinder.bindView(view, div, oldDiv, divView) verify(view).setPadding(any(), any(), any(), any()) verify(view, atLeastOnce()).requestLayout() @@ -90,7 +89,7 @@ class DivBaseBinderTest { transitionTriggers = listOf(DivTransitionTrigger.STATE_CHANGE) ) - baseBinder.bindView(context, view, div, null) + baseBinder.bindView(view, div, null, divView) verify(view, never()).clearAnimation() } @@ -103,7 +102,7 @@ class DivBaseBinderTest { transitionTriggers = listOf(DivTransitionTrigger.STATE_CHANGE) ) - baseBinder.bindView(context, view, div, null) + baseBinder.bindView(view, div, null, divView) verify(view).clearAnimation() } @@ -116,7 +115,7 @@ class DivBaseBinderTest { transitionTriggers = listOf(DivTransitionTrigger.STATE_CHANGE) ) - baseBinder.bindView(context, view, div, null) + baseBinder.bindView(view, div, null, divView) verify(view).clearAnimation() } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBinderTest.kt index efa37b342..77952de3e 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivBinderTest.kt @@ -8,7 +8,6 @@ import com.yandex.div.core.dagger.Div2Component import com.yandex.div.core.dagger.Div2ViewComponent import com.yandex.div.core.extension.DivExtensionController import com.yandex.div.core.images.DivImageLoader -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.DivTransitionBuilder import com.yandex.div.core.view2.DivValidator @@ -51,11 +50,10 @@ open class DivBinderTest { on { handleUri(any()) }.thenCallRealMethod() on { logId } doReturn "id" on { config } doReturn mock() - on { getExpressionResolver(any()) } doReturn expressionResolver + on { expressionResolver } doReturn expressionResolver on { oldExpressionResolver } doReturn oldExpressionResolver on { divTransitionHandler } doReturn DivTransitionHandler(mock) } - internal val bindingContext = BindingContext(divView, expressionResolver) private val divExtensionController = DivExtensionController(emptyList()) internal val visitor: ReleaseViewVisitor = spy( diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivContainerBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivContainerBinderTest.kt index abf64e8e3..ef55a5320 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivContainerBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivContainerBinderTest.kt @@ -35,9 +35,9 @@ class DivContainerBinderTest : DivBinderTest() { val view = viewCreator.create(div, ExpressionResolver.EMPTY) as DivLinearLayout view.layoutParams = defaultLayoutParams() - binder.bindView(bindingContext, view, divContainer, rootPath()) + binder.bindView(view, divContainer, divView, rootPath()) - assertActionApplied(bindingContext, view, Expected.ACTION_URI) + assertActionApplied(divView, view, Expected.ACTION_URI) } @Test @@ -47,9 +47,9 @@ class DivContainerBinderTest : DivBinderTest() { val view = viewCreator.create(div, ExpressionResolver.EMPTY) as DivLinearLayout view.layoutParams = defaultLayoutParams() - binder.bindView(bindingContext, view, divContainer, rootPath()) + binder.bindView(view, divContainer, divView, rootPath()) - assertActionApplied(bindingContext, view, Expected.STATE_ACTION_URI) + assertActionApplied(divView, view, Expected.STATE_ACTION_URI) } @Test @@ -60,13 +60,13 @@ class DivContainerBinderTest : DivBinderTest() { val view = viewCreator.create(div, ExpressionResolver.EMPTY) as DivLinearLayout view.layoutParams = defaultLayoutParams() - binder.bindView(bindingContext, view, divContainer, rootPath()) + binder.bindView(view, divContainer, divView, rootPath()) verify(visitor, never()).release(any()) val children: List = view.childrenToFlatList() - binder.bindView(bindingContext, view, otherDiv.value() as DivContainer, rootPath()) + binder.bindView(view, otherDiv.value() as DivContainer, divView, rootPath()) verify(visitor, times(children.size)).release(any()) children.forEach { child: View -> @@ -83,9 +83,9 @@ class DivContainerBinderTest : DivBinderTest() { view.layoutParams = defaultLayoutParams() view.layout(0, 0, 100, 100) - binder.bindView(bindingContext, view, divContainer, rootPath()) + binder.bindView(view, divContainer, divView, rootPath()) - binder.bindView(bindingContext, view, newData.value() as DivContainer, rootPath()) + binder.bindView(view, newData.value() as DivContainer, divView, rootPath()) verify(visitor, atLeast(1)).release(any()) } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivFocusBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivFocusBinderTest.kt index c9e5c782b..aa303d0ab 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivFocusBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivFocusBinderTest.kt @@ -3,7 +3,6 @@ package com.yandex.div.core.view2.divs import android.content.res.Resources import android.graphics.Color import android.view.View -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.widgets.DivLineHeightTextView import com.yandex.div.json.expressions.Expression @@ -56,7 +55,6 @@ class DivFocusBinderTest { } private val divView = mock() private val resolver = mock() - private val context = BindingContext(divView, resolver) private val defaultBorder = DivBorder(hasShadow = Expression.constant(true)) private val focusActions = listOf(mock()) private val blurActions = listOf(mock()) @@ -365,7 +363,7 @@ class DivFocusBinderTest { focusedBorder: DivBorder? = null, blurredBorder: DivBorder = defaultBorder, viewToBind: View = view - ) = underTest.bindDivBorder(viewToBind, context, focusedBorder, blurredBorder) + ) = underTest.bindDivBorder(viewToBind, divView, resolver, focusedBorder, blurredBorder) private fun setViewNotFocused() = whenever(view.isFocused).thenReturn(false) @@ -379,7 +377,7 @@ class DivFocusBinderTest { private fun bindActions( onFocus: List? = focusActions, onBlur: List? = blurActions - ) = underTest.bindDivFocusActions(view, context, onFocus, onBlur) + ) = underTest.bindDivFocusActions(view, divView, resolver, onFocus, onBlur) private fun onFocusChange(hasFocus: Boolean) = focusListener?.onFocusChange(view, hasFocus) diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGalleryBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGalleryBinderTest.kt index 4d9e2bd18..76d6e8671 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGalleryBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGalleryBinderTest.kt @@ -56,27 +56,27 @@ class DivGalleryBinderTest : DivBinderTest() { @Test fun `scroll to default item`() { - underTest.bindView(bindingContext, recyclerView, divGallery, rootPath()) + underTest.bindView(recyclerView, divGallery, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM, recyclerView.layoutManager.shadow().position) } @Test fun `keep scroll position on rebind`() { - underTest.bindView(bindingContext, recyclerView, divGallery, rootPath()) + underTest.bindView(recyclerView, divGallery, divView, rootPath()) (recyclerView.layoutManager as? DivLinearLayoutManager)!!.instantScrollToPosition( DEFAULT_ITEM + 1, ScrollPosition.DEFAULT ) - underTest.bindView(bindingContext, recyclerView, divGallery, rootPath()) + underTest.bindView(recyclerView, divGallery, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM + 1, recyclerView.layoutManager.shadow().position) } @Test fun `set default item when has current state without visible item index`() { - underTest.bindView(bindingContext, recyclerView, divGallery, rootPath()) + underTest.bindView(recyclerView, divGallery, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM, recyclerView.layoutManager.shadow().position) } @@ -85,7 +85,7 @@ class DivGalleryBinderTest : DivBinderTest() { fun `restore previous position`() { whenever(divViewState.getBlockState(any())).thenReturn(GalleryState(DEFAULT_ITEM + 1, 0)) - underTest.bindView(bindingContext, recyclerView, divGallery, rootPath()) + underTest.bindView(recyclerView, divGallery, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM + 1, recyclerView.layoutManager.shadow().position) } @@ -96,7 +96,7 @@ class DivGalleryBinderTest : DivBinderTest() { galleryJson.remove("default_item") val divGallery = DivGallery(DivParsingEnvironment(ParsingErrorLogger.ASSERT), galleryJson) - underTest.bindView(bindingContext, recyclerView, divGallery, rootPath()) + underTest.bindView(recyclerView, divGallery, divView, rootPath()) Assert.assertEquals(0, recyclerView.layoutManager.shadow().position) verify(recyclerView, never()).scrollToPosition(any()) @@ -112,7 +112,6 @@ class DivGalleryBinderTest : DivBinderTest() { return Shadow.extract(this) as ShadowDivLinearLayoutManager } - @Suppress("unused", "UNUSED_PARAMETER") @Implements(DivLinearLayoutManager::class) class ShadowDivLinearLayoutManager { diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGridBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGridBinderTest.kt index 3fb4c8255..bfc19156c 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGridBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivGridBinderTest.kt @@ -24,18 +24,18 @@ class DivGridBinderTest : DivBinderTest() { fun `url action applied`() { val (divGrid, view) = createTestData("with-action.json") - binder.bindView(bindingContext, view, divGrid, DivStatePath.parse("0")) + binder.bindView(view, divGrid, divView, DivStatePath.parse("0")) - assertActionApplied(bindingContext, view, Expected.ACTION_URI) + assertActionApplied(divView, view, Expected.ACTION_URI) } @Test fun `state action applied`() { val (divGrid, view) = createTestData("with-set-state-action.json") - binder.bindView(bindingContext, view, divGrid, DivStatePath.parse("0")) + binder.bindView(view, divGrid, divView, DivStatePath.parse("0")) - assertActionApplied(bindingContext, view, Expected.STATE_ACTION_URI) + assertActionApplied(divView, view, Expected.STATE_ACTION_URI) } private fun createTestData(filename: String): Pair { diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivImageBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivImageBinderTest.kt index f1e9f2db5..cc361366f 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivImageBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivImageBinderTest.kt @@ -49,18 +49,18 @@ class DivImageBinderTest : DivBinderTest() { fun `url action applied`() { val (view, divImage) = createTestDiv("with_action.json") - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) - assertActionApplied(bindingContext, view, Expected.ACTION_URI) + assertActionApplied(divView, view, Expected.ACTION_URI) } @Test fun `state action applied`() { val (view, divImage) = createTestDiv("with_set_state_action.json") - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) - assertActionApplied(bindingContext, view, Expected.STATE_ACTION_URI) + assertActionApplied(divView, view, Expected.STATE_ACTION_URI) } @Test @@ -73,7 +73,7 @@ class DivImageBinderTest : DivBinderTest() { highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) verify(placeholderLoader).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any()) verify(imageLoader).loadImage(eq(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()), any()) @@ -89,7 +89,7 @@ class DivImageBinderTest : DivBinderTest() { highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) val nextDivImage = DivImage( imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(), @@ -97,7 +97,7 @@ class DivImageBinderTest : DivBinderTest() { highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, nextDivImage) + binder.bindView(view, nextDivImage, divView) verify(placeholderLoader).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any()) verify(imageLoader).loadImage(eq(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()), any()) @@ -107,13 +107,13 @@ class DivImageBinderTest : DivBinderTest() { fun `do not bind image when imageUrl did not change and bitmap was loaded`() { val (view, divImage) = createTestDiv("with_action.json") - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) reset(placeholderLoader) whenImageLoaded(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()) val (_, nextDivImage) = createTestDiv("with_action.json") - binder.bindView(bindingContext, view, nextDivImage) + binder.bindView(view, nextDivImage, divView) verifyNoMoreInteractions(placeholderLoader) verifyNoMoreInteractions(imageLoader) } @@ -128,12 +128,12 @@ class DivImageBinderTest : DivBinderTest() { highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) whenImageLoaded(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()) val nextDivImage = DivImage(imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression()) - binder.bindView(bindingContext, view, nextDivImage) + binder.bindView(view, nextDivImage, divView) verify(placeholderLoader).applyPlaceholder(any(), any(), anyOrNull(), any(), any(), any(), any()) verify(imageLoader).loadImage(eq(nextDivImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()), any()) @@ -148,7 +148,7 @@ class DivImageBinderTest : DivBinderTest() { preview = PREVIEW.asExpression(), highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) verify(placeholderLoader).applyPlaceholder( any(), any(), anyOrNull(), any(), synchronous = eq(true), any(), any() @@ -161,7 +161,7 @@ class DivImageBinderTest : DivBinderTest() { preview = PREVIEW.asExpression(), highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, nextDivImage) + binder.bindView(view, nextDivImage, divView) verify(placeholderLoader).applyPlaceholder( any(), any(), eq(PREVIEW), any(), @@ -177,7 +177,7 @@ class DivImageBinderTest : DivBinderTest() { imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(), highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) whenImageLoaded(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()) @@ -187,7 +187,7 @@ class DivImageBinderTest : DivBinderTest() { imageUrl = Uri.parse("https://foo.bar/bar.png").asExpression(), highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, spyView, nextDivImage) + binder.bindView(spyView, nextDivImage, divView) verify(spyView).resetImageLoaded() } @@ -200,7 +200,7 @@ class DivImageBinderTest : DivBinderTest() { imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(), highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) whenImageLoaded(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()) @@ -210,7 +210,7 @@ class DivImageBinderTest : DivBinderTest() { imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(), highPriorityPreviewShow = true.asExpression() ) - binder.bindView(bindingContext, spyView, nextDivImage) + binder.bindView(spyView, nextDivImage, divView) verify(spyView, never()).resetImageLoaded() } @@ -222,7 +222,7 @@ class DivImageBinderTest : DivBinderTest() { imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(), tintColor = Color.parseColor("#ffffff").asExpression()) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) Assert.assertNull(view.colorFilter) whenImageLoaded(divImage.imageUrl.evaluate(ExpressionResolver.EMPTY).toString()) Assert.assertNotNull(view.colorFilter) @@ -231,14 +231,14 @@ class DivImageBinderTest : DivBinderTest() { val nextDivImage = DivImage( imageUrl = Uri.parse("https://foo.bar/foo.png").asExpression(), tintColor = Color.parseColor("#ffffff").asExpression()) - binder.bindView(bindingContext, view, nextDivImage) + binder.bindView(view, nextDivImage, divView) Assert.assertNotNull(view.colorFilter) // with another image url val anotherDivImage = DivImage( imageUrl = Uri.parse("https://another_image.png").asExpression(), tintColor = Color.parseColor("#ffffff").asExpression()) - binder.bindView(bindingContext, view, anotherDivImage) + binder.bindView(view, anotherDivImage, divView) Assert.assertNull(view.colorFilter) } @@ -250,7 +250,7 @@ class DivImageBinderTest : DivBinderTest() { preview = PREVIEW.asExpression(), tintColor = Color.parseColor("#ffffff").asExpression()) - binder.bindView(bindingContext, view, divImage) + binder.bindView(view, divImage, divView) Assert.assertNull(view.colorFilter) whenPreviewLoaded() Assert.assertNotNull(view.colorFilter) diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt index 15096919c..9ea0cdae1 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt @@ -5,7 +5,6 @@ import com.yandex.div.core.ScrollDirection import com.yandex.div.core.state.DivViewState import com.yandex.div.core.state.PagerState import com.yandex.div.core.util.AccessibilityStateProvider -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.divs.widgets.DivPagerView import com.yandex.div.data.DivParsingEnvironment @@ -57,24 +56,24 @@ class DivPagerBinderTest: DivBinderTest() { @Test fun `set default item`() { - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM, divPagerView.currentItem) } @Test fun `keep selected item on rebind`() { - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) divPagerView.currentItem = DEFAULT_ITEM + 1 - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM + 1, divPagerView.viewPager.currentItem) } @Test fun `set default item when has current state without current page index`() { - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM, divPagerView.currentItem) } @@ -83,14 +82,14 @@ class DivPagerBinderTest: DivBinderTest() { fun `restore previously selected page`() { whenever(divViewState.getBlockState(any())).thenReturn(PagerState(DEFAULT_ITEM + 1)) - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) Assert.assertEquals(DEFAULT_ITEM + 1, divPagerView.currentItem) } @Test fun `do not log page change when selected page for the first time`() { - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) divPagerView.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM) @@ -104,7 +103,7 @@ class DivPagerBinderTest: DivBinderTest() { @Test fun `log page change when selected next page`() { - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) divPagerView.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM) divPagerView.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM + 1) @@ -124,7 +123,7 @@ class DivPagerBinderTest: DivBinderTest() { .getJSONObject(DEFAULT_ITEM) .put("visibility_action", DivVisibilityAction(logId = "test").writeToJSON()) val divPager = DivPager(DivParsingEnvironment(ParsingErrorLogger.ASSERT), pagerJson) - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) divPagerView.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM) @@ -133,7 +132,7 @@ class DivPagerBinderTest: DivBinderTest() { @Test fun `unbind view from div on previously selected page`() { - underTest.bindView(bindingContext, divPagerView, divPager, rootPath()) + underTest.bindView(divPagerView, divPager, divView, rootPath()) divPagerView.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM) divPagerView.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM + 1) diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSelectBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSelectBinderTest.kt index b24727460..b9dcc5511 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSelectBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSelectBinderTest.kt @@ -25,7 +25,7 @@ import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class DivSelectBinderTest : DivBinderTest() { private val divTypefaceResolver = mock() - private val variableBinder = mock { + private val variableBinder = mock() { on { bindVariable(any(), any(), any()) } doReturn mock() } private val errorCollectors = mock { @@ -48,7 +48,7 @@ class DivSelectBinderTest : DivBinderTest() { @Test fun `bind value_variable`() { - underTest.bindView(bindingContext, view, divSelect) + underTest.bindView(view, divSelect, divView) verify(variableBinder).bindVariable(any(), eq(divSelect.valueVariable), any()) verifyNoMoreInteractions(variableBinder) @@ -56,7 +56,7 @@ class DivSelectBinderTest : DivBinderTest() { @Test fun `update text after variable changed`() { - underTest.bindView(bindingContext, view, divSelect) + underTest.bindView(view, divSelect, divView) verify(variableBinder).bindVariable(any(), any(), captor.capture()) val (optionText, optionValue) = divSelect.options.evaluateLastOption() @@ -73,7 +73,7 @@ class DivSelectBinderTest : DivBinderTest() { fun `update text and variable after option selected`() { val viewStateChangeListener = mock<(String) -> Unit>() - underTest.bindView(bindingContext, view, divSelect) + underTest.bindView(view, divSelect, divView) verify(variableBinder).bindVariable(any(), any(), captor.capture()) val (optionText, optionValue) = divSelect.options.evaluateLastOption() @@ -94,8 +94,8 @@ class DivSelectBinderTest : DivBinderTest() { private fun List.evaluateLastOption(): Pair { val option = last() - val optionValue = option.value.evaluate(bindingContext.expressionResolver) - val optionText = option.text?.evaluate(bindingContext.expressionResolver) ?: optionValue + val optionValue = option.value.evaluate(divView.expressionResolver) + val optionText = option.text?.evaluate(divView.expressionResolver) ?: optionValue return optionText to optionValue } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSeparatorBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSeparatorBinderTest.kt index 0f0303f41..216247b54 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSeparatorBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivSeparatorBinderTest.kt @@ -21,9 +21,9 @@ class DivSeparatorBinderTest : DivBinderTest() { val view = viewCreator.create(div, ExpressionResolver.EMPTY) as DivSeparatorView view.layoutParams = defaultLayoutParams() - binder.bindView(bindingContext, view, divContainer) + binder.bindView(view, divContainer, divView) - assertActionApplied(bindingContext, view, Expected.ACTION_URI) + assertActionApplied(divView, view, Expected.ACTION_URI) } @Test @@ -33,9 +33,9 @@ class DivSeparatorBinderTest : DivBinderTest() { val view = viewCreator.create(div, ExpressionResolver.EMPTY) as DivSeparatorView view.layoutParams = defaultLayoutParams() - binder.bindView(bindingContext, view, divContainer) + binder.bindView(view, divContainer, divView) - assertActionApplied(bindingContext, view, Expected.STATE_ACTION_URI) + assertActionApplied(divView, view, Expected.STATE_ACTION_URI) } companion object { diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderReleaseViewTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderReleaseViewTest.kt index ecbfc3937..e0c03874e 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderReleaseViewTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderReleaseViewTest.kt @@ -67,32 +67,32 @@ class DivStateBinderReleaseViewTest: DivBinderTest() { @Test fun `initial bind do not call release`() { - stateBinder.bindView(bindingContext, stateLayout, divOne.asDivState, rootPath()) + stateBinder.bindView(stateLayout, divOne.asDivState, divView, rootPath()) verify(visitor, never()).release(any()) } @Test fun `rebind do call release on old views`() { - stateBinder.bindView(bindingContext, stateLayout, divOne.asDivState, rootPath()) + stateBinder.bindView(stateLayout, divOne.asDivState, divView, rootPath()) val allChildren = stateLayout.childrenToFlatList() - stateBinder.bindView(bindingContext, stateLayout, divTwo.asDivState, rootPath()) + stateBinder.bindView(stateLayout, divTwo.asDivState, divView, rootPath()) verifyAllChildrenReleased(allChildren) } @Test fun `change state release old views`() { - stateBinder.bindView(bindingContext, stateLayout, divOne.asDivState, rootPath()) + stateBinder.bindView(stateLayout, divOne.asDivState, divView, rootPath()) switchToState("second") val stateToBeSwitched: DivStateLayout = stateLayout .findStateLayout(DivStatePath.parse("0/state_container/first")) ?: throw AssertionError("failed to find state") val allChildren: List = stateToBeSwitched.childrenToFlatList() - stateBinder.bindView(bindingContext, stateLayout, divOne.asDivState, rootPath()) + stateBinder.bindView(stateLayout, divOne.asDivState, divView, rootPath()) verifyAllChildrenReleased(allChildren) } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderTest.kt index 0423fbcc3..650fe4657 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivStateBinderTest.kt @@ -68,7 +68,7 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `first state path applied when no defaultStateId`() { - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) assertEquals(pathToState("first"), stateLayout.path) } @@ -80,7 +80,7 @@ class DivStateBinderTest: DivBinderTest() { val stateLayout = viewCreator.create(div, ExpressionResolver.EMPTY) as DivStateLayout stateLayout.layoutParams = defaultLayoutParams() - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) assertEquals(pathToState("default"), stateLayout.path) } @@ -88,7 +88,7 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `selected state path applied`() { switchToState("second") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) assertEquals(pathToState("second"), stateLayout.path) } @@ -96,14 +96,14 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `empty state path applied`() { switchToState("empty") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) assertEquals(pathToState("empty"), stateLayout.path) } @Test fun `default state bound`() { - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) val expectedStateDiv = divState.states[0].div!! assertStateBound(pathToState("first"), expectedStateDiv) @@ -112,7 +112,7 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `selected state bound`() { switchToState("second") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) val expectedStateDiv = divState.states[1].div!! assertStateBound(pathToState("second"), expectedStateDiv) @@ -121,7 +121,7 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `selected temporary state bound`() { switchToState(stateId = "first", temporaryStateId = "second") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) val expectedStateDiv = divState.states[1].div!! assertStateBound(pathToState("second"), expectedStateDiv) @@ -132,17 +132,17 @@ class DivStateBinderTest: DivBinderTest() { clearInvocations(viewCreator) switchToState("empty") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) assertStateNotBound(pathToState("empty")) } @Test fun `the same state rebound`() { - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) clearInvocations(viewCreator, viewBinder) - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) val expectedStateDiv = divState.states[0].div!! assertStateRebound(pathToState("first"), expectedStateDiv) @@ -150,11 +150,11 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `new state bound`() { - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) clearInvocations(viewCreator, viewBinder) switchToState("second") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) val expectedStateDiv = divState.states[1].div!! assertStateBound(pathToState("second"), expectedStateDiv) @@ -164,9 +164,9 @@ class DivStateBinderTest: DivBinderTest() { fun `rebind adds swipes`() { val oldData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "old_state_no_swipe_actions.json").asDivState val newData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "old_state.json").asDivState - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) - stateBinder.bindView(bindingContext, stateLayout, newData, rootPath()) + stateBinder.bindView(stateLayout, newData, divView, rootPath()) assertNotNull(stateLayout.swipeOutCallback) } @@ -175,10 +175,10 @@ class DivStateBinderTest: DivBinderTest() { fun `rebind removes old view tracking`() { val oldData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "old_state.json").asDivState val newData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "new_state_incompatible.json").asDivState - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) val child = stateLayout.getChildAt(0) - stateBinder.bindView(bindingContext, stateLayout, newData, rootPath()) + stateBinder.bindView(stateLayout, newData, divView, rootPath()) val inOrder = inOrder(divView) inOrder.verify(divView).unbindViewFromDiv(child) @@ -189,10 +189,10 @@ class DivStateBinderTest: DivBinderTest() { fun `rebind to empty state clears everything`() { val oldData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "old_state.json").asDivState val newData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "new_state_empty_state.json").asDivState - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) val child = stateLayout.getChildAt(0) - stateBinder.bindView(bindingContext, stateLayout, newData, rootPath()) + stateBinder.bindView(stateLayout, newData, divView, rootPath()) assertNull(stateLayout.swipeOutCallback) assertEquals(0, stateLayout.childCount) @@ -202,38 +202,38 @@ class DivStateBinderTest: DivBinderTest() { @Test fun `rebind from same state do not untrack visibility actions`() { val oldData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "new_state_empty_state.json").asDivState - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) - verify(divVisibilityActionTracker, never()).trackVisibilityActionsOf(any(), any(), eq(null), any(), any()) + verify(divVisibilityActionTracker, never()).trackVisibilityActionsOf(any(), eq(null), any(), any()) } @Test fun `selecting state causes untracking`() { - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) switchToState("second") - stateBinder.bindView(bindingContext, stateLayout, divState, rootPath()) + stateBinder.bindView(stateLayout, divState, divView, rootPath()) - verify(divVisibilityActionTracker, times(1)).trackVisibilityActionsOf(any(), any(), eq(null), any(), any()) + verify(divVisibilityActionTracker, times(1)).trackVisibilityActionsOf(any(), eq(null), any(), any()) } @Test fun `rebind from different state untrack visibility actions`() { val oldData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "old_state.json").asDivState val newData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "new_state_empty_state.json").asDivState - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) - stateBinder.bindView(bindingContext, stateLayout, newData, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) + stateBinder.bindView(stateLayout, newData, divView, rootPath()) - verify(divVisibilityActionTracker, times(1)).trackVisibilityActionsOf(any(), any(), eq(null), any(), any()) + verify(divVisibilityActionTracker, times(1)).trackVisibilityActionsOf(any(), eq(null), any(), any()) } @Test fun `rebind from empty state inits everything`() { val oldData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "new_state_empty_state.json").asDivState val newData = UnitTestData(STATE_DIR_AUTOANIMATIONS, "new_state_incompatible.json").asDivState - stateBinder.bindView(bindingContext, stateLayout, oldData, rootPath()) + stateBinder.bindView(stateLayout, oldData, divView, rootPath()) - stateBinder.bindView(bindingContext, stateLayout, newData, rootPath()) + stateBinder.bindView(stateLayout, newData, divView, rootPath()) assertNotNull(stateLayout.swipeOutCallback) assertEquals(1, stateLayout.childCount) @@ -256,12 +256,12 @@ class DivStateBinderTest: DivBinderTest() { private fun assertStateBound(path: DivStatePath, div: Div) { verify(viewCreator).create(eq(div), any()) - verify(viewBinder).bind(eq(bindingContext), any(), eq(div), eq(path)) + verify(viewBinder).bind(any(), eq(div), eq(divView), eq(path)) } private fun assertStateRebound(path: DivStatePath, div: Div) { verify(viewCreator, never()).create(eq(div), any()) - verify(viewBinder).bind(eq(bindingContext), any(), eq(div), eq(path)) + verify(viewBinder).bind(any(), eq(div), eq(divView), eq(path)) } private val UnitTestData.asDivState: DivState diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivTextBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivTextBinderTest.kt index fdbc5e487..dfe20c730 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivTextBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivTextBinderTest.kt @@ -33,18 +33,18 @@ class DivTextBinderTest : DivBinderTest() { fun `url action applied`() { val (divText, view) = createTestData("with_action.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) - assertActionApplied(bindingContext, view, Expected.ACTION_URI) + assertActionApplied(divView, view, Expected.ACTION_URI) } @Test fun `state action applied`() { val (divText, view) = createTestData("with_set_state_action.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) - assertActionApplied(bindingContext, view, Expected.STATE_ACTION_URI) + assertActionApplied(divView, view, Expected.STATE_ACTION_URI) } @Test @@ -52,7 +52,7 @@ class DivTextBinderTest : DivBinderTest() { fun `apply hyphenation for text with soft hyphens`() { val (divText, view) = createTestData("with_hyphenation.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) Assert.assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, view.hyphenationFrequency) } @@ -62,7 +62,7 @@ class DivTextBinderTest : DivBinderTest() { fun `set hyphenation frequency to none if word break is to long`() { val (divText, view) = createTestData("with_hyphenation_long_word_break.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) Assert.assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, view.hyphenationFrequency) } @@ -73,7 +73,7 @@ class DivTextBinderTest : DivBinderTest() { val binder = createBinder(isHyphenationEnabled = false) val (divText, view) = createTestData("with_hyphenation.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) Assert.assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, view.hyphenationFrequency) } @@ -83,7 +83,7 @@ class DivTextBinderTest : DivBinderTest() { fun `apply hyphenation if text has ellipsis`() { val (divText, view) = createTestData("with_hyphenation_ellipsis.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) Assert.assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, view.hyphenationFrequency) } @@ -93,11 +93,11 @@ class DivTextBinderTest : DivBinderTest() { fun `reset hyphenation after text has no soft hyphens`() { val (divText, view) = createTestData("with_hyphenation.json") - binder.bindView(bindingContext, view, divText) + binder.bindView(view, divText, divView) val (newDivText, newView) = createTestData("with_action.json") - binder.bindView(bindingContext, newView, newDivText) + binder.bindView(newView, newDivText, divView) Assert.assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, newView.hyphenationFrequency) } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcherTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcherTest.kt index 8d042ad0b..6d4d4a424 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcherTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/PagerSelectedActionsDispatcherTest.kt @@ -2,7 +2,6 @@ package com.yandex.div.core.view2.divs import androidx.test.core.app.ApplicationProvider import androidx.viewpager2.widget.ViewPager2 -import com.yandex.div.core.view2.BindingContext import com.yandex.div.core.view2.Div2View import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.DivAction @@ -28,13 +27,12 @@ class PagerSelectedActionsDispatcherTest { private val divActionBinder = mock() private val divView = divView(logId = CARD_ID, divTag = CARD_ID) - private val bindingContext = BindingContext(divView, ExpressionResolver.EMPTY) private val bulkActionsArgumentCaptor = argumentCaptor<() -> Unit>() private val div = UnitTestData(PAGER_DIR, "pager_selected_actions.json").div private val divPager = div.value() as DivPager - private val underTest = PagerSelectedActionsDispatcher(bindingContext, ArrayList(divPager.items), divActionBinder) + private val underTest = PagerSelectedActionsDispatcher(divView, divPager, ArrayList(divPager.items), divActionBinder) @Before fun setUp() { @@ -45,7 +43,7 @@ class PagerSelectedActionsDispatcherTest { fun `no actions dispatched when selected item has no selected actions`() { val divPager = UnitTestData(PAGER_DIR, "pager_default_item.json").div.value() as DivPager - val underTest = PagerSelectedActionsDispatcher(bindingContext, ArrayList(divPager.items), divActionBinder) + val underTest = PagerSelectedActionsDispatcher(divView, divPager, ArrayList(divPager.items), divActionBinder) underTest.whenAttached() underTest.whenPageSelected(0) @@ -157,12 +155,11 @@ class PagerSelectedActionsDispatcherTest { } private fun verifyActionHandled(urlStr: String, times: Int = 1) { - verify(divActionBinder, times(times)) - .handleAction(eq(divView), any(), urlEq(urlStr), any(), anyOrNull(), anyOrNull()) + verify(divActionBinder, times(times)).handleAction(eq(divView), urlEq(urlStr), any(), anyOrNull(), anyOrNull()) } private fun InOrderOnType.verifyActionHandled(div2View: Div2View, url: String) { - verify().handleAction(eq(div2View), any(), urlEq(url), any(), anyOrNull(), anyOrNull()) + verify().handleAction(eq(div2View), urlEq(url), any(), anyOrNull(), anyOrNull()) } private companion object { diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcherTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcherTest.kt index 16470380c..03ed2f2fc 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcherTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivJoinedStateSwitcherTest.kt @@ -52,7 +52,7 @@ class DivJoinedStateSwitcherTest { stateSwitcher.switchStates(divDataState, listOf(notActiveState), resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(DivStatePath.fromState(0))) + verify(viewBinder).bind(any(), eq(div), any(), eq(DivStatePath.fromState(0))) } @Test @@ -62,7 +62,7 @@ class DivJoinedStateSwitcherTest { stateSwitcher.switchStates(divDataState, listOf(activeState), resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(activeState.parentState())) + verify(viewBinder).bind(any(), eq(div), any(), eq(activeState.parentState())) } @Test @@ -72,7 +72,7 @@ class DivJoinedStateSwitcherTest { stateSwitcher.switchStates(divDataState, listOf(activeState), resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(activeState.parentState())) + verify(viewBinder).bind(any(), eq(div), any(), eq(activeState.parentState())) } @Test @@ -85,7 +85,7 @@ class DivJoinedStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(commonPath.parentState())) + verify(viewBinder).bind(any(), eq(div), any(), eq(commonPath.parentState())) } @Test @@ -99,7 +99,7 @@ class DivJoinedStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(commonPath.parentState())) + verify(viewBinder).bind(any(), eq(div), any(), eq(commonPath.parentState())) } @Test @@ -111,6 +111,6 @@ class DivJoinedStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(rootDiv), eq(commonPath)) + verify(viewBinder).bind(any(), eq(rootDiv), any(), eq(commonPath)) } } diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcherTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcherTest.kt index dc17bb95a..beb41d4f2 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcherTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/state/DivMultipleStateSwitcherTest.kt @@ -57,7 +57,7 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, listOf(activeState), resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(activeState.parentState())) + verify(viewBinder).bind(any(), eq(div), any(), eq(activeState.parentState())) } @Test @@ -67,14 +67,17 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, listOf(activeState), resolver) - verify(viewBinder).bind(any(), any(), eq(div), eq(activeState.parentState())) + verify(viewBinder).bind(any(), eq(div), any(), eq(activeState.parentState())) } @Test fun `switch to single state of missing state layout binds root div`() { val inactiveState = "0/state_container/second/second_state/hidden".path + val div = rootDiv.findDivState(inactiveState.parentState(), resolver)!! + stateSwitcher.switchStates(divDataState, listOf(inactiveState), resolver) - verify(viewBinder).bind(any(), any(), eq(rootDiv), eq(DivStatePath.fromState(0))) + + verify(viewBinder).bind(any(), eq(rootDiv), any(), eq(DivStatePath.fromState(0))) } @Test @@ -87,8 +90,8 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(firstDiv), eq(firstPath.parentState())) - verify(viewBinder).bind(any(), any(), eq(secondDiv), eq(secondPath.parentState())) + verify(viewBinder).bind(any(), eq(firstDiv), any(), eq(firstPath.parentState())) + verify(viewBinder).bind(any(), eq(secondDiv), any(), eq(secondPath.parentState())) } @Test @@ -100,7 +103,7 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(firstDiv), eq(firstPath.parentState())) + verify(viewBinder).bind(any(), eq(firstDiv), any(), eq(firstPath.parentState())) } @Test @@ -112,7 +115,7 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(firstDiv), eq(firstPath.parentState())) + verify(viewBinder).bind(any(), eq(firstDiv), any(), eq(firstPath.parentState())) } @Test @@ -125,8 +128,8 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(firstDiv), eq(firstPath.parentState())) - verify(viewBinder, never()).bind(any(), any(), eq(secondDiv), any()) + verify(viewBinder).bind(any(), eq(firstDiv), any(), eq(firstPath.parentState())) + verify(viewBinder, never()).bind(any(), eq(secondDiv), any(), any()) } @Test @@ -137,6 +140,6 @@ class DivMultipleStateSwitcherTest { stateSwitcher.switchStates(divDataState, paths, resolver) - verify(viewBinder).bind(any(), any(), eq(rootDiv), eq(DivStatePath.fromState(0))) + verify(viewBinder).bind(any(), eq(rootDiv), any(), eq(DivStatePath.fromState(0))) } } diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index a5027b1cd..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 94bc0a1e2..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index 05d0928fc..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index 1a74db9ac..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index a5027b1cd..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index 0dae233f4..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index c8ef3436c..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API23_HDPI_480x800/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index e66fadfb6..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 97ad0cd1e..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index 58d6ef527..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index 887f0db8b..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index e66fadfb6..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index b3ac3d2fb..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 4c2ff62e4..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API24_XXHDPI_1080x1920/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index 4d541b3d3..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 56efa831e..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index e18e24722..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index f44cbdf6b..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index 4d541b3d3..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index 2a8e8d29a..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 6dbcfec44..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API25_XHDPI_720x1280/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index de3ef6a0a..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index c9d5a8074..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index cb24a13ea..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index aeabfca18..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index de3ef6a0a..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index 60d310384..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 8daa84dd2..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index 8d02b5b5b..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 58099610c..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index 4d4ad7dc5..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index 24a63cb5b..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index 8d02b5b5b..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index c598fe1fa..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 626900bfa..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API26_XXXHDPI_1440x2560/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index 0c3cf38c9..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 3e4c27467..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index 2f7d91619..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index a2278ed20..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index 0c3cf38c9..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index 291d7504d..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index f7a0f9b8e..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index cd4927f04..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index e8bec2cd4..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index 09b96cc82..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index f12aedfb8..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index cd4927f04..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index 4d512323f..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 75161e611..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API27_XHDPI_720x1440/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index d4fc93be0..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 9389df041..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index d4c0d08ef..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index b19482f1c..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index d4fc93be0..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index f0ace91e8..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 28247887e..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewPixelCopy/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png deleted file mode 100644 index 20416a9f0..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step0.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png deleted file mode 100644 index 564f0a44b..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step1.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png deleted file mode 100644 index 945ef8a44..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step2.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png deleted file mode 100644 index 6db0e9794..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2InteractiveScreenshotTest/div-container/item_builder/step3.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png deleted file mode 100644 index 20416a9f0..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/item-builder.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png deleted file mode 100644 index 2c7c284d0..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/nested-builders.png and /dev/null differ diff --git a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png b/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png deleted file mode 100644 index 5e04cee5d..000000000 Binary files a/client/android/divkit-demo-app/src/screenshotTest/screenshots/API28_XHDPI_1080x2160/viewRender/com.yandex.div.Div2ScreenshotTest/div-container/item_builder/non-unique-matched-selectors.png and /dev/null differ diff --git a/schema/div-collection-item-builder.json b/schema/div-collection-item-builder.json index e8325f581..15dac37ca 100644 --- a/schema/div-collection-item-builder.json +++ b/schema/div-collection-item-builder.json @@ -1,15 +1,4 @@ { - "codegen": { - "kotlin": { - "additional_fields": [ - { - "name": "result", - "type": "List?", - "default_value": "null" - } - ] - } - }, "type": "object", "properties": { "data_element_name": { diff --git a/schema/div-container.json b/schema/div-container.json index 7422ac035..a851a3c67 100644 --- a/schema/div-container.json +++ b/schema/div-container.json @@ -30,6 +30,11 @@ "swift": { "generate_optional_arguments": false }, + "kotlin": { + "properties_to_patch": [ + "items" + ] + }, "typescript": { "union_interfaces": [ { @@ -135,7 +140,11 @@ }, "item_builder": { "$ref": "div-collection-item-builder.json", - "$description": "translations.json#/div_collection_item_builder" + "$description": "translations.json#/div_collection_item_builder", + "platforms": [ + "ios", + "web" + ] }, "aspect": { "$ref": "div-aspect.json", diff --git a/schema/div-gallery.json b/schema/div-gallery.json index c2b1cb68b..56963db99 100644 --- a/schema/div-gallery.json +++ b/schema/div-gallery.json @@ -4,6 +4,11 @@ "codegen": { "swift": { "generate_optional_arguments": false + }, + "kotlin": { + "properties_to_patch": [ + "items" + ] } }, "allOf": [ diff --git a/schema/div-grid.json b/schema/div-grid.json index 5b5110327..ce11f8362 100644 --- a/schema/div-grid.json +++ b/schema/div-grid.json @@ -4,6 +4,11 @@ "codegen": { "swift": { "generate_optional_arguments": false + }, + "kotlin": { + "properties_to_patch": [ + "items" + ] } }, "allOf": [ diff --git a/schema/div-pager.json b/schema/div-pager.json index b25ff5359..f4c03995c 100644 --- a/schema/div-pager.json +++ b/schema/div-pager.json @@ -4,6 +4,11 @@ "codegen": { "swift": { "generate_optional_arguments": false + }, + "kotlin": { + "properties_to_patch": [ + "items" + ] } }, "allOf": [ diff --git a/schema/div-state.json b/schema/div-state.json index 0445613c4..3e0710f7c 100644 --- a/schema/div-state.json +++ b/schema/div-state.json @@ -4,6 +4,11 @@ "codegen": { "swift": { "generate_optional_arguments": false + }, + "kotlin": { + "properties_to_patch": [ + "states" + ] } }, "definitions": { diff --git a/schema/div-tabs.json b/schema/div-tabs.json index 295332865..327ee4add 100644 --- a/schema/div-tabs.json +++ b/schema/div-tabs.json @@ -4,6 +4,11 @@ "codegen": { "swift": { "generate_optional_arguments": false + }, + "kotlin": { + "properties_to_patch": [ + "items" + ] } }, "definitions": { diff --git a/test_data/interactive_snapshot_test_data/div-container/item_builder.json b/test_data/interactive_snapshot_test_data/div-container/item_builder.json index 5c4b01b09..d02ba7ef5 100644 --- a/test_data/interactive_snapshot_test_data/div-container/item_builder.json +++ b/test_data/interactive_snapshot_test_data/div-container/item_builder.json @@ -1,7 +1,6 @@ { "description": "Container with item_builder.", "platforms": [ - "android", "ios", "web" ], diff --git a/test_data/snapshot_test_data/div-container/item_builder/item-builder.json b/test_data/snapshot_test_data/div-container/item_builder/item-builder.json index bfa2cef57..2c0d07d69 100644 --- a/test_data/snapshot_test_data/div-container/item_builder/item-builder.json +++ b/test_data/snapshot_test_data/div-container/item_builder/item-builder.json @@ -1,7 +1,6 @@ { "description": "Container with item_builder.", "platforms": [ - "android", "ios", "web" ], diff --git a/test_data/snapshot_test_data/div-container/item_builder/nested-builders.json b/test_data/snapshot_test_data/div-container/item_builder/nested-builders.json index cbab9bb6d..87bcbde37 100644 --- a/test_data/snapshot_test_data/div-container/item_builder/nested-builders.json +++ b/test_data/snapshot_test_data/div-container/item_builder/nested-builders.json @@ -1,7 +1,6 @@ { "description": "Inner data_element_name should override outer one.", "platforms": [ - "android", "ios", "web" ], diff --git a/test_data/snapshot_test_data/div-container/item_builder/non-unique-matched-selectors.json b/test_data/snapshot_test_data/div-container/item_builder/non-unique-matched-selectors.json index ae1544072..ac79f168b 100644 --- a/test_data/snapshot_test_data/div-container/item_builder/non-unique-matched-selectors.json +++ b/test_data/snapshot_test_data/div-container/item_builder/non-unique-matched-selectors.json @@ -1,7 +1,6 @@ { "description": "Only the first matched selector should be used. Zero matched selectors means no error.", "platforms": [ - "android", "ios", "web" ], diff --git a/test_data/test_schema/entity_with_array.json b/test_data/test_schema/entity_with_array.json index 8e8523a60..c0e7df0c6 100644 --- a/test_data/test_schema/entity_with_array.json +++ b/test_data/test_schema/entity_with_array.json @@ -5,6 +5,13 @@ "ios", "web" ], + "codegen": { + "kotlin": { + "properties_to_patch": [ + "array" + ] + } + }, "properties": { "type": { "type": "string", diff --git a/test_data/test_schema/entity_with_array_of_enums.json b/test_data/test_schema/entity_with_array_of_enums.json index c1ca71f34..589968083 100644 --- a/test_data/test_schema/entity_with_array_of_enums.json +++ b/test_data/test_schema/entity_with_array_of_enums.json @@ -1,5 +1,12 @@ { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "properties": { "type": { "type": "string", diff --git a/test_data/test_schema/entity_with_array_of_nested_items.json b/test_data/test_schema/entity_with_array_of_nested_items.json index 7e7576192..1bd7b3c58 100644 --- a/test_data/test_schema/entity_with_array_of_nested_items.json +++ b/test_data/test_schema/entity_with_array_of_nested_items.json @@ -1,5 +1,12 @@ { "type": "object", + "codegen": { + "kotlin": { + "properties_to_patch": [ + "items" + ] + } + }, "definitions": { "item": { "type": "object",