diff --git a/client/ios/DivKit.xcodeproj/project.pbxproj b/client/ios/DivKit.xcodeproj/project.pbxproj index d91a8ef85..269a1136b 100644 --- a/client/ios/DivKit.xcodeproj/project.pbxproj +++ b/client/ios/DivKit.xcodeproj/project.pbxproj @@ -44,7 +44,6 @@ 8C0E7371288AE219009BEB3C /* DivKit in Frameworks */ = {isa = PBXBuildFile; productRef = 8C0E7370288AE219009BEB3C /* DivKit */; }; 8C0E7373288AE563009BEB3C /* snapshot_test_data in Resources */ = {isa = PBXBuildFile; fileRef = 8C0E7372288AE563009BEB3C /* snapshot_test_data */; }; 8C0E7375288AE576009BEB3C /* production_data in Resources */ = {isa = PBXBuildFile; fileRef = 8C0E7374288AE576009BEB3C /* production_data */; }; - 8C0E7381288AE9BB009BEB3C /* FontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C0E7380288AE9BB009BEB3C /* FontProvider.swift */; }; 8C0E7395288AEF18009BEB3C /* YSText-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8C0E7391288AEF18009BEB3C /* YSText-Medium.ttf */; }; 8C0E7396288AEF18009BEB3C /* YSText-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8C0E7392288AEF18009BEB3C /* YSText-Light.ttf */; }; 8C0E7397288AEF18009BEB3C /* YSText-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8C0E7393288AEF18009BEB3C /* YSText-Regular.ttf */; }; @@ -197,11 +196,14 @@ 8C9284FA288ADEEA00BEA1FA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9284F9288ADEEA00BEA1FA /* AppDelegate.swift */; }; 8C9284FE288ADEEA00BEA1FA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9284FD288ADEEA00BEA1FA /* ViewController.swift */; }; 8C928503288ADEEA00BEA1FA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8C928502288ADEEA00BEA1FA /* Assets.xcassets */; }; + 8C9898402A4C570400FDC858 /* YSFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C0E7380288AE9BB009BEB3C /* YSFontProvider.swift */; }; + 8C9898422A4C59DF00FDC858 /* YSFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9898412A4C59DF00FDC858 /* YSFontProvider.swift */; }; 8CA382DF287C5CF000C99F4F /* DivKitExtensions in Frameworks */ = {isa = PBXBuildFile; productRef = 8CA382DE287C5CF000C99F4F /* DivKitExtensions */; }; 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 */; }; 8CD1521028CF217B0061128B /* ExpressionResolverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CD1520F28CF217B0061128B /* ExpressionResolverTests.swift */; }; + 8CD907BB2A4C8AF3001C4B7B /* StringUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CD907BA2A4C8AF3001C4B7B /* StringUtils.swift */; }; 8CF1296128B0018E00351F65 /* UrlInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF1296028B0018E00351F65 /* UrlInputView.swift */; }; 8CF1296328B0021F00351F65 /* UserPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF1296228B0021F00351F65 /* UserPreferences.swift */; }; 8CF1296528B0036F00351F65 /* Themes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF1296428B0036F00351F65 /* Themes.swift */; }; @@ -279,7 +281,7 @@ 8C0DC7112865CA1100286F6B /* DivKitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DivKitTests.swift; sourceTree = ""; }; 8C0E7372288AE563009BEB3C /* snapshot_test_data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = snapshot_test_data; path = ../../../test_data/snapshot_test_data; sourceTree = ""; }; 8C0E7374288AE576009BEB3C /* production_data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = production_data; path = ../../../test_data/production_data; sourceTree = ""; }; - 8C0E7380288AE9BB009BEB3C /* FontProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FontProvider.swift; sourceTree = ""; }; + 8C0E7380288AE9BB009BEB3C /* YSFontProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YSFontProvider.swift; sourceTree = ""; }; 8C0E7391288AEF18009BEB3C /* YSText-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "YSText-Medium.ttf"; sourceTree = ""; }; 8C0E7392288AEF18009BEB3C /* YSText-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "YSText-Light.ttf"; sourceTree = ""; }; 8C0E7393288AEF18009BEB3C /* YSText-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "YSText-Regular.ttf"; sourceTree = ""; }; @@ -444,10 +446,12 @@ 8C9284FD288ADEEA00BEA1FA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 8C928502288ADEEA00BEA1FA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 8C928507288ADEEA00BEA1FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8C9898412A4C59DF00FDC858 /* YSFontProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YSFontProvider.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 = ""; }; 8CD1520F28CF217B0061128B /* ExpressionResolverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpressionResolverTests.swift; sourceTree = ""; }; + 8CD907BA2A4C8AF3001C4B7B /* StringUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringUtils.swift; sourceTree = ""; }; 8CF1296028B0018E00351F65 /* UrlInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlInputView.swift; sourceTree = ""; }; 8CF1296228B0021F00351F65 /* UserPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferences.swift; sourceTree = ""; }; 8CF1296428B0036F00351F65 /* Themes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Themes.swift; sourceTree = ""; }; @@ -833,6 +837,7 @@ 8C88636028AB802C00D04928 /* ReferenceSet.swift */, 8C6E40BB28AAA4F30038E107 /* SwitchableContainerSnapshotTest.swift */, 8C6E40BD28AAA4F30038E107 /* TooltipFactorySnapshotTests.swift */, + 8C9898412A4C59DF00FDC858 /* YSFontProvider.swift */, ); path = LayoutKitSnapshotTests; sourceTree = ""; @@ -867,12 +872,13 @@ 8C7B18832864CA380036EF4C /* Alert.swift */, 8C1A376828B41BA000A047C8 /* DemoAppLogger.swift */, 8C1A374828B4187B00A047C8 /* DeviceInfo.swift */, + 89D02B1928C8EBC40041EC18 /* Palette.swift */, + E9E484C029AF434D00C803A8 /* RegressionFile.swift */, 8C2BFA5728C10F5B00A16E9B /* TestData.swift */, + 893D19632902AD8F005540DF /* TimeMeasure.swift */, 8C7B18842864CA380036EF4C /* UrlOpener.swift */, 8CF1296228B0021F00351F65 /* UserPreferences.swift */, - 89D02B1928C8EBC40041EC18 /* Palette.swift */, - 893D19632902AD8F005540DF /* TimeMeasure.swift */, - E9E484C029AF434D00C803A8 /* RegressionFile.swift */, + 8CD907BA2A4C8AF3001C4B7B /* StringUtils.swift */, ); path = Utils; sourceTree = ""; @@ -1004,12 +1010,13 @@ 8C9284CE288ACCE400BEA1FA /* SnapshotTestKit */, 8C035199288EC5AB0016A747 /* Images.xcassets */, 8C9284D9288ACCE400BEA1FA /* DivIndicatorTests.swift */, + E94B516428D0AC7900AFACEA /* DivInteractiveSnapshotTests.swift */, 8C9284D6288ACCE400BEA1FA /* DivKitSnapshotTestCase.swift */, 8C9284D4288ACCE400BEA1FA /* DivSnapshotTests.swift */, 8C9284D7288ACCE400BEA1FA /* MordaProductionTests.swift */, 8C9284D5288ACCE400BEA1FA /* ReferenceSet.swift */, 8C9284D3288ACCE400BEA1FA /* RuntimeTestCase.swift */, - E94B516428D0AC7900AFACEA /* DivInteractiveSnapshotTests.swift */, + 8C0E7380288AE9BB009BEB3C /* YSFontProvider.swift */, ); path = DivKitSnapshotTests; sourceTree = ""; @@ -1018,9 +1025,9 @@ isa = PBXGroup; children = ( 8C9284CF288ACCE400BEA1FA /* Diff.swift */, + 8C9284D2288ACCE400BEA1FA /* ScreenSize.swift */, 8C9284D0288ACCE400BEA1FA /* Snapshot.swift */, 8C9284D1288ACCE400BEA1FA /* SnapshotTestKit.swift */, - 8C9284D2288ACCE400BEA1FA /* ScreenSize.swift */, ); path = SnapshotTestKit; sourceTree = ""; @@ -1032,7 +1039,6 @@ 8C928502288ADEEA00BEA1FA /* Assets.xcassets */, 8C928507288ADEEA00BEA1FA /* Info.plist */, 8C9284F9288ADEEA00BEA1FA /* AppDelegate.swift */, - 8C0E7380288AE9BB009BEB3C /* FontProvider.swift */, 8C9284FD288ADEEA00BEA1FA /* ViewController.swift */, 8C0C0766288FE8F30052C4A9 /* Main.storyboard */, ); @@ -1551,6 +1557,7 @@ 8C4504DC28B3AA30005712FD /* SamplesView.swift in Sources */, 8C1A383228B61A2B00A047C8 /* AppComponents.swift in Sources */, 8CF1296128B0018E00351F65 /* UrlInputView.swift in Sources */, + 8CD907BB2A4C8AF3001C4B7B /* StringUtils.swift in Sources */, 8C1A377B28B4E3E700A047C8 /* Payload.swift in Sources */, 8C1A376D28B4DC2400A047C8 /* SettingsView.swift in Sources */, 8C1A378028B4E47900A047C8 /* WebPreviewSocket.swift in Sources */, @@ -1577,6 +1584,7 @@ 8C88636128AB802C00D04928 /* ReferenceSet.swift in Sources */, 8C6E40BF28AAA4F30038E107 /* SwitchableContainerSnapshotTest.swift in Sources */, 8C6E40C128AAA4F30038E107 /* TooltipFactorySnapshotTests.swift in Sources */, + 8C9898422A4C59DF00FDC858 /* YSFontProvider.swift in Sources */, 8C6E40C028AAA4F30038E107 /* AnchorBlockTests.swift in Sources */, 8C6E40CD28AAA6F30038E107 /* Snapshot.swift in Sources */, ); @@ -1690,6 +1698,7 @@ 8C9284E0288ACCE400BEA1FA /* ReferenceSet.swift in Sources */, 8C9284DD288ACCE400BEA1FA /* ScreenSize.swift in Sources */, 8C9284DE288ACCE400BEA1FA /* RuntimeTestCase.swift in Sources */, + 8C9898402A4C570400FDC858 /* YSFontProvider.swift in Sources */, 8C9284E1288ACCE400BEA1FA /* DivKitSnapshotTestCase.swift in Sources */, 8C9284DB288ACCE400BEA1FA /* Snapshot.swift in Sources */, 8C9284E2288ACCE400BEA1FA /* MordaProductionTests.swift in Sources */, @@ -1702,7 +1711,6 @@ buildActionMask = 2147483647; files = ( 8C9284FE288ADEEA00BEA1FA /* ViewController.swift in Sources */, - 8C0E7381288AE9BB009BEB3C /* FontProvider.swift in Sources */, 8C9284FA288ADEEA00BEA1FA /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/client/ios/DivKit/Debug/Block+DebugInfo.swift b/client/ios/DivKit/Debug/Block+DebugInfo.swift index d9ecdff63..7d7c61e02 100644 --- a/client/ios/DivKit/Debug/Block+DebugInfo.swift +++ b/client/ios/DivKit/Debug/Block+DebugInfo.swift @@ -6,15 +6,13 @@ import CommonCorePublic import LayoutKit extension Block { - func addingDebugInfo( - debugParams: DebugParams, - errors: [DivError], - parentPath: UIElementPath - ) -> Block { + func addingDebugInfo(context: DivBlockModelingContext) -> Block { + let debugParams = context.debugParams guard debugParams.isDebugInfoEnabled else { return self } + let errors = context.errorsStorage.errors let errorsCount = errors.count guard errorsCount > 0 else { return self @@ -24,12 +22,12 @@ extension Block { ? "\(maxCount)+" : "\(errorsCount)" - let typo = Typo(size: FontSize(rawValue: 14), weight: .regular) + let typo = Typo(font: context.fontProvider.font(size: 14)) .with(color: .white) let action = UserInterfaceAction( payload: .url(DebugInfoBlock.showOverlayURL), - path: parentPath + "div_errors_indicator", + path: context.parentPath + "div_errors_indicator", accessibilityElement: nil ) diff --git a/client/ios/DivKit/DivBlockModelingContext.swift b/client/ios/DivKit/DivBlockModelingContext.swift index 252f59f04..9cfc052eb 100644 --- a/client/ios/DivKit/DivBlockModelingContext.swift +++ b/client/ios/DivKit/DivBlockModelingContext.swift @@ -18,7 +18,7 @@ public struct DivBlockModelingContext { public let imageHolderFactory: ImageHolderFactory public let highPriorityImageHolderFactory: ImageHolderFactory? public let divCustomBlockFactory: DivCustomBlockFactory - public let fontSpecifiers: FontSpecifiers + public let fontProvider: DivFontProvider public let flagsInfo: DivFlagsInfo public let extensionHandlers: [String: DivExtensionHandler] public let stateInterceptors: [String: DivStateInterceptor] @@ -51,7 +51,7 @@ public struct DivBlockModelingContext { imageHolderFactory: ImageHolderFactory, highPriorityImageHolderFactory: ImageHolderFactory? = nil, divCustomBlockFactory: DivCustomBlockFactory = EmptyDivCustomBlockFactory(), - fontSpecifiers: FontSpecifiers = BaseUIPublic.fontSpecifiers, + fontProvider: DivFontProvider? = nil, flagsInfo: DivFlagsInfo = .default, extensionHandlers: [DivExtensionHandler] = [], stateInterceptors: [DivStateInterceptor] = [], @@ -74,7 +74,7 @@ public struct DivBlockModelingContext { self.highPriorityImageHolderFactory = highPriorityImageHolderFactory self.divCustomBlockFactory = divCustomBlockFactory self.flagsInfo = flagsInfo - self.fontSpecifiers = fontSpecifiers + self.fontProvider = fontProvider ?? DefaultFontProvider() self.playerFactory = playerFactory self.debugParams = debugParams self.childrenA11yDescription = childrenA11yDescription diff --git a/client/ios/DivKit/DivFontProvider.swift b/client/ios/DivKit/DivFontProvider.swift new file mode 100644 index 000000000..78db4a32c --- /dev/null +++ b/client/ios/DivKit/DivFontProvider.swift @@ -0,0 +1,36 @@ +import CoreGraphics + +import BasePublic +import BaseUIPublic + +public protocol DivFontProvider { + func font(family: String, weight: DivFontWeight, size: CGFloat) -> Font +} + +extension DivFontProvider { + public func font(weight: DivFontWeight = .regular, size: CGFloat) -> Font { + font(family: "", weight: weight, size: size) + } +} + +final class DefaultFontProvider: DivFontProvider { + func font(family: String, weight: DivFontWeight, size: CGFloat) -> Font { + let fontSpecifier = family == "display" ? fontSpecifiers.display : fontSpecifiers.text + return fontSpecifier.font(weight: weight.baseUIFontWeight, size: size) + } +} + +extension DivFontWeight { + fileprivate var baseUIFontWeight: BaseUIPublic.FontWeight { + switch self { + case .light: + return .light + case .regular: + return .regular + case .medium: + return .medium + case .bold: + return .bold + } + } +} diff --git a/client/ios/DivKit/DivKitComponents.swift b/client/ios/DivKit/DivKitComponents.swift index bb9bd8d35..394ce61db 100644 --- a/client/ios/DivKit/DivKitComponents.swift +++ b/client/ios/DivKit/DivKitComponents.swift @@ -14,7 +14,7 @@ public final class DivKitComponents { public let divCustomBlockFactory: DivCustomBlockFactory public var extensionHandlers: [DivExtensionHandler] public let flagsInfo: DivFlagsInfo - public let fontSpecifiers: FontSpecifiers + public let fontProvider: DivFontProvider public let imageHolderFactory: ImageHolderFactory public let patchProvider: DivPatchProvider public let playerFactory: PlayerFactory? @@ -34,7 +34,7 @@ public final class DivKitComponents { divCustomBlockFactory: DivCustomBlockFactory = EmptyDivCustomBlockFactory(), extensionHandlers: [DivExtensionHandler] = [], flagsInfo: DivFlagsInfo = .default, - fontSpecifiers: FontSpecifiers = BaseUIPublic.fontSpecifiers, + fontProvider: DivFontProvider? = nil, imageHolderFactory: ImageHolderFactory? = nil, patchProvider: DivPatchProvider? = nil, requestPerformer: URLRequestPerforming? = nil, @@ -50,7 +50,7 @@ public final class DivKitComponents { self.divCustomBlockFactory = divCustomBlockFactory self.extensionHandlers = extensionHandlers self.flagsInfo = flagsInfo - self.fontSpecifiers = fontSpecifiers + self.fontProvider = fontProvider ?? DefaultFontProvider() self.playerFactory = playerFactory ?? defaultPlayerFactory self.showToolip = showTooltip self.stateManagement = stateManagement @@ -180,7 +180,7 @@ public final class DivKitComponents { imageHolderFactory: imageHolderFactory .withInMemoryCache(cachedImageHolders: cachedImageHolders), divCustomBlockFactory: divCustomBlockFactory, - fontSpecifiers: fontSpecifiers, + fontProvider: fontProvider, flagsInfo: flagsInfo, extensionHandlers: extensionHandlers, variables: variablesStorage.makeVariables(for: cardId), diff --git a/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift b/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift index 96b207d1f..f8b2e0d0d 100644 --- a/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift +++ b/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift @@ -36,11 +36,7 @@ extension DivData: DivBlockModeling { .addingStateBlock( ids: stateManager.getVisibleIds(statePath: statePath) ) - .addingDebugInfo( - debugParams: divContext.debugParams, - errors: divContext.errorsStorage.errors, - parentPath: divContext.parentPath - ) + .addingDebugInfo(context: divContext) } private func getCurrentState( diff --git a/client/ios/DivKit/Extensions/DivFontWeightExtensions.swift b/client/ios/DivKit/Extensions/DivFontWeightExtensions.swift index 4899b6108..27e358782 100644 --- a/client/ios/DivKit/Extensions/DivFontWeightExtensions.swift +++ b/client/ios/DivKit/Extensions/DivFontWeightExtensions.swift @@ -1,7 +1,7 @@ -import BaseUIPublic +import BasePublic extension DivFontWeight { - var fontWeight: FontWeight { + var fontWeight: Font.Weight { switch self { case .light: return .light @@ -14,14 +14,3 @@ extension DivFontWeight { } } } - -extension DivFontFamily { - var fontFamily: FontFamily { - switch self { - case .display: - return .YSDisplay - case .text: - return .YSText - } - } -} diff --git a/client/ios/DivKit/Extensions/DivInputExtensions.swift b/client/ios/DivKit/Extensions/DivInputExtensions.swift index 9193a7cd7..2f3772bfb 100644 --- a/client/ios/DivKit/Extensions/DivInputExtensions.swift +++ b/client/ios/DivKit/Extensions/DivInputExtensions.swift @@ -19,39 +19,27 @@ extension DivInput: DivBlockModeling { } private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block { - let font = context.fontSpecifiers.font( - family: resolveFontFamily(context.expressionResolver).fontFamily, - weight: resolveFontWeight(context.expressionResolver).fontWeight, - size: resolveFontSizeUnit(context.expressionResolver) - .makeScaledValue(resolveFontSize(context.expressionResolver)) + let expressionResolver = context.expressionResolver + + let font = context.fontProvider.font( + family: resolveFontFamily(expressionResolver) ?? "", + weight: resolveFontWeight(expressionResolver), + size: resolveFontSizeUnit(expressionResolver) + .makeScaledValue(resolveFontSize(expressionResolver)) ) var typo = Typo(font: font).allowHeightOverrun - let kern = CGFloat(resolveLetterSpacing(context.expressionResolver)) + let kern = CGFloat(resolveLetterSpacing(expressionResolver)) if !kern.isApproximatelyEqualTo(0) { typo = typo.kerned(kern) } - if let lineHeight = resolveLineHeight(context.expressionResolver) { + if let lineHeight = resolveLineHeight(expressionResolver) { typo = typo.with(height: CGFloat(lineHeight)) } - let resolvedHintColor: Color = resolveHintColor(context.expressionResolver) - let hintTypo = typo.with(color: resolvedHintColor) - let hintValue = resolveHintText(context.expressionResolver) ?? "" - - let resolvedColor: Color = resolveTextColor(context.expressionResolver) - let textTypo = typo.with(color: resolvedColor) - - let textValue = Binding(context: context, name: textVariable) - - let highlightColor = resolveHighlightColor(context.expressionResolver) - - let keyboardType = resolveKeyboardType(context.expressionResolver) - - let maxVisibleLines = resolveMaxVisibleLines(context.expressionResolver) - - let selectAllOnFocus = resolveSelectAllOnFocus(context.expressionResolver) + let hintValue = resolveHintText(expressionResolver) ?? "" + let keyboardType = resolveKeyboardType(expressionResolver) let onFocusActions = (focus?.onFocus ?? []).map { $0.uiAction(context: context.actionContext) @@ -60,22 +48,19 @@ extension DivInput: DivBlockModeling { $0.uiAction(context: context.actionContext) } - let maskValidator = mask?.makeMaskValidator(context.expressionResolver) - let rawTextValue: Binding? = mask?.makeRawVariable(context) - return TextInputBlock( widthTrait: makeContentWidthTrait(with: context), heightTrait: makeContentHeightTrait(with: context), - hint: hintValue.with(typo: hintTypo), - textValue: textValue, - rawTextValue: rawTextValue, - textTypo: textTypo, + hint: hintValue.with(typo: typo.with(color: resolveHintColor(expressionResolver))), + textValue: Binding(context: context, name: textVariable), + rawTextValue: mask?.makeRawVariable(context), + textTypo: typo.with(color: resolveTextColor(expressionResolver)), multiLineMode: keyboardType == .multiLineText, inputType: keyboardType.system, - highlightColor: highlightColor, - maxVisibleLines: maxVisibleLines, - selectAllOnFocus: selectAllOnFocus, - maskValidator: maskValidator, + highlightColor: resolveHighlightColor(expressionResolver), + maxVisibleLines: resolveMaxVisibleLines(expressionResolver), + selectAllOnFocus: resolveSelectAllOnFocus(expressionResolver), + maskValidator: mask?.makeMaskValidator(expressionResolver), path: context.parentPath, onFocusActions: onFocusActions, onBlurActions: onBlurActions, diff --git a/client/ios/DivKit/Extensions/DivSelectExtensions.swift b/client/ios/DivKit/Extensions/DivSelectExtensions.swift index 8ebc960fa..838ab5273 100644 --- a/client/ios/DivKit/Extensions/DivSelectExtensions.swift +++ b/client/ios/DivKit/Extensions/DivSelectExtensions.swift @@ -19,28 +19,30 @@ extension DivSelect: DivBlockModeling { } private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block { - let font = context.fontSpecifiers.font( - family: resolveFontFamily(context.expressionResolver).fontFamily, - weight: resolveFontWeight(context.expressionResolver).fontWeight, - size: resolveFontSizeUnit(context.expressionResolver) - .makeScaledValue(resolveFontSize(context.expressionResolver)) + let expressionResolver = context.expressionResolver + + let font = context.fontProvider.font( + family: resolveFontFamily(expressionResolver) ?? "", + weight: resolveFontWeight(expressionResolver), + size: resolveFontSizeUnit(expressionResolver) + .makeScaledValue(resolveFontSize(expressionResolver)) ) var typo = Typo(font: font).allowHeightOverrun - let kern = CGFloat(resolveLetterSpacing(context.expressionResolver)) + let kern = CGFloat(resolveLetterSpacing(expressionResolver)) if !kern.isApproximatelyEqualTo(0) { typo = typo.kerned(kern) } - if let lineHeight = resolveLineHeight(context.expressionResolver) { + if let lineHeight = resolveLineHeight(expressionResolver) { typo = typo.with(height: CGFloat(lineHeight)) } - let resolvedHintColor: Color = resolveHintColor(context.expressionResolver) + let resolvedHintColor: Color = resolveHintColor(expressionResolver) let hintTypo = typo.with(color: resolvedHintColor) - let hintValue = resolveHintText(context.expressionResolver) ?? "" + let hintValue = resolveHintText(expressionResolver) ?? "" - let resolvedColor: Color = resolveTextColor(context.expressionResolver) + let resolvedColor: Color = resolveTextColor(expressionResolver) let textTypo = typo.with(color: resolvedColor) let textValue = Binding(context: context, name: valueVariable) @@ -59,7 +61,7 @@ extension DivSelect: DivBlockModeling { textValue: textValue, rawTextValue: nil, textTypo: textTypo, - inputType: makeInputType(context.expressionResolver), + inputType: makeInputType(expressionResolver), path: context.parentPath, onFocusActions: onFocusActions, onBlurActions: onBlurActions, diff --git a/client/ios/DivKit/Extensions/DivSliderExtensions.swift b/client/ios/DivKit/Extensions/DivSliderExtensions.swift index 3c9cfb781..d55d24b31 100644 --- a/client/ios/DivKit/Extensions/DivSliderExtensions.swift +++ b/client/ios/DivKit/Extensions/DivSliderExtensions.swift @@ -146,14 +146,15 @@ extension DivSlider.TextStyle { context: DivBlockModelingContext, value: Int ) -> Block { + let expressionResolver = context.expressionResolver + let typo = Typo( - size: FontSize( - rawValue: resolveFontSize(context.expressionResolver) - .flatMap(CGFloat.init) ?? 16 - ), - weight: resolveFontWeight(context.expressionResolver).fontWeight + font: context.fontProvider.font( + weight: resolveFontWeight(expressionResolver), + size: resolveFontSize(expressionResolver).map(CGFloat.init) ?? 16 + ) ) - .with(color: resolveTextColor(context.expressionResolver)) + .with(color: resolveTextColor(expressionResolver)) .with(alignment: .center) return TextBlock( diff --git a/client/ios/DivKit/Extensions/DivTabsExtensions.swift b/client/ios/DivKit/Extensions/DivTabsExtensions.swift index 88654cbcf..eff33d224 100644 --- a/client/ios/DivKit/Extensions/DivTabsExtensions.swift +++ b/client/ios/DivKit/Extensions/DivTabsExtensions.swift @@ -39,7 +39,7 @@ extension DivTabs: DivBlockModeling { let listModel = TabListViewModel( tabTitles: tabs.map { $0.title }, titleStyle: tabTitleStyle.makeTitleStyle( - fontSpecifiers: context.fontSpecifiers, + fontProvider: context.fontProvider, expressionResolver: context.expressionResolver ), listPaddings: titlePaddings.makeEdgeInsets(with: context.expressionResolver) @@ -104,12 +104,12 @@ typealias Tab = (title: UILink, page: TabPageViewModel) extension DivTabs.TabTitleStyle { private func makeTypo( - fontSpecifiers: FontSpecifiers, - fontWeight: FontWeight, - with expressionResolver: ExpressionResolver + fontProvider: DivFontProvider, + fontWeight: DivFontWeight, + expressionResolver: ExpressionResolver ) -> Typo { - let font = fontSpecifiers.font( - family: resolveFontFamily(expressionResolver).fontFamily, + let font = fontProvider.font( + family: resolveFontFamily(expressionResolver) ?? "", weight: fontWeight, size: resolveFontSizeUnit(expressionResolver) .makeScaledValue(resolveFontSize(expressionResolver)) @@ -121,20 +121,20 @@ extension DivTabs.TabTitleStyle { } fileprivate func makeTitleStyle( - fontSpecifiers: FontSpecifiers, + fontProvider: DivFontProvider, expressionResolver: ExpressionResolver ) -> LayoutKit.TabTitleStyle { - let defaultTypo = resolveFontWeight(expressionResolver).fontWeight + let defaultFontWeight = resolveFontWeight(expressionResolver) return LayoutKit.TabTitleStyle( typo: makeTypo( - fontSpecifiers: fontSpecifiers, - fontWeight: resolveActiveFontWeight(expressionResolver)?.fontWeight ?? defaultTypo, - with: expressionResolver + fontProvider: fontProvider, + fontWeight: resolveActiveFontWeight(expressionResolver) ?? defaultFontWeight, + expressionResolver: expressionResolver ), inactiveTypo: makeTypo( - fontSpecifiers: fontSpecifiers, - fontWeight: resolveInactiveFontWeight(expressionResolver)?.fontWeight ?? defaultTypo, - with: expressionResolver + fontProvider: fontProvider, + fontWeight: resolveInactiveFontWeight(expressionResolver) ?? defaultFontWeight, + expressionResolver: expressionResolver ), paddings: paddings.makeEdgeInsets(with: expressionResolver), cornerRadius: makeCornerRadii(with: expressionResolver), diff --git a/client/ios/DivKit/Extensions/DivTextExtensions.swift b/client/ios/DivKit/Extensions/DivTextExtensions.swift index dc06e6a05..e54cefd2e 100644 --- a/client/ios/DivKit/Extensions/DivTextExtensions.swift +++ b/client/ios/DivKit/Extensions/DivTextExtensions.swift @@ -21,46 +21,48 @@ extension DivText: DivBlockModeling { } private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block { - let font = context.fontSpecifiers.font( - family: resolveFontFamily(context.expressionResolver).fontFamily, - weight: resolveFontWeight(context.expressionResolver).fontWeight, - size: resolveFontSizeUnit(context.expressionResolver) - .makeScaledValue(resolveFontSize(context.expressionResolver)) + let expressionResolver = context.expressionResolver + + let font = context.fontProvider.font( + family: resolveFontFamily(expressionResolver) ?? "", + weight: resolveFontWeight(expressionResolver), + size: resolveFontSizeUnit(expressionResolver) + .makeScaledValue(resolveFontSize(expressionResolver)) ) var typo = Typo(font: font).allowHeightOverrun - let alignment = resolveTextAlignmentHorizontal(context.expressionResolver).system + let alignment = resolveTextAlignmentHorizontal(expressionResolver).system if alignment != .left { typo = typo.with(alignment: alignment) } - let kern = CGFloat(resolveLetterSpacing(context.expressionResolver)) + let kern = CGFloat(resolveLetterSpacing(expressionResolver)) if !kern.isApproximatelyEqualTo(0) { typo = typo.kerned(kern) } - let resolvedColor: Color = resolveTextColor(context.expressionResolver) + let resolvedColor: Color = resolveTextColor(expressionResolver) if resolvedColor != .black { typo = typo.with(color: resolvedColor) } - if let lineHeight = resolveLineHeight(context.expressionResolver) { + if let lineHeight = resolveLineHeight(expressionResolver) { typo = typo.with(height: CGFloat(lineHeight)) } - switch resolveStrike(context.expressionResolver) { + switch resolveStrike(expressionResolver) { case .none: break case .single: typo = typo.struckThrough(.single) } - switch resolveUnderline(context.expressionResolver) { + switch resolveUnderline(expressionResolver) { case .none: break case .single: typo = typo.underlined(.single) } let attributedString = makeAttributedString( - text: resolveText(context.expressionResolver) ?? ("" as CFString), + text: resolveText(expressionResolver) ?? ("" as CFString), typo: typo, ranges: ranges, actions: nil, @@ -75,7 +77,7 @@ extension DivText: DivBlockModeling { let truncationToken = ellipsis.map { makeAttributedString( - text: ($0.resolveText(context.expressionResolver) ?? "") as CFString, + text: ($0.resolveText(expressionResolver) ?? "") as CFString, typo: typo, ranges: $0.ranges, actions: $0.makeActions(context: context.actionContext), @@ -92,15 +94,15 @@ extension DivText: DivBlockModeling { widthTrait: makeContentWidthTrait(with: context), heightTrait: makeContentHeightTrait(with: context), text: attributedString, - textGradient: makeGradient(context.expressionResolver), + textGradient: makeGradient(expressionResolver), verticalAlignment: - resolveTextAlignmentVertical(context.expressionResolver).alignment, - maxIntrinsicNumberOfLines: resolveMaxLines(context.expressionResolver) ?? .max, - minNumberOfHiddenLines: resolveMinHiddenLines(context.expressionResolver) ?? 0, + resolveTextAlignmentVertical(expressionResolver).alignment, + maxIntrinsicNumberOfLines: resolveMaxLines(expressionResolver) ?? .max, + minNumberOfHiddenLines: resolveMinHiddenLines(expressionResolver) ?? 0, images: images, truncationToken: truncationToken, truncationImages: truncationImages, - canSelect: resolveSelectable(context.expressionResolver) + canSelect: resolveSelectable(expressionResolver) ) } @@ -147,39 +149,41 @@ extension DivText: DivBlockModeling { to string: CFMutableAttributedString, context: DivBlockModelingContext ) { - let start = range.resolveStart(context.expressionResolver) ?? 0 - let end = range.resolveEnd(context.expressionResolver) ?? 0 + let expressionResolver = context.expressionResolver + + let start = range.resolveStart(expressionResolver) ?? 0 + let end = range.resolveEnd(expressionResolver) ?? 0 guard end > start && start < CFAttributedStringGetLength(string) else { return } let fontTypo: Typo? if range.fontSize != nil || range.fontWeight != nil { - let font = context.fontSpecifiers.font( - family: range.resolveFontFamily(context.expressionResolver)?.fontFamily - ?? resolveFontFamily(context.expressionResolver).fontFamily, + let font = context.fontProvider.font( + family: range.resolveFontFamily(expressionResolver) + ?? resolveFontFamily(expressionResolver) ?? "", weight: ( - range.resolveFontWeight(context.expressionResolver) - ?? resolveFontWeight(context.expressionResolver) - ).fontWeight, + range.resolveFontWeight(expressionResolver) + ?? resolveFontWeight(expressionResolver) + ), size: CGFloat( - range.resolveFontSize(context.expressionResolver) - ?? resolveFontSize(context.expressionResolver) + range.resolveFontSize(expressionResolver) + ?? resolveFontSize(expressionResolver) ) ) fontTypo = Typo(font: font) } else { fontTypo = nil } - let colorTypo = range.resolveTextColor(context.expressionResolver) + let colorTypo = range.resolveTextColor(expressionResolver) .map { Typo(color: $0) } - let heightTypo = range.resolveLineHeight(context.expressionResolver) + let heightTypo = range.resolveLineHeight(expressionResolver) .map { Typo(height: CGFloat($0)) } - let spacingTypo = range.resolveLetterSpacing(context.expressionResolver) + let spacingTypo = range.resolveLetterSpacing(expressionResolver) .map { Typo(kern: CGFloat($0)) } - let strikethroughTypo = range.resolveStrike(context.expressionResolver) + let strikethroughTypo = range.resolveStrike(expressionResolver) .map { Typo(strikethrough: $0.underlineStyle) } - let underlineTypo = range.resolveUnderline(context.expressionResolver) + let underlineTypo = range.resolveUnderline(expressionResolver) .map { Typo(underline: $0.underlineStyle) } let typos = [fontTypo, colorTypo, heightTypo, spacingTypo, strikethroughTypo, underlineTypo] .compactMap { $0 } @@ -193,10 +197,10 @@ extension DivText: DivBlockModeling { typos.forEach { $0.apply(to: string, at: cfRange) } string.apply(actions, at: cfRange) - range.makeBackground(range: cfRange, resolver: context.expressionResolver)? + range.makeBackground(range: cfRange, resolver: expressionResolver)? .apply(to: string, at: cfRange) - range.makeBorder(range: cfRange, resolver: context.expressionResolver)? + range.makeBorder(range: cfRange, resolver: expressionResolver)? .apply(to: string, at: cfRange) } diff --git a/client/ios/DivKit/generated_sources/DivFontFamily.swift b/client/ios/DivKit/generated_sources/DivFontFamily.swift deleted file mode 100644 index f0e5d3c13..000000000 --- a/client/ios/DivKit/generated_sources/DivFontFamily.swift +++ /dev/null @@ -1,11 +0,0 @@ -// Generated code. Do not modify. - -import CommonCorePublic -import Foundation -import Serialization - -@frozen -public enum DivFontFamily: String, CaseIterable { - case text = "text" - case display = "display" -} diff --git a/client/ios/DivKit/generated_sources/DivInput.swift b/client/ios/DivKit/generated_sources/DivInput.swift index 5fef5bb48..e980f244b 100644 --- a/client/ios/DivKit/generated_sources/DivInput.swift +++ b/client/ios/DivKit/generated_sources/DivInput.swift @@ -40,7 +40,7 @@ public final class DivInput: DivBase { public let disappearActions: [DivDisappearAction]? // at least 1 elements public let extensions: [DivExtension]? // at least 1 elements public let focus: DivFocus? - public let fontFamily: Expression // default value: text + public let fontFamily: Expression? // at least 1 char public let fontSize: Expression // constraint: number >= 0; default value: 12 public let fontSizeUnit: Expression // default value: sp public let fontWeight: Expression // default value: regular @@ -92,8 +92,8 @@ public final class DivInput: DivBase { resolver.resolveNumericValue(expression: columnSpan) } - public func resolveFontFamily(_ resolver: ExpressionResolver) -> DivFontFamily { - resolver.resolveStringBasedValue(expression: fontFamily, initializer: DivFontFamily.init(rawValue:)) ?? DivFontFamily.text + public func resolveFontFamily(_ resolver: ExpressionResolver) -> String? { + resolver.resolveStringBasedValue(expression: fontFamily, initializer: { $0 }) } public func resolveFontSize(_ resolver: ExpressionResolver) -> Int { @@ -190,8 +190,8 @@ public final class DivInput: DivBase { static let focusValidator: AnyValueValidator = makeNoOpValueValidator() - static let fontFamilyValidator: AnyValueValidator = - makeNoOpValueValidator() + static let fontFamilyValidator: AnyValueValidator = + makeStringValidator(minLength: 1) static let fontSizeValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -303,7 +303,7 @@ public final class DivInput: DivBase { disappearActions: [DivDisappearAction]? = nil, extensions: [DivExtension]? = nil, focus: DivFocus? = nil, - fontFamily: Expression? = nil, + fontFamily: Expression? = nil, fontSize: Expression? = nil, fontSizeUnit: Expression? = nil, fontWeight: Expression? = nil, @@ -349,7 +349,7 @@ public final class DivInput: DivBase { self.disappearActions = disappearActions self.extensions = extensions self.focus = focus - self.fontFamily = fontFamily ?? .value(.text) + self.fontFamily = fontFamily self.fontSize = fontSize ?? .value(12) self.fontSizeUnit = fontSizeUnit ?? .value(.sp) self.fontWeight = fontWeight ?? .value(.regular) @@ -514,7 +514,7 @@ extension DivInput: Serializable { result["disappear_actions"] = disappearActions?.map { $0.toDictionary() } result["extensions"] = extensions?.map { $0.toDictionary() } result["focus"] = focus?.toDictionary() - result["font_family"] = fontFamily.toValidSerializationValue() + result["font_family"] = fontFamily?.toValidSerializationValue() result["font_size"] = fontSize.toValidSerializationValue() result["font_size_unit"] = fontSizeUnit.toValidSerializationValue() result["font_weight"] = fontWeight.toValidSerializationValue() diff --git a/client/ios/DivKit/generated_sources/DivInputTemplate.swift b/client/ios/DivKit/generated_sources/DivInputTemplate.swift index 204c2064c..5efeeb1b8 100644 --- a/client/ios/DivKit/generated_sources/DivInputTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivInputTemplate.swift @@ -97,7 +97,7 @@ public final class DivInputTemplate: TemplateValue { public let disappearActions: Field<[DivDisappearActionTemplate]>? // at least 1 elements public let extensions: Field<[DivExtensionTemplate]>? // at least 1 elements public let focus: Field? - public let fontFamily: Field>? // default value: text + public let fontFamily: Field>? // at least 1 char public let fontSize: Field>? // constraint: number >= 0; default value: 12 public let fontSizeUnit: Field>? // default value: sp public let fontWeight: Field>? // default value: regular @@ -203,7 +203,7 @@ public final class DivInputTemplate: TemplateValue { disappearActions: Field<[DivDisappearActionTemplate]>? = nil, extensions: Field<[DivExtensionTemplate]>? = nil, focus: Field? = nil, - fontFamily: Field>? = nil, + fontFamily: Field>? = nil, fontSize: Field>? = nil, fontSizeUnit: Field>? = nil, fontWeight: Field>? = nil, @@ -452,7 +452,7 @@ public final class DivInputTemplate: TemplateValue { var disappearActionsValue: DeserializationResult<[DivDisappearAction]> = .noValue var extensionsValue: DeserializationResult<[DivExtension]> = .noValue var focusValue: DeserializationResult = .noValue - var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue + var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue var fontSizeValue: DeserializationResult> = parent?.fontSize?.value() ?? .noValue var fontSizeUnitValue: DeserializationResult> = parent?.fontSizeUnit?.value() ?? .noValue var fontWeightValue: DeserializationResult> = parent?.fontWeight?.value() ?? .noValue diff --git a/client/ios/DivKit/generated_sources/DivSelect.swift b/client/ios/DivKit/generated_sources/DivSelect.swift index 482e08067..248c6c22b 100644 --- a/client/ios/DivKit/generated_sources/DivSelect.swift +++ b/client/ios/DivKit/generated_sources/DivSelect.swift @@ -40,7 +40,7 @@ public final class DivSelect: DivBase { public let disappearActions: [DivDisappearAction]? // at least 1 elements public let extensions: [DivExtension]? // at least 1 elements public let focus: DivFocus? - public let fontFamily: Expression // default value: text + public let fontFamily: Expression? // at least 1 char public let fontSize: Expression // constraint: number >= 0; default value: 12 public let fontSizeUnit: Expression // default value: sp public let fontWeight: Expression // default value: regular @@ -84,8 +84,8 @@ public final class DivSelect: DivBase { resolver.resolveNumericValue(expression: columnSpan) } - public func resolveFontFamily(_ resolver: ExpressionResolver) -> DivFontFamily { - resolver.resolveStringBasedValue(expression: fontFamily, initializer: DivFontFamily.init(rawValue:)) ?? DivFontFamily.text + public func resolveFontFamily(_ resolver: ExpressionResolver) -> String? { + resolver.resolveStringBasedValue(expression: fontFamily, initializer: { $0 }) } public func resolveFontSize(_ resolver: ExpressionResolver) -> Int { @@ -158,8 +158,8 @@ public final class DivSelect: DivBase { static let focusValidator: AnyValueValidator = makeNoOpValueValidator() - static let fontFamilyValidator: AnyValueValidator = - makeNoOpValueValidator() + static let fontFamilyValidator: AnyValueValidator = + makeStringValidator(minLength: 1) static let fontSizeValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -247,7 +247,7 @@ public final class DivSelect: DivBase { disappearActions: [DivDisappearAction]? = nil, extensions: [DivExtension]? = nil, focus: DivFocus? = nil, - fontFamily: Expression? = nil, + fontFamily: Expression? = nil, fontSize: Expression? = nil, fontSizeUnit: Expression? = nil, fontWeight: Expression? = nil, @@ -285,7 +285,7 @@ public final class DivSelect: DivBase { self.disappearActions = disappearActions self.extensions = extensions self.focus = focus - self.fontFamily = fontFamily ?? .value(.text) + self.fontFamily = fontFamily self.fontSize = fontSize ?? .value(12) self.fontSizeUnit = fontSizeUnit ?? .value(.sp) self.fontWeight = fontWeight ?? .value(.regular) @@ -426,7 +426,7 @@ extension DivSelect: Serializable { result["disappear_actions"] = disappearActions?.map { $0.toDictionary() } result["extensions"] = extensions?.map { $0.toDictionary() } result["focus"] = focus?.toDictionary() - result["font_family"] = fontFamily.toValidSerializationValue() + result["font_family"] = fontFamily?.toValidSerializationValue() result["font_size"] = fontSize.toValidSerializationValue() result["font_size_unit"] = fontSizeUnit.toValidSerializationValue() result["font_weight"] = fontWeight.toValidSerializationValue() diff --git a/client/ios/DivKit/generated_sources/DivSelectTemplate.swift b/client/ios/DivKit/generated_sources/DivSelectTemplate.swift index 2af1ac558..436eba44b 100644 --- a/client/ios/DivKit/generated_sources/DivSelectTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivSelectTemplate.swift @@ -109,7 +109,7 @@ public final class DivSelectTemplate: TemplateValue { public let disappearActions: Field<[DivDisappearActionTemplate]>? // at least 1 elements public let extensions: Field<[DivExtensionTemplate]>? // at least 1 elements public let focus: Field? - public let fontFamily: Field>? // default value: text + public let fontFamily: Field>? // at least 1 char public let fontSize: Field>? // constraint: number >= 0; default value: 12 public let fontSizeUnit: Field>? // default value: sp public let fontWeight: Field>? // default value: regular @@ -199,7 +199,7 @@ public final class DivSelectTemplate: TemplateValue { disappearActions: Field<[DivDisappearActionTemplate]>? = nil, extensions: Field<[DivExtensionTemplate]>? = nil, focus: Field? = nil, - fontFamily: Field>? = nil, + fontFamily: Field>? = nil, fontSize: Field>? = nil, fontSizeUnit: Field>? = nil, fontWeight: Field>? = nil, @@ -412,7 +412,7 @@ public final class DivSelectTemplate: TemplateValue { var disappearActionsValue: DeserializationResult<[DivDisappearAction]> = .noValue var extensionsValue: DeserializationResult<[DivExtension]> = .noValue var focusValue: DeserializationResult = .noValue - var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue + var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue var fontSizeValue: DeserializationResult> = parent?.fontSize?.value() ?? .noValue var fontSizeUnitValue: DeserializationResult> = parent?.fontSizeUnit?.value() ?? .noValue var fontWeightValue: DeserializationResult> = parent?.fontWeight?.value() ?? .noValue diff --git a/client/ios/DivKit/generated_sources/DivTabs.swift b/client/ios/DivKit/generated_sources/DivTabs.swift index 7dcc70db2..c88a64c1c 100644 --- a/client/ios/DivKit/generated_sources/DivTabs.swift +++ b/client/ios/DivKit/generated_sources/DivTabs.swift @@ -46,7 +46,7 @@ public final class DivTabs: DivBase { public let animationType: Expression // default value: slide public let cornerRadius: Expression? // constraint: number >= 0 public let cornersRadius: DivCornersRadius? - public let fontFamily: Expression // default value: text + public let fontFamily: Expression? // at least 1 char public let fontSize: Expression // constraint: number >= 0; default value: 12 public let fontSizeUnit: Expression // default value: sp public let fontWeight: Expression // default value: regular @@ -82,8 +82,8 @@ public final class DivTabs: DivBase { resolver.resolveNumericValue(expression: cornerRadius) } - public func resolveFontFamily(_ resolver: ExpressionResolver) -> DivFontFamily { - resolver.resolveStringBasedValue(expression: fontFamily, initializer: DivFontFamily.init(rawValue:)) ?? DivFontFamily.text + public func resolveFontFamily(_ resolver: ExpressionResolver) -> String? { + resolver.resolveStringBasedValue(expression: fontFamily, initializer: { $0 }) } public func resolveFontSize(_ resolver: ExpressionResolver) -> Int { @@ -143,8 +143,8 @@ public final class DivTabs: DivBase { static let cornersRadiusValidator: AnyValueValidator = makeNoOpValueValidator() - static let fontFamilyValidator: AnyValueValidator = - makeNoOpValueValidator() + static let fontFamilyValidator: AnyValueValidator = + makeStringValidator(minLength: 1) static let fontSizeValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -181,7 +181,7 @@ public final class DivTabs: DivBase { animationType: Expression? = nil, cornerRadius: Expression? = nil, cornersRadius: DivCornersRadius? = nil, - fontFamily: Expression? = nil, + fontFamily: Expression? = nil, fontSize: Expression? = nil, fontSizeUnit: Expression? = nil, fontWeight: Expression? = nil, @@ -200,7 +200,7 @@ public final class DivTabs: DivBase { self.animationType = animationType ?? .value(.slide) self.cornerRadius = cornerRadius self.cornersRadius = cornersRadius - self.fontFamily = fontFamily ?? .value(.text) + self.fontFamily = fontFamily self.fontSize = fontSize ?? .value(12) self.fontSizeUnit = fontSizeUnit ?? .value(.sp) self.fontWeight = fontWeight ?? .value(.regular) @@ -706,7 +706,7 @@ extension DivTabs.TabTitleStyle: Serializable { result["animation_type"] = animationType.toValidSerializationValue() result["corner_radius"] = cornerRadius?.toValidSerializationValue() result["corners_radius"] = cornersRadius?.toDictionary() - result["font_family"] = fontFamily.toValidSerializationValue() + result["font_family"] = fontFamily?.toValidSerializationValue() result["font_size"] = fontSize.toValidSerializationValue() result["font_size_unit"] = fontSizeUnit.toValidSerializationValue() result["font_weight"] = fontWeight.toValidSerializationValue() diff --git a/client/ios/DivKit/generated_sources/DivTabsTemplate.swift b/client/ios/DivKit/generated_sources/DivTabsTemplate.swift index df2261c85..9dfc944e6 100644 --- a/client/ios/DivKit/generated_sources/DivTabsTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivTabsTemplate.swift @@ -139,7 +139,7 @@ public final class DivTabsTemplate: TemplateValue { public let animationType: Field>? // default value: slide public let cornerRadius: Field>? // constraint: number >= 0 public let cornersRadius: Field? - public let fontFamily: Field>? // default value: text + public let fontFamily: Field>? // at least 1 char public let fontSize: Field>? // constraint: number >= 0; default value: 12 public let fontSizeUnit: Field>? // default value: sp public let fontWeight: Field>? // default value: regular @@ -182,7 +182,7 @@ public final class DivTabsTemplate: TemplateValue { animationType: Field>? = nil, cornerRadius: Field>? = nil, cornersRadius: Field? = nil, - fontFamily: Field>? = nil, + fontFamily: Field>? = nil, fontSize: Field>? = nil, fontSizeUnit: Field>? = nil, fontWeight: Field>? = nil, @@ -287,7 +287,7 @@ public final class DivTabsTemplate: TemplateValue { var animationTypeValue: DeserializationResult> = parent?.animationType?.value() ?? .noValue var cornerRadiusValue: DeserializationResult> = parent?.cornerRadius?.value() ?? .noValue var cornersRadiusValue: DeserializationResult = .noValue - var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue + var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue var fontSizeValue: DeserializationResult> = parent?.fontSize?.value() ?? .noValue var fontSizeUnitValue: DeserializationResult> = parent?.fontSizeUnit?.value() ?? .noValue var fontWeightValue: DeserializationResult> = parent?.fontWeight?.value() ?? .noValue diff --git a/client/ios/DivKit/generated_sources/DivText.swift b/client/ios/DivKit/generated_sources/DivText.swift index e84725069..d7ec76b92 100644 --- a/client/ios/DivKit/generated_sources/DivText.swift +++ b/client/ios/DivKit/generated_sources/DivText.swift @@ -101,7 +101,7 @@ public final class DivText: DivBase { public let background: DivTextRangeBackground? public let border: DivTextRangeBorder? public let end: Expression // constraint: number > 0 - public let fontFamily: Expression? + public let fontFamily: Expression? // at least 1 char public let fontSize: Expression? // constraint: number >= 0 public let fontSizeUnit: Expression // default value: sp public let fontWeight: Expression? @@ -117,8 +117,8 @@ public final class DivText: DivBase { resolver.resolveNumericValue(expression: end) } - public func resolveFontFamily(_ resolver: ExpressionResolver) -> DivFontFamily? { - resolver.resolveStringBasedValue(expression: fontFamily, initializer: DivFontFamily.init(rawValue:)) + public func resolveFontFamily(_ resolver: ExpressionResolver) -> String? { + resolver.resolveStringBasedValue(expression: fontFamily, initializer: { $0 }) } public func resolveFontSize(_ resolver: ExpressionResolver) -> Int? { @@ -173,8 +173,8 @@ public final class DivText: DivBase { static let endValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) - static let fontFamilyValidator: AnyValueValidator = - makeNoOpValueValidator() + static let fontFamilyValidator: AnyValueValidator = + makeStringValidator(minLength: 1) static let fontSizeValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -208,7 +208,7 @@ public final class DivText: DivBase { background: DivTextRangeBackground? = nil, border: DivTextRangeBorder? = nil, end: Expression, - fontFamily: Expression? = nil, + fontFamily: Expression? = nil, fontSize: Expression? = nil, fontSizeUnit: Expression? = nil, fontWeight: Expression? = nil, @@ -256,7 +256,7 @@ public final class DivText: DivBase { public let extensions: [DivExtension]? // at least 1 elements public let focus: DivFocus? public let focusedTextColor: Expression? - public let fontFamily: Expression // default value: text + public let fontFamily: Expression? // at least 1 char public let fontSize: Expression // constraint: number >= 0; default value: 12 public let fontSizeUnit: Expression // default value: sp public let fontWeight: Expression // default value: regular @@ -316,8 +316,8 @@ public final class DivText: DivBase { resolver.resolveStringBasedValue(expression: focusedTextColor, initializer: Color.color(withHexString:)) } - public func resolveFontFamily(_ resolver: ExpressionResolver) -> DivFontFamily { - resolver.resolveStringBasedValue(expression: fontFamily, initializer: DivFontFamily.init(rawValue:)) ?? DivFontFamily.text + public func resolveFontFamily(_ resolver: ExpressionResolver) -> String? { + resolver.resolveStringBasedValue(expression: fontFamily, initializer: { $0 }) } public func resolveFontSize(_ resolver: ExpressionResolver) -> Int { @@ -435,8 +435,8 @@ public final class DivText: DivBase { static let focusedTextColorValidator: AnyValueValidator = makeNoOpValueValidator() - static let fontFamilyValidator: AnyValueValidator = - makeNoOpValueValidator() + static let fontFamilyValidator: AnyValueValidator = + makeStringValidator(minLength: 1) static let fontSizeValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -555,7 +555,7 @@ public final class DivText: DivBase { extensions: [DivExtension]? = nil, focus: DivFocus? = nil, focusedTextColor: Expression? = nil, - fontFamily: Expression? = nil, + fontFamily: Expression? = nil, fontSize: Expression? = nil, fontSizeUnit: Expression? = nil, fontWeight: Expression? = nil, @@ -608,7 +608,7 @@ public final class DivText: DivBase { self.extensions = extensions self.focus = focus self.focusedTextColor = focusedTextColor - self.fontFamily = fontFamily ?? .value(.text) + self.fontFamily = fontFamily self.fontSize = fontSize ?? .value(12) self.fontSizeUnit = fontSizeUnit ?? .value(.sp) self.fontWeight = fontWeight ?? .value(.regular) @@ -799,7 +799,7 @@ extension DivText: Serializable { result["extensions"] = extensions?.map { $0.toDictionary() } result["focus"] = focus?.toDictionary() result["focused_text_color"] = focusedTextColor?.toValidSerializationValue() - result["font_family"] = fontFamily.toValidSerializationValue() + result["font_family"] = fontFamily?.toValidSerializationValue() result["font_size"] = fontSize.toValidSerializationValue() result["font_size_unit"] = fontSizeUnit.toValidSerializationValue() result["font_weight"] = fontWeight.toValidSerializationValue() diff --git a/client/ios/DivKit/generated_sources/DivTextTemplate.swift b/client/ios/DivKit/generated_sources/DivTextTemplate.swift index fc77bf113..8ac70e186 100644 --- a/client/ios/DivKit/generated_sources/DivTextTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivTextTemplate.swift @@ -311,7 +311,7 @@ public final class DivTextTemplate: TemplateValue { public let background: Field? public let border: Field? public let end: Field>? // constraint: number > 0 - public let fontFamily: Field>? + public let fontFamily: Field>? // at least 1 char public let fontSize: Field>? // constraint: number >= 0 public let fontSizeUnit: Field>? // default value: sp public let fontWeight: Field>? @@ -352,7 +352,7 @@ public final class DivTextTemplate: TemplateValue { background: Field? = nil, border: Field? = nil, end: Field>? = nil, - fontFamily: Field>? = nil, + fontFamily: Field>? = nil, fontSize: Field>? = nil, fontSizeUnit: Field>? = nil, fontWeight: Field>? = nil, @@ -454,7 +454,7 @@ public final class DivTextTemplate: TemplateValue { var backgroundValue: DeserializationResult = .noValue var borderValue: DeserializationResult = .noValue var endValue: DeserializationResult> = parent?.end?.value() ?? .noValue - var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue + var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue var fontSizeValue: DeserializationResult> = parent?.fontSize?.value() ?? .noValue var fontSizeUnitValue: DeserializationResult> = parent?.fontSizeUnit?.value() ?? .noValue var fontWeightValue: DeserializationResult> = parent?.fontWeight?.value() ?? .noValue @@ -630,7 +630,7 @@ public final class DivTextTemplate: TemplateValue { public let extensions: Field<[DivExtensionTemplate]>? // at least 1 elements public let focus: Field? public let focusedTextColor: Field>? - public let fontFamily: Field>? // default value: text + public let fontFamily: Field>? // at least 1 char public let fontSize: Field>? // constraint: number >= 0; default value: 12 public let fontSizeUnit: Field>? // default value: sp public let fontWeight: Field>? // default value: regular @@ -750,7 +750,7 @@ public final class DivTextTemplate: TemplateValue { extensions: Field<[DivExtensionTemplate]>? = nil, focus: Field? = nil, focusedTextColor: Field>? = nil, - fontFamily: Field>? = nil, + fontFamily: Field>? = nil, fontSize: Field>? = nil, fontSizeUnit: Field>? = nil, fontWeight: Field>? = nil, @@ -1034,7 +1034,7 @@ public final class DivTextTemplate: TemplateValue { var extensionsValue: DeserializationResult<[DivExtension]> = .noValue var focusValue: DeserializationResult = .noValue var focusedTextColorValue: DeserializationResult> = parent?.focusedTextColor?.value() ?? .noValue - var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue + var fontFamilyValue: DeserializationResult> = parent?.fontFamily?.value() ?? .noValue var fontSizeValue: DeserializationResult> = parent?.fontSize?.value() ?? .noValue var fontSizeUnitValue: DeserializationResult> = parent?.fontSizeUnit?.value() ?? .noValue var fontWeightValue: DeserializationResult> = parent?.fontWeight?.value() ?? .noValue diff --git a/client/ios/DivKitPlayground/AppComponents.swift b/client/ios/DivKitPlayground/AppComponents.swift index a29995353..ab6810bca 100644 --- a/client/ios/DivKitPlayground/AppComponents.swift +++ b/client/ios/DivKitPlayground/AppComponents.swift @@ -7,6 +7,8 @@ import LayoutKit import NetworkingPublic enum AppComponents { + static let fontProvider = YSFontProvider() + static func makeDivKitComponents( updateCardAction: DivKitComponents.UpdateCardAction? = nil, urlOpener: @escaping UrlOpener = { _ in } @@ -29,6 +31,7 @@ enum AppComponents { ShimmerImagePreviewExtension(), ], flagsInfo: DivFlagsInfo(), + fontProvider: fontProvider, patchProvider: DemoPatchProvider(), trackVisibility: { logId, cardId in print( diff --git a/client/ios/DivKitPlayground/DivKit/DivBlockProvider.swift b/client/ios/DivKitPlayground/DivKit/DivBlockProvider.swift index f27d9f8ea..9ffef5e09 100644 --- a/client/ios/DivKitPlayground/DivKit/DivBlockProvider.swift +++ b/client/ios/DivKitPlayground/DivKit/DivBlockProvider.swift @@ -1,6 +1,5 @@ import UIKit -import BaseUIPublic import CommonCorePublic import DivKit import DivKitExtensions @@ -182,7 +181,7 @@ private let noDataBlock = EmptyBlock.zeroSized private func makeErrorBlock(_ text: String) -> Block { TextBlock( widthTrait: .resizable, - text: text.with(typo: Typo(size: 18, weight: .regular)) + text: text.withTypo(size: 18) ).addingEdgeGaps(20) } @@ -194,13 +193,13 @@ private func makeErrorsBlock(_ errors: [String]) -> Block { let separator = SeparatorBlock(color: .gray, direction: .horizontal) let errorsHeader = TextBlock( widthTrait: .resizable, - text: "Errors: \(errors.count)".with(typo: Typo(size: 18, weight: .bold)) + text: "Errors: \(errors.count)".withTypo(size: 18, weight: .bold) ).addingEdgeGaps(10) let errorBlocks = errors.map { TextBlock( widthTrait: .resizable, - text: $0.with(typo: Typo(size: 14, weight: .regular)) + text: $0.withTypo(size: 14, weight: .regular) ).addingEdgeGaps(10) } return try! ContainerBlock( @@ -233,7 +232,7 @@ extension Block { let textBlock = TextBlock( widthTrait: .resizable, - text: text.with(typo: Typo(size: 18, weight: .regular)) + text: text.withTypo(size: 18) ).addingEdgeGaps(20) let block = try? ContainerBlock( diff --git a/client/ios/DivKitPlayground/DivKit/PlaygroundDivCustomBlockFactory.swift b/client/ios/DivKitPlayground/DivKit/PlaygroundDivCustomBlockFactory.swift index 369c7bd1a..d6028492b 100644 --- a/client/ios/DivKitPlayground/DivKit/PlaygroundDivCustomBlockFactory.swift +++ b/client/ios/DivKitPlayground/DivKit/PlaygroundDivCustomBlockFactory.swift @@ -1,7 +1,4 @@ -import Foundation - import BasePublic -import BaseUIPublic import DivKit import LayoutKit @@ -21,8 +18,7 @@ struct PlaygroundDivCustomBlockFactory: DivCustomBlockFactory { } else { return TextBlock( widthTrait: .intrinsic, - text: NSAttributedString(string: "DivCustom(custom_type = \(data.name))") - .with(typo: Typo(size: 16, weight: .regular)) + text: "DivCustom(custom_type = \(data.name))".withTypo(size: 16, weight: .regular) ) } } diff --git a/client/ios/DivKitPlayground/DivKitPlaygroundApp.swift b/client/ios/DivKitPlayground/DivKitPlaygroundApp.swift index 0c34afceb..c23809d8f 100644 --- a/client/ios/DivKitPlayground/DivKitPlaygroundApp.swift +++ b/client/ios/DivKitPlayground/DivKitPlaygroundApp.swift @@ -7,12 +7,6 @@ import DivKit struct DivKitPlaygroundApp: App { init() { DivKitLogger.isEnabled = true - - let fontProvider = YSFontProvider() - fontSpecifiers = FontSpecifiers( - text: fontProvider, - display: fontProvider - ) } var body: some Scene { diff --git a/client/ios/DivKitPlayground/Fonts/YSFontProvider.swift b/client/ios/DivKitPlayground/Fonts/YSFontProvider.swift index db5c64794..e75fd0e4f 100644 --- a/client/ios/DivKitPlayground/Fonts/YSFontProvider.swift +++ b/client/ios/DivKitPlayground/Fonts/YSFontProvider.swift @@ -1,25 +1,24 @@ -import CoreGraphics import UIKit -import BaseUIPublic +import DivKit -final class YSFontProvider: FontSpecifying { +final class YSFontProvider: DivFontProvider { static let mediumFontName = "YSText-Medium" static let regularFontName = "YSText-Regular" - func font(weight: FontWeight, size: CGFloat) -> UIFont { + func font(family _: String, weight: DivFontWeight, size: CGFloat) -> UIFont { UIFont(name: weight.fontName, size: size)! } } -extension FontWeight { +extension DivFontWeight { fileprivate var fontName: String { switch self { case .light: return "YSText-Light" case .regular: return YSFontProvider.regularFontName - case .medium, .semibold: + case .medium: return YSFontProvider.mediumFontName case .bold: return "YSText-Bold" diff --git a/client/ios/DivKitPlayground/UI/DivView/SimpleDivView.swift b/client/ios/DivKitPlayground/UI/DivView/SimpleDivView.swift index 2fcbbda2f..126ed797c 100644 --- a/client/ios/DivKitPlayground/UI/DivView/SimpleDivView.swift +++ b/client/ios/DivKitPlayground/UI/DivView/SimpleDivView.swift @@ -1,7 +1,6 @@ import SwiftUI import UIKit -import BaseUIPublic import CommonCorePublic import DivKit import LayoutKit @@ -139,6 +138,6 @@ private let noDataBlock = EmptyBlock.zeroSized private func makeErrorBlock(_ text: String) -> Block { TextBlock( widthTrait: .resizable, - text: text.with(typo: Typo(size: 18, weight: .regular)) + text: text.withTypo(size: 18) ).addingEdgeGaps(20) } diff --git a/client/ios/DivKitPlayground/Utils/StringUtils.swift b/client/ios/DivKitPlayground/Utils/StringUtils.swift new file mode 100644 index 000000000..3a07cc88a --- /dev/null +++ b/client/ios/DivKitPlayground/Utils/StringUtils.swift @@ -0,0 +1,14 @@ +import Foundation +import CoreGraphics + +import BaseUIPublic +import DivKit + +extension String { + func withTypo(size: CGFloat, weight: DivFontWeight = .regular) -> NSAttributedString { + let typo = Typo( + font: AppComponents.fontProvider.font(weight: weight, size: size) + ) + return NSAttributedString(string: self).with(typo: typo) + } +} diff --git a/client/ios/DivKitSnapshotTests/DivKitSnapshotTestCase.swift b/client/ios/DivKitSnapshotTests/DivKitSnapshotTestCase.swift index 8dc181a85..115ea37c4 100644 --- a/client/ios/DivKitSnapshotTests/DivKitSnapshotTestCase.swift +++ b/client/ios/DivKitSnapshotTests/DivKitSnapshotTestCase.swift @@ -57,7 +57,7 @@ open class DivKitSnapshotTestCase: XCTestCase { let divKitComponents = DivKitComponents( extensionHandlers: extensions, - flagsInfo: DivFlagsInfo(), + fontProvider: YSFontProvider(), imageHolderFactory: imageHolderFactory ?? makeImageHolderFactory(), updateCardAction: nil, urlOpener: { _ in } diff --git a/client/ios/DivKitSnapshotTests/YSFontProvider.swift b/client/ios/DivKitSnapshotTests/YSFontProvider.swift new file mode 100644 index 000000000..6a09923e7 --- /dev/null +++ b/client/ios/DivKitSnapshotTests/YSFontProvider.swift @@ -0,0 +1,25 @@ +import UIKit + +import BaseUIPublic +import DivKit + +final class YSFontProvider: DivFontProvider { + func font(family _: String, weight: DivFontWeight, size: CGFloat) -> UIFont { + UIFont(name: weight.fontName, size: size)! + } +} + +extension DivFontWeight { + fileprivate var fontName: String { + switch self { + case .light: + return "YSText-Light" + case .regular: + return "YSText-Regular" + case .medium: + return "YSText-Medium" + case .bold: + return "YSText-Bold" + } + } +} diff --git a/client/ios/LayoutKitSnapshotTests/AnchorBlockTests.swift b/client/ios/LayoutKitSnapshotTests/AnchorBlockTests.swift index adef5731b..13e156090 100644 --- a/client/ios/LayoutKitSnapshotTests/AnchorBlockTests.swift +++ b/client/ios/LayoutKitSnapshotTests/AnchorBlockTests.swift @@ -1,11 +1,10 @@ import CoreGraphics -import XCTest import BaseUIPublic import CommonCorePublic import LayoutKit -final class AnchorBlockTests: XCTestCase { +final class AnchorBlockTests: LayoutKitSnapshotTest { func test_OnlyCenter_Fits() { perform(.crossResizables(center: 100)) } @@ -114,7 +113,7 @@ final class AnchorBlockTests: XCTestCase { ).addingDecorations(border: .init(color: .blue)) ).addingDecorations(border: .init(color: .red)) - LayoutKitSnapshotTest.perform( + perform( on: makeCenterOverlay(content: anchor, color: .red) .addingDecorations(border: .init(color: .gray)), size: size, diff --git a/client/ios/LayoutKitSnapshotTests/LayoutKitSnapshotTest.swift b/client/ios/LayoutKitSnapshotTests/LayoutKitSnapshotTest.swift index 2332e20ca..800c19627 100644 --- a/client/ios/LayoutKitSnapshotTests/LayoutKitSnapshotTest.swift +++ b/client/ios/LayoutKitSnapshotTests/LayoutKitSnapshotTest.swift @@ -1,10 +1,19 @@ import CoreGraphics -import Foundation +import XCTest +import BaseUIPublic import LayoutKit -enum LayoutKitSnapshotTest { - static func perform( +class LayoutKitSnapshotTest: XCTestCase { + override func setUp() { + let fontProvider = YSFontProvider() + fontSpecifiers = FontSpecifiers( + text: fontProvider, + display: fontProvider + ) + } + + func perform( on renderable: UIViewRenderable, size: CGSize, name: String = #function, diff --git a/client/ios/LayoutKitSnapshotTests/SwitchableContainerSnapshotTest.swift b/client/ios/LayoutKitSnapshotTests/SwitchableContainerSnapshotTest.swift index c1259bf66..bc27567d2 100644 --- a/client/ios/LayoutKitSnapshotTests/SwitchableContainerSnapshotTest.swift +++ b/client/ios/LayoutKitSnapshotTests/SwitchableContainerSnapshotTest.swift @@ -1,10 +1,8 @@ -import XCTest - import BaseUIPublic import CommonCorePublic import LayoutKit -final class SwitchableContainerSnapshotTest: XCTestCase { +final class SwitchableContainerSnapshotTest: LayoutKitSnapshotTest { func test_LeftSideSelected() { performTest(selection: .left, mode: mode) } @@ -106,7 +104,7 @@ final class SwitchableContainerSnapshotTest: XCTestCase { path: UIElementPath("R") ) - LayoutKitSnapshotTest.perform(on: block, size: blockViewSize, name: name, mode: mode) + perform(on: block, size: blockViewSize, name: name, mode: mode) } } diff --git a/client/ios/LayoutKitSnapshotTests/TooltipFactorySnapshotTests.swift b/client/ios/LayoutKitSnapshotTests/TooltipFactorySnapshotTests.swift index 857979266..af69b75ce 100644 --- a/client/ios/LayoutKitSnapshotTests/TooltipFactorySnapshotTests.swift +++ b/client/ios/LayoutKitSnapshotTests/TooltipFactorySnapshotTests.swift @@ -1,10 +1,9 @@ import CoreGraphics -import XCTest import CommonCorePublic import LayoutKit -final class TooltipFactorySnapshotTests: XCTestCase { +final class TooltipFactorySnapshotTests: LayoutKitSnapshotTest { func test_Orientations() { BlockTooltip.Position.allCases.forEach { perform(text: "Тултип", position: $0, width: nil) @@ -30,7 +29,7 @@ final class TooltipFactorySnapshotTests: XCTestCase { position: position, width: width ) - LayoutKitSnapshotTest.perform( + perform( on: block, size: block.intrinsicSize, name: "\(name)_\(position)", diff --git a/client/ios/SnapshotTestsHostApp/FontProvider.swift b/client/ios/LayoutKitSnapshotTests/YSFontProvider.swift similarity index 87% rename from client/ios/SnapshotTestsHostApp/FontProvider.swift rename to client/ios/LayoutKitSnapshotTests/YSFontProvider.swift index 85d1a1fc5..a8e317be4 100644 --- a/client/ios/SnapshotTestsHostApp/FontProvider.swift +++ b/client/ios/LayoutKitSnapshotTests/YSFontProvider.swift @@ -1,9 +1,8 @@ -import CoreGraphics import UIKit import BaseUIPublic -final class FontProvider: FontSpecifying { +final class YSFontProvider: FontSpecifying { func font(weight: FontWeight, size: CGFloat) -> UIFont { UIFont(name: weight.fontName, size: size)! } diff --git a/client/ios/SnapshotTestsHostApp/AppDelegate.swift b/client/ios/SnapshotTestsHostApp/AppDelegate.swift index 678645bd4..3ce0e7ac8 100644 --- a/client/ios/SnapshotTestsHostApp/AppDelegate.swift +++ b/client/ios/SnapshotTestsHostApp/AppDelegate.swift @@ -1,7 +1,5 @@ import UIKit -import BaseUIPublic - @UIApplicationMain final class AppDelegate: NSObject, UIApplicationDelegate { var window: UIWindow? = UIWindow() @@ -10,9 +8,6 @@ final class AppDelegate: NSObject, UIApplicationDelegate { _: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - let provider = FontProvider() - fontSpecifiers = FontSpecifiers(text: provider, display: provider) - window?.rootViewController = ViewController(nibName: nil, bundle: nil) window?.makeKeyAndVisible()