diff --git a/.mapping.json b/.mapping.json index 2e9b1ce89..3a79ebe14 100644 --- a/.mapping.json +++ b/.mapping.json @@ -9751,6 +9751,7 @@ "client/ios/DivKitTests/Extensions/DivGifImageExtensionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivGifImageExtensionsTests.swift", "client/ios/DivKitTests/Extensions/DivGridExtensionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivGridExtensionsTests.swift", "client/ios/DivKitTests/Extensions/DivImageExtensionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivImageExtensionsTests.swift", + "client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift", "client/ios/DivKitTests/Extensions/DivSeparatorExtensionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivSeparatorExtensionsTests.swift", "client/ios/DivKitTests/Extensions/DivStateExtensionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivStateExtensionsTests.swift", "client/ios/DivKitTests/Extensions/DivTabsExtensionsTests.swift":"divkit/public/client/ios/DivKitTests/Extensions/DivTabsExtensionsTests.swift", diff --git a/client/ios/DivKit.xcodeproj/project.pbxproj b/client/ios/DivKit.xcodeproj/project.pbxproj index 7d23b3539..d08fe1565 100644 --- a/client/ios/DivKit.xcodeproj/project.pbxproj +++ b/client/ios/DivKit.xcodeproj/project.pbxproj @@ -214,6 +214,7 @@ 8CA382DF287C5CF000C99F4F /* DivKitExtensions in Frameworks */ = {isa = PBXBuildFile; productRef = 8CA382DE287C5CF000C99F4F /* DivKitExtensions */; }; 8CAB089A2B39AC15009330F3 /* heavy.json in Resources */ = {isa = PBXBuildFile; fileRef = 8CAB08992B39AC15009330F3 /* heavy.json */; }; 8CB03C1F2A66A07300847A65 /* PlaygroundUrlHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB03C1E2A66A07300847A65 /* PlaygroundUrlHandler.swift */; }; + 8CB74F032B6D456D00397DCF /* DivInputExtentionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB74F022B6D456D00397DCF /* DivInputExtentionsTests.swift */; }; 8CB960E428883B8300D16E47 /* DivTriggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB960E328883B8300D16E47 /* DivTriggerTests.swift */; }; 8CB960E628883B8E00D16E47 /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB960E528883B8E00D16E47 /* Platform.swift */; }; 8CB960E828883B9A00D16E47 /* FunctionSignaturesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB960E728883B9A00D16E47 /* FunctionSignaturesTests.swift */; }; @@ -483,6 +484,7 @@ 8CA22DD02B519C7300CCB48E /* Screen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Screen.swift; sourceTree = ""; }; 8CAB08992B39AC15009330F3 /* heavy.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = heavy.json; sourceTree = ""; }; 8CB03C1E2A66A07300847A65 /* PlaygroundUrlHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlaygroundUrlHandler.swift; sourceTree = ""; }; + 8CB74F022B6D456D00397DCF /* DivInputExtentionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DivInputExtentionsTests.swift; sourceTree = ""; }; 8CB960E328883B8300D16E47 /* DivTriggerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DivTriggerTests.swift; sourceTree = ""; }; 8CB960E528883B8E00D16E47 /* Platform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Platform.swift; sourceTree = ""; }; 8CB960E728883B9A00D16E47 /* FunctionSignaturesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionSignaturesTests.swift; sourceTree = ""; }; @@ -934,6 +936,7 @@ 8C7B1B2A2865C01C0036EF4C /* DivGifImageExtensionsTests.swift */, 8C7B1B262865C01C0036EF4C /* DivGridExtensionsTests.swift */, 8C7B1B2B2865C01C0036EF4C /* DivImageExtensionsTests.swift */, + 8CB74F022B6D456D00397DCF /* DivInputExtentionsTests.swift */, 8C7B1B2F2865C01C0036EF4C /* DivSeparatorExtensionsTests.swift */, 52CD80682A7159C200B828B0 /* DivStateExtensionsTests.swift */, 8C7B1B252865C01C0036EF4C /* DivTabsExtensionsTests.swift */, @@ -1618,6 +1621,7 @@ 8C64FEE52A5D7373008B1909 /* DivVariableTrackerTests.swift in Sources */, 8C23F44529DDB3810069F3F7 /* PropertyTests.swift in Sources */, 8C23F44629DDB3810069F3F7 /* SimplePropertiesTests.swift in Sources */, + 8CB74F032B6D456D00397DCF /* DivInputExtentionsTests.swift in Sources */, 8C23F43E29DDB3810069F3F7 /* DefaultValueTests.swift in Sources */, 8C23F41E29DDB3810069F3F7 /* EntityWithComplexPropertyTemplate.swift in Sources */, 8C23F41629DDB3810069F3F7 /* EntityWithArrayOfExpressions.swift in Sources */, diff --git a/client/ios/DivKit/Extensions/DivInputExtensions.swift b/client/ios/DivKit/Extensions/DivInputExtensions.swift index e6230e70a..d4221a73c 100644 --- a/client/ios/DivKit/Extensions/DivInputExtensions.swift +++ b/client/ios/DivKit/Extensions/DivInputExtensions.swift @@ -8,14 +8,21 @@ import LayoutKit extension DivInput: DivBlockModeling { public func makeBlock(context: DivBlockModelingContext) throws -> Block { - try applyBaseProperties( - to: { try makeBaseBlock(context: context) }, + let textBinding = context.makeBinding(variableName: textVariable, defaultValue: "") + return try applyBaseProperties( + to: { try makeBaseBlock(context: context, textBinding: textBinding) }, context: context, - actionsHolder: nil + actionsHolder: nil, + customAccessibilityParams: CustomAccessibilityParams { [unowned self] in + accessibility?.resolveDescription(context.expressionResolver) ?? textBinding.value + } ) } - private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block { + private func makeBaseBlock( + context: DivBlockModelingContext, + textBinding: Binding + ) throws -> Block { let expressionResolver = context.expressionResolver let font = context.fontProvider.font( @@ -54,7 +61,7 @@ extension DivInput: DivBlockModeling { widthTrait: resolveContentWidthTrait(context), heightTrait: resolveContentHeightTrait(context), hint: hintValue.with(typo: typo.with(color: resolveHintColor(expressionResolver))), - textValue: context.makeBinding(variableName: textVariable, defaultValue: ""), + textValue: textBinding, rawTextValue: mask?.makeRawVariable(context), textTypo: typo.with(color: resolveTextColor(expressionResolver)), multiLineMode: keyboardType == .multiLineText, diff --git a/client/ios/DivKitTests/DivKitTests.swift b/client/ios/DivKitTests/DivKitTests.swift index dc26b2d26..836b6c397 100644 --- a/client/ios/DivKitTests/DivKitTests.swift +++ b/client/ios/DivKitTests/DivKitTests.swift @@ -81,7 +81,8 @@ extension DivBlockModelingContext { init( blockStateStorage: DivBlockStateStorage = DivBlockStateStorage(), extensionHandlers: [DivExtensionHandler] = [], - scheduler: Scheduling? = nil + scheduler: Scheduling? = nil, + variableStorage: DivVariableStorage? = nil ) { self.init( cardId: DivKitTests.cardId, @@ -90,6 +91,7 @@ extension DivBlockModelingContext { blockStateStorage: blockStateStorage, imageHolderFactory: FakeImageHolderFactory(), extensionHandlers: extensionHandlers, + variablesStorage: DivVariablesStorage(outerStorage: variableStorage), scheduler: scheduler, persistentValuesStorage: DivPersistentValuesStorage() ) diff --git a/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift b/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift new file mode 100644 index 000000000..7c8583dbd --- /dev/null +++ b/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift @@ -0,0 +1,68 @@ +@testable import DivKit +@testable import LayoutKit + +import XCTest + +import BaseUIPublic +import CommonCorePublic + +final class DivInputExtensionsTests: XCTestCase { + private let variableStorage = DivVariableStorage() + private var context: DivBlockModelingContext! + + override func setUp() { + variableStorage.put(name: "input_variable", value: .string("Hello!")) + context = DivBlockModelingContext(variableStorage: variableStorage) + } + + func test_WithTextVariable() { + let block = makeBlock( + divInput(textVariable: "input_variable"), + context: context + ) + + let expectedBlock = StateBlock( + child: DecoratingBlock( + child: TextInputBlock( + hint: NSAttributedString(string: ""), + textValue: context.makeBinding(variableName: "input_variable", defaultValue: ""), + textTypo: Typo(font: fontSpecifiers.text.font(weight: .regular, size: 12)) + .with(color: Color.colorWithARGBHexCode(0xFF000000)), + path: .root + "0", + layoutDirection: .leftToRight + ), + accessibilityElement: accessibility(label: "Hello!") + ), + ids: [] + ) + + assertEqual(block, expectedBlock) + } + + func test_WithAccessibility() { + let block = makeBlock( + divInput( + accessibility: DivAccessibility(description: .value("Description")), + textVariable: "input_variable" + ), + context: context + ) + + let expectedBlock = StateBlock( + child: DecoratingBlock( + child: TextInputBlock( + hint: NSAttributedString(string: ""), + textValue: context.makeBinding(variableName: "input_variable", defaultValue: ""), + textTypo: Typo(font: fontSpecifiers.text.font(weight: .regular, size: 12)) + .with(color: Color.colorWithARGBHexCode(0xFF000000)), + path: .root + "0", + layoutDirection: .leftToRight + ), + accessibilityElement: accessibility(label: "Description") + ), + ids: [] + ) + + assertEqual(block, expectedBlock) + } +} diff --git a/client/ios/DivKitTests/Utils/BlockModelingUtils.swift b/client/ios/DivKitTests/Utils/BlockModelingUtils.swift index ec164db23..fd568aedf 100644 --- a/client/ios/DivKitTests/Utils/BlockModelingUtils.swift +++ b/client/ios/DivKitTests/Utils/BlockModelingUtils.swift @@ -6,8 +6,11 @@ import Foundation import BaseUIPublic import CommonCorePublic -func makeBlock(_ div: Div) -> StateBlock { - try! divData(div).makeBlock(context: .default) as! StateBlock +func makeBlock( + _ div: Div, + context: DivBlockModelingContext = .default +) -> StateBlock { + try! divData(div).makeBlock(context: context) as! StateBlock } func separatorBlock() -> Block { diff --git a/client/ios/DivKitTests/Utils/DivBuilders.swift b/client/ios/DivKitTests/Utils/DivBuilders.swift index 5f1c669d6..6471bd56e 100644 --- a/client/ios/DivKitTests/Utils/DivBuilders.swift +++ b/client/ios/DivKitTests/Utils/DivBuilders.swift @@ -36,6 +36,16 @@ func divGifImage( )) } +func divInput( + accessibility: DivAccessibility? = nil, + textVariable: String +) -> Div { + .divInput(DivInput( + accessibility: accessibility, + textVariable: textVariable + )) +} + func divImage( accessibility: DivAccessibility? = nil, height: DivSize? = nil, diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift b/client/ios/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift index b37983a53..23315679b 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift @@ -80,7 +80,7 @@ public final class TextInputBlock: BlockWithTraits { heightTrait: LayoutTrait = .intrinsic, hint: NSAttributedString, textValue: Binding, - rawTextValue: Binding?, + rawTextValue: Binding? = nil, textTypo: Typo, multiLineMode: Bool = true, inputType: InputType = .default, @@ -89,7 +89,7 @@ public final class TextInputBlock: BlockWithTraits { selectAllOnFocus: Bool = false, maskValidator: MaskValidator? = nil, path: UIElementPath, - isFocused: Bool, + isFocused: Bool = false, onFocusActions: [UserInterfaceAction] = [], onBlurActions: [UserInterfaceAction] = [], parentScrollView: ScrollView? = nil,