From b489b36d9217ea83362f6318d8680438f164cf04 Mon Sep 17 00:00:00 2001 From: booster Date: Thu, 17 Jul 2025 17:25:25 +0300 Subject: [PATCH] Fixed file path in precommit hook commit_hash:f7df7bc7f68f49dd4b005691712d8784e092107e --- .../UpdateStructureActionHandler.swift | 33 +++-- client/ios/DivKit/DivBlockStateStorage.swift | 9 +- client/ios/DivKit/DivImageHolderFactory.swift | 3 +- .../CalcExpression/CalcExpression.swift | 2 +- .../DivKit/Expressions/ExpressionLink.swift | 2 +- .../Expressions/ExpressionResolver.swift | 2 +- .../Expressions/Functions/DictFunctions.swift | 6 +- .../Expressions/FunctionsProvider.swift | 4 +- .../DivBase/DivBaseExtensions.swift | 16 ++- .../DivCollectionItemsBuilderExtensions.swift | 4 +- .../DivContainer/DivContainerExtensions.swift | 2 +- .../DivGallery/DivGalleryProtocol.swift | 3 +- .../DivKit/Extensions/DivGridExtensions.swift | 3 +- .../Extensions/DivTypedValueExtensions.swift | 6 +- .../DivDataResourcesPreloader.swift | 15 ++- .../ResourceDivExtensions.swift | 10 +- client/ios/DivKit/Types.swift | 5 +- .../DivKit/Variables/DivTriggersStorage.swift | 5 +- .../ios/DivKit/Views/DivBlockProvider.swift | 2 +- .../Lottie/LottieExtensionParams.swift | 25 ++-- .../ios/DivKitExtensions/DivExtensions.swift | 5 +- .../InputPropertiesExtensionHandler.swift | 2 +- .../Serialization+Extensions.swift | 2 +- .../InputExtensionHandlersTests.swift | 14 +-- .../LottieExtensionHandlerTests.swift | 22 ++-- .../ios/DivKitPlayground/AppComponents.swift | 9 +- .../DivKit/RiveContainerView.swift | 2 +- .../UI/DivView/DivViewController.swift | 4 +- .../Expressions/CustomFunctionTests.swift | 2 +- .../ExpressionResolverAnyTests.swift | 2 +- .../Expressions/ExpressionResolverTests.swift | 6 +- .../Expressions/ExpressionTests.swift | 10 +- ...ns+AccessibilityElementsStorageTests.swift | 2 +- .../Extensions/DivBaseExtensionsTests.swift | 2 +- .../DivContainerExtensionsTests.swift | 2 +- .../Extensions/DivDataExtensionsTests.swift | 2 +- .../Extensions/DivGridExtensionsTests.swift | 2 +- .../Extensions/DivInputExtentionsTests.swift | 2 +- .../DivSeparatorExtensionsTests.swift | 2 +- .../Extensions/DivStateExtensionsTests.swift | 2 +- .../Extensions/DivTextExtensionsTests.swift | 2 +- .../DivTooltipExtensionsTests.swift | 2 +- client/ios/DivKitTests/IntegrationTests.swift | 26 ++-- .../DivDataResourcesPreloaderTests.swift | 115 +++++++++--------- .../BlockModelingUtils.swift | 2 +- .../ios/DivKitTestsSupport/DivBuilders.swift | 5 +- .../MockURLResourceRequester.swift | 2 +- .../Base/Masks/PhoneMaskFormatter.swift | 8 +- .../Blocks/DetachableAnimationBlock.swift | 2 +- .../LayoutKit/Blocks/EmptyBlock.swift | 2 +- .../Slider/MarksConfigurationModel.swift | 4 +- .../LayoutKit/Blocks/Slider/MarksLayer.swift | 8 +- .../LayoutKit/Blocks/Slider/SliderModel.swift | 4 +- .../LayoutKit/Tooltips/TooltipManager.swift | 5 +- .../TextBlock+UIViewRenderableBlock.swift | 18 +-- ...TextInputBlock+UIViewRenderableBlock.swift | 22 ++-- .../Views/TabbedPages/TabContentsView.swift | 10 +- .../UI/Views/TabbedPages/TabListView.swift | 6 +- .../Views/TabbedPages/TabbedPagesView.swift | 2 +- .../DivKitSample/ContentView.swift | 2 +- 60 files changed, 278 insertions(+), 222 deletions(-) diff --git a/client/ios/DivKit/Actions/UpdateStructureActionHandler.swift b/client/ios/DivKit/Actions/UpdateStructureActionHandler.swift index d6a6b4e0b..272599ad8 100644 --- a/client/ios/DivKit/Actions/UpdateStructureActionHandler.swift +++ b/client/ios/DivKit/Actions/UpdateStructureActionHandler.swift @@ -16,9 +16,15 @@ final class UpdateStructureActionHandler { } let updatedValue: DivVariableValue? - if let dict: DivDictionary = context.variablesStorage.getVariableValue(path: context.path, name: divVariableName) { + if let dict: DivDictionary = context.variablesStorage.getVariableValue( + path: context.path, + name: divVariableName + ) { updatedValue = updateDictionary(dict, newValue: newValue, path: pathComponents) - } else if let array: DivArray = context.variablesStorage.getVariableValue(path: context.path, name: divVariableName) { + } else if let array: DivArray = context.variablesStorage.getVariableValue( + path: context.path, + name: divVariableName + ) { updatedValue = updateArray(array, newValue: newValue, path: pathComponents) } else { DivKitLogger.error("Action requires array or dictionary variable") @@ -106,9 +112,11 @@ private func updateElement( newValue: AnyHashable ) -> AnyHashable? { if let nestedArray = currentElement as? DivArray { - return updateArray(nestedArray, newValue: newValue, path: path, pathIndex: pathIndex)?.arrayValue + return updateArray(nestedArray, newValue: newValue, path: path, pathIndex: pathIndex)? + .arrayValue } else if let nestedDict = currentElement as? DivDictionary { - return updateDictionary(nestedDict, newValue: newValue, path: path, pathIndex: pathIndex)?.dictValue + return updateDictionary(nestedDict, newValue: newValue, path: path, pathIndex: pathIndex)? + .dictValue } else { DivKitLogger.error( "Element with path '\(path[0.. Element? { +extension Array { + fileprivate subscript(insert index: Int) -> Element? { get { (0.. ImageHolder { var localImage: ImageHolder? if url?.scheme == "divkit-asset", let name = url?.host { - //To restrict access to resources, all divkit asset images must start with the 'divkit.' prefix. + // To restrict access to resources, all divkit asset images must start with the 'divkit.' + // prefix. localImage = Image(named: "divkit.\(name)") } return localImage ?? imageHolderFactory.make(url, placeholder) diff --git a/client/ios/DivKit/Expressions/CalcExpression/CalcExpression.swift b/client/ios/DivKit/Expressions/CalcExpression/CalcExpression.swift index a14314d74..dcce930f3 100644 --- a/client/ios/DivKit/Expressions/CalcExpression/CalcExpression.swift +++ b/client/ios/DivKit/Expressions/CalcExpression/CalcExpression.swift @@ -50,7 +50,7 @@ struct CalcExpression { return nil } } - + func extractDynamicVariableNames(_ context: ExpressionContext) throws -> [String] { try root.extractDynamicVariableNames(context) } diff --git a/client/ios/DivKit/Expressions/ExpressionLink.swift b/client/ios/DivKit/Expressions/ExpressionLink.swift index 84d1e88de..e345a2efa 100644 --- a/client/ios/DivKit/Expressions/ExpressionLink.swift +++ b/client/ios/DivKit/Expressions/ExpressionLink.swift @@ -84,7 +84,7 @@ public struct ExpressionLink: Sendable { self.rawValue = rawValue self.validator = validator } - + func extractDynamicVariableNames(_ context: ExpressionContext) -> [String] { items.flatMap { item in switch item { diff --git a/client/ios/DivKit/Expressions/ExpressionResolver.swift b/client/ios/DivKit/Expressions/ExpressionResolver.swift index ba1c49688..f6e59f005 100644 --- a/client/ios/DivKit/Expressions/ExpressionResolver.swift +++ b/client/ios/DivKit/Expressions/ExpressionResolver.swift @@ -134,7 +134,7 @@ public final class ExpressionResolver { resolveNumeric(expression) } - func extractDynamicVariables(_ link: ExpressionLink) -> [String] { + func extractDynamicVariables(_ link: ExpressionLink) -> [String] { link.extractDynamicVariableNames(context) } diff --git a/client/ios/DivKit/Expressions/Functions/DictFunctions.swift b/client/ios/DivKit/Expressions/Functions/DictFunctions.swift index 24c5be663..e9dd2067d 100644 --- a/client/ios/DivKit/Expressions/Functions/DictFunctions.swift +++ b/client/ios/DivKit/Expressions/Functions/DictFunctions.swift @@ -26,9 +26,9 @@ extension [String: Function] { addFunctions("Url", _getUrl) addFunctions("OptUrl", _getOptUrl) - + addFunction("len", _len) - + addFunction("getDictKeys", _getDictKeys) addFunction("getDictValues", _getDictValues) } @@ -45,7 +45,7 @@ extension [String: Function] { addFunction("isEmpty", _isEmpty) addFunction("containsKey", _containsKey) - + addFunction("getKeys", _getDictKeys) addFunction("getValues", _getDictValues) } diff --git a/client/ios/DivKit/Expressions/FunctionsProvider.swift b/client/ios/DivKit/Expressions/FunctionsProvider.swift index c94341dc0..811bb1522 100644 --- a/client/ios/DivKit/Expressions/FunctionsProvider.swift +++ b/client/ios/DivKit/Expressions/FunctionsProvider.swift @@ -166,7 +166,7 @@ private struct FunctionEvaluator: Function { } private struct DynamicVariablesEvaluator: Function { - func invoke(_ args: [Any], context: ExpressionContext) throws -> Any { + func invoke(_ args: [Any], context _: ExpressionContext) throws -> Any { guard let arg = args.first else { throw ExpressionError("There is no arguments in getValueFunction") } @@ -221,5 +221,5 @@ private let getValueFunctions = [ "getIntegerValue", "getNumberValue", "getStringValue", - "getUrlValue" + "getUrlValue", ] diff --git a/client/ios/DivKit/Extensions/DivBase/DivBaseExtensions.swift b/client/ios/DivKit/Extensions/DivBase/DivBaseExtensions.swift index 4d238dc75..526b6e320 100644 --- a/client/ios/DivKit/Extensions/DivBase/DivBaseExtensions.swift +++ b/client/ios/DivKit/Extensions/DivBase/DivBaseExtensions.swift @@ -130,8 +130,8 @@ extension DivBase { return blockActions } - - func setupContextWithVariablesAndFunctions( + + func setupContextWithVariablesAndFunctions( context: DivBlockModelingContext ) { context.functionsStorage?.setIfNeeded( @@ -245,9 +245,17 @@ extension Block { for extensionHandler in extensionHandlers { switch order { case .beforeBaseProperties: - newBlock = extensionHandler.applyBeforeBaseProperties(to: newBlock, div: div, context: context) + newBlock = extensionHandler.applyBeforeBaseProperties( + to: newBlock, + div: div, + context: context + ) case .afterBaseProperties: - newBlock = extensionHandler.applyAfterBaseProperties(to: newBlock, div: div, context: context) + newBlock = extensionHandler.applyAfterBaseProperties( + to: newBlock, + div: div, + context: context + ) } } return newBlock diff --git a/client/ios/DivKit/Extensions/DivContainer/DivCollectionItemsBuilderExtensions.swift b/client/ios/DivKit/Extensions/DivContainer/DivCollectionItemsBuilderExtensions.swift index c851adfb5..bb6e01b89 100644 --- a/client/ios/DivKit/Extensions/DivContainer/DivCollectionItemsBuilderExtensions.swift +++ b/client/ios/DivKit/Extensions/DivContainer/DivCollectionItemsBuilderExtensions.swift @@ -6,7 +6,7 @@ extension DivCollectionItemBuilder { context: DivBlockModelingContext, mappedBy modificator: (Div, Block, DivBlockModelingContext) -> T ) -> [T] { - makeItemDivAndContexts(context: context).compactMap { (div, itemContext) in + makeItemDivAndContexts(context: context).compactMap { div, itemContext in do { return try modifyError({ DivBlockModelingError($0.message, path: itemContext.path) @@ -20,7 +20,7 @@ extension DivCollectionItemBuilder { } } } - + func makeItemDivAndContexts( context: DivBlockModelingContext ) -> [(Div, DivBlockModelingContext)] { diff --git a/client/ios/DivKit/Extensions/DivContainer/DivContainerExtensions.swift b/client/ios/DivKit/Extensions/DivContainer/DivContainerExtensions.swift index f0c8037f4..644a42394 100644 --- a/client/ios/DivKit/Extensions/DivContainer/DivContainerExtensions.swift +++ b/client/ios/DivKit/Extensions/DivContainer/DivContainerExtensions.swift @@ -230,7 +230,7 @@ extension DivContainer.Orientation { extension DivAlignmentHorizontal { func alignment(isRTLLayout: Bool) -> Alignment { switch self { - case .left: + case .left: isRTLLayout ? .trailing : .leading case .right: isRTLLayout ? .leading : .trailing diff --git a/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift b/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift index 7d9974acf..f2604ee9c 100644 --- a/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift +++ b/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift @@ -34,7 +34,8 @@ extension DivGalleryProtocol { crossAlignment: ( direction.isHorizontal ? div.value.resolveAlignmentVertical(expressionResolver)?.alignment - : div.value.resolveAlignmentHorizontal(expressionResolver)?.alignment(isRTLLayout: context.layoutDirection == .rightToLeft) + : div.value.resolveAlignmentHorizontal(expressionResolver)? + .alignment(isRTLLayout: context.layoutDirection == .rightToLeft) ) ?? defaultCrossAlignment, content: block ) diff --git a/client/ios/DivKit/Extensions/DivGridExtensions.swift b/client/ios/DivKit/Extensions/DivGridExtensions.swift index 3691617b9..9fd92e5f0 100644 --- a/client/ios/DivKit/Extensions/DivGridExtensions.swift +++ b/client/ios/DivKit/Extensions/DivGridExtensions.swift @@ -66,7 +66,8 @@ extension DivGrid: DivBlockModeling { isRTLLayout: Bool ) -> BlockAlignment2D { BlockAlignment2D( - horizontal: resolveContentAlignmentHorizontal(expressionResolver).alignment(isRTLLayout: isRTLLayout), + horizontal: resolveContentAlignmentHorizontal(expressionResolver) + .alignment(isRTLLayout: isRTLLayout), vertical: resolveContentAlignmentVertical(expressionResolver).alignment ) } diff --git a/client/ios/DivKit/Extensions/DivTypedValueExtensions.swift b/client/ios/DivKit/Extensions/DivTypedValueExtensions.swift index d44f62151..dd80e6d06 100644 --- a/client/ios/DivKit/Extensions/DivTypedValueExtensions.swift +++ b/client/ios/DivKit/Extensions/DivTypedValueExtensions.swift @@ -70,9 +70,9 @@ extension DivTypedValue { } return nil case let .dictValue(value): - if let dictValue = value.resolveValue(expressionResolver) { - return DivDictionary.fromAny(dictValue) - } + if let dictValue = value.resolveValue(expressionResolver) { + return DivDictionary.fromAny(dictValue) + } return nil case let .integerValue(value): if let integerValue = value.resolveValue(expressionResolver) { diff --git a/client/ios/DivKit/ResourcesPreloader/DivDataResourcesPreloader.swift b/client/ios/DivKit/ResourcesPreloader/DivDataResourcesPreloader.swift index c995f5916..3e8005221 100644 --- a/client/ios/DivKit/ResourcesPreloader/DivDataResourcesPreloader.swift +++ b/client/ios/DivKit/ResourcesPreloader/DivDataResourcesPreloader.swift @@ -6,7 +6,6 @@ public enum ResourcePreloadFilter { } public final class DivDataResourcesPreloader { - private let resourceRequester: URLResourceRequesting public init( @@ -25,13 +24,13 @@ public final class DivDataResourcesPreloader { let validURLs = divData.flatMap( { let extensionURLs = $0.makeExtensionPreloadURLs( - extensionHandlers: extensionHandlers, + extensionHandlers: extensionHandlers, expressionResolver: $1.expressionResolver ) let imageURLs = $0.makeImageURLs(with: $1.expressionResolver, filter: filter) let videoURLs = $0.makeVideoURLs(with: $1.expressionResolver, filter: filter) return extensionURLs + imageURLs + videoURLs - }, + }, context: context ) .flatMap { $0 } @@ -62,11 +61,11 @@ public final class DivDataResourcesPreloader { extension DivData { fileprivate func flatMap( - _ transform: (Div, DivBlockModelingContext) -> T, + _ transform: (Div, DivBlockModelingContext) -> T, context: DivBlockModelingContext ) -> [T] { var result: [T] = [] - + context.functionsStorage?.setIfNeeded( path: context.path, functions: functions ?? [] @@ -76,17 +75,17 @@ extension DivData { path: context.path, variables: variables?.extractDivVariableValues(context.expressionResolver) ?? [:] ) - + func traverse(div: Div, divContext: DivBlockModelingContext) { div.value.setupContextWithVariablesAndFunctions(context: divContext) result.append(transform(div, divContext)) - + if let container = div.value as? DivContainer, let itemBuilder = container.itemBuilder { itemBuilder.makeItemDivAndContexts(context: divContext).forEach { div, itemContext in traverse(div: div, divContext: itemContext) } } - + div.children.forEach { let childContext = $0.value.modifiedContextParentPath(divContext) traverse(div: $0, divContext: childContext) diff --git a/client/ios/DivKit/ResourcesPreloader/ResourceDivExtensions.swift b/client/ios/DivKit/ResourcesPreloader/ResourceDivExtensions.swift index 84daa02b1..dfe0713d0 100644 --- a/client/ios/DivKit/ResourcesPreloader/ResourceDivExtensions.swift +++ b/client/ios/DivKit/ResourcesPreloader/ResourceDivExtensions.swift @@ -68,14 +68,14 @@ extension Div { [] } } - + func makeExtensionPreloadURLs( - extensionHandlers: [String : DivExtensionHandler], + extensionHandlers: [String: DivExtensionHandler], expressionResolver: ExpressionResolver ) -> [URL] { - guard !extensionHandlers.isEmpty else { return [] } - return value.extensions?.compactMap { - extensionHandlers[$0.id]?.getPreloadURLs(div: value, expressionResolver: expressionResolver) + guard !extensionHandlers.isEmpty else { return [] } + return value.extensions?.compactMap { + extensionHandlers[$0.id]?.getPreloadURLs(div: value, expressionResolver: expressionResolver) }.flatMap { $0 } ?? [] } } diff --git a/client/ios/DivKit/Types.swift b/client/ios/DivKit/Types.swift index ad05e59d3..69507a9cc 100644 --- a/client/ios/DivKit/Types.swift +++ b/client/ios/DivKit/Types.swift @@ -11,10 +11,10 @@ extension DivArray { extension DivArray { func isEqualUnordered(_ other: DivArray?) -> Bool { guard let other, - self.count == other.count else { + self.count == other.count else { return false } - + return self.countElements() == other.countElements() } } @@ -26,4 +26,3 @@ extension DivDictionary { NSDictionary(dictionary: value) as? DivDictionary } } - diff --git a/client/ios/DivKit/Variables/DivTriggersStorage.swift b/client/ios/DivKit/Variables/DivTriggersStorage.swift index 7abefa4f2..23a4ff9f8 100644 --- a/client/ios/DivKit/Variables/DivTriggersStorage.swift +++ b/client/ios/DivKit/Variables/DivTriggersStorage.swift @@ -260,7 +260,10 @@ extension Expression { fileprivate func getVariablesNames(_ resolver: ExpressionResolver) -> Set { switch self { case let .link(link): - let dynamicNames = Set(resolver.extractDynamicVariables(link).map(DivVariableName.init(rawValue:))) + let dynamicNames = Set( + resolver.extractDynamicVariables(link) + .map(DivVariableName.init(rawValue:)) + ) let staticNames = Set(link.variablesNames.map(DivVariableName.init(rawValue:))) return staticNames.union(dynamicNames) case .value: diff --git a/client/ios/DivKit/Views/DivBlockProvider.swift b/client/ios/DivKit/Views/DivBlockProvider.swift index baa63bddd..36f498045 100644 --- a/client/ios/DivKit/Views/DivBlockProvider.swift +++ b/client/ios/DivKit/Views/DivBlockProvider.swift @@ -173,7 +173,7 @@ final class DivBlockProvider { self.divData = nil return } - + if let resourcesPreloader = divKitComponents.resourcesPreloader { resourcesPreloader.downloadResources( for: divData, diff --git a/client/ios/DivKitExtensions/Animations/Lottie/LottieExtensionParams.swift b/client/ios/DivKitExtensions/Animations/Lottie/LottieExtensionParams.swift index 60841dea3..ab14ba2fe 100644 --- a/client/ios/DivKitExtensions/Animations/Lottie/LottieExtensionParams.swift +++ b/client/ios/DivKitExtensions/Animations/Lottie/LottieExtensionParams.swift @@ -1,6 +1,6 @@ import DivKit -import LayoutKitInterface import Foundation +import LayoutKitInterface import VGSL struct LottieExtensionParams { @@ -34,15 +34,24 @@ struct LottieExtensionParams { return nil } - self.repeatCount = (try? paramsDictionary.getOptionalFloat("repeat_count", expressionResolver: expressionResolver)).map(Float.init) + self + .repeatCount = ( + try? paramsDictionary + .getOptionalFloat("repeat_count", expressionResolver: expressionResolver) + ).map(Float.init) ?? Defaults.defaultRepeatCount self.repeatMode = (paramsDictionary["repeat_mode"] as? String) - .flatMap(expressionResolver.resolveString) - .flatMap(AnimationRepeatMode.init) - ?? Defaults.defaultRepeatMode + .flatMap(expressionResolver.resolveString) + .flatMap(AnimationRepeatMode.init) + ?? Defaults.defaultRepeatMode - self.isPlaying = (try? paramsDictionary.getOptionalBool("is_playing", expressionResolver: expressionResolver)) ?? Defaults.defaultIsPlaying + self + .isPlaying = ( + try? paramsDictionary + .getOptionalBool("is_playing", expressionResolver: expressionResolver) + ) ?? Defaults + .defaultIsPlaying } init(source: Source, repeatCount: Float, repeatMode: AnimationRepeatMode, isPlaying: Bool) { @@ -53,8 +62,8 @@ struct LottieExtensionParams { } } -private extension AnimationRepeatMode { - init?(repeatModeString: String) { +extension AnimationRepeatMode { + fileprivate init?(repeatModeString: String) { switch repeatModeString { case "reverse": self = .reverse diff --git a/client/ios/DivKitExtensions/DivExtensions.swift b/client/ios/DivKitExtensions/DivExtensions.swift index abe1d232c..461544235 100644 --- a/client/ios/DivKitExtensions/DivExtensions.swift +++ b/client/ios/DivKitExtensions/DivExtensions.swift @@ -7,7 +7,10 @@ extension Div { var urls: [URL] = value.background?.compactMap { $0.resolveImageURL(expressionResolver) } ?? [] - if let url = LottieExtensionHandler.getPreloadURL(div: value, expressionResolver: expressionResolver) { + if let url = LottieExtensionHandler.getPreloadURL( + div: value, + expressionResolver: expressionResolver + ) { urls.append(url) } switch self { diff --git a/client/ios/DivKitExtensions/ExtensionHandlers/InputPropertiesExtensionHandler.swift b/client/ios/DivKitExtensions/ExtensionHandlers/InputPropertiesExtensionHandler.swift index 3a8f4bf28..a77def2f6 100644 --- a/client/ios/DivKitExtensions/ExtensionHandlers/InputPropertiesExtensionHandler.swift +++ b/client/ios/DivKitExtensions/ExtensionHandlers/InputPropertiesExtensionHandler.swift @@ -17,7 +17,7 @@ public final class InputPropertiesExtensionHandler: DivExtensionHandler { } let params = getExtensionParams(div) - + var newBlock = textInputBlock if let enablesReturnKeyAutomatically = try? params.getOptionalBool( diff --git a/client/ios/DivKitExtensions/Serialization+Extensions.swift b/client/ios/DivKitExtensions/Serialization+Extensions.swift index ca8038488..c0334b5d2 100644 --- a/client/ios/DivKitExtensions/Serialization+Extensions.swift +++ b/client/ios/DivKitExtensions/Serialization+Extensions.swift @@ -16,7 +16,7 @@ extension Dictionary where Key == String { } return result } - + func getOptionalFloat( _ key: Key, expressionResolver: ExpressionResolver diff --git a/client/ios/DivKitExtensionsTests/InputExtensionHandlersTests.swift b/client/ios/DivKitExtensionsTests/InputExtensionHandlersTests.swift index 26d5334da..fae12a6c7 100644 --- a/client/ios/DivKitExtensionsTests/InputExtensionHandlersTests.swift +++ b/client/ios/DivKitExtensionsTests/InputExtensionHandlersTests.swift @@ -1,24 +1,24 @@ @testable import DivKit -@testable import LayoutKit @testable import DivKitExtensions import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest final class InputExtensionHandlersTests: 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_ApplyAllExtensionsToTextInput() throws { let contextWithExtensions = DivBlockModelingContext( extensionHandlers: [ InputPropertiesExtensionHandler(), - InputAutocorrectionExtensionHandler() + InputAutocorrectionExtensionHandler(), ], variableStorage: variableStorage ) @@ -30,15 +30,15 @@ final class InputExtensionHandlersTests: XCTestCase { id: "input_properties", params: [ "enables_return_key_automatically": true, - "spell_checking": true + "spell_checking": true, ] ), DivExtension( id: "input_autocorrection", params: [ - "enabled": true + "enabled": true, ] - ) + ), ], textVariable: "input_variable" ), diff --git a/client/ios/DivKitExtensionsTests/LottieExtensionHandlerTests.swift b/client/ios/DivKitExtensionsTests/LottieExtensionHandlerTests.swift index fa8900157..ebda79873 100644 --- a/client/ios/DivKitExtensionsTests/LottieExtensionHandlerTests.swift +++ b/client/ios/DivKitExtensionsTests/LottieExtensionHandlerTests.swift @@ -1,7 +1,7 @@ @testable import DivKit @testable import DivKitExtensions -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest @@ -13,7 +13,7 @@ final class LottieExtensionHandlerTests: XCTestCase { factory: factory, requester: requester ) - + func test_getPreloadURLs() { let lottieURLString = "https://example.com/DivGif9.json" let divWithExtension = divContainer( @@ -24,9 +24,9 @@ final class LottieExtensionHandlerTests: XCTestCase { params: [ "lottie_url": lottieURLString, "repeat_count": 2, - "repeat_mode": "reverse" + "repeat_mode": "reverse", ] - ) + ), ], items: [] ) @@ -61,9 +61,9 @@ final class LottieExtensionHandlerTests: XCTestCase { params: [ "lottie_url": "@{lottie_url}", "repeat_count": "@{repeat_count}", - "repeat_mode": "@{repeat_mode}" + "repeat_mode": "@{repeat_mode}", ] - ) + ), ], items: [] ), @@ -85,8 +85,8 @@ final class LottieExtensionHandlerTests: XCTestCase { private final class MockLottieAnimationFactory: AsyncSourceAnimatableViewFactory { var returnView = MockAnimatableView(frame: .zero) - func createAsyncSourceAnimatableView(withMode mode: AnimationRepeatMode, repeatCount count: Float) - -> AsyncSourceAnimatableView { + func createAsyncSourceAnimatableView(withMode _: AnimationRepeatMode, repeatCount _: Float) + -> AsyncSourceAnimatableView { returnView } } @@ -94,13 +94,13 @@ private final class MockLottieAnimationFactory: AsyncSourceAnimatableViewFactory private final class MockAnimatableView: UIView, AsyncSourceAnimatableView { var playCallsCount = 0 var receivedSources: [any DivKitExtensions.AnimationSourceType] = [] - + func play() { playCallsCount += 1 } - + func pause() {} - + func setSourceAsync(_ source: any DivKitExtensions.AnimationSourceType) async { receivedSources.append(source) } diff --git a/client/ios/DivKitPlayground/AppComponents.swift b/client/ios/DivKitPlayground/AppComponents.swift index 264aff6ee..5a4053855 100644 --- a/client/ios/DivKitPlayground/AppComponents.swift +++ b/client/ios/DivKitPlayground/AppComponents.swift @@ -84,10 +84,10 @@ private func makeCachingPlayerFactory(requester: URLResourceRequesting) -> Playe private func makeResourcesPreloader( requestPerformer: URLRequestPerforming? ) -> DivDataResourcesPreloader? { - guard let requestPerformer = requestPerformer else { + guard let requestPerformer else { return nil } - + let cacheQueue = OperationQueue.serialQueue( name: "divkit.resources-preloader.cache-queue", qos: .utility @@ -100,7 +100,10 @@ private func makeResourcesPreloader( reportError: { _ in } ) let networkRequester = NetworkURLResourceRequester(performer: requestPerformer) - let cachedRequester = CachedURLResourceRequester(cache: diskCache, cachemissRequester: networkRequester) + let cachedRequester = CachedURLResourceRequester( + cache: diskCache, + cachemissRequester: networkRequester + ) return DivDataResourcesPreloader(resourceRequester: cachedRequester) } diff --git a/client/ios/DivKitPlayground/DivKit/RiveContainerView.swift b/client/ios/DivKitPlayground/DivKit/RiveContainerView.swift index 6db4c0db2..45efddfa0 100644 --- a/client/ios/DivKitPlayground/DivKit/RiveContainerView.swift +++ b/client/ios/DivKitPlayground/DivKit/RiveContainerView.swift @@ -70,7 +70,7 @@ extension RiveContainerView: AsyncSourceAnimatableView { func play() { riveViewModel?.play(loop: loop) } - + func pause() { riveViewModel?.pause() } diff --git a/client/ios/DivKitPlayground/UI/DivView/DivViewController.swift b/client/ios/DivKitPlayground/UI/DivView/DivViewController.swift index 39d8c2421..6ebeab89e 100644 --- a/client/ios/DivKitPlayground/UI/DivView/DivViewController.swift +++ b/client/ios/DivKitPlayground/UI/DivView/DivViewController.swift @@ -8,7 +8,7 @@ open class DivViewController: UIViewController { private let divKitComponents: DivKitComponents private let debugParams: DebugParams private var divView: DivView? - + private let scrollView = VisibilityTrackingScrollView() private var cancellables = Set() @@ -65,7 +65,7 @@ open class DivViewController: UIViewController { divView.setParentScrollView(scrollView) divView.accessibilityIdentifier = identifier - + return divView } diff --git a/client/ios/DivKitTests/Expressions/CustomFunctionTests.swift b/client/ios/DivKitTests/Expressions/CustomFunctionTests.swift index 9870f9767..08d7588b8 100644 --- a/client/ios/DivKitTests/Expressions/CustomFunctionTests.swift +++ b/client/ios/DivKitTests/Expressions/CustomFunctionTests.swift @@ -1,7 +1,7 @@ @testable @_spi(Internal) import DivKit +import DivKitTestsSupport @testable import LayoutKit import XCTest -import DivKitTestsSupport final class CustomFunctionTests: XCTestCase { private let incrementFunction = DivFunction( diff --git a/client/ios/DivKitTests/Expressions/ExpressionResolverAnyTests.swift b/client/ios/DivKitTests/Expressions/ExpressionResolverAnyTests.swift index c1c6e29b5..7a2b1c909 100644 --- a/client/ios/DivKitTests/Expressions/ExpressionResolverAnyTests.swift +++ b/client/ios/DivKitTests/Expressions/ExpressionResolverAnyTests.swift @@ -5,7 +5,7 @@ import XCTest final class ExpressionResolverAnyTests: XCTestCase { private var isErrorExpected = false - private var error: String? = nil + private var error: String? private var variables: DivVariables = [:] diff --git a/client/ios/DivKitTests/Expressions/ExpressionResolverTests.swift b/client/ios/DivKitTests/Expressions/ExpressionResolverTests.swift index 01817823d..26e07cfd4 100644 --- a/client/ios/DivKitTests/Expressions/ExpressionResolverTests.swift +++ b/client/ios/DivKitTests/Expressions/ExpressionResolverTests.swift @@ -535,7 +535,8 @@ final class ExpressionResolverTests: XCTestCase { } func test_extractDynamicVariables_WithNestedGetValueFunctionsAndUnknownVars() { - let expression = "@{getStringValue('outer_var_' + getStringValue('inner_var_' + string_var, ''), '')}" + let expression = + "@{getStringValue('outer_var_' + getStringValue('inner_var_' + string_var, ''), '')}" XCTAssertEqual( expressionResolver.extractDynamicVariables( @@ -546,7 +547,8 @@ final class ExpressionResolverTests: XCTestCase { } func test_extractDynamicVariables_WithGetValueFunctionsWithFallbackValue() { - let expression = "@{getStringValue('outer_var_' + getStringValue('inner_var_' + string_var, 'value'), '')}" + let expression = + "@{getStringValue('outer_var_' + getStringValue('inner_var_' + string_var, 'value'), '')}" XCTAssertEqual( expressionResolver.extractDynamicVariables( diff --git a/client/ios/DivKitTests/Expressions/ExpressionTests.swift b/client/ios/DivKitTests/Expressions/ExpressionTests.swift index 8db1d2d39..fb6194e02 100644 --- a/client/ios/DivKitTests/Expressions/ExpressionTests.swift +++ b/client/ios/DivKitTests/Expressions/ExpressionTests.swift @@ -168,12 +168,12 @@ private struct ExpressionTestCase: Decodable { } extension ExpressionTestCase: Hashable { - static func == (lhs: ExpressionTestCase, rhs: ExpressionTestCase) -> Bool { - return lhs.expression == rhs.expression && - lhs.variables == rhs.variables && - lhs.expected.description == rhs.expected.description + static func ==(lhs: ExpressionTestCase, rhs: ExpressionTestCase) -> Bool { + lhs.expression == rhs.expression && + lhs.variables == rhs.variables && + lhs.expected.description == rhs.expected.description } - + func hash(into hasher: inout Hasher) { hasher.combine(expression) hasher.combine(variables) diff --git a/client/ios/DivKitTests/Extensions/DivBaseExtensions+AccessibilityElementsStorageTests.swift b/client/ios/DivKitTests/Extensions/DivBaseExtensions+AccessibilityElementsStorageTests.swift index 1a8aefa69..fb1af4b5c 100644 --- a/client/ios/DivKitTests/Extensions/DivBaseExtensions+AccessibilityElementsStorageTests.swift +++ b/client/ios/DivKitTests/Extensions/DivBaseExtensions+AccessibilityElementsStorageTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import Testing import UIKit import VGSL diff --git a/client/ios/DivKitTests/Extensions/DivBaseExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivBaseExtensionsTests.swift index 76a548105..e76550ab6 100644 --- a/client/ios/DivKitTests/Extensions/DivBaseExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivBaseExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest diff --git a/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift index 5591f3dc4..4fa5ada31 100644 --- a/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivContainerExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import XCTest final class DivContainerExtensionsTests: XCTestCase { diff --git a/client/ios/DivKitTests/Extensions/DivDataExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivDataExtensionsTests.swift index 4d20bd5b3..9a3d929f1 100644 --- a/client/ios/DivKitTests/Extensions/DivDataExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivDataExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import XCTest final class DivDataExtensionsTests: XCTestCase { diff --git a/client/ios/DivKitTests/Extensions/DivGridExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivGridExtensionsTests.swift index d5224512f..8bf2f87af 100644 --- a/client/ios/DivKitTests/Extensions/DivGridExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivGridExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest diff --git a/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift b/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift index 3d9d2d861..b6b3ff4fd 100644 --- a/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivInputExtentionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest diff --git a/client/ios/DivKitTests/Extensions/DivSeparatorExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivSeparatorExtensionsTests.swift index d70649152..dd14c21bb 100644 --- a/client/ios/DivKitTests/Extensions/DivSeparatorExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivSeparatorExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import XCTest final class DivSeparatorExtensionsTests: XCTestCase { diff --git a/client/ios/DivKitTests/Extensions/DivStateExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivStateExtensionsTests.swift index 074af74e2..63a6b4d42 100644 --- a/client/ios/DivKitTests/Extensions/DivStateExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivStateExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import XCTest final class DivStateExtensionsTests: XCTestCase { diff --git a/client/ios/DivKitTests/Extensions/DivTextExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivTextExtensionsTests.swift index b9c1797a8..dd06c5648 100644 --- a/client/ios/DivKitTests/Extensions/DivTextExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivTextExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest diff --git a/client/ios/DivKitTests/Extensions/DivTooltipExtensionsTests.swift b/client/ios/DivKitTests/Extensions/DivTooltipExtensionsTests.swift index 33d1b3b57..529ca36f2 100644 --- a/client/ios/DivKitTests/Extensions/DivTooltipExtensionsTests.swift +++ b/client/ios/DivKitTests/Extensions/DivTooltipExtensionsTests.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import DivKitTestsSupport +@testable import LayoutKit import VGSL import XCTest diff --git a/client/ios/DivKitTests/IntegrationTests.swift b/client/ios/DivKitTests/IntegrationTests.swift index 8dd41adfe..6e36f44c4 100644 --- a/client/ios/DivKitTests/IntegrationTests.swift +++ b/client/ios/DivKitTests/IntegrationTests.swift @@ -75,8 +75,12 @@ private func runTest(_ testData: IntegrationTestData) async { cardId: cardId, name: DivVariableName(rawValue: name) ) - if case .unorderedArray(let expectedArray) = value { - let variableArray: DivArray? = if case .array(let arr) = variableValue { arr } else { nil } + if case let .unorderedArray(expectedArray) = value { + let variableArray: DivArray? = if case let .array(arr) = variableValue { + arr + } else { + nil + } XCTAssertTrue( expectedArray.isEqualUnordered(variableArray), "Variable name - '\(name)'" @@ -266,23 +270,23 @@ extension [Expected] { private func makeDefault(_ value: ExpectedValue) -> DivVariableValue? { switch value { case .string, .datetime: - .string("") + .string("") case .integer: - .integer(0) + .integer(0) case .double: - .number(0.0) + .number(0.0) case .bool: - .bool(false) + .bool(false) case .color: - .color(.black) + .color(.black) case .url: - .url(URL(string: "empty://")!) + .url(URL(string: "empty://")!) case .array: - .array([]) + .array([]) case .dict: - .dict([:]) + .dict([:]) case .unorderedArray: - .array([]) + .array([]) case .error: nil } diff --git a/client/ios/DivKitTests/ResourcesPreloader/DivDataResourcesPreloaderTests.swift b/client/ios/DivKitTests/ResourcesPreloader/DivDataResourcesPreloaderTests.swift index 2be35b79f..ee52ce6ad 100644 --- a/client/ios/DivKitTests/ResourcesPreloader/DivDataResourcesPreloaderTests.swift +++ b/client/ios/DivKitTests/ResourcesPreloader/DivDataResourcesPreloaderTests.swift @@ -105,7 +105,7 @@ final class DivDataResourcesPreloaderTests: XCTestCase { let context = DivBlockModelingContext( extensionHandlers: [ mockExtensionHandler, - invalidExtensionHandler + invalidExtensionHandler, ] ) @@ -127,90 +127,95 @@ final class DivDataResourcesPreloaderTests: XCTestCase { let divData = divData(divWithExtension) downloadResourcesAndWait( - for: divData, + for: divData, using: preloader, context: context ) XCTAssertEqual(mockRequester.requestedURLs, [mockExtensionHandler.preloadURL]) } - + func test_WhenContainerHasNestedItemBuilders_WithAllFilter_PreloadsAllResources() { let divData = createDivDataWithNestedItemBuilders() - + downloadResourcesAndWait(for: divData, using: preloader) - + XCTAssertEqual( - Set(mockRequester.requestedURLs.map { $0.absoluteString }), + Set(mockRequester.requestedURLs.map(\.absoluteString)), Set([requiredImageURL, optionalImageURL, validImageURL]) ) } - + func test_WhenItemBuilderUsesVariables_WithRequiredFilter_PreloadsOnlyRequiredResources() { let mockRequester = MockURLResourceRequester() mockRequester.shouldSucceed = true let preloader = DivDataResourcesPreloader(resourceRequester: mockRequester) - + let variableStorage = DivVariableStorage() variableStorage.put(name: "image_url_var", value: .url(URL(string: requiredImageURL)!)) variableStorage.put(name: "preload_required_var", value: .bool(true)) - + let context = DivBlockModelingContext(variableStorage: variableStorage) let divData = createDivDataWithVariables() - - downloadResourcesAndWait(for: divData, using: preloader, filter: .onlyRequired, context: context) - + + downloadResourcesAndWait( + for: divData, + using: preloader, + filter: .onlyRequired, + context: context + ) + XCTAssertEqual( - Set(mockRequester.requestedURLs.map { $0.absoluteString }), + Set(mockRequester.requestedURLs.map(\.absoluteString)), Set([requiredImageURL]) ) } - + func test_WhenContainerHasItemBuilder_WithRequiredFilter_OnlyDownloadsRequiredResources() { let divData = createDivDataWithMixedItemBuilderResources() - + downloadResourcesAndWait(for: divData, using: preloader, filter: .onlyRequired) - + XCTAssertEqual( - Set(mockRequester.requestedURLs.map { $0.absoluteString }), + Set(mockRequester.requestedURLs.map(\.absoluteString)), Set([requiredImageURL, requiredVideoURL]) ) } - + func test_WhenContainerHasItemBuilder_WithAllFilter_DownloadsAllResources() { let divData = createDivDataWithMixedItemBuilderResources() - + downloadResourcesAndWait(for: divData, using: preloader) - + XCTAssertEqual( - Set(mockRequester.requestedURLs.map { $0.absoluteString }), + Set(mockRequester.requestedURLs.map(\.absoluteString)), Set([requiredImageURL, optionalImageURL, requiredVideoURL, optionalVideoURL]) ) } - + func test_WhenDivDataHasVariables_WithRequiredFilter_PreloadsCorrectly() { let divData = createDivDataWithDivVariables() - + downloadResourcesAndWait(for: divData, using: preloader, filter: .onlyRequired) - + XCTAssertEqual( - Set(mockRequester.requestedURLs.map { $0.absoluteString }), + Set(mockRequester.requestedURLs.map(\.absoluteString)), Set([requiredImageURL]) ) } - + private func createDivDataWithDivVariables() -> DivData { let imageWithVariable = divImage( id: "image_with_variable", imageUrlExpression: "@{image_var}", preloadRequired: true ) - + let container = divContainer( id: "container_with_variables", items: [imageWithVariable] ) - + return DivData( functions: nil, logId: DivBlockModelingContext.testCardId.rawValue, @@ -219,11 +224,11 @@ final class DivDataResourcesPreloaderTests: XCTestCase { transitionAnimationSelector: nil, variableTriggers: nil, variables: [ - .urlVariable(UrlVariable(name: "image_var", value: .value(URL(string: requiredImageURL)!))) + .urlVariable(UrlVariable(name: "image_var", value: .value(URL(string: requiredImageURL)!))), ] ) } - + private func downloadResourcesAndWait( for divData: DivData, using preloader: DivDataResourcesPreloader, @@ -244,19 +249,19 @@ final class DivDataResourcesPreloaderTests: XCTestCase { } expectation.fulfill() } - + wait(for: [expectation], timeout: 1.0) } - + private func createDivDataWithNestedItemBuilders() -> DivData { let outerData: [Any] = [ ["type": "container", "items": [ ["url": requiredImageURL, "preload_required": true], - ["url": optionalImageURL, "preload_required": false] + ["url": optionalImageURL, "preload_required": false], ]], - ["type": "image", "url": validImageURL, "preload_required": true] + ["type": "image", "url": validImageURL, "preload_required": true], ] - + let innerImagePrototype = DivCollectionItemBuilder.Prototype( div: divImage( id: "inner_image", @@ -264,7 +269,7 @@ final class DivDataResourcesPreloaderTests: XCTestCase { preloadRequiredExpression: "@{getBooleanFromDict(item, 'preload_required')}" ) ) - + let innerItemBuilder = DivCollectionItemBuilder( data: .value(outerData.flatMap { item in guard let dict = item as? [String: Any], @@ -274,7 +279,7 @@ final class DivDataResourcesPreloaderTests: XCTestCase { dataElementName: "item", prototypes: [innerImagePrototype] ) - + let containerPrototype = DivCollectionItemBuilder.Prototype( div: divContainer( id: "container_from_item_builder", @@ -282,7 +287,7 @@ final class DivDataResourcesPreloaderTests: XCTestCase { ), selector: expression("@{getStringFromDict(item, 'type') == 'container'}") ) - + let imagePrototype = DivCollectionItemBuilder.Prototype( div: divImage( id: "image_from_item_builder", @@ -291,27 +296,27 @@ final class DivDataResourcesPreloaderTests: XCTestCase { ), selector: expression("@{getStringFromDict(item, 'type') == 'image'}") ) - + let outerItemBuilder = DivCollectionItemBuilder( data: .value(outerData), dataElementName: "item", prototypes: [containerPrototype, imagePrototype] ) - + let container = divContainer( id: "container_with_nested_item_builders", itemBuilder: outerItemBuilder ) - + return divData(container) } - + private func createDivDataWithVariables() -> DivData { let data: [Any] = [ ["type": "image", "use_variable": true], - ["type": "image", "url": optionalImageURL, "preload_required": false] + ["type": "image", "url": optionalImageURL, "preload_required": false], ] - + let variableImagePrototype = DivCollectionItemBuilder.Prototype( div: divImage( id: "image_with_variable", @@ -320,27 +325,27 @@ final class DivDataResourcesPreloaderTests: XCTestCase { ), selector: expression("@{getStringFromDict(item, 'type') == 'image'}") ) - + let itemBuilder = DivCollectionItemBuilder( data: .value(data), dataElementName: "item", prototypes: [variableImagePrototype] ) - + let container = divContainer( id: "container_with_variables", itemBuilder: itemBuilder ) - + return divData(container) } - + private func createDivDataWithMixedItemBuilderResources() -> DivData { let data: [[String: Any]] = [ ["type": "image", "url": requiredImageURL, "preload_required": true], ["type": "image", "url": optionalImageURL, "preload_required": false], ["type": "video", "url": requiredVideoURL, "preload_required": true], - ["type": "video", "url": optionalVideoURL, "preload_required": false] + ["type": "video", "url": optionalVideoURL, "preload_required": false], ] let imagePrototype = DivCollectionItemBuilder.Prototype( @@ -351,7 +356,7 @@ final class DivDataResourcesPreloaderTests: XCTestCase { ), selector: expression("@{getStringFromDict(it, 'type') == 'image'}") ) - + let videoPrototype = DivCollectionItemBuilder.Prototype( div: divVideo( id: "video_from_item_builder", @@ -359,23 +364,23 @@ final class DivDataResourcesPreloaderTests: XCTestCase { divVideoSource( mimeType: "video/mp4", urlExpression: "@{getStringFromDict(it, 'url')}" - ) + ), ], preloadRequiredExpression: "@{getBooleanFromDict(it, 'preload_required')}" ), selector: expression("@{getStringFromDict(it, 'type') == 'video'}") ) - + let itemBuilder = DivCollectionItemBuilder( data: .value(data), prototypes: [videoPrototype, imagePrototype] ) - + let container = divContainer( id: "container_with_item_builder", itemBuilder: itemBuilder ) - + return divData(container) } } @@ -566,7 +571,7 @@ private func createDivDataWithInvalidURLs() -> DivData { } private func testURL(_ path: String, domain: String = "example.com") -> String { - return "https://\(domain)/\(path)" + "https://\(domain)/\(path)" } private let requiredImageURL = testURL("required_image.jpg") diff --git a/client/ios/DivKitTestsSupport/BlockModelingUtils.swift b/client/ios/DivKitTestsSupport/BlockModelingUtils.swift index 63b37c6e1..009d69245 100644 --- a/client/ios/DivKitTestsSupport/BlockModelingUtils.swift +++ b/client/ios/DivKitTestsSupport/BlockModelingUtils.swift @@ -1,6 +1,6 @@ @testable import DivKit -@testable import LayoutKit import Foundation +@testable import LayoutKit import VGSL import XCTest diff --git a/client/ios/DivKitTestsSupport/DivBuilders.swift b/client/ios/DivKitTestsSupport/DivBuilders.swift index d93d72794..704dd9f11 100644 --- a/client/ios/DivKitTestsSupport/DivBuilders.swift +++ b/client/ios/DivKitTestsSupport/DivBuilders.swift @@ -101,7 +101,7 @@ public func divImage( } else { .value(url(imageUrl)) } - + let preloadRequiredValue: Expression? = if let preloadRequiredExpression { expression(preloadRequiredExpression) } else { @@ -575,7 +575,6 @@ public func variable(_ name: String, _ value: String) -> DivVariable { .stringVariable(StringVariable(name: name, value: .value(value))) } - public func solidBackground(_ color: RGBAColor) -> DivBackground { .divSolidBackground(DivSolidBackground(color: .value(color))) } @@ -591,7 +590,7 @@ public func divVideo( } else { preloadRequired.map { .value($0) } } - + return .divVideo(DivVideo( id: id, preloadRequired: preloadRequiredValue, diff --git a/client/ios/DivKitTestsSupport/MockURLResourceRequester.swift b/client/ios/DivKitTestsSupport/MockURLResourceRequester.swift index 33be79fd3..020828ab6 100644 --- a/client/ios/DivKitTestsSupport/MockURLResourceRequester.swift +++ b/client/ios/DivKitTestsSupport/MockURLResourceRequester.swift @@ -5,7 +5,7 @@ public final class MockURLResourceRequester: URLResourceRequesting { public var requestedURLs: [URL] = [] public var shouldSucceed = true public var customBehavior: ((URL) -> Bool)? - + public init() {} @MainActor diff --git a/client/ios/LayoutKit/LayoutKit/Base/Masks/PhoneMaskFormatter.swift b/client/ios/LayoutKit/LayoutKit/Base/Masks/PhoneMaskFormatter.swift index f1770e13c..9876afe7d 100644 --- a/client/ios/LayoutKit/LayoutKit/Base/Masks/PhoneMaskFormatter.swift +++ b/client/ios/LayoutKit/LayoutKit/Base/Masks/PhoneMaskFormatter.swift @@ -16,7 +16,7 @@ public final class PhoneMaskFormatter: MaskFormatter { var stringIndex = rawText.startIndex var newCursorPosition: CursorPosition? let mask = findMask(for: rawText) - + maskLoop: for element in mask { if element.isPlaceHolder { guard stringIndex < rawText.endIndex else { @@ -28,7 +28,7 @@ public final class PhoneMaskFormatter: MaskFormatter { break maskLoop } } - + text.append(rawText[stringIndex]) let textString = String(text) @@ -42,7 +42,7 @@ public final class PhoneMaskFormatter: MaskFormatter { text.append(element) } } - + let textString = String(text) if let rawCursorPosition { let cursorIndex = rawCursorPosition.cursorPosition.rawValue @@ -107,7 +107,7 @@ extension Character { fileprivate var isPlaceHolder: Bool { self == "0" } - + fileprivate var isHyphen: Bool { self == "-" } diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/DetachableAnimationBlock.swift b/client/ios/LayoutKit/LayoutKit/Blocks/DetachableAnimationBlock.swift index d14951d2b..953c668ec 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/DetachableAnimationBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/DetachableAnimationBlock.swift @@ -79,7 +79,7 @@ extension DetachableAnimationBlock: ElementStateUpdating { if updatedChild === child, animationIn == nil { return self } - + return Self( child: updatedChild, id: id, diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift b/client/ios/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift index f1ae953bb..03122399d 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift @@ -27,7 +27,7 @@ public final class EmptyBlock: BlockWithTraits { public var isEmpty: Bool { self == EmptyBlock.zeroSized } - + public func equals(_ other: Block) -> Bool { guard let other = other as? EmptyBlock else { return false diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksConfigurationModel.swift b/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksConfigurationModel.swift index 58baa06f8..d688d6000 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksConfigurationModel.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksConfigurationModel.swift @@ -7,7 +7,7 @@ public struct MarksConfigurationModel: Equatable { let activeMark: RoundedRectangle let inactiveMark: RoundedRectangle let layoutDirection: UserInterfaceLayoutDirection - + public init( minValue: CGFloat, maxValue: CGFloat, @@ -21,7 +21,7 @@ public struct MarksConfigurationModel: Equatable { self.inactiveMark = inactiveMark self.layoutDirection = layoutDirection } - + public static let empty = Self( minValue: 0, maxValue: 0, diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift b/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift index 405eeaa93..de7c0c53b 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift @@ -4,19 +4,19 @@ final class MarksLayer: CALayer { var firstThumbProgress: CGFloat = 0 var secondThumbProgress: CGFloat = 0 var configuration = MarksConfiguration.empty - + private var maxValue: CGFloat { configuration.modelConfiguration.maxValue } - + private var minValue: CGFloat { configuration.modelConfiguration.minValue } - + private var activeMark: MarksConfigurationModel.RoundedRectangle { configuration.modelConfiguration.activeMark } - + private var inactiveMark: MarksConfigurationModel.RoundedRectangle { configuration.modelConfiguration.inactiveMark } diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift b/client/ios/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift index eae442286..80f101cd9 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift @@ -99,7 +99,7 @@ public struct SliderModel: Equatable { public let layoutDirection: UserInterfaceLayoutDirection public let path: UIElementPath? public let isEnabled: Bool - + public var marksConfiguration: MarksConfiguration { MarksConfiguration( modelConfiguration: marksModelConfiguration, @@ -110,7 +110,7 @@ public struct SliderModel: Equatable { public var valueRange: Int { maxValue - minValue } - + private let marksModelConfiguration: MarksConfigurationModel public var sliderHeight: CGFloat { diff --git a/client/ios/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift b/client/ios/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift index a31501fc7..824ceeec8 100644 --- a/client/ios/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift +++ b/client/ios/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift @@ -196,8 +196,9 @@ public class DefaultTooltipManager: TooltipManager { guard tooltipWindowManager == nil else { return } let scenes = UIApplication.shared.connectedScenes - guard let windowScene = scenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene, - let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }) else { + guard let windowScene = scenes + .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene, + let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }) else { return } diff --git a/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift b/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift index 7afc84ba6..55c5c4d61 100644 --- a/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift @@ -123,7 +123,7 @@ private class GradientContainerView: UIView { private let model: TextBlock.GradientModel private let rangedTextWithColorTextBlockView: TextBlockView let gradientView: UIView - + init?(model: TextBlock.GradientModel?, mask: UIView) { guard let model else { return nil @@ -131,27 +131,29 @@ private class GradientContainerView: UIView { self.model = model gradientView = model.gradient.uiView gradientView.mask = mask - + rangedTextWithColorTextBlockView = TextBlockView() - + super.init(frame: .zero) - + gradientView.addSubview(rangedTextWithColorTextBlockView) addSubview(gradientView) } - + + @available(*, unavailable) required init(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func layoutSubviews() { super.layoutSubviews() gradientView.frame = bounds rangedTextWithColorTextBlockView.frame = bounds } - + func configureRangedTextColor(textBlockViewModel: TextBlockView.Model) { - rangedTextWithColorTextBlockView.model = textBlockViewModel.updated(with: model.rangedTextWithColor) + rangedTextWithColorTextBlockView.model = textBlockViewModel + .updated(with: model.rangedTextWithColor) } } diff --git a/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift b/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift index 8ab7cca8a..fc67cc647 100644 --- a/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift @@ -358,7 +358,7 @@ private final class TextInputBlockView: BlockView, VisibleBoundsTrackingLeaf { setSmartInsertDeleteType(.default) } } - + func setSmartInsertDeleteType(_ type: UITextSmartInsertDeleteType) { singleLineInput.smartInsertDeleteType = type multiLineInput.smartInsertDeleteType = type @@ -909,7 +909,7 @@ extension UITextField { guard let selectedRange = self.selectedTextRange else { return nil } - + let beginning = self.beginningOfDocument let startPosition = self.offset(from: beginning, to: selectedRange.start) let endPosition = self.offset(from: beginning, to: selectedRange.end) @@ -939,12 +939,16 @@ private class PatchedUITextField: UITextField { guard let string = UIPasteboard.general.string else { return } - + guard let range = self.selectedNSRange else { return } - - if (self.delegate as? TextInputBlockView)?.textField(self, shouldChangeCharactersIn: range, replacementString: string) == true { + + if (self.delegate as? TextInputBlockView)?.textField( + self, + shouldChangeCharactersIn: range, + replacementString: string + ) == true { super.paste(sender) } } @@ -962,8 +966,12 @@ private class PatchedUITextView: UITextView { guard let string = UIPasteboard.general.string else { return } - - if (self.delegate as? TextInputBlockView)?.textView(self, shouldChangeTextIn: self.selectedRange, replacementText: string) == true { + + if (self.delegate as? TextInputBlockView)?.textView( + self, + shouldChangeTextIn: self.selectedRange, + replacementText: string + ) == true { isPasting = true super.paste(sender) } diff --git a/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift b/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift index 47fcfaa0e..2541194f3 100644 --- a/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift +++ b/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift @@ -178,16 +178,16 @@ final class TabContentsView: BlockView { relativeContentOffset = offset updateSelectedPageIndexIfNeeded(relativeContentOffset) } - + func updateSelectedPageIndexIfNeeded(_ idx: CGFloat) { guard selectedPageIndex.isApproximatelyNotEqualTo(idx) else { delegate?.tabContentsViewDidEndAnimation() return } - + selectedPageIndex = idx } - + private func updateContentOffset(animated: Bool = true) { collectionView.setContentOffset(selectedPageContentOffset, animated: animated) } @@ -203,7 +203,7 @@ final class TabContentsView: BlockView { collectionView.frame = bounds updateContentOffset(animated: false) } - + let newLayout = TabContentsViewLayout( pages: model.pages.map(\.block), footer: model.footer, @@ -232,7 +232,7 @@ final class TabContentsView: BlockView { return } let index = isIntermediate ? selectedPageIndex : roundedIndex - + updateSelectedPageIndexIfNeeded(index) updatesDelegate?.onSelectedPageIndexChanged(index, inModel: model) let state = TabViewState(selectedPageIndex: index, countOfPages: countOfPages) diff --git a/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift b/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift index c3398f249..f8f2955db 100644 --- a/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift +++ b/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift @@ -46,7 +46,7 @@ final class TabListView: UIView { contentSize: CGSize, selection: CGFloat )? - + private var animationInfo: AnimationInfo? { didSet { setNeedsLayout() @@ -66,7 +66,7 @@ final class TabListView: UIView { init() { collectionView = makeCollectionView(layout: collectionViewLayout) delegate = TabListViewDelegate(collectionView: collectionView) - + super.init(frame: .zero) clipsToBounds = true @@ -176,7 +176,7 @@ final class TabListView: UIView { func endScrollingAnimation() { animationInfo = nil } - + func setInitialModel(_ model: TabTitlesViewModel) { guard !setInitialModel else { return } self.model = model diff --git a/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift b/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift index a75d5e1c5..85f93263c 100644 --- a/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift +++ b/client/ios/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift @@ -26,7 +26,7 @@ public final class TabbedPagesView: BlockView, VisibleBoundsTrackingContainer { public var effectiveBackgroundColor: UIColor? { tabContentsView.effectiveBackgroundColor } public var layoutReporter: LayoutReporter? - + public func configure( model: TabViewModel, state: TabViewState, diff --git a/client/ios/Samples/SwiftUIIntegration/DivKitSample/ContentView.swift b/client/ios/Samples/SwiftUIIntegration/DivKitSample/ContentView.swift index 6c75430de..b6a52e9bd 100644 --- a/client/ios/Samples/SwiftUIIntegration/DivKitSample/ContentView.swift +++ b/client/ios/Samples/SwiftUIIntegration/DivKitSample/ContentView.swift @@ -1,5 +1,5 @@ -import SwiftUI import DivKit +import SwiftUI struct ContentView: View { @State private var isPresented: Bool = false