fix autocorrection for password type, add isSecure field

commit_hash:22c0a70edb259644142904b5165d370db94b7d33
This commit is contained in:
babaevmm
2025-03-13 12:17:45 +03:00
parent c4fe3712a9
commit 30b464733b
5 changed files with 108 additions and 64 deletions
@@ -89,7 +89,9 @@ extension DivInput: DivBlockModeling {
paddings: paddings?.resolve(context),
isEnabled: resolveIsEnabled(expressionResolver),
maxLength: resolveMaxLength(expressionResolver),
shouldClearFocus: shouldClearFocus
shouldClearFocus: shouldClearFocus,
autocorrection: keyboardType.autocorrection,
isSecure: keyboardType.isSecure
)
}
@@ -208,7 +210,7 @@ extension DivAlignmentVertical {
extension DivInput.KeyboardType {
fileprivate var system: TextInputBlock.InputType {
switch self {
case .singleLineText, .multiLineText:
case .singleLineText, .multiLineText, .password:
return .default
case .phone:
return .keyboard(.phonePad)
@@ -218,9 +220,34 @@ extension DivInput.KeyboardType {
return .keyboard(.emailAddress)
case .uri:
return .keyboard(.URL)
}
}
fileprivate var autocorrection: Bool {
switch self {
case .singleLineText,
.multiLineText:
true
case .phone,
.number,
.email,
.uri,
.password:
false
}
}
fileprivate var isSecure: Bool {
switch self {
case .password:
DivKitLogger.warning("Keyboard type '\(self.rawValue)' is not supported")
return .default
true
case .singleLineText,
.multiLineText,
.phone,
.number,
.email,
.uri:
false
}
}
}
@@ -18,19 +18,9 @@ final class DivInputExtensionsTests: XCTestCase {
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(0xFF_00_00_00)),
path: .root + "0",
layoutDirection: .leftToRight
),
accessibilityElement: accessibility(label: "Hello!")
),
ids: []
let expectedBlock = makeExpectedBlockBlock(
accessibilityElement: accessibility(label: "Hello!"),
context: context
)
assertEqual(block, expectedBlock)
@@ -45,21 +35,56 @@ final class DivInputExtensionsTests: XCTestCase {
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(0xFF_00_00_00)),
path: .root + "0",
layoutDirection: .leftToRight
),
accessibilityElement: accessibility(label: "Description")
let expectedBlock = makeExpectedBlockBlock(
accessibilityElement: accessibility(label: "Description"),
context: context
)
assertEqual(block, expectedBlock)
}
func test_WithPasswordType() {
let block = makeBlock(
divInput(
keyboardType: .password,
textVariable: "input_variable"
),
ids: []
context: context
)
let expectedBlock = makeExpectedBlockBlock(
autocorrection: false,
isSecure: true,
multilineMode: false,
context: context
)
assertEqual(block, expectedBlock)
}
}
private func makeExpectedBlockBlock(
accessibilityElement: AccessibilityElement? = nil,
autocorrection: Bool = true,
isSecure: Bool = false,
multilineMode: Bool = true,
context: DivBlockModelingContext
) -> StateBlock {
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(0xFF_00_00_00)),
multiLineMode: multilineMode,
path: .root + "0" + "input",
layoutDirection: .leftToRight,
autocorrection: autocorrection,
isSecure: isSecure
),
accessibilityElement: accessibilityElement ?? accessibility(label: "Hello!")
),
ids: []
)
}
@@ -69,10 +69,12 @@ func divGifImage(
func divInput(
accessibility: DivAccessibility? = nil,
keyboardType: DivInput.KeyboardType? = nil,
textVariable: String
) -> Div {
.divInput(DivInput(
accessibility: accessibility,
keyboardType: keyboardType.map { .value($0) },
textVariable: textVariable
))
}
@@ -8,17 +8,11 @@ public final class TextInputBlock: BlockWithTraits {
public enum InputType: Equatable {
public enum KeyboardType: Equatable {
case `default`
case asciiCapable
case numbersAndPunctuation
case URL
case numberPad
case phonePad
case namePhonePad
case emailAddress
case decimalPad
case twitter
case webSearch
case asciiCapableNumberPad
}
public struct SelectionItem: Equatable {
@@ -95,6 +89,8 @@ public final class TextInputBlock: BlockWithTraits {
public let paddings: EdgeInsets?
public let isEnabled: Bool
public let maxLength: Int?
public let autocorrection: Bool
public let isSecure: Bool
let shouldClearFocus: Variable<Bool>
@@ -128,7 +124,9 @@ public final class TextInputBlock: BlockWithTraits {
paddings: EdgeInsets? = nil,
isEnabled: Bool = true,
maxLength: Int? = nil,
shouldClearFocus: Variable<Bool> = .constant(true)
shouldClearFocus: Variable<Bool> = .constant(true),
autocorrection: Bool = false,
isSecure: Bool = false
) {
self.widthTrait = widthTrait
self.heightTrait = heightTrait
@@ -160,6 +158,8 @@ public final class TextInputBlock: BlockWithTraits {
self.isEnabled = isEnabled
self.maxLength = maxLength
self.shouldClearFocus = shouldClearFocus
self.autocorrection = autocorrection
self.isSecure = isSecure
}
public var intrinsicContentWidth: CGFloat {
@@ -240,6 +240,8 @@ extension TextInputBlock {
&& lhs.textTypo == rhs.textTypo
&& lhs.textValue.value == rhs.textValue.value
&& lhs.widthTrait == rhs.widthTrait
&& lhs.autocorrection == rhs.autocorrection
&& lhs.isSecure == rhs.isSecure
}
}
@@ -280,7 +282,9 @@ extension TextInputBlock: ElementFocusUpdating {
textAlignmentVertical: textAlignmentVertical,
paddings: paddings,
isEnabled: isEnabled,
maxLength: maxLength
maxLength: maxLength,
autocorrection: autocorrection,
isSecure: isSecure
)
}
}
@@ -14,6 +14,8 @@ extension TextInputBlock {
inputView.setLayoutDirection(layoutDirection)
inputView.setInputType(inputType)
inputView.setInputAccessoryView(accessoryView)
inputView.setAutocorrection(autocorrection)
inputView.setSecure(isSecure)
inputView.setAutocapitalizationType(autocapitalizationType)
inputView.setEnterKeyType(enterKeyType)
inputView.setValidators(validators)
@@ -195,9 +197,6 @@ private final class TextInputBlockView: BlockView, VisibleBoundsTrackingLeaf {
private func setKeyboardType(_ type: TextInputBlock.InputType.KeyboardType) {
multiLineInput.keyboardType = type.uiType
singleLineInput.keyboardType = type.uiType
singleLineInput.autocorrectionType = type.autoCorrectionType
multiLineInput.autocorrectionType = type.autoCorrectionType
}
func setInputAccessoryView(_ accessoryView: ViewType?) {
@@ -205,6 +204,17 @@ private final class TextInputBlockView: BlockView, VisibleBoundsTrackingLeaf {
singleLineInput.inputAccessoryView = accessoryView
}
func setAutocorrection(_ isEnabled: Bool) {
let uiType: UITextAutocorrectionType = isEnabled ? .yes : .no
multiLineInput.autocorrectionType = uiType
singleLineInput.autocorrectionType = uiType
}
func setSecure(_ isSecure: Bool) {
multiLineInput.isSecureTextEntry = isSecure
singleLineInput.isSecureTextEntry = isSecure
}
func setAutocapitalizationType(_ type: TextInputBlock.AutocapitalizationType) {
singleLineInput.autocapitalizationType = type.uiType
multiLineInput.autocapitalizationType = type.uiType
@@ -777,14 +787,8 @@ extension TextInputBlock.InputType.KeyboardType {
switch self {
case .default:
.default
case .asciiCapable:
.asciiCapable
case .numbersAndPunctuation:
.numbersAndPunctuation
case .URL:
.URL
case .numberPad:
.numberPad
case .phonePad:
.phonePad
case .namePhonePad:
@@ -793,24 +797,6 @@ extension TextInputBlock.InputType.KeyboardType {
.emailAddress
case .decimalPad:
.decimalPad
case .twitter:
.twitter
case .webSearch:
.webSearch
case .asciiCapableNumberPad:
.asciiCapableNumberPad
}
}
fileprivate var autoCorrectionType: UITextAutocorrectionType {
switch self {
case .URL, .webSearch, .twitter, .emailAddress:
return .no
case .default:
return .default
case .asciiCapable, .numbersAndPunctuation, .numberPad, .phonePad,
.namePhonePad, .decimalPad, .asciiCapableNumberPad:
return .yes
}
}
}