diff --git a/.mapping.json b/.mapping.json index 67f4d729..17eac1b6 100644 --- a/.mapping.json +++ b/.mapping.json @@ -28,6 +28,9 @@ "DivKit/Animators/ProgressInterpolator.swift":"divkit/public-ios/DivKit/Animators/ProgressInterpolator.swift", "DivKit/Animators/ValueInterpolator.swift":"divkit/public-ios/DivKit/Animators/ValueInterpolator.swift", "DivKit/Debug/Block+DebugInfo.swift":"divkit/public-ios/DivKit/Debug/Block+DebugInfo.swift", + "DivKit/Debug/DebugBlock+UIViewRenderableBlock.swift":"divkit/public-ios/DivKit/Debug/DebugBlock+UIViewRenderableBlock.swift", + "DivKit/Debug/DebugBlock.swift":"divkit/public-ios/DivKit/Debug/DebugBlock.swift", + "DivKit/Debug/DebugErrorCollector.swift":"divkit/public-ios/DivKit/Debug/DebugErrorCollector.swift", "DivKit/Debug/DebugParams.swift":"divkit/public-ios/DivKit/Debug/DebugParams.swift", "DivKit/Debug/ErrorListView.swift":"divkit/public-ios/DivKit/Debug/ErrorListView.swift", "DivKit/DivAccessibilityElementsStorage.swift":"divkit/public-ios/DivKit/DivAccessibilityElementsStorage.swift", @@ -181,6 +184,7 @@ "DivKit/Timers/DivTimerStorage.swift":"divkit/public-ios/DivKit/Timers/DivTimerStorage.swift", "DivKit/Timers/TimeIntervalMeasuring.swift":"divkit/public-ios/DivKit/Timers/TimeIntervalMeasuring.swift", "DivKit/Tooltips/DivTooltipViewFactory.swift":"divkit/public-ios/DivKit/Tooltips/DivTooltipViewFactory.swift", + "DivKit/Types.swift":"divkit/public-ios/DivKit/Types.swift", "DivKit/Variables/DivTriggersStorage.swift":"divkit/public-ios/DivKit/Variables/DivTriggersStorage.swift", "DivKit/Variables/DivVariableName.swift":"divkit/public-ios/DivKit/Variables/DivVariableName.swift", "DivKit/Variables/DivVariableStorage.swift":"divkit/public-ios/DivKit/Variables/DivVariableStorage.swift", @@ -483,6 +487,14 @@ "DivKit/generated_sources/DivTextRangeBackgroundTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeBackgroundTemplate.swift", "DivKit/generated_sources/DivTextRangeBorder.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeBorder.swift", "DivKit/generated_sources/DivTextRangeBorderTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeBorderTemplate.swift", + "DivKit/generated_sources/DivTextRangeMask.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMask.swift", + "DivKit/generated_sources/DivTextRangeMaskBase.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskBase.swift", + "DivKit/generated_sources/DivTextRangeMaskBaseTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskBaseTemplate.swift", + "DivKit/generated_sources/DivTextRangeMaskParticles.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskParticles.swift", + "DivKit/generated_sources/DivTextRangeMaskParticlesTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskParticlesTemplate.swift", + "DivKit/generated_sources/DivTextRangeMaskSolid.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskSolid.swift", + "DivKit/generated_sources/DivTextRangeMaskSolidTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskSolidTemplate.swift", + "DivKit/generated_sources/DivTextRangeMaskTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextRangeMaskTemplate.swift", "DivKit/generated_sources/DivTextTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTextTemplate.swift", "DivKit/generated_sources/DivTimer.swift":"divkit/public-ios/DivKit/generated_sources/DivTimer.swift", "DivKit/generated_sources/DivTimerTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivTimerTemplate.swift", @@ -717,6 +729,7 @@ "LayoutKit/LayoutKit/ClosureIntrinsicCalculator.swift":"divkit/public-ios/LayoutKit/LayoutKit/ClosureIntrinsicCalculator.swift", "LayoutKit/LayoutKit/Exports.swift":"divkit/public-ios/LayoutKit/LayoutKit/Exports.swift", "LayoutKit/LayoutKit/GenericViewBlock.swift":"divkit/public-ios/LayoutKit/LayoutKit/GenericViewBlock.swift", + "LayoutKit/LayoutKit/Tooltips/TooltipAnchorView.swift":"divkit/public-ios/LayoutKit/LayoutKit/Tooltips/TooltipAnchorView.swift", "LayoutKit/LayoutKit/Tooltips/TooltipFactory.swift":"divkit/public-ios/LayoutKit/LayoutKit/Tooltips/TooltipFactory.swift", "LayoutKit/LayoutKit/Tooltips/TooltipManager.swift":"divkit/public-ios/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift", "LayoutKit/LayoutKit/Types.swift":"divkit/public-ios/LayoutKit/LayoutKit/Types.swift", @@ -1011,6 +1024,7 @@ "Specs/DivKit/30.30.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.30.0/DivKit.podspec", "Specs/DivKit/30.31.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.31.0/DivKit.podspec", "Specs/DivKit/30.32.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.32.0/DivKit.podspec", + "Specs/DivKit/30.33.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.33.0/DivKit.podspec", "Specs/DivKit/30.4.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.4.0/DivKit.podspec", "Specs/DivKit/30.5.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.5.0/DivKit.podspec", "Specs/DivKit/30.6.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/30.6.0/DivKit.podspec", @@ -1095,6 +1109,7 @@ "Specs/DivKitExtensions/30.30.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.30.0/DivKitExtensions.podspec", "Specs/DivKitExtensions/30.31.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.31.0/DivKitExtensions.podspec", "Specs/DivKitExtensions/30.32.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.32.0/DivKitExtensions.podspec", + "Specs/DivKitExtensions/30.33.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.33.0/DivKitExtensions.podspec", "Specs/DivKitExtensions/30.4.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.4.0/DivKitExtensions.podspec", "Specs/DivKitExtensions/30.5.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.5.0/DivKitExtensions.podspec", "Specs/DivKitExtensions/30.6.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/30.6.0/DivKitExtensions.podspec", @@ -1161,6 +1176,7 @@ "Specs/DivKit_LayoutKit/30.30.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.30.0/DivKit_LayoutKit.podspec", "Specs/DivKit_LayoutKit/30.31.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.31.0/DivKit_LayoutKit.podspec", "Specs/DivKit_LayoutKit/30.32.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.32.0/DivKit_LayoutKit.podspec", + "Specs/DivKit_LayoutKit/30.33.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.33.0/DivKit_LayoutKit.podspec", "Specs/DivKit_LayoutKit/30.4.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.4.0/DivKit_LayoutKit.podspec", "Specs/DivKit_LayoutKit/30.5.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.5.0/DivKit_LayoutKit.podspec", "Specs/DivKit_LayoutKit/30.6.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/30.6.0/DivKit_LayoutKit.podspec", @@ -1227,6 +1243,7 @@ "Specs/DivKit_LayoutKitInterface/30.30.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.30.0/DivKit_LayoutKitInterface.podspec", "Specs/DivKit_LayoutKitInterface/30.31.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.31.0/DivKit_LayoutKitInterface.podspec", "Specs/DivKit_LayoutKitInterface/30.32.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.32.0/DivKit_LayoutKitInterface.podspec", + "Specs/DivKit_LayoutKitInterface/30.33.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.33.0/DivKit_LayoutKitInterface.podspec", "Specs/DivKit_LayoutKitInterface/30.4.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.4.0/DivKit_LayoutKitInterface.podspec", "Specs/DivKit_LayoutKitInterface/30.5.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.5.0/DivKit_LayoutKitInterface.podspec", "Specs/DivKit_LayoutKitInterface/30.6.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/30.6.0/DivKit_LayoutKitInterface.podspec", @@ -1293,6 +1310,7 @@ "Specs/DivKit_Serialization/30.30.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.30.0/DivKit_Serialization.podspec", "Specs/DivKit_Serialization/30.31.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.31.0/DivKit_Serialization.podspec", "Specs/DivKit_Serialization/30.32.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.32.0/DivKit_Serialization.podspec", + "Specs/DivKit_Serialization/30.33.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.33.0/DivKit_Serialization.podspec", "Specs/DivKit_Serialization/30.4.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.4.0/DivKit_Serialization.podspec", "Specs/DivKit_Serialization/30.5.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.5.0/DivKit_Serialization.podspec", "Specs/DivKit_Serialization/30.6.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/30.6.0/DivKit_Serialization.podspec", diff --git a/DivKit/Actions/ArrayActionsHandler.swift b/DivKit/Actions/ArrayActionsHandler.swift index 5e46a40f..4316cab4 100644 --- a/DivKit/Actions/ArrayActionsHandler.swift +++ b/DivKit/Actions/ArrayActionsHandler.swift @@ -65,11 +65,11 @@ final class ArrayActionsHandler { } extension DivActionHandlingContext { - fileprivate func getVariableValue(_ name: DivVariableName) -> [AnyHashable]? { + fileprivate func getVariableValue(_ name: DivVariableName) -> DivArray? { variablesStorage.getVariableValue(path: path, name: name) } - fileprivate func setVariableValue(_ name: DivVariableName, _ value: [AnyHashable]) { + fileprivate func setVariableValue(_ name: DivVariableName, _ value: DivArray) { variablesStorage.update(path: path, name: name, value: .array(value)) } } diff --git a/DivKit/Actions/DivActionInfo.swift b/DivKit/Actions/DivActionInfo.swift index e9df8595..d7156392 100644 --- a/DivKit/Actions/DivActionInfo.swift +++ b/DivKit/Actions/DivActionInfo.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit public struct DivActionInfo { diff --git a/DivKit/Actions/DivActionIntent.swift b/DivKit/Actions/DivActionIntent.swift index 7c0dce29..1fe1eba2 100644 --- a/DivKit/Actions/DivActionIntent.swift +++ b/DivKit/Actions/DivActionIntent.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL enum DivActionIntent { diff --git a/DivKit/Actions/DivActionURLHandler.swift b/DivKit/Actions/DivActionURLHandler.swift index f35993c4..20bf79ab 100644 --- a/DivKit/Actions/DivActionURLHandler.swift +++ b/DivKit/Actions/DivActionURLHandler.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Actions/SetStoredValueActionHandler.swift b/DivKit/Actions/SetStoredValueActionHandler.swift index 310d0571..98f3ca30 100644 --- a/DivKit/Actions/SetStoredValueActionHandler.swift +++ b/DivKit/Actions/SetStoredValueActionHandler.swift @@ -40,8 +40,10 @@ extension DivTypedValue { .string case .urlValue: .url - case .arrayValue, .dictValue: - nil + case .arrayValue: + .array + case .dictValue: + .dict } } } diff --git a/DivKit/Debug/Block+DebugInfo.swift b/DivKit/Debug/Block+DebugInfo.swift index 487cb199..d8cd21d5 100644 --- a/DivKit/Debug/Block+DebugInfo.swift +++ b/DivKit/Debug/Block+DebugInfo.swift @@ -1,83 +1,28 @@ import CoreGraphics import Foundation - import LayoutKit import VGSL extension 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 { + guard debugParams.isDebugInfoEnabled, + let debugErrorCollector = context.debugErrorCollector else { return self } - let counterText = errorsCount > maxCount - ? "\(maxCount)+" - : "\(errorsCount)" - - let typo = Typo(font: context.fontProvider.font(size: 14)) - .with(color: .white) - - let action = UserInterfaceAction( - payload: .url(DebugInfoBlock.showOverlayURL), - path: context.parentPath + "div_errors_indicator", - accessibilityElement: nil - ) - - let counter = TextBlock( - widthTrait: .intrinsic, - text: counterText.with(typo: typo) - ) - - let indicator = counter - .addingVerticalGaps(errorsButtonCounterGaps) - .addingHorizontalGaps(calculateCounterHorizontalGaps(counter: counter)) - .addingDecorations( - boundary: .clipCorner(radius: 10), - backgroundColor: .red - ) - .addingEdgeInsets(debugParams.errorCounterInsets) - .addingEdgeGaps(2) - .addingAccessibilityID(withTraits: ( - "divLayoutErrorCounter", - .button - )) - .addingDecorations(action: action) - - let debugInfoBlock = DebugInfoBlock( - child: indicator, - showDebugInfo: { - #if os(iOS) - debugParams.showDebugInfo(ErrorListView(errors: errors.map(\.prettyMessage))) - #else - return - #endif - } + let debugBlock = DebugBlock( + errorCollector: debugErrorCollector, + showDebugInfo: debugParams.showDebugInfo ) let block = LayeredBlock( widthTrait: calculatedWidthTrait, heightTrait: calculatedHeightTrait, - children: [self, debugInfoBlock] + verticalChildrenAlignment: .center, + children: [self, debugBlock] ) return block } } - -private func calculateCounterHorizontalGaps(counter: Block) -> CGFloat { - let additionalGap = (counter.intrinsicSize.height - counter.intrinsicSize.width) / 2 - return max( - errorsButtonCounterGaps, - errorsButtonCounterGaps + additionalGap - ) -} - -private let errorsButtonCounterGaps: CGFloat = 4 -private let maxCount = 9999 diff --git a/DivKit/Debug/DebugBlock+UIViewRenderableBlock.swift b/DivKit/Debug/DebugBlock+UIViewRenderableBlock.swift new file mode 100644 index 00000000..2e78a0ee --- /dev/null +++ b/DivKit/Debug/DebugBlock+UIViewRenderableBlock.swift @@ -0,0 +1,98 @@ +import LayoutKit +import UIKit +import VGSL + +extension DebugBlock: UIViewRenderable { + static func makeBlockView() -> any LayoutKit.BlockView { + DebugBlockView() + } + + func canConfigureBlockView(_ view: any LayoutKit.BlockView) -> Bool { + view is DebugBlockView + } + + func configureBlockView( + _ view: BlockView, + observer _: ElementStateObserver?, + overscrollDelegate _: ScrollDelegate?, + renderingDelegate _: RenderingDelegate? + ) { + (view as? DebugBlockView)?.configure( + errorCollector: errorCollector, + showDebugInfo: showDebugInfo + ) + } +} + +private final class DebugBlockView: BlockView, VisibleBoundsTrackingContainer { + let effectiveBackgroundColor: UIColor? = nil + let visibleBoundsTrackingSubviews: [VisibleBoundsTrackingView] = [] + + private var showDebugInfo: ((ViewType) -> Void)? + private var errorCollector: DebugErrorCollector? + private let disposePool = AutodisposePool() + + private let errorsLabel: UILabel = { + let label = UILabel(frame: CGRect(origin: .zero, size: CGSize(squareDimension: 50.0))) + label.text = "0" + label.numberOfLines = 1 + label.font = .systemFont(ofSize: 14) + label.textColor = .white + label.textAlignment = .center + label.backgroundColor = .red + label.isHidden = true + return label + }() + + init() { + super.init(frame: .zero) + addSubview(errorsLabel) + accessibilityIdentifier = "divLayoutErrorCounter" + accessibilityTraits = .button + clipsToBounds = true + addGestureRecognizer(UITapGestureRecognizer( + target: self, + action: #selector(handleTapGesture(_:)) + )) + } + + @available(*, unavailable) + required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configure( + errorCollector: DebugErrorCollector, + showDebugInfo: @escaping (ViewType) -> Void + ) { + self.showDebugInfo = showDebugInfo + if self.errorCollector !== errorCollector { + self.errorCollector = errorCollector + errorCollector.observableErrorCount.currentAndNewValues.addObserver { [weak self] _ in + self?.updateCountLabel() + }.dispose(in: disposePool) + } + } + + override func layoutSubviews() { + super.layoutSubviews() + errorsLabel.frame = bounds + layer.cornerRadius = bounds.size.height / 2 + } + + private func updateCountLabel() { + let errorsCount = errorCollector?.totalErrorCount ?? 0 + let isHidden = errorsCount == 0 + isUserInteractionEnabled = !isHidden + errorsLabel.isHidden = isHidden + errorsLabel.text = "\(min(maxCount, errorsCount))" + } + + @objc func handleTapGesture(_: UITapGestureRecognizer) { + guard let showDebugInfo, let errorCollector, errorCollector.totalErrorCount > 0 else { return } + showDebugInfo(ErrorListView(errors: errorCollector.errorList)) + } +} + +private let showOverlayURL = URL(string: "debugInfo://show")! +private let maxCount = 9999 diff --git a/DivKit/Debug/DebugBlock.swift b/DivKit/Debug/DebugBlock.swift new file mode 100644 index 00000000..1edf65de --- /dev/null +++ b/DivKit/Debug/DebugBlock.swift @@ -0,0 +1,47 @@ +import Foundation +import LayoutKit +import VGSL + +final class DebugBlock: BlockWithTraits, LayoutCachingDefaultImpl { + let widthTrait = LayoutTrait.fixed(buttonSize) + let heightTrait = LayoutTrait.fixed(buttonSize) + + var intrinsicContentWidth: CGFloat { + widthTrait.fixedValue ?? 0.0 + } + + func intrinsicContentHeight(forWidth _: CGFloat) -> CGFloat { + heightTrait.fixedValue ?? 0.0 + } + + let errorCollector: DebugErrorCollector + let showDebugInfo: (ViewType) -> Void + + init( + errorCollector: DebugErrorCollector, + showDebugInfo: @escaping (ViewType) -> Void + ) { + self.errorCollector = errorCollector + self.showDebugInfo = showDebugInfo + } + + func equals(_ other: any LayoutKit.Block) -> Bool { + if self === other { return true } + guard let other = other as? DebugBlock else { return false } + return errorCollector === other.errorCollector + } + + var debugDescription: String { + "DebugBlock errors: \(errorCollector.debugDescription))" + } + + func getImageHolders() -> [any VGSLUI.ImageHolder] { + [] + } + + func updated(withStates _: LayoutKit.BlocksState) throws -> Self { + self + } +} + +private let buttonSize = 50.0 diff --git a/DivKit/Debug/DebugErrorCollector.swift b/DivKit/Debug/DebugErrorCollector.swift new file mode 100644 index 00000000..c9b1c48e --- /dev/null +++ b/DivKit/Debug/DebugErrorCollector.swift @@ -0,0 +1,50 @@ +import VGSLFundamentals + +final class DebugErrorCollector: DivReporter { + private let wrappedDivReporter: DivReporter + + var errorStorage: DivErrorsStorage + + private(set) var layoutErrors = [DivError]() + let observableErrorCount = ObservableProperty(initialValue: 0) + + init( + wrappedDivReporter: DivReporter, + errorStorage: DivErrorsStorage + ) { + self.wrappedDivReporter = wrappedDivReporter + self.errorStorage = errorStorage + } + + func reportError(cardId: DivCardID, error: DivError) { + wrappedDivReporter.reportError(cardId: cardId, error: error) + guard !hasError(error) else { return } + layoutErrors.append(error) + observableErrorCount.value += 1 + } + + func reportAction(cardId: DivCardID, info: DivActionInfo) { + wrappedDivReporter.reportAction(cardId: cardId, info: info) + } + + var totalErrorCount: Int { + errorStorage.errors.count + layoutErrors.count + } + + var errorList: [String] { + errorStorage.errors.map(\.prettyMessage) + layoutErrors.map(\.prettyMessage) + } + + var debugDescription: String { + "Errors: \(errorList)" + } + + private func hasError(_ error: DivError) -> Bool { + layoutErrors.contains { + $0.kind == error.kind + && $0.message == error.message + && $0.path == error.path + && $0.level == error.level + } + } +} diff --git a/DivKit/Debug/ErrorListView.swift b/DivKit/Debug/ErrorListView.swift index 04e8676c..5aeafe6a 100644 --- a/DivKit/Debug/ErrorListView.swift +++ b/DivKit/Debug/ErrorListView.swift @@ -1,7 +1,6 @@ import Foundation -import UIKit - import LayoutKit +import UIKit import VGSL final class ErrorListView: UIView { diff --git a/DivKit/DivBlockModelingContext.swift b/DivKit/DivBlockModelingContext.swift index af2d1513..5cc6dd9b 100644 --- a/DivKit/DivBlockModelingContext.swift +++ b/DivKit/DivBlockModelingContext.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL @@ -10,7 +9,7 @@ import AppKit #endif public struct DivBlockModelingContext { - let viewId: DivViewId + private(set) var viewId: DivViewId private(set) var cardLogId: String? private(set) var parentDivStatePath: DivStatePath? let stateManager: DivStateManager @@ -30,6 +29,7 @@ public struct DivBlockModelingContext { let playerFactory: PlayerFactory? private(set) weak var parentScrollView: ScrollView? public private(set) var errorsStorage: DivErrorsStorage + let debugErrorCollector: DebugErrorCollector? private let persistentValuesStorage: DivPersistentValuesStorage let tooltipViewFactory: DivTooltipViewFactory? let functionsStorage: DivFunctionsStorage? @@ -102,6 +102,7 @@ public struct DivBlockModelingContext { scheduler: scheduler, parentScrollView: parentScrollView, errorsStorage: errorsStorage, + debugErrorCollector: nil, layoutDirection: layoutDirection, variableTracker: variableTracker, persistentValuesStorage: persistentValuesStorage, @@ -136,6 +137,7 @@ public struct DivBlockModelingContext { scheduler: Scheduling?, parentScrollView: ScrollView?, errorsStorage: DivErrorsStorage?, + debugErrorCollector: DebugErrorCollector?, layoutDirection: UserInterfaceLayoutDirection, variableTracker: DivVariableTracker?, persistentValuesStorage: DivPersistentValuesStorage?, @@ -146,8 +148,7 @@ public struct DivBlockModelingContext { ) { self.viewId = viewId self.cardLogId = cardLogId - let cardId = viewId.cardId - let parentPath = parentPath ?? UIElementPath(cardId.rawValue) + let parentPath = parentPath ?? makeParentPath(viewId: viewId) self.parentPath = parentPath self.parentDivStatePath = parentDivStatePath self.stateManager = stateManager @@ -165,6 +166,7 @@ public struct DivBlockModelingContext { self.scheduler = scheduler ?? TimerScheduler() self.parentScrollView = parentScrollView let errorsStorage = errorsStorage ?? DivErrorsStorage(errors: []) + self.debugErrorCollector = debugErrorCollector self.errorsStorage = errorsStorage self.layoutDirection = layoutDirection self.variableTracker = variableTracker @@ -296,6 +298,14 @@ public struct DivBlockModelingContext { return context } + + func cloneForTooltip(tooltipId: String) -> Self { + var context = self + let viewId = DivViewId(cardId: cardId, additionalId: tooltipId) + context.viewId = DivViewId(cardId: cardId, additionalId: tooltipId) + context.parentPath = makeParentPath(viewId: viewId) + return context + } } struct PrototypeParams { @@ -333,6 +343,15 @@ private func makeExpressionResolver( ) } +private func makeParentPath(viewId: DivViewId) -> UIElementPath { + let cardIdPath = UIElementPath(viewId.cardId.rawValue) + return if let additionalId = viewId.additionalId { + cardIdPath + additionalId + } else { + cardIdPath + } +} + extension [DivExtensionHandler] { var dictionary: [String: DivExtensionHandler] { var extensionsHandlersDictionary = [String: DivExtensionHandler]() diff --git a/DivKit/DivBlockStateStorage.swift b/DivKit/DivBlockStateStorage.swift index a9bc886c..bf046498 100644 --- a/DivKit/DivBlockStateStorage.swift +++ b/DivKit/DivBlockStateStorage.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKit/DivError.swift b/DivKit/DivError.swift index bc6b94ec..98485a61 100644 --- a/DivKit/DivError.swift +++ b/DivKit/DivError.swift @@ -13,6 +13,7 @@ public protocol DivError: CustomStringConvertible { public enum DivErrorKind: String { case deserialization case blockModeling = "divModeling" + case layout case expression case unknown } @@ -105,6 +106,32 @@ struct DivBlockModelingWarning: DivError { } } +struct DivLayoutError: DivError { + public let kind = DivErrorKind.layout + public let level = DivErrorLevel.error + public let message: String + public let path: UIElementPath + + init(_ message: String, path: UIElementPath) { + self.message = message + self.path = path + DivKitLogger.error(description) + } +} + +struct DivLayoutWarning: DivError { + public let kind = DivErrorKind.layout + public let level = DivErrorLevel.warning + public let message: String + public let path: UIElementPath + + init(_ message: String, path: UIElementPath) { + self.message = message + self.path = path + DivKitLogger.warning(description) + } +} + struct DivExpressionError: Error, DivError { public let kind = DivErrorKind.expression public let message: String diff --git a/DivKit/DivExtensionHandler.swift b/DivKit/DivExtensionHandler.swift index 3c823304..2329f240 100644 --- a/DivKit/DivExtensionHandler.swift +++ b/DivKit/DivExtensionHandler.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit /// The `DivExtensionHandler` protocol enables you to extend the functionality of an existing block diff --git a/DivKit/DivFlagsInfo.swift b/DivKit/DivFlagsInfo.swift index c2986137..f59677d5 100644 --- a/DivKit/DivFlagsInfo.swift +++ b/DivKit/DivFlagsInfo.swift @@ -13,15 +13,26 @@ public struct DivFlagsInfo { public let imageBlurPreferMetal: Bool public let imageTintPreferMetal: Bool + /// Indicates if legacy (pre 31.0) behavior should be applied to measure the tooltip width. + /// + /// `true` - `match_parent` width is interpreted as `wrap_content`. No way to achieve + /// `match_parent` behavior. + /// + /// `false` - tooltips with `match_parent` width (default value for `DivBase.width`) will be + /// streched to the full width of the window. + public let useTooltipLegacyWidth: Bool + /// Creates an instance of `DivFlagsInfo`. public init( imageLoadingOptimizationEnabled: Bool = true, imageBlurPreferMetal: Bool = true, - imageTintPreferMetal: Bool = true + imageTintPreferMetal: Bool = true, + useTooltipLegacyWidth: Bool = true ) { self.imageLoadingOptimizationEnabled = imageLoadingOptimizationEnabled self.imageBlurPreferMetal = imageBlurPreferMetal self.imageTintPreferMetal = imageTintPreferMetal + self.useTooltipLegacyWidth = useTooltipLegacyWidth } /// The default instance of `DivFlagsInfo`. diff --git a/DivKit/DivImageHolderFactory.swift b/DivKit/DivImageHolderFactory.swift index 45a4f4e9..81f8b348 100644 --- a/DivKit/DivImageHolderFactory.swift +++ b/DivKit/DivImageHolderFactory.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL /// Loads images for `DivKit` views. diff --git a/DivKit/DivKitComponents.swift b/DivKit/DivKitComponents.swift index 51f9663f..3334bef7 100644 --- a/DivKit/DivKitComponents.swift +++ b/DivKit/DivKitComponents.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import Serialization import VGSL @@ -50,6 +49,7 @@ public final class DivKitComponents { private let variableTracker = DivVariableTracker() private let idToPath = IdToPath() private let animatorController = DivAnimatorController() + private var debugErrorCollectors = [DivCardID: DebugErrorCollector]() /// You can create an instance of `DivKitComponents` with various optional parameters that allow /// you to customize the behavior and functionality of `DivKit` to suit your specific needs. @@ -231,6 +231,7 @@ public final class DivKitComponents { tooltipManager.reset() idToPath.reset() animatorController.reset() + debugErrorCollectors = [:] } public func reset(cardId: DivCardID) { @@ -244,6 +245,7 @@ public final class DivKitComponents { timerStorage.reset(cardId: cardId) idToPath.reset(cardId: cardId) animatorController.reset(cardId: cardId) + debugErrorCollectors[cardId] = nil } /// When using DivView, use DivData.resolve to avoid adding variables twice. @@ -271,8 +273,7 @@ public final class DivKitComponents { templates: rawDivData.templates ).asCardResult(cardId: cardId) if let divData = result.value { - setVariablesAndTriggers(divData: divData, cardId: cardId) - setTimers(divData: divData, cardId: cardId) + setCardData(divData: divData, cardId: cardId) } return result } @@ -313,6 +314,7 @@ public final class DivKitComponents { ? DivStateManager() : stateManagement.getStateManagerForCard(cardId: cardId) + let errorsStorage = DivErrorsStorage(errors: []) return DivBlockModelingContext( viewId: viewId, cardLogId: nil, @@ -337,7 +339,12 @@ public final class DivKitComponents { debugParams: debugParams, scheduler: nil, parentScrollView: parentScrollView, - errorsStorage: nil, + errorsStorage: errorsStorage, + debugErrorCollector: debugErrorCollector( + for: cardId, + debugParams: debugParams, + errorsStorage: errorsStorage + ), layoutDirection: layoutDirection, variableTracker: variableTracker, persistentValuesStorage: persistentValuesStorage, @@ -351,6 +358,11 @@ public final class DivKitComponents { ) } + public func setCardData(divData: DivData, cardId: DivCardID) { + setTimers(divData: divData, cardId: cardId) + setVariablesAndTriggers(divData: divData, cardId: cardId) + } + public func setVariablesAndTriggers(divData: DivData, cardId: DivCardID) { updateAggregator.performWithNoUpdates { let divDataVariables = divData.variables?.extractDivVariableValues() ?? [:] @@ -379,6 +391,30 @@ public final class DivKitComponents { updateAggregator.forceUpdate() } + #if os(iOS) + @_spi(Internal) + public func renderingDelegate(for cardId: DivCardID) -> RenderingDelegate { + ErrorsReportingRenderingDelegate( + wrappedRenderingDelegate: tooltipManager, + cardId: cardId, + divReporter: debugErrorCollectors[cardId] + ) + } + #endif + + private func debugErrorCollector( + for cardId: DivCardID, + debugParams: DebugParams, + errorsStorage: DivErrorsStorage + ) -> DebugErrorCollector? { + guard debugParams.isDebugInfoEnabled else { return nil } + let collector = debugErrorCollectors.getOrCreate(cardId, factory: { + DebugErrorCollector(wrappedDivReporter: reporter, errorStorage: errorsStorage) + }) + collector.errorStorage = errorsStorage + return collector + } + private func onVariablesChanged(event: DivVariablesStorage.ChangeEvent) { switch event.kind { case let .global(variables): @@ -397,3 +433,48 @@ let defaultPlayerFactory: PlayerFactory? = DefaultPlayerFactory() #else let defaultPlayerFactory: PlayerFactory? = nil #endif + +#if os(iOS) +private final class ErrorsReportingRenderingDelegate: RenderingDelegate { + private let wrappedRenderingDelegate: RenderingDelegate + private let cardId: DivCardID + private let divReporter: DivReporter? + + init( + wrappedRenderingDelegate: RenderingDelegate, + cardId: DivCardID, + divReporter: DivReporter? + ) { + self.wrappedRenderingDelegate = wrappedRenderingDelegate + self.cardId = cardId + self.divReporter = divReporter + } + + func reportRenderingError(message: String, isWarning: Bool, path: UIElementPath) { + wrappedRenderingDelegate.reportRenderingError( + message: message, + isWarning: isWarning, + path: path + ) + guard let divReporter else { return } + let error: DivError = if isWarning { + DivLayoutWarning(message, path: path) + } else { + DivLayoutError(message, path: path) + } + divReporter.reportError(cardId: cardId, error: error) + } + + func mapView(_ view: any LayoutKit.BlockView, to id: LayoutKit.BlockViewID) { + wrappedRenderingDelegate.mapView(view, to: id) + } + + func tooltipAnchorViewAdded(anchorView: any LayoutKit.TooltipAnchorView) { + wrappedRenderingDelegate.tooltipAnchorViewAdded(anchorView: anchorView) + } + + func tooltipAnchorViewRemoved(anchorView: any LayoutKit.TooltipAnchorView) { + wrappedRenderingDelegate.tooltipAnchorViewRemoved(anchorView: anchorView) + } +} +#endif diff --git a/DivKit/DivKitInfo.swift b/DivKit/DivKitInfo.swift index 36ea42cd..d5baef95 100644 --- a/DivKit/DivKitInfo.swift +++ b/DivKit/DivKitInfo.swift @@ -1,3 +1,3 @@ public enum DivKitInfo { - public static let version = "30.32.0" + public static let version = "30.33.0" } diff --git a/DivKit/DivLastVisibleBoundsCache.swift b/DivKit/DivLastVisibleBoundsCache.swift index 5e518445..0ba3b75e 100644 --- a/DivKit/DivLastVisibleBoundsCache.swift +++ b/DivKit/DivLastVisibleBoundsCache.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/DivReporter.swift b/DivKit/DivReporter.swift index 1f32fdcb..8f1fc6e3 100644 --- a/DivKit/DivReporter.swift +++ b/DivKit/DivReporter.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit /// The ``DivReporter`` protocol allows you to learn about actions and errors that occur in the diff --git a/DivKit/Expressions/CalcExpression/CalcExpression.swift b/DivKit/Expressions/CalcExpression/CalcExpression.swift index 42423324..50a458b1 100644 --- a/DivKit/Expressions/CalcExpression/CalcExpression.swift +++ b/DivKit/Expressions/CalcExpression/CalcExpression.swift @@ -32,7 +32,6 @@ // import Foundation - import VGSL struct CalcExpression { @@ -65,7 +64,7 @@ enum Subexpression { switch self { case let .symbol(symbol, args) where args.isEmpty: switch symbol { - case .infix, .prefix, .postfix: + case .infix, .prefix: false default: true @@ -104,7 +103,7 @@ enum Subexpression { // MARK: Expression parsing // Workaround for horribly slow Substring.UnicodeScalarView perf -struct UnicodeScalarView { +fileprivate struct UnicodeScalarView { typealias Index = String.UnicodeScalarView.Index private let characters: String.UnicodeScalarView @@ -157,15 +156,13 @@ struct UnicodeScalarView { } /// Returns the remaining characters - fileprivate var unicodeScalars: Substring.UnicodeScalarView { + var unicodeScalars: Substring.UnicodeScalarView { characters[startIndex.. Subexpression { var stack: [Subexpression] = [] @@ -452,53 +449,34 @@ extension UnicodeScalarView { let rhs = stack[i + 1] if lhs.isOperand { if rhs.isOperand { - guard case let .symbol(.postfix(op), args) = lhs else { - // Cannot follow an operand - throw ExpressionError.unexpectedToken("\(rhs)") - } - // Assume postfix operator was actually an infix operator - stack[i] = args[0] - stack.insert(.symbol(.infix(op), []), at: i + 1) - try collapseStack(from: i) - } else if case let .symbol(symbol, _) = rhs { - switch symbol { - case _ where stack.count <= i + 2, .postfix: - stack[i...i + 1] = [.symbol(.postfix(symbol.name), [lhs])] - try collapseStack(from: 0) - default: - let rhs = stack[i + 2] - if rhs.isOperand { - if stack.count > i + 3 { - switch stack[i + 3] { - case let .symbol(.infix(op2), _), - let .symbol(.prefix(op2), _), - let .symbol(.postfix(op2), _): - guard stack.count > i + 4, - takesPrecedence(symbol.name, over: op2) - else { - fallthrough - } - default: - try collapseStack(from: i + 2) - return + throw ExpressionError.unexpectedToken("\(rhs)") + } + if case let .symbol(symbol, _) = rhs { + let rhs = stack[i + 2] + if rhs.isOperand { + if stack.count > i + 3 { + switch stack[i + 3] { + case let .symbol(.infix(op2), _), + let .symbol(.prefix(op2), _): + guard stack.count > i + 4, + takesPrecedence(symbol.name, over: op2) + else { + fallthrough } - } - if symbol.name == ":", // ternary - case let .symbol(.infix(_), args) = lhs { - stack[i...i + 2] = [.symbol(.infix("?:"), [args[0], args[1], rhs])] - } else { - stack[i...i + 2] = [.symbol(.infix(symbol.name), [lhs, rhs])] - } - let from = symbol.name == "?" ? i : 0 - try collapseStack(from: from) - } else if case let .symbol(symbol2, _) = rhs { - if case .prefix = symbol2 { - try collapseStack(from: i + 2) - } else { - stack[i + 2] = .symbol(.prefix(symbol2.name), []) + default: try collapseStack(from: i + 2) + return } } + stack[i...i + 2] = [.symbol(.infix(symbol.name), [lhs, rhs])] + try collapseStack(from: 0) + } else if case let .symbol(symbol2, _) = rhs { + if case .prefix = symbol2 { + try collapseStack(from: i + 2) + } else { + stack[i + 2] = .symbol(.prefix(symbol2.name), []) + try collapseStack(from: i + 2) + } } } } else if case let .symbol(symbol, _) = lhs { @@ -512,6 +490,17 @@ extension UnicodeScalarView { } } } + + func collapseStackToSingleExpression() throws -> Subexpression { + try collapseStack(from: 0) + if let first = stack.first { + if first.isOperand { + return first + } + throw ExpressionError("Operand expected") + } + throw ExpressionError("Empty expression") + } func scanArguments() throws -> [Subexpression] { let delimiter: Unicode.Scalar = ")" @@ -539,6 +528,16 @@ extension UnicodeScalarView { switch expression { case let .symbol(.infix(name), _): switch name { + // ternary ?: operator + case "?": + let arg0 = try collapseStackToSingleExpression() + let arg1 = try parseSubexpression(upTo: [":"]) + guard scanCharacter(":") else { + throw ExpressionError(": expected.") + } + let arg2 = try parseSubexpression(upTo: delimiters) + stack[stack.count - 1] = .symbol(.ternary, [arg0, arg1, arg2]) + // method call case ".": guard let lastSymbol = stack.last else { throw ExpressionError.unexpectedToken(".") @@ -549,6 +548,7 @@ extension UnicodeScalarView { var args = try scanArguments() args.insert(lastSymbol, at: 0) stack[stack.count - 1] = makeMethod(methodName, args) + // function or method args case "(": switch stack.last { case let .symbol(.variable(name), _)?: @@ -558,7 +558,7 @@ extension UnicodeScalarView { // function() stack[stack.count - 1] = makeFunction(name, args) } else { - // variable.function() + // variable.method() let variableName = parts.dropLast().joined(separator: ".") args.insert(makeVariable(variableName), at: 0) stack[stack.count - 1] = makeMethod(String(parts.last!), args) @@ -574,18 +574,13 @@ extension UnicodeScalarView { followedByWhitespace = skipWhitespace() default: switch (precededByWhitespace, followedByWhitespace) { - case (true, true), (false, false): - stack.append(expression) case (true, false): stack.append(.symbol(.prefix(name), [])) - case (false, true): - stack.append(.symbol(.postfix(name), [])) + default: + stack.append(expression) } operandPosition = true } - case let .symbol(.variable(name), _) where !operandPosition: - operandPosition = true - stack.append(.symbol(.infix(name), [])) default: operandPosition = false stack.append(expression) @@ -600,16 +595,7 @@ extension UnicodeScalarView { self = start throw ExpressionError.unexpectedToken(junk) } - try collapseStack(from: 0) - switch stack.first { - case let result?: - if result.isOperand { - return result - } - throw ExpressionError("Operand expected") - case nil: - throw ExpressionError("Empty expression") - } + return try collapseStackToSingleExpression() } } diff --git a/DivKit/Expressions/CalcExpression/CalcExpressionSymbol.swift b/DivKit/Expressions/CalcExpression/CalcExpressionSymbol.swift index 813263a5..b4a3b52f 100644 --- a/DivKit/Expressions/CalcExpression/CalcExpressionSymbol.swift +++ b/DivKit/Expressions/CalcExpression/CalcExpressionSymbol.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension CalcExpression { @@ -7,7 +6,7 @@ extension CalcExpression { case variable(String) case infix(String) case prefix(String) - case postfix(String) + case ternary case function(String) case method(String) @@ -15,7 +14,7 @@ extension CalcExpression { switch self { case .variable: "variable" - case .prefix, .infix, .postfix: + case .infix, .prefix, .ternary: "operator" case .function: "function" @@ -29,10 +28,11 @@ extension CalcExpression { case let .variable(name), let .infix(name), let .prefix(name), - let .postfix(name), let .function(name), let .method(name): name + case .ternary: + "?:" } } @@ -40,7 +40,7 @@ extension CalcExpression { switch self { case .prefix: "\(name)\(formatArgForError(args[0]))" - case .infix, .postfix, .variable: + case .infix, .ternary, .variable: name case .function: formatFunction(args) diff --git a/DivKit/Expressions/Expression.swift b/DivKit/Expressions/Expression.swift index 55428323..85396923 100644 --- a/DivKit/Expressions/Expression.swift +++ b/DivKit/Expressions/Expression.swift @@ -1,7 +1,7 @@ import Foundation @frozen -public enum Expression { +public enum Expression: Sendable { case value(T) case link(ExpressionLink) } diff --git a/DivKit/Expressions/ExpressionLink.swift b/DivKit/Expressions/ExpressionLink.swift index 5b27bbee..8ed10c8b 100644 --- a/DivKit/Expressions/ExpressionLink.swift +++ b/DivKit/Expressions/ExpressionLink.swift @@ -1,9 +1,8 @@ import Foundation - import Serialization import VGSL -public struct ExpressionLink { +public struct ExpressionLink: Sendable { enum Item { case string(String) case calcExpression(CalcExpression) diff --git a/DivKit/Expressions/ExpressionValueConverter.swift b/DivKit/Expressions/ExpressionValueConverter.swift index e2fe49fe..436c74c5 100644 --- a/DivKit/Expressions/ExpressionValueConverter.swift +++ b/DivKit/Expressions/ExpressionValueConverter.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL enum ExpressionValueConverter { @@ -56,7 +55,7 @@ enum ExpressionValueConverter { dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" dateFormatter.timeZone = TimeZone(abbreviation: "UTC") return dateFormatter.string(from: date) - case let array as [AnyHashable]: + case let array as DivArray: return "[\(array.map { formatValue($0) }.joined(separator: ","))]" case let dict as DivDictionary: let properties = dict @@ -134,7 +133,7 @@ func formatTypeForError(_ type: Any.Type) -> String { "Color" case is Date.Type: "DateTime" - case is [AnyHashable].Type: + case is DivArray.Type: "Array" case is DivDictionary.Type, is [AnyHashable: AnyHashable].Type: "Dict" diff --git a/DivKit/Expressions/Functions/ArrayFunctions.swift b/DivKit/Expressions/Functions/ArrayFunctions.swift index 6c5ca5cb..7f1e25e6 100644 --- a/DivKit/Expressions/Functions/ArrayFunctions.swift +++ b/DivKit/Expressions/Functions/ArrayFunctions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension [String: Function] { @@ -28,7 +27,7 @@ extension [String: Function] { addFunctions("Url", _getUrl) addFunctions("OptUrl", _getOptUrl) - addFunction("len", FunctionUnary<[AnyHashable], Int> { $0.count }) + addFunction("len", FunctionUnary { $0.count }) } mutating func addArrayMethods() { @@ -52,55 +51,55 @@ extension [String: Function] { } } -private let _getArray = FunctionBinary<[AnyHashable], Int, [AnyHashable]> { +private let _getArray = FunctionBinary { try $0.getArray(index: $1) } -private let _getBoolean = FunctionBinary<[AnyHashable], Int, Bool> { +private let _getBoolean = FunctionBinary { try $0.getBoolean(index: $1) } -private let _getColor = FunctionBinary<[AnyHashable], Int, Color> { +private let _getColor = FunctionBinary { try $0.getColor(index: $1) } -private let _getDict = FunctionBinary<[AnyHashable], Int, DivDictionary> { +private let _getDict = FunctionBinary { try $0.getDict(index: $1) } -private let _getInteger = FunctionBinary<[AnyHashable], Int, Int> { +private let _getInteger = FunctionBinary { try $0.getInteger(index: $1) } -private let _getNumber = FunctionBinary<[AnyHashable], Int, Double> { +private let _getNumber = FunctionBinary { try $0.getNumber(index: $1) } -private let _getString = FunctionBinary<[AnyHashable], Int, String> { +private let _getString = FunctionBinary { try $0.getString(index: $1) } -private let _getUrl = FunctionBinary<[AnyHashable], Int, URL> { +private let _getUrl = FunctionBinary { try $0.getUrl(index: $1) } -private let _isEmpty = FunctionUnary<[AnyHashable], Bool> { +private let _isEmpty = FunctionUnary { $0.isEmpty } -private let _getOptArray = FunctionBinary<[AnyHashable], Int, [AnyHashable]> { +private let _getOptArray = FunctionBinary { (try? $0.getArray(index: $1)) ?? [] } -private let _getOptBoolean = FunctionTernary<[AnyHashable], Int, Bool, Bool> { +private let _getOptBoolean = FunctionTernary { (try? $0.getBoolean(index: $1)) ?? $2 } private let _getOptColor = OverloadedFunction(functions: [ - FunctionTernary<[AnyHashable], Int, Color, Color> { + FunctionTernary { (try? $0.getColor(index: $1)) ?? $2 }, - FunctionTernary<[AnyHashable], Int, String, Color> { + FunctionTernary { if let value = try? $0.getColor(index: $1) { return value } @@ -108,27 +107,27 @@ private let _getOptColor = OverloadedFunction(functions: [ }, ]) -private let _getOptDict = FunctionBinary<[AnyHashable], Int, DivDictionary> { +private let _getOptDict = FunctionBinary { (try? $0.getDict(index: $1)) ?? [:] } -private let _getOptInteger = FunctionTernary<[AnyHashable], Int, Int, Int> { +private let _getOptInteger = FunctionTernary { (try? $0.getInteger(index: $1)) ?? $2 } -private let _getOptNumber = FunctionTernary<[AnyHashable], Int, Double, Double> { +private let _getOptNumber = FunctionTernary { (try? $0.getNumber(index: $1)) ?? $2 } -private let _getOptString = FunctionTernary<[AnyHashable], Int, String, String> { +private let _getOptString = FunctionTernary { (try? $0.getString(index: $1)) ?? $2 } private let _getOptUrl = OverloadedFunction(functions: [ - FunctionTernary<[AnyHashable], Int, URL, URL> { + FunctionTernary { (try? $0.getUrl(index: $1)) ?? $2 }, - FunctionTernary<[AnyHashable], Int, String, URL> { + FunctionTernary { if let value = try? $0.getUrl(index: $1) { return value } @@ -136,10 +135,10 @@ private let _getOptUrl = OverloadedFunction(functions: [ }, ]) -extension [AnyHashable] { - fileprivate func getArray(index: Int) throws -> [AnyHashable] { +extension DivArray { + fileprivate func getArray(index: Int) throws -> DivArray { let value = try getValue(index: index) - guard let arrayValue = value as? [AnyHashable] else { + guard let arrayValue = value as? DivArray else { throw ExpressionError.incorrectType("Array", value) } return arrayValue diff --git a/DivKit/Expressions/Functions/BooleanOperators.swift b/DivKit/Expressions/Functions/BooleanOperators.swift index 5bd5de45..bbc8232f 100644 --- a/DivKit/Expressions/Functions/BooleanOperators.swift +++ b/DivKit/Expressions/Functions/BooleanOperators.swift @@ -14,7 +14,7 @@ extension [CalcExpression.Symbol: Function] { self[.infix("&&")] = andOperator self[.infix("||")] = orOperator - self[.infix("?:")] = ternaryOperator + self[.ternary] = ternaryOperator } } diff --git a/DivKit/Expressions/Functions/CastFunctions.swift b/DivKit/Expressions/Functions/CastFunctions.swift index 07c0ba88..da9dcd10 100644 --- a/DivKit/Expressions/Functions/CastFunctions.swift +++ b/DivKit/Expressions/Functions/CastFunctions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension [String: Function] { diff --git a/DivKit/Expressions/Functions/ColorFunctions.swift b/DivKit/Expressions/Functions/ColorFunctions.swift index 01f81785..a4e7178b 100644 --- a/DivKit/Expressions/Functions/ColorFunctions.swift +++ b/DivKit/Expressions/Functions/ColorFunctions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension [String: Function] { diff --git a/DivKit/Expressions/Functions/DateTimeFunctions.swift b/DivKit/Expressions/Functions/DateTimeFunctions.swift index 7fd0af41..70ec4085 100644 --- a/DivKit/Expressions/Functions/DateTimeFunctions.swift +++ b/DivKit/Expressions/Functions/DateTimeFunctions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension [String: Function] { diff --git a/DivKit/Expressions/Functions/DictFunctions.swift b/DivKit/Expressions/Functions/DictFunctions.swift index a2f39df9..aa8d2cb2 100644 --- a/DivKit/Expressions/Functions/DictFunctions.swift +++ b/DivKit/Expressions/Functions/DictFunctions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension [String: Function] { @@ -52,7 +51,7 @@ extension [String: Function] { } } -private let _getArray = FunctionVarBinary { +private let _getArray = FunctionVarBinary { try $0.getArray(path: $1) } @@ -88,7 +87,7 @@ private let _isEmpty = FunctionUnary { $0.isEmpty } -private let _getOptArray = FunctionVarBinary { +private let _getOptArray = FunctionVarBinary { (try? $0.getArray(path: $1)) ?? [] } @@ -141,9 +140,9 @@ private let _containsKey = FunctionBinary { dict, k } extension DivDictionary { - fileprivate func getArray(path: [String]) throws -> [AnyHashable] { + fileprivate func getArray(path: [String]) throws -> DivArray { let value = try getValue(path: path) - guard let dictValue = value as? [AnyHashable] else { + guard let dictValue = value as? DivArray else { throw ExpressionError.incorrectType("Array", value) } return dictValue diff --git a/DivKit/Expressions/Functions/EqualityOperators.swift b/DivKit/Expressions/Functions/EqualityOperators.swift index 8f161d9e..b5c1d505 100644 --- a/DivKit/Expressions/Functions/EqualityOperators.swift +++ b/DivKit/Expressions/Functions/EqualityOperators.swift @@ -16,7 +16,7 @@ enum EqualityOperators: String, CaseIterable { makeFunction() as FunctionBinary, makeFunction() as FunctionBinary, makeFunction() as FunctionBinary, - makeFunction() as FunctionBinary<[AnyHashable], [AnyHashable], Bool>, + makeFunction() as FunctionBinary, ], makeError: { ExpressionError.unsupportedType(op: rawValue, args: $0) diff --git a/DivKit/Expressions/Functions/Function.swift b/DivKit/Expressions/Functions/Function.swift index b103e3a8..cbad36d5 100644 --- a/DivKit/Expressions/Functions/Function.swift +++ b/DivKit/Expressions/Functions/Function.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL protocol _SimpleFunctionsProvider { diff --git a/DivKit/Expressions/Functions/GetStoredValueFunctions.swift b/DivKit/Expressions/Functions/GetStoredValueFunctions.swift index 942bc3b8..1f579e9e 100644 --- a/DivKit/Expressions/Functions/GetStoredValueFunctions.swift +++ b/DivKit/Expressions/Functions/GetStoredValueFunctions.swift @@ -1,55 +1,26 @@ import Foundation import VGSL -enum GetStoredValueFunctions: String, CaseIterable { - case getStoredIntegerValue - case getStoredNumberValue - case getStoredStringValue - case getStoredUrlValue - case getStoredColorValue - case getStoredBooleanValue - - func getFunction( +extension [String: Function] { + mutating func addGetStoredValueFunctions( _ valueProvider: @escaping (String) -> Any? - ) -> Function { - switch self { - case .getStoredIntegerValue: - return makeFunction(valueProvider) as FunctionBinary - case .getStoredNumberValue: - return makeFunction(valueProvider) as FunctionBinary - case .getStoredStringValue: - return makeFunction(valueProvider) as FunctionBinary - case .getStoredUrlValue: - let fromUrlFunction: FunctionBinary = makeFunction(valueProvider) - let fromStringFunction: FunctionBinary = - makeFunction(valueProvider) { - guard let url = URL(string: $0) else { - throw ExpressionError( - "Failed to get URL from (\($0)). Unable to convert value to URL." - ) - } - return url - } - return OverloadedFunction(functions: [fromUrlFunction, fromStringFunction]) - case .getStoredColorValue: - let fromColorFunction: FunctionBinary = makeFunction(valueProvider) - let fromStringFunction: FunctionBinary = - makeFunction(valueProvider) { - guard let color = Color.color(withHexString: $0) else { - throw ExpressionError( - "Failed to get Color from (\($0)). Unable to convert value to Color." - ) - } - return color - } - return OverloadedFunction(functions: [fromColorFunction, fromStringFunction]) - case .getStoredBooleanValue: - return makeFunction(valueProvider) as FunctionBinary - } + ) { + addFunction("getStoredBooleanValue", makeFunction(Bool.self, valueProvider)) + addFunction("getStoredIntegerValue", makeFunction(Int.self, valueProvider)) + addFunction("getStoredNumberValue", makeFunction(Double.self, valueProvider)) + addFunction("getStoredStringValue", makeFunction(String.self, valueProvider)) + addFunction("getStoredColorValue", makeColorFunction(valueProvider)) + addFunction("getStoredUrlValue", makeUrlFunction(valueProvider)) + addFunction("getStoredArrayValue", makeFunctionWithoutFallback(DivArray.self, valueProvider)) + addFunction( + "getStoredDictValue", + makeFunctionWithoutFallback(DivDictionary.self, valueProvider) + ) } } private func makeFunction( + _: T.Type, _ valueProvider: @escaping (String) -> Any? ) -> FunctionBinary { makeFunction(valueProvider) { $0 } @@ -66,3 +37,43 @@ private func makeFunction( return value } } + +private func makeFunctionWithoutFallback( + _: T.Type, + _ valueProvider: @escaping (String) -> Any? +) -> FunctionUnary { + FunctionUnary { + if let value = valueProvider($0) as? T { + return value + } + throw ExpressionError("Missing value.") + } +} + +private func makeColorFunction(_ valueProvider: @escaping (String) -> Any?) -> Function { + let fromColorFunction = makeFunction(Color.self, valueProvider) + let fromStringFunction: FunctionBinary = + makeFunction(valueProvider) { + guard let color = Color.color(withHexString: $0) else { + throw ExpressionError( + "Failed to get Color from (\($0)). Unable to convert value to Color." + ) + } + return color + } + return OverloadedFunction(functions: [fromColorFunction, fromStringFunction]) +} + +private func makeUrlFunction(_ valueProvider: @escaping (String) -> Any?) -> Function { + let fromUrlFunction = makeFunction(URL.self, valueProvider) + let fromStringFunction: FunctionBinary = + makeFunction(valueProvider) { + guard let url = URL(string: $0) else { + throw ExpressionError( + "Failed to get URL from (\($0)). Unable to convert value to URL." + ) + } + return url + } + return OverloadedFunction(functions: [fromUrlFunction, fromStringFunction]) +} diff --git a/DivKit/Expressions/Functions/GetValueFunctions.swift b/DivKit/Expressions/Functions/GetValueFunctions.swift index 25d00142..582b2381 100644 --- a/DivKit/Expressions/Functions/GetValueFunctions.swift +++ b/DivKit/Expressions/Functions/GetValueFunctions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension [String: Function] { diff --git a/DivKit/Expressions/Functions/ToStringFunctions.swift b/DivKit/Expressions/Functions/ToStringFunctions.swift index 9ea83da6..bfa3fb37 100644 --- a/DivKit/Expressions/Functions/ToStringFunctions.swift +++ b/DivKit/Expressions/Functions/ToStringFunctions.swift @@ -1,11 +1,10 @@ import Foundation - import VGSL extension [String: Function] { mutating func addToStringFunctions() { self["toString"] = OverloadedFunction(functions: [ - FunctionUnary<[AnyHashable], String> { ExpressionValueConverter.stringify($0) }, + FunctionUnary { ExpressionValueConverter.stringify($0) }, FunctionUnary { $0.description }, FunctionUnary { $0.argbString }, FunctionUnary { ExpressionValueConverter.stringify($0) }, diff --git a/DivKit/Expressions/Functions/TrigonometricFunctions.swift b/DivKit/Expressions/Functions/TrigonometricFunctions.swift index 72830b36..e4527ba1 100644 --- a/DivKit/Expressions/Functions/TrigonometricFunctions.swift +++ b/DivKit/Expressions/Functions/TrigonometricFunctions.swift @@ -5,6 +5,10 @@ extension [String: Function] { addFunction("pi", ConstantFunction(Double.pi)) addFunction("sin", _sinFunction) addFunction("cos", _cosFunction) + addFunction("tan", _tanFunction) + addFunction("asin", _asinFunction) + addFunction("acos", _acosFunction) + addFunction("atan", _atanFunction) addFunction("toRadians", _toRadians) addFunction("toDegrees", _toDegrees) } @@ -18,8 +22,32 @@ private let _cosFunction = FunctionUnary { (radians: Double) in cos(radians) } +private let _tanFunction = FunctionUnary { (radians: Double) in + tan(radians) +} + +private let _asinFunction = FunctionUnary { (value: Double) in + let result = asin(value) + if result.isNaN { + throw ExpressionError("Arcsine is undefined for the given value.") + } + return result +} + +private let _acosFunction = FunctionUnary { (value: Double) in + let result = acos(value) + if result.isNaN { + throw ExpressionError("Arccosine is undefined for the given value.") + } + return result +} + +private let _atanFunction = FunctionUnary { (value: Double) in + atan(value) +} + private let _toRadians = FunctionUnary { (degrees: Double) in - degrees * Double.pi / 180 + degrees * Double.pi / 180 } private let _toDegrees = FunctionUnary { (radians: Double) in diff --git a/DivKit/Expressions/FunctionsProvider.swift b/DivKit/Expressions/FunctionsProvider.swift index 95647b76..ece645fa 100644 --- a/DivKit/Expressions/FunctionsProvider.swift +++ b/DivKit/Expressions/FunctionsProvider.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL final class FunctionsProvider { @@ -23,9 +22,7 @@ final class FunctionsProvider { lazy var functions: [String: Function] = lock.withLock { var functions = staticFunctions - for item in GetStoredValueFunctions.allCases { - functions[item.rawValue] = item.getFunction(persistentValuesStorage.get) - } + functions.addGetStoredValueFunctions(persistentValuesStorage.get) return functions } @@ -44,7 +41,7 @@ final class FunctionsProvider { } throw ExpressionError("Variable '\(name)' is missing.") } - case .infix, .prefix: + case .infix, .prefix, .ternary: return operators[symbol] case let .function(name): guard let self else { @@ -59,8 +56,6 @@ final class FunctionsProvider { ) case let .method(name): return FunctionEvaluator(symbol, functions: FunctionsProvider.methods) - case .postfix: - return nil } } } diff --git a/DivKit/Expressions/Serialization/DictionaryExtensions.swift b/DivKit/Expressions/Serialization/DictionaryExtensions.swift index 85623674..d917ec60 100644 --- a/DivKit/Expressions/Serialization/DictionaryExtensions.swift +++ b/DivKit/Expressions/Serialization/DictionaryExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import Serialization import VGSL diff --git a/DivKit/Expressions/Serialization/Expression+Helpers.swift b/DivKit/Expressions/Serialization/Expression+Helpers.swift index f2b519d8..e20fa848 100644 --- a/DivKit/Expressions/Serialization/Expression+Helpers.swift +++ b/DivKit/Expressions/Serialization/Expression+Helpers.swift @@ -1,5 +1,4 @@ import Foundation - import Serialization import VGSL diff --git a/DivKit/Expressions/Serialization/Expression+ValidSerializationValue.swift b/DivKit/Expressions/Serialization/Expression+ValidSerializationValue.swift index 186a3d15..f1d107ef 100644 --- a/DivKit/Expressions/Serialization/Expression+ValidSerializationValue.swift +++ b/DivKit/Expressions/Serialization/Expression+ValidSerializationValue.swift @@ -1,5 +1,4 @@ import Foundation - import Serialization import VGSL diff --git a/DivKit/Expressions/Serialization/FieldExtensions.swift b/DivKit/Expressions/Serialization/FieldExtensions.swift index 5893f8ad..ce8d8888 100644 --- a/DivKit/Expressions/Serialization/FieldExtensions.swift +++ b/DivKit/Expressions/Serialization/FieldExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import Serialization import VGSL @@ -23,9 +22,9 @@ extension Field { ) -> DeserializationResult where T == Expression, E.RawValue == String { switch self { case let .value(value): - return .success(value) + .success(value) case let .link(link): - return safeValueForLink { + safeValueForLink { try context.templateData.getField( link, transform: { @@ -44,9 +43,9 @@ extension Field { ) -> DeserializationResult where T == Expression { switch self { case let .value(value): - return .success(value) + .success(value) case let .link(link): - return safeValueForLink { + safeValueForLink { try context.templateData.getField( link, transform: { expressionTransform($0, transform: transform, validator: validator) } diff --git a/DivKit/Extensions/DivAbsoluteEdgeInsetsExtensions.swift b/DivKit/Extensions/DivAbsoluteEdgeInsetsExtensions.swift index a9da9f89..e4130815 100644 --- a/DivKit/Extensions/DivAbsoluteEdgeInsetsExtensions.swift +++ b/DivKit/Extensions/DivAbsoluteEdgeInsetsExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension DivAbsoluteEdgeInsets { diff --git a/DivKit/Extensions/DivAccessibilityExtensions.swift b/DivKit/Extensions/DivAccessibilityExtensions.swift index ce39c8b7..baf326c8 100644 --- a/DivKit/Extensions/DivAccessibilityExtensions.swift +++ b/DivKit/Extensions/DivAccessibilityExtensions.swift @@ -47,7 +47,7 @@ extension DivAccessibility { return .image case .text: return .staticText - case .editText, .select, .tabBar: + case .checkbox, .editText, .radio, .select, .tabBar: DivKitLogger.warning("Unsupported accessibility type") return AccessibilityElement.Traits.none case .none, .list: diff --git a/DivKit/Extensions/DivAction/DivActionBase.swift b/DivKit/Extensions/DivAction/DivActionBase.swift index 4292cf99..9cc6a1c6 100644 --- a/DivKit/Extensions/DivAction/DivActionBase.swift +++ b/DivKit/Extensions/DivAction/DivActionBase.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import Serialization import VGSL diff --git a/DivKit/Extensions/DivAction/DivActionsHolder.swift b/DivKit/Extensions/DivAction/DivActionsHolder.swift index 72f61769..0469f2ea 100644 --- a/DivKit/Extensions/DivAction/DivActionsHolder.swift +++ b/DivKit/Extensions/DivAction/DivActionsHolder.swift @@ -72,7 +72,8 @@ extension Block { actionAnimation: actionsHolder.actionAnimation .resolveActionAnimation(context.expressionResolver), doubleTapActions: doubletapActions, - longTapActions: longtapActions + longTapActions: longtapActions, + path: context.parentPath ) } } diff --git a/DivKit/Extensions/DivBackgroundExtensions.swift b/DivKit/Extensions/DivBackgroundExtensions.swift index 8ebf6774..13527818 100644 --- a/DivKit/Extensions/DivBackgroundExtensions.swift +++ b/DivKit/Extensions/DivBackgroundExtensions.swift @@ -1,9 +1,7 @@ import CoreGraphics import Foundation - -import VGSL - import LayoutKit +import VGSL extension DivBackground { func makeBlockBackground( diff --git a/DivKit/Extensions/DivBase/DivBaseExtensions.swift b/DivKit/Extensions/DivBase/DivBaseExtensions.swift index 9abc0ed0..aad06603 100644 --- a/DivKit/Extensions/DivBase/DivBaseExtensions.swift +++ b/DivKit/Extensions/DivBase/DivBaseExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivCustom/DivCustomExtensions.swift b/DivKit/Extensions/DivCustom/DivCustomExtensions.swift index f8651f9e..4a622db4 100644 --- a/DivKit/Extensions/DivCustom/DivCustomExtensions.swift +++ b/DivKit/Extensions/DivCustom/DivCustomExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivData/DivDataPatchExtensions.swift b/DivKit/Extensions/DivData/DivDataPatchExtensions.swift index a692fab5..54f5610a 100644 --- a/DivKit/Extensions/DivData/DivDataPatchExtensions.swift +++ b/DivKit/Extensions/DivData/DivDataPatchExtensions.swift @@ -131,6 +131,8 @@ extension DivContainer { focus: focus, functions: functions, height: height, + hoverEndActions: hoverEndActions, + hoverStartActions: hoverStartActions, id: id, itemBuilder: itemBuilder, items: patchedItems, @@ -141,6 +143,8 @@ extension DivContainer { margins: margins, orientation: orientation, paddings: paddings, + pressEndActions: pressEndActions, + pressStartActions: pressStartActions, reuseId: reuseId, rowSpan: rowSpan, selectedActions: selectedActions, @@ -238,12 +242,16 @@ extension DivGrid { focus: focus, functions: functions, height: height, + hoverEndActions: hoverEndActions, + hoverStartActions: hoverStartActions, id: id, items: patchedItems, layoutProvider: layoutProvider, longtapActions: longtapActions, margins: margins, paddings: paddings, + pressEndActions: pressEndActions, + pressStartActions: pressStartActions, reuseId: reuseId, rowSpan: rowSpan, selectedActions: selectedActions, @@ -333,6 +341,7 @@ extension DivState { animators: animators, background: background, border: border, + clipToBounds: clipToBounds, columnSpan: columnSpan, defaultStateId: defaultStateId, disappearActions: disappearActions, diff --git a/DivKit/Extensions/DivDisappearActionExtensions.swift b/DivKit/Extensions/DivDisappearActionExtensions.swift index 670a448a..11baa781 100644 --- a/DivKit/Extensions/DivDisappearActionExtensions.swift +++ b/DivKit/Extensions/DivDisappearActionExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivDrawable/DivDrawableExtensions.swift b/DivKit/Extensions/DivDrawable/DivDrawableExtensions.swift index 68edd7a1..3fecb3cb 100644 --- a/DivKit/Extensions/DivDrawable/DivDrawableExtensions.swift +++ b/DivKit/Extensions/DivDrawable/DivDrawableExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivDrawable/DivShapeExtensions.swift b/DivKit/Extensions/DivDrawable/DivShapeExtensions.swift index 94b78858..b9629e34 100644 --- a/DivKit/Extensions/DivDrawable/DivShapeExtensions.swift +++ b/DivKit/Extensions/DivDrawable/DivShapeExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivEdgeInsetsExtensions.swift b/DivKit/Extensions/DivEdgeInsetsExtensions.swift index 80172f0d..33ee2b3f 100644 --- a/DivKit/Extensions/DivEdgeInsetsExtensions.swift +++ b/DivKit/Extensions/DivEdgeInsetsExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivEvaluableTypeExtensions.swift b/DivKit/Extensions/DivEvaluableTypeExtensions.swift index 0ad2a08d..1742cf0e 100644 --- a/DivKit/Extensions/DivEvaluableTypeExtensions.swift +++ b/DivKit/Extensions/DivEvaluableTypeExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension DivEvaluableType { @@ -13,7 +12,7 @@ extension DivEvaluableType { case .color: Color.self case .url: URL.self case .dict: DivDictionary.self - case .array: [AnyHashable].self + case .array: DivArray.self } } } diff --git a/DivKit/Extensions/DivGallery/DivGalleryExtensions.swift b/DivKit/Extensions/DivGallery/DivGalleryExtensions.swift index 0dc76d05..4da6cbb5 100644 --- a/DivKit/Extensions/DivGallery/DivGalleryExtensions.swift +++ b/DivKit/Extensions/DivGallery/DivGalleryExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL @@ -23,9 +22,10 @@ extension DivGallery: DivBlockModeling, DivGalleryProtocol { let model = try makeGalleryModel( context: context, direction: resolveOrientation(expressionResolver).direction, + alignment: .center, spacing: CGFloat(itemSpacing), crossSpacing: CGFloat(resolveCrossSpacing(expressionResolver) ?? itemSpacing), - defaultAlignment: resolveCrossContentAlignment(expressionResolver).blockAlignment, + defaultCrossAlignment: resolveCrossContentAlignment(expressionResolver).blockAlignment, scrollMode: resolveScrollMode(expressionResolver).blockScrollMode, columnCount: resolveColumnCount(expressionResolver), scrollbar: resolveScrollbar(expressionResolver).blockScrollbar diff --git a/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift b/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift index ad52d01b..7399c54f 100644 --- a/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift +++ b/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL @@ -16,12 +15,14 @@ extension DivGalleryProtocol { func makeGalleryModel( context: DivBlockModelingContext, direction: ScrollDirection, + alignment: Alignment, spacing: CGFloat, crossSpacing: CGFloat, - defaultAlignment: Alignment, + defaultCrossAlignment: Alignment, scrollMode: GalleryViewModel.ScrollMode, columnCount: Int? = nil, infiniteScroll: Bool = false, + bufferSize: Int = 1, scrollbar: GalleryViewModel.Scrollbar = .none, transformation: ElementsTransformation? = nil ) throws -> GalleryViewModel { @@ -34,7 +35,7 @@ extension DivGalleryProtocol { direction.isHorizontal ? div.value.resolveAlignmentVertical(expressionResolver)?.alignment : div.value.resolveAlignmentHorizontal(expressionResolver)?.alignment - ) ?? defaultAlignment, + ) ?? defaultCrossAlignment, content: block ) } @@ -53,10 +54,10 @@ extension DivGalleryProtocol { ) } - if infiniteScroll, - let last = children.last, - let first = children.first { - children = [last] + children + [first] + if infiniteScroll, children.count > 2 { + let leadingBuffer = children[.. Int { + switch self { + case let .pageSize(relativeValue): + Int(1 / relativeValue.rawValue) + 1 + case .neighbourPageSize: + 2 + case .pageContentSize: + itemsCount + } + } +} + extension DivPager.Orientation { var direction: ScrollDirection { switch self { diff --git a/DivKit/Extensions/DivPivotExtensions.swift b/DivKit/Extensions/DivPivotExtensions.swift index 24aa3d49..f6187962 100644 --- a/DivKit/Extensions/DivPivotExtensions.swift +++ b/DivKit/Extensions/DivPivotExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit extension DivPivot { diff --git a/DivKit/Extensions/DivSelectExtensions.swift b/DivKit/Extensions/DivSelectExtensions.swift index 8fc50306..b3578f51 100644 --- a/DivKit/Extensions/DivSelectExtensions.swift +++ b/DivKit/Extensions/DivSelectExtensions.swift @@ -1,7 +1,6 @@ import CoreFoundation import CoreGraphics import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivSeparatorExtensions.swift b/DivKit/Extensions/DivSeparatorExtensions.swift index 026d6121..1886502b 100644 --- a/DivKit/Extensions/DivSeparatorExtensions.swift +++ b/DivKit/Extensions/DivSeparatorExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit extension DivSeparator: DivBlockModeling { diff --git a/DivKit/Extensions/DivSizeExtensions.swift b/DivKit/Extensions/DivSizeExtensions.swift index 7d631622..a776b4c0 100644 --- a/DivKit/Extensions/DivSizeExtensions.swift +++ b/DivKit/Extensions/DivSizeExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivSizeUnitExtensions.swift b/DivKit/Extensions/DivSizeUnitExtensions.swift index f8828981..cd7eb48e 100644 --- a/DivKit/Extensions/DivSizeUnitExtensions.swift +++ b/DivKit/Extensions/DivSizeUnitExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivSliderExtensions.swift b/DivKit/Extensions/DivSliderExtensions.swift index 47090056..49b52766 100644 --- a/DivKit/Extensions/DivSliderExtensions.swift +++ b/DivKit/Extensions/DivSliderExtensions.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivStateExtensions.swift b/DivKit/Extensions/DivStateExtensions.swift index ad1d54b8..a746c93d 100644 --- a/DivKit/Extensions/DivStateExtensions.swift +++ b/DivKit/Extensions/DivStateExtensions.swift @@ -1,7 +1,6 @@ import CoreFoundation import CoreGraphics import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivTabsExtensions.swift b/DivKit/Extensions/DivTabsExtensions.swift index 0c224f87..af92c90f 100644 --- a/DivKit/Extensions/DivTabsExtensions.swift +++ b/DivKit/Extensions/DivTabsExtensions.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivTextExtensions.swift b/DivKit/Extensions/DivTextExtensions.swift index a56d560b..0d950da6 100644 --- a/DivKit/Extensions/DivTextExtensions.swift +++ b/DivKit/Extensions/DivTextExtensions.swift @@ -1,7 +1,6 @@ import CoreFoundation import CoreGraphics import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/DivTooltipExtensions.swift b/DivKit/Extensions/DivTooltipExtensions.swift index 7ce9d504..89b057c9 100644 --- a/DivKit/Extensions/DivTooltipExtensions.swift +++ b/DivKit/Extensions/DivTooltipExtensions.swift @@ -11,19 +11,21 @@ extension DivTooltip { return nil } - let tooltipViewFactory: TooltipViewFactory = Variable { [weak self] in + let tooltipViewFactory: TooltipViewFactory = { [weak self] in guard let self, let tooltipViewFactory = context.tooltipViewFactory else { return nil } - return tooltipViewFactory.makeView(div: self.div, tooltipId: self.id) + return await tooltipViewFactory.makeView(div: self.div, tooltipId: self.id) } return try BlockTooltip( id: id, + // Legacy behavior. Views should be created with tooltipViewFactory. block: div.value.makeBlock(context: context), duration: Duration(milliseconds: resolveDuration(expressionResolver)), offset: offset?.resolve(expressionResolver) ?? .zero, position: position, + useLegacyWidth: context.flagsInfo.useTooltipLegacyWidth, tooltipViewFactory: tooltipViewFactory ) } @@ -49,11 +51,20 @@ extension [DivTooltip]? { func makeTooltips( context: DivBlockModelingContext ) throws -> [BlockTooltip] { - try self?.iterativeFlatMap { div, index in - let tooltipContext = context.modifying( - parentPath: context.parentPath + "tooltip" + index + let items = self ?? [] + if !items.isEmpty, context.viewId.isTooltip { + context.errorsStorage.add( + DivBlockModelingError( + "Tooltip can not host another tooltips", + path: context.parentPath + ) ) - return try div.makeTooltip(context: tooltipContext) - } ?? [] + return [] + } + + return try items.compactMap { + let tooltipContext = context.cloneForTooltip(tooltipId: $0.id) + return try $0.makeTooltip(context: tooltipContext) + } } } diff --git a/DivKit/Extensions/DivTypedValueExtensions.swift b/DivKit/Extensions/DivTypedValueExtensions.swift index e3c5d4bc..7942c3e1 100644 --- a/DivKit/Extensions/DivTypedValueExtensions.swift +++ b/DivKit/Extensions/DivTypedValueExtensions.swift @@ -6,7 +6,7 @@ extension DivTypedValue { ) -> DivVariableValue? { switch self { case let .arrayValue(value): - if let arrayValue = value.resolveValue(expressionResolver) as? [AnyHashable] { + if let arrayValue = value.resolveValue(expressionResolver) as? DivArray { return .array(arrayValue) } return nil @@ -21,8 +21,8 @@ extension DivTypedValue { } return nil case let .dictValue(value): - if let divDict = DivDictionary.make(from: value.value) { - return .dict(divDict) + if let dictValue = DivDictionary.fromAny(value.value) { + return .dict(dictValue) } return nil case let .integerValue(value): @@ -53,7 +53,7 @@ extension DivTypedValue { ) -> AnyHashable? { switch self { case let .arrayValue(value): - if let arrayValue = value.resolveValue(expressionResolver) as? [AnyHashable] { + if let arrayValue = value.resolveValue(expressionResolver) as? DivArray { return arrayValue } return nil diff --git a/DivKit/Extensions/DivVisibilityActionExtensions.swift b/DivKit/Extensions/DivVisibilityActionExtensions.swift index f7b184bf..874f81c3 100644 --- a/DivKit/Extensions/DivVisibilityActionExtensions.swift +++ b/DivKit/Extensions/DivVisibilityActionExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Extensions/GradientExtentions.swift b/DivKit/Extensions/GradientExtentions.swift index d6293126..c0adbc71 100644 --- a/DivKit/Extensions/GradientExtentions.swift +++ b/DivKit/Extensions/GradientExtentions.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL extension Gradient.Linear { diff --git a/DivKit/Extensions/RelativeValueExtensions.swift b/DivKit/Extensions/RelativeValueExtensions.swift index 09d0c3c4..7115e3c0 100644 --- a/DivKit/Extensions/RelativeValueExtensions.swift +++ b/DivKit/Extensions/RelativeValueExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension RelativeValue { diff --git a/DivKit/Fonts/DefaultFontProvider.swift b/DivKit/Fonts/DefaultFontProvider.swift index 5a56af06..c47ae298 100644 --- a/DivKit/Fonts/DefaultFontProvider.swift +++ b/DivKit/Fonts/DefaultFontProvider.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL final class DefaultFontProvider: DivFontProvider { diff --git a/DivKit/Fonts/DivFontProvider.swift b/DivKit/Fonts/DivFontProvider.swift index 193a61da..9ac4421b 100644 --- a/DivKit/Fonts/DivFontProvider.swift +++ b/DivKit/Fonts/DivFontProvider.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL /// The `DivFontProvider` protocol is used to enable the transfer of custom fonts used in your diff --git a/DivKit/LayoutProvider/SizeProviderBlock+UIViewRenderable.swift b/DivKit/LayoutProvider/SizeProviderBlock+UIViewRenderable.swift index 8e306e8f..c4c52709 100644 --- a/DivKit/LayoutProvider/SizeProviderBlock+UIViewRenderable.swift +++ b/DivKit/LayoutProvider/SizeProviderBlock+UIViewRenderable.swift @@ -1,6 +1,5 @@ -import UIKit - import LayoutKit +import UIKit import VGSL extension SizeProviderBlock { diff --git a/DivKit/Patches/DivPatchDownloader.swift b/DivKit/Patches/DivPatchDownloader.swift index e00b3fef..37aa3159 100644 --- a/DivKit/Patches/DivPatchDownloader.swift +++ b/DivKit/Patches/DivPatchDownloader.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public class DivPatchDownloader: DivPatchProvider { diff --git a/DivKit/Patches/DivPatchProvider.swift b/DivKit/Patches/DivPatchProvider.swift index f87398a9..f363224b 100644 --- a/DivKit/Patches/DivPatchProvider.swift +++ b/DivKit/Patches/DivPatchProvider.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL /// The `DivPatchProvider` protocol is responsible for downloading DivKit patches. diff --git a/DivKit/StoredValues/DivPersistentValuesStorage.swift b/DivKit/StoredValues/DivPersistentValuesStorage.swift index 45f0664e..18fe1f41 100644 --- a/DivKit/StoredValues/DivPersistentValuesStorage.swift +++ b/DivKit/StoredValues/DivPersistentValuesStorage.swift @@ -119,6 +119,20 @@ extension DivStoredValue { } else { nil } + case .array: + if let rawValue = try? JSONSerialization.jsonObject(jsonString: value) as? [Any], + let array = DivArray.fromAny(rawValue) { + .array(array) + } else { + nil + } + case .dict: + if let rawValue = try? JSONSerialization.jsonObject(jsonString: value) as? [String: Any], + let dict = DivDictionary.fromAny(rawValue) { + .dict(dict) + } else { + nil + } } } diff --git a/DivKit/StoredValues/DivStoredValue.swift b/DivKit/StoredValues/DivStoredValue.swift index 85cec886..d03e6d4c 100644 --- a/DivKit/StoredValues/DivStoredValue.swift +++ b/DivKit/StoredValues/DivStoredValue.swift @@ -9,6 +9,8 @@ struct DivStoredValue { case bool // invalid value, used for backward compatibility case color case url + case array + case dict } let name: String diff --git a/DivKit/Templates/DivTemplates.swift b/DivKit/Templates/DivTemplates.swift index 1cd827f9..d4922575 100644 --- a/DivKit/Templates/DivTemplates.swift +++ b/DivKit/Templates/DivTemplates.swift @@ -1,5 +1,4 @@ import Foundation - import Serialization import VGSL diff --git a/DivKit/Templates/Field.swift b/DivKit/Templates/Field.swift index f766b3ba..dad2c146 100644 --- a/DivKit/Templates/Field.swift +++ b/DivKit/Templates/Field.swift @@ -1,6 +1,5 @@ import CoreFoundation import Foundation - import Serialization import VGSL @@ -240,11 +239,11 @@ extension Field { ) -> DeserializationResult.ResolvedValue> where Array == T { switch self { case let .value(value): - return value + value .resolveParent(templates: context.templates) .resolveValue(context: context, validator: validator) case let .link(link): - return context.getArray(link, validator: validator, type: T.Element.self) + context.getArray(link, validator: validator, type: T.Element.self) } } diff --git a/DivKit/Templates/SerializationExtensions.swift b/DivKit/Templates/SerializationExtensions.swift index 2b2004d2..eafcc2d6 100644 --- a/DivKit/Templates/SerializationExtensions.swift +++ b/DivKit/Templates/SerializationExtensions.swift @@ -1,5 +1,4 @@ import CoreFoundation - import Serialization import VGSL diff --git a/DivKit/Timers/DivTimerController.swift b/DivKit/Timers/DivTimerController.swift index 5f0f39c7..130421ee 100644 --- a/DivKit/Timers/DivTimerController.swift +++ b/DivKit/Timers/DivTimerController.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL final class DivTimerController { @@ -57,6 +56,10 @@ final class DivTimerController { self.reporter = reporter } + deinit { + cancel() + } + func start() { if state != .stopped { DivKitLogger.error("Timer '\(divTimer.id)' can't start because it has state '\(state)'.") diff --git a/DivKit/Timers/DivTimerStorage.swift b/DivKit/Timers/DivTimerStorage.swift index a2ec160e..8ea8d72b 100644 --- a/DivKit/Timers/DivTimerStorage.swift +++ b/DivKit/Timers/DivTimerStorage.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Tooltips/DivTooltipViewFactory.swift b/DivKit/Tooltips/DivTooltipViewFactory.swift index 85ff1814..fa7c2fce 100644 --- a/DivKit/Tooltips/DivTooltipViewFactory.swift +++ b/DivKit/Tooltips/DivTooltipViewFactory.swift @@ -13,7 +13,8 @@ public struct DivTooltipViewFactory { } #if os(iOS) - func makeView(div: Div, tooltipId: String) -> VisibleBoundsTrackingView { + @MainActor + func makeView(div: Div, tooltipId: String) async -> VisibleBoundsTrackingView { let view = DivView(divKitComponents: divKitComponents) let divData = DivData( logId: tooltipId, @@ -23,20 +24,18 @@ public struct DivTooltipViewFactory { variableTriggers: nil, variables: nil ) - Task { - await view.setSource( - DivViewSource( - kind: .divData(divData), - cardId: cardId, - additionalId: tooltipId - ) + await view.setSource( + DivViewSource( + kind: .divData(divData), + cardId: cardId, + additionalId: tooltipId ) - } + ) return view } #else - func makeView(div _: Div, tooltipId _: String) -> ViewType { + func makeView(div _: Div, tooltipId _: String) async -> ViewType { self as AnyObject } #endif diff --git a/DivKit/Types.swift b/DivKit/Types.swift new file mode 100644 index 00000000..d837fb5a --- /dev/null +++ b/DivKit/Types.swift @@ -0,0 +1,17 @@ +import Foundation + +public typealias DivArray = [AnyHashable] + +extension DivArray { + static func fromAny(_ value: [Any]) -> DivArray? { + NSArray(array: value) as? DivArray + } +} + +public typealias DivDictionary = [String: AnyHashable] + +extension DivDictionary { + static func fromAny(_ value: [String: Any]) -> DivDictionary? { + NSDictionary(dictionary: value) as? DivDictionary + } +} diff --git a/DivKit/Variables/DivTriggersStorage.swift b/DivKit/Variables/DivTriggersStorage.swift index 8b3fc792..aed11ac0 100644 --- a/DivKit/Variables/DivTriggersStorage.swift +++ b/DivKit/Variables/DivTriggersStorage.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKit/Variables/DivVariableName.swift b/DivKit/Variables/DivVariableName.swift index 3cd22bde..4a773afc 100644 --- a/DivKit/Variables/DivVariableName.swift +++ b/DivKit/Variables/DivVariableName.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public enum DivVariableNameTag {} diff --git a/DivKit/Variables/DivVariableStorage.swift b/DivKit/Variables/DivVariableStorage.swift index d515511b..13214b71 100644 --- a/DivKit/Variables/DivVariableStorage.swift +++ b/DivKit/Variables/DivVariableStorage.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL /// Stores variables. diff --git a/DivKit/Variables/DivVariableValue.swift b/DivKit/Variables/DivVariableValue.swift index 81f0a243..2b9694cd 100644 --- a/DivKit/Variables/DivVariableValue.swift +++ b/DivKit/Variables/DivVariableValue.swift @@ -1,15 +1,6 @@ import Foundation - import VGSL -public typealias DivDictionary = [String: AnyHashable] - -extension DivDictionary { - static func make(from dict: [String: Any]) -> DivDictionary? { - NSDictionary(dictionary: dict) as? DivDictionary - } -} - @frozen public enum DivVariableValue: Hashable { case string(String) @@ -19,7 +10,7 @@ public enum DivVariableValue: Hashable { case color(Color) case url(URL) case dict(DivDictionary) - case array([AnyHashable]) + case array(DivArray) @inlinable public func typedValue() -> T? { @@ -59,7 +50,7 @@ public enum DivVariableValue: Hashable { self = .url(value) case let value as DivDictionary: self = .dict(value) - case let value as [AnyHashable]: + case let value as DivArray: self = .array(value) default: DivKitLogger.error("Unsupported variable value: \(value)") diff --git a/DivKit/Variables/DivVariablesStorage.swift b/DivKit/Variables/DivVariablesStorage.swift index cf0e75fe..ce65dd5f 100644 --- a/DivKit/Variables/DivVariablesStorage.swift +++ b/DivKit/Variables/DivVariablesStorage.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL @@ -371,7 +370,7 @@ extension Collection { case let .dictVariable(dictVariable): let name = DivVariableName(rawValue: dictVariable.name) if variables.keys.contains(name) { return } - if let dictionary = DivDictionary.make(from: dictVariable.value) { + if let dictionary = DivDictionary.fromAny(dictVariable.value) { variables[name] = .dict(dictionary) } else { DivKitLogger.error("Incorrect value for dict variable \(name): \(dictVariable.value)") @@ -380,7 +379,7 @@ extension Collection { case let .arrayVariable(arrayVariable): let name = DivVariableName(rawValue: arrayVariable.name) if variables.keys.contains(name) { return } - if let array = NSArray(array: arrayVariable.value) as? [AnyHashable] { + if let array = DivArray.fromAny(arrayVariable.value) { variables[name] = .array(array) } else { DivKitLogger.error("Incorrect value for array variable \(name): \(arrayVariable.value)") diff --git a/DivKit/Views/DivBlockProvider.swift b/DivKit/Views/DivBlockProvider.swift index 07313d4b..6a67433a 100644 --- a/DivKit/Views/DivBlockProvider.swift +++ b/DivKit/Views/DivBlockProvider.swift @@ -1,7 +1,6 @@ -import UIKit - import LayoutKit import Serialization +import UIKit import VGSL @MainActor @@ -174,8 +173,7 @@ final class DivBlockProvider { return } if !id.isTooltip { - divKitComponents.setVariablesAndTriggers(divData: divData, cardId: cardId) - divKitComponents.setTimers(divData: divData, cardId: cardId) + divKitComponents.setCardData(divData: divData, cardId: cardId) } self.divData = divData } diff --git a/DivKit/Views/DivView.swift b/DivKit/Views/DivView.swift index 2c5ca519..811d0e13 100644 --- a/DivKit/Views/DivView.swift +++ b/DivKit/Views/DivView.swift @@ -1,6 +1,5 @@ -import UIKit - import LayoutKit +import UIKit import VGSL /// ``DivView`` is a view that allows you to draw the layout for `DivKit`. @@ -180,17 +179,23 @@ public final class DivView: VisibleBoundsTrackingView { } private func update(block: Block) { + let renderingDelegate: RenderingDelegate? = if blockProvider?.id != nil, + let divCardId = blockProvider?.cardId { + divKitComponents.renderingDelegate(for: divCardId) + } else { + nil + } if let blockView, block.canConfigureBlockView(blockView) { block.configureBlockView( blockView, observer: self, overscrollDelegate: nil, - renderingDelegate: divKitComponents.tooltipManager + renderingDelegate: renderingDelegate ) } else { blockView = block.makeBlockView( observer: self, - renderingDelegate: divKitComponents.tooltipManager + renderingDelegate: renderingDelegate ) } invalidateIntrinsicContentSize() diff --git a/DivKit/generated_sources/DivAccessibility.swift b/DivKit/generated_sources/DivAccessibility.swift index 3fa68569..f04e4000 100644 --- a/DivKit/generated_sources/DivAccessibility.swift +++ b/DivKit/generated_sources/DivAccessibility.swift @@ -16,6 +16,8 @@ public final class DivAccessibility { case tabBar = "tab_bar" case list = "list" case select = "select" + case checkbox = "checkbox" + case radio = "radio" case auto = "auto" } @@ -28,6 +30,7 @@ public final class DivAccessibility { public let description: Expression? public let hint: Expression? + public let isChecked: Expression? public let mode: Expression // default value: default public let muteAfterAction: Expression // default value: false public let stateDescription: Expression? @@ -41,6 +44,10 @@ public final class DivAccessibility { resolver.resolveString(hint) } + public func resolveIsChecked(_ resolver: ExpressionResolver) -> Bool? { + resolver.resolveNumeric(isChecked) + } + public func resolveMode(_ resolver: ExpressionResolver) -> Mode { resolver.resolveEnum(mode) ?? Mode.default } @@ -56,6 +63,7 @@ public final class DivAccessibility { init( description: Expression? = nil, hint: Expression? = nil, + isChecked: Expression? = nil, mode: Expression? = nil, muteAfterAction: Expression? = nil, stateDescription: Expression? = nil, @@ -63,6 +71,7 @@ public final class DivAccessibility { ) { self.description = description self.hint = hint + self.isChecked = isChecked self.mode = mode ?? .value(.default) self.muteAfterAction = muteAfterAction ?? .value(false) self.stateDescription = stateDescription @@ -76,13 +85,18 @@ extension DivAccessibility: Equatable { guard lhs.description == rhs.description, lhs.hint == rhs.hint, - lhs.mode == rhs.mode + lhs.isChecked == rhs.isChecked else { return false } guard + lhs.mode == rhs.mode, lhs.muteAfterAction == rhs.muteAfterAction, - lhs.stateDescription == rhs.stateDescription, + lhs.stateDescription == rhs.stateDescription + else { + return false + } + guard lhs.type == rhs.type else { return false @@ -97,6 +111,7 @@ extension DivAccessibility: Serializable { var result: [String: ValidSerializationValue] = [:] result["description"] = description?.toValidSerializationValue() result["hint"] = hint?.toValidSerializationValue() + result["is_checked"] = isChecked?.toValidSerializationValue() result["mode"] = mode.toValidSerializationValue() result["mute_after_action"] = muteAfterAction.toValidSerializationValue() result["state_description"] = stateDescription?.toValidSerializationValue() diff --git a/DivKit/generated_sources/DivAccessibilityTemplate.swift b/DivKit/generated_sources/DivAccessibilityTemplate.swift index 7b9f45c1..f0e29cd9 100644 --- a/DivKit/generated_sources/DivAccessibilityTemplate.swift +++ b/DivKit/generated_sources/DivAccessibilityTemplate.swift @@ -11,6 +11,7 @@ public final class DivAccessibilityTemplate: TemplateValue { public let description: Field>? public let hint: Field>? + public let isChecked: Field>? public let mode: Field>? // default value: default public let muteAfterAction: Field>? // default value: false public let stateDescription: Field>? @@ -20,6 +21,7 @@ public final class DivAccessibilityTemplate: TemplateValue { self.init( description: dictionary.getOptionalExpressionField("description"), hint: dictionary.getOptionalExpressionField("hint"), + isChecked: dictionary.getOptionalExpressionField("is_checked"), mode: dictionary.getOptionalExpressionField("mode"), muteAfterAction: dictionary.getOptionalExpressionField("mute_after_action"), stateDescription: dictionary.getOptionalExpressionField("state_description"), @@ -30,6 +32,7 @@ public final class DivAccessibilityTemplate: TemplateValue { init( description: Field>? = nil, hint: Field>? = nil, + isChecked: Field>? = nil, mode: Field>? = nil, muteAfterAction: Field>? = nil, stateDescription: Field>? = nil, @@ -37,6 +40,7 @@ public final class DivAccessibilityTemplate: TemplateValue { ) { self.description = description self.hint = hint + self.isChecked = isChecked self.mode = mode self.muteAfterAction = muteAfterAction self.stateDescription = stateDescription @@ -46,6 +50,7 @@ public final class DivAccessibilityTemplate: TemplateValue { private static func resolveOnlyLinks(context: TemplatesContext, parent: DivAccessibilityTemplate?) -> DeserializationResult { let descriptionValue = { parent?.description?.resolveOptionalValue(context: context) ?? .noValue }() let hintValue = { parent?.hint?.resolveOptionalValue(context: context) ?? .noValue }() + let isCheckedValue = { parent?.isChecked?.resolveOptionalValue(context: context) ?? .noValue }() let modeValue = { parent?.mode?.resolveOptionalValue(context: context) ?? .noValue }() let muteAfterActionValue = { parent?.muteAfterAction?.resolveOptionalValue(context: context) ?? .noValue }() let stateDescriptionValue = { parent?.stateDescription?.resolveOptionalValue(context: context) ?? .noValue }() @@ -53,6 +58,7 @@ public final class DivAccessibilityTemplate: TemplateValue { let errors = mergeErrors( descriptionValue.errorsOrWarnings?.map { .nestedObjectError(field: "description", error: $0) }, hintValue.errorsOrWarnings?.map { .nestedObjectError(field: "hint", error: $0) }, + isCheckedValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_checked", error: $0) }, modeValue.errorsOrWarnings?.map { .nestedObjectError(field: "mode", error: $0) }, muteAfterActionValue.errorsOrWarnings?.map { .nestedObjectError(field: "mute_after_action", error: $0) }, stateDescriptionValue.errorsOrWarnings?.map { .nestedObjectError(field: "state_description", error: $0) }, @@ -61,6 +67,7 @@ public final class DivAccessibilityTemplate: TemplateValue { let result = DivAccessibility( description: { descriptionValue.value }(), hint: { hintValue.value }(), + isChecked: { isCheckedValue.value }(), mode: { modeValue.value }(), muteAfterAction: { muteAfterActionValue.value }(), stateDescription: { stateDescriptionValue.value }(), @@ -75,6 +82,7 @@ public final class DivAccessibilityTemplate: TemplateValue { } var descriptionValue: DeserializationResult> = { parent?.description?.value() ?? .noValue }() var hintValue: DeserializationResult> = { parent?.hint?.value() ?? .noValue }() + var isCheckedValue: DeserializationResult> = { parent?.isChecked?.value() ?? .noValue }() var modeValue: DeserializationResult> = { parent?.mode?.value() ?? .noValue }() var muteAfterActionValue: DeserializationResult> = { parent?.muteAfterAction?.value() ?? .noValue }() var stateDescriptionValue: DeserializationResult> = { parent?.stateDescription?.value() ?? .noValue }() @@ -94,6 +102,11 @@ public final class DivAccessibilityTemplate: TemplateValue { hintValue = deserialize(__dictValue).merged(with: hintValue) } }() + _ = { + if key == "is_checked" { + isCheckedValue = deserialize(__dictValue).merged(with: isCheckedValue) + } + }() _ = { if key == "mode" { modeValue = deserialize(__dictValue).merged(with: modeValue) @@ -124,6 +137,11 @@ public final class DivAccessibilityTemplate: TemplateValue { hintValue = hintValue.merged(with: { deserialize(__dictValue) }) } }() + _ = { + if key == parent?.isChecked?.link { + isCheckedValue = isCheckedValue.merged(with: { deserialize(__dictValue) }) + } + }() _ = { if key == parent?.mode?.link { modeValue = modeValue.merged(with: { deserialize(__dictValue) }) @@ -149,6 +167,7 @@ public final class DivAccessibilityTemplate: TemplateValue { let errors = mergeErrors( descriptionValue.errorsOrWarnings?.map { .nestedObjectError(field: "description", error: $0) }, hintValue.errorsOrWarnings?.map { .nestedObjectError(field: "hint", error: $0) }, + isCheckedValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_checked", error: $0) }, modeValue.errorsOrWarnings?.map { .nestedObjectError(field: "mode", error: $0) }, muteAfterActionValue.errorsOrWarnings?.map { .nestedObjectError(field: "mute_after_action", error: $0) }, stateDescriptionValue.errorsOrWarnings?.map { .nestedObjectError(field: "state_description", error: $0) }, @@ -157,6 +176,7 @@ public final class DivAccessibilityTemplate: TemplateValue { let result = DivAccessibility( description: { descriptionValue.value }(), hint: { hintValue.value }(), + isChecked: { isCheckedValue.value }(), mode: { modeValue.value }(), muteAfterAction: { muteAfterActionValue.value }(), stateDescription: { stateDescriptionValue.value }(), diff --git a/DivKit/generated_sources/DivContainer.swift b/DivKit/generated_sources/DivContainer.swift index 253d3692..8731d5fe 100644 --- a/DivKit/generated_sources/DivContainer.swift +++ b/DivKit/generated_sources/DivContainer.swift @@ -74,6 +74,8 @@ public final class DivContainer: DivBase { public let focus: DivFocus? public let functions: [DivFunction]? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: [DivAction]? + public let hoverStartActions: [DivAction]? public let id: String? public let itemBuilder: DivCollectionItemBuilder? public let items: [Div]? @@ -84,6 +86,8 @@ public final class DivContainer: DivBase { public let margins: DivEdgeInsets? public let orientation: Expression // default value: vertical public let paddings: DivEdgeInsets? + public let pressEndActions: [DivAction]? + public let pressStartActions: [DivAction]? public let reuseId: Expression? public let rowSpan: Expression? // constraint: number >= 0 public let selectedActions: [DivAction]? @@ -183,6 +187,8 @@ public final class DivContainer: DivBase { focus: DivFocus?, functions: [DivFunction]?, height: DivSize?, + hoverEndActions: [DivAction]?, + hoverStartActions: [DivAction]?, id: String?, itemBuilder: DivCollectionItemBuilder?, items: [Div]?, @@ -193,6 +199,8 @@ public final class DivContainer: DivBase { margins: DivEdgeInsets?, orientation: Expression?, paddings: DivEdgeInsets?, + pressEndActions: [DivAction]?, + pressStartActions: [DivAction]?, reuseId: Expression?, rowSpan: Expression?, selectedActions: [DivAction]?, @@ -231,6 +239,8 @@ public final class DivContainer: DivBase { self.focus = focus self.functions = functions self.height = height ?? .divWrapContentSize(DivWrapContentSize()) + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.itemBuilder = itemBuilder self.items = items @@ -241,6 +251,8 @@ public final class DivContainer: DivBase { self.margins = margins self.orientation = orientation ?? .value(.vertical) self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.reuseId = reuseId self.rowSpan = rowSpan self.selectedActions = selectedActions @@ -313,62 +325,70 @@ extension DivContainer: Equatable { return false } guard - lhs.id == rhs.id, + lhs.hoverEndActions == rhs.hoverEndActions, + lhs.hoverStartActions == rhs.hoverStartActions, + lhs.id == rhs.id + else { + return false + } + guard lhs.itemBuilder == rhs.itemBuilder, - lhs.items == rhs.items + lhs.items == rhs.items, + lhs.layoutMode == rhs.layoutMode else { return false } guard - lhs.layoutMode == rhs.layoutMode, lhs.layoutProvider == rhs.layoutProvider, - lhs.lineSeparator == rhs.lineSeparator + lhs.lineSeparator == rhs.lineSeparator, + lhs.longtapActions == rhs.longtapActions else { return false } guard - lhs.longtapActions == rhs.longtapActions, lhs.margins == rhs.margins, - lhs.orientation == rhs.orientation + lhs.orientation == rhs.orientation, + lhs.paddings == rhs.paddings else { return false } guard - lhs.paddings == rhs.paddings, - lhs.reuseId == rhs.reuseId, - lhs.rowSpan == rhs.rowSpan + lhs.pressEndActions == rhs.pressEndActions, + lhs.pressStartActions == rhs.pressStartActions, + lhs.reuseId == rhs.reuseId else { return false } guard + lhs.rowSpan == rhs.rowSpan, lhs.selectedActions == rhs.selectedActions, - lhs.separator == rhs.separator, - lhs.tooltips == rhs.tooltips + lhs.separator == rhs.separator else { return false } guard + lhs.tooltips == rhs.tooltips, lhs.transform == rhs.transform, - lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn + lhs.transitionChange == rhs.transitionChange else { return false } guard + lhs.transitionIn == rhs.transitionIn, lhs.transitionOut == rhs.transitionOut, - lhs.transitionTriggers == rhs.transitionTriggers, - lhs.variableTriggers == rhs.variableTriggers + lhs.transitionTriggers == rhs.transitionTriggers else { return false } guard + lhs.variableTriggers == rhs.variableTriggers, lhs.variables == rhs.variables, - lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction + lhs.visibility == rhs.visibility else { return false } guard + lhs.visibilityAction == rhs.visibilityAction, lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { @@ -404,6 +424,8 @@ extension DivContainer: Serializable { result["focus"] = focus?.toDictionary() result["functions"] = functions?.map { $0.toDictionary() } result["height"] = height.toDictionary() + result["hover_end_actions"] = hoverEndActions?.map { $0.toDictionary() } + result["hover_start_actions"] = hoverStartActions?.map { $0.toDictionary() } result["id"] = id result["item_builder"] = itemBuilder?.toDictionary() result["items"] = items?.map { $0.toDictionary() } @@ -414,6 +436,8 @@ extension DivContainer: Serializable { result["margins"] = margins?.toDictionary() result["orientation"] = orientation.toValidSerializationValue() result["paddings"] = paddings?.toDictionary() + result["press_end_actions"] = pressEndActions?.map { $0.toDictionary() } + result["press_start_actions"] = pressStartActions?.map { $0.toDictionary() } result["reuse_id"] = reuseId?.toValidSerializationValue() result["row_span"] = rowSpan?.toValidSerializationValue() result["selected_actions"] = selectedActions?.map { $0.toDictionary() } diff --git a/DivKit/generated_sources/DivContainerTemplate.swift b/DivKit/generated_sources/DivContainerTemplate.swift index cb412468..b030d5ea 100644 --- a/DivKit/generated_sources/DivContainerTemplate.swift +++ b/DivKit/generated_sources/DivContainerTemplate.swift @@ -206,6 +206,8 @@ public final class DivContainerTemplate: TemplateValue { public let focus: Field? public let functions: Field<[DivFunctionTemplate]>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: Field<[DivActionTemplate]>? + public let hoverStartActions: Field<[DivActionTemplate]>? public let id: Field? public let itemBuilder: Field? public let items: Field<[DivTemplate]>? @@ -216,6 +218,8 @@ public final class DivContainerTemplate: TemplateValue { public let margins: Field? public let orientation: Field>? // default value: vertical public let paddings: Field? + public let pressEndActions: Field<[DivActionTemplate]>? + public let pressStartActions: Field<[DivActionTemplate]>? public let reuseId: Field>? public let rowSpan: Field>? // constraint: number >= 0 public let selectedActions: Field<[DivActionTemplate]>? @@ -257,6 +261,8 @@ public final class DivContainerTemplate: TemplateValue { focus: dictionary.getOptionalField("focus", templateToType: templateToType), functions: dictionary.getOptionalArray("functions", templateToType: templateToType), height: dictionary.getOptionalField("height", templateToType: templateToType), + hoverEndActions: dictionary.getOptionalArray("hover_end_actions", templateToType: templateToType), + hoverStartActions: dictionary.getOptionalArray("hover_start_actions", templateToType: templateToType), id: dictionary.getOptionalField("id"), itemBuilder: dictionary.getOptionalField("item_builder", templateToType: templateToType), items: dictionary.getOptionalArray("items", templateToType: templateToType), @@ -267,6 +273,8 @@ public final class DivContainerTemplate: TemplateValue { margins: dictionary.getOptionalField("margins", templateToType: templateToType), orientation: dictionary.getOptionalExpressionField("orientation"), paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), + pressEndActions: dictionary.getOptionalArray("press_end_actions", templateToType: templateToType), + pressStartActions: dictionary.getOptionalArray("press_start_actions", templateToType: templateToType), reuseId: dictionary.getOptionalExpressionField("reuse_id"), rowSpan: dictionary.getOptionalExpressionField("row_span"), selectedActions: dictionary.getOptionalArray("selected_actions", templateToType: templateToType), @@ -309,6 +317,8 @@ public final class DivContainerTemplate: TemplateValue { focus: Field? = nil, functions: Field<[DivFunctionTemplate]>? = nil, height: Field? = nil, + hoverEndActions: Field<[DivActionTemplate]>? = nil, + hoverStartActions: Field<[DivActionTemplate]>? = nil, id: Field? = nil, itemBuilder: Field? = nil, items: Field<[DivTemplate]>? = nil, @@ -319,6 +329,8 @@ public final class DivContainerTemplate: TemplateValue { margins: Field? = nil, orientation: Field>? = nil, paddings: Field? = nil, + pressEndActions: Field<[DivActionTemplate]>? = nil, + pressStartActions: Field<[DivActionTemplate]>? = nil, reuseId: Field>? = nil, rowSpan: Field>? = nil, selectedActions: Field<[DivActionTemplate]>? = nil, @@ -358,6 +370,8 @@ public final class DivContainerTemplate: TemplateValue { self.focus = focus self.functions = functions self.height = height + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.itemBuilder = itemBuilder self.items = items @@ -368,6 +382,8 @@ public final class DivContainerTemplate: TemplateValue { self.margins = margins self.orientation = orientation self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.reuseId = reuseId self.rowSpan = rowSpan self.selectedActions = selectedActions @@ -408,6 +424,8 @@ public final class DivContainerTemplate: TemplateValue { let focusValue = { parent?.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverEndActionsValue = { parent?.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverStartActionsValue = { parent?.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() let itemBuilderValue = { parent?.itemBuilder?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let itemsValue = { parent?.items?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -418,6 +436,8 @@ public final class DivContainerTemplate: TemplateValue { let marginsValue = { parent?.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let orientationValue = { parent?.orientation?.resolveOptionalValue(context: context) ?? .noValue }() let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressEndActionsValue = { parent?.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressStartActionsValue = { parent?.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() let selectedActionsValue = { parent?.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -456,6 +476,8 @@ public final class DivContainerTemplate: TemplateValue { focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, itemBuilderValue.errorsOrWarnings?.map { .nestedObjectError(field: "item_builder", error: $0) }, itemsValue.errorsOrWarnings?.map { .nestedObjectError(field: "items", error: $0) }, @@ -466,6 +488,8 @@ public final class DivContainerTemplate: TemplateValue { marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, orientationValue.errorsOrWarnings?.map { .nestedObjectError(field: "orientation", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, @@ -505,6 +529,8 @@ public final class DivContainerTemplate: TemplateValue { focus: { focusValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), itemBuilder: { itemBuilderValue.value }(), items: { itemsValue.value }(), @@ -515,6 +541,8 @@ public final class DivContainerTemplate: TemplateValue { margins: { marginsValue.value }(), orientation: { orientationValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), selectedActions: { selectedActionsValue.value }(), @@ -560,6 +588,8 @@ public final class DivContainerTemplate: TemplateValue { var focusValue: DeserializationResult = .noValue var functionsValue: DeserializationResult<[DivFunction]> = .noValue var heightValue: DeserializationResult = .noValue + var hoverEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var hoverStartActionsValue: DeserializationResult<[DivAction]> = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() var itemBuilderValue: DeserializationResult = .noValue var itemsValue: DeserializationResult<[Div]> = .noValue @@ -570,6 +600,8 @@ public final class DivContainerTemplate: TemplateValue { var marginsValue: DeserializationResult = .noValue var orientationValue: DeserializationResult> = { parent?.orientation?.value() ?? .noValue }() var paddingsValue: DeserializationResult = .noValue + var pressEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var pressStartActionsValue: DeserializationResult<[DivAction]> = .noValue var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() var selectedActionsValue: DeserializationResult<[DivAction]> = .noValue @@ -696,6 +728,16 @@ public final class DivContainerTemplate: TemplateValue { heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: heightValue) } }() + _ = { + if key == "hover_end_actions" { + hoverEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverEndActionsValue) + } + }() + _ = { + if key == "hover_start_actions" { + hoverStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverStartActionsValue) + } + }() _ = { if key == "id" { idValue = deserialize(__dictValue).merged(with: idValue) @@ -746,6 +788,16 @@ public final class DivContainerTemplate: TemplateValue { paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) } }() + _ = { + if key == "press_end_actions" { + pressEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressEndActionsValue) + } + }() + _ = { + if key == "press_start_actions" { + pressStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressStartActionsValue) + } + }() _ = { if key == "reuse_id" { reuseIdValue = deserialize(__dictValue).merged(with: reuseIdValue) @@ -931,6 +983,16 @@ public final class DivContainerTemplate: TemplateValue { heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) } }() + _ = { + if key == parent?.hoverEndActions?.link { + hoverEndActionsValue = hoverEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.hoverStartActions?.link { + hoverStartActionsValue = hoverStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.id?.link { idValue = idValue.merged(with: { deserialize(__dictValue) }) @@ -981,6 +1043,16 @@ public final class DivContainerTemplate: TemplateValue { paddingsValue = paddingsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self) }) } }() + _ = { + if key == parent?.pressEndActions?.link { + pressEndActionsValue = pressEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.pressStartActions?.link { + pressStartActionsValue = pressStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.reuseId?.link { reuseIdValue = reuseIdValue.merged(with: { deserialize(__dictValue) }) @@ -1078,6 +1150,8 @@ public final class DivContainerTemplate: TemplateValue { _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverEndActionsValue = hoverEndActionsValue.merged(with: { parent.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverStartActionsValue = hoverStartActionsValue.merged(with: { parent.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { itemBuilderValue = itemBuilderValue.merged(with: { parent.itemBuilder?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { itemsValue = itemsValue.merged(with: { parent.items?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -1085,6 +1159,8 @@ public final class DivContainerTemplate: TemplateValue { _ = { longtapActionsValue = longtapActionsValue.merged(with: { parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressEndActionsValue = pressEndActionsValue.merged(with: { parent.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressStartActionsValue = pressStartActionsValue.merged(with: { parent.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { separatorValue = separatorValue.merged(with: { parent.separator?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { tooltipsValue = tooltipsValue.merged(with: { parent.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -1120,6 +1196,8 @@ public final class DivContainerTemplate: TemplateValue { focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, itemBuilderValue.errorsOrWarnings?.map { .nestedObjectError(field: "item_builder", error: $0) }, itemsValue.errorsOrWarnings?.map { .nestedObjectError(field: "items", error: $0) }, @@ -1130,6 +1208,8 @@ public final class DivContainerTemplate: TemplateValue { marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, orientationValue.errorsOrWarnings?.map { .nestedObjectError(field: "orientation", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, @@ -1169,6 +1249,8 @@ public final class DivContainerTemplate: TemplateValue { focus: { focusValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), itemBuilder: { itemBuilderValue.value }(), items: { itemsValue.value }(), @@ -1179,6 +1261,8 @@ public final class DivContainerTemplate: TemplateValue { margins: { marginsValue.value }(), orientation: { orientationValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), selectedActions: { selectedActionsValue.value }(), @@ -1229,6 +1313,8 @@ public final class DivContainerTemplate: TemplateValue { focus: focus ?? mergedParent.focus, functions: functions ?? mergedParent.functions, height: height ?? mergedParent.height, + hoverEndActions: hoverEndActions ?? mergedParent.hoverEndActions, + hoverStartActions: hoverStartActions ?? mergedParent.hoverStartActions, id: id ?? mergedParent.id, itemBuilder: itemBuilder ?? mergedParent.itemBuilder, items: items ?? mergedParent.items, @@ -1239,6 +1325,8 @@ public final class DivContainerTemplate: TemplateValue { margins: margins ?? mergedParent.margins, orientation: orientation ?? mergedParent.orientation, paddings: paddings ?? mergedParent.paddings, + pressEndActions: pressEndActions ?? mergedParent.pressEndActions, + pressStartActions: pressStartActions ?? mergedParent.pressStartActions, reuseId: reuseId ?? mergedParent.reuseId, rowSpan: rowSpan ?? mergedParent.rowSpan, selectedActions: selectedActions ?? mergedParent.selectedActions, @@ -1284,6 +1372,8 @@ public final class DivContainerTemplate: TemplateValue { focus: merged.focus?.tryResolveParent(templates: templates), functions: merged.functions?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), + hoverEndActions: merged.hoverEndActions?.tryResolveParent(templates: templates), + hoverStartActions: merged.hoverStartActions?.tryResolveParent(templates: templates), id: merged.id, itemBuilder: merged.itemBuilder?.tryResolveParent(templates: templates), items: merged.items?.tryResolveParent(templates: templates), @@ -1294,6 +1384,8 @@ public final class DivContainerTemplate: TemplateValue { margins: merged.margins?.tryResolveParent(templates: templates), orientation: merged.orientation, paddings: merged.paddings?.tryResolveParent(templates: templates), + pressEndActions: merged.pressEndActions?.tryResolveParent(templates: templates), + pressStartActions: merged.pressStartActions?.tryResolveParent(templates: templates), reuseId: merged.reuseId, rowSpan: merged.rowSpan, selectedActions: merged.selectedActions?.tryResolveParent(templates: templates), diff --git a/DivKit/generated_sources/DivGifImage.swift b/DivKit/generated_sources/DivGifImage.swift index d167a50d..3dff1c5d 100644 --- a/DivKit/generated_sources/DivGifImage.swift +++ b/DivKit/generated_sources/DivGifImage.swift @@ -27,6 +27,8 @@ public final class DivGifImage: DivBase { public let functions: [DivFunction]? public let gifUrl: Expression public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: [DivAction]? + public let hoverStartActions: [DivAction]? public let id: String? public let layoutProvider: DivLayoutProvider? public let longtapActions: [DivAction]? @@ -34,6 +36,8 @@ public final class DivGifImage: DivBase { public let paddings: DivEdgeInsets? public let placeholderColor: Expression // default value: #14000000 public let preloadRequired: Expression // default value: false + public let pressEndActions: [DivAction]? + public let pressStartActions: [DivAction]? public let preview: Expression? public let reuseId: Expression? public let rowSpan: Expression? // constraint: number >= 0 @@ -142,6 +146,8 @@ public final class DivGifImage: DivBase { functions: [DivFunction]? = nil, gifUrl: Expression, height: DivSize? = nil, + hoverEndActions: [DivAction]? = nil, + hoverStartActions: [DivAction]? = nil, id: String? = nil, layoutProvider: DivLayoutProvider? = nil, longtapActions: [DivAction]? = nil, @@ -149,6 +155,8 @@ public final class DivGifImage: DivBase { paddings: DivEdgeInsets? = nil, placeholderColor: Expression? = nil, preloadRequired: Expression? = nil, + pressEndActions: [DivAction]? = nil, + pressStartActions: [DivAction]? = nil, preview: Expression? = nil, reuseId: Expression? = nil, rowSpan: Expression? = nil, @@ -188,6 +196,8 @@ public final class DivGifImage: DivBase { self.functions = functions self.gifUrl = gifUrl self.height = height ?? .divWrapContentSize(DivWrapContentSize()) + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.layoutProvider = layoutProvider self.longtapActions = longtapActions @@ -195,6 +205,8 @@ public final class DivGifImage: DivBase { self.paddings = paddings self.placeholderColor = placeholderColor ?? .value(Color.colorWithARGBHexCode(0x14000000)) self.preloadRequired = preloadRequired ?? .value(false) + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.preview = preview self.reuseId = reuseId self.rowSpan = rowSpan @@ -268,57 +280,69 @@ extension DivGifImage: Equatable { return false } guard - lhs.id == rhs.id, + lhs.hoverEndActions == rhs.hoverEndActions, + lhs.hoverStartActions == rhs.hoverStartActions, + lhs.id == rhs.id + else { + return false + } + guard lhs.layoutProvider == rhs.layoutProvider, - lhs.longtapActions == rhs.longtapActions + lhs.longtapActions == rhs.longtapActions, + lhs.margins == rhs.margins else { return false } guard - lhs.margins == rhs.margins, lhs.paddings == rhs.paddings, - lhs.placeholderColor == rhs.placeholderColor + lhs.placeholderColor == rhs.placeholderColor, + lhs.preloadRequired == rhs.preloadRequired else { return false } guard - lhs.preloadRequired == rhs.preloadRequired, - lhs.preview == rhs.preview, - lhs.reuseId == rhs.reuseId + lhs.pressEndActions == rhs.pressEndActions, + lhs.pressStartActions == rhs.pressStartActions, + lhs.preview == rhs.preview else { return false } guard + lhs.reuseId == rhs.reuseId, lhs.rowSpan == rhs.rowSpan, - lhs.scale == rhs.scale, - lhs.selectedActions == rhs.selectedActions + lhs.scale == rhs.scale else { return false } guard + lhs.selectedActions == rhs.selectedActions, lhs.tooltips == rhs.tooltips, - lhs.transform == rhs.transform, - lhs.transitionChange == rhs.transitionChange + lhs.transform == rhs.transform else { return false } guard + lhs.transitionChange == rhs.transitionChange, lhs.transitionIn == rhs.transitionIn, - lhs.transitionOut == rhs.transitionOut, - lhs.transitionTriggers == rhs.transitionTriggers + lhs.transitionOut == rhs.transitionOut else { return false } guard + lhs.transitionTriggers == rhs.transitionTriggers, lhs.variableTriggers == rhs.variableTriggers, - lhs.variables == rhs.variables, - lhs.visibility == rhs.visibility + lhs.variables == rhs.variables else { return false } guard + lhs.visibility == rhs.visibility, lhs.visibilityAction == rhs.visibilityAction, - lhs.visibilityActions == rhs.visibilityActions, + lhs.visibilityActions == rhs.visibilityActions + else { + return false + } + guard lhs.width == rhs.width else { return false @@ -353,6 +377,8 @@ extension DivGifImage: Serializable { result["functions"] = functions?.map { $0.toDictionary() } result["gif_url"] = gifUrl.toValidSerializationValue() result["height"] = height.toDictionary() + result["hover_end_actions"] = hoverEndActions?.map { $0.toDictionary() } + result["hover_start_actions"] = hoverStartActions?.map { $0.toDictionary() } result["id"] = id result["layout_provider"] = layoutProvider?.toDictionary() result["longtap_actions"] = longtapActions?.map { $0.toDictionary() } @@ -360,6 +386,8 @@ extension DivGifImage: Serializable { result["paddings"] = paddings?.toDictionary() result["placeholder_color"] = placeholderColor.toValidSerializationValue() result["preload_required"] = preloadRequired.toValidSerializationValue() + result["press_end_actions"] = pressEndActions?.map { $0.toDictionary() } + result["press_start_actions"] = pressStartActions?.map { $0.toDictionary() } result["preview"] = preview?.toValidSerializationValue() result["reuse_id"] = reuseId?.toValidSerializationValue() result["row_span"] = rowSpan?.toValidSerializationValue() diff --git a/DivKit/generated_sources/DivGifImageTemplate.swift b/DivKit/generated_sources/DivGifImageTemplate.swift index a01a3b20..a37fae23 100644 --- a/DivKit/generated_sources/DivGifImageTemplate.swift +++ b/DivKit/generated_sources/DivGifImageTemplate.swift @@ -28,6 +28,8 @@ public final class DivGifImageTemplate: TemplateValue { public let functions: Field<[DivFunctionTemplate]>? public let gifUrl: Field>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: Field<[DivActionTemplate]>? + public let hoverStartActions: Field<[DivActionTemplate]>? public let id: Field? public let layoutProvider: Field? public let longtapActions: Field<[DivActionTemplate]>? @@ -35,6 +37,8 @@ public final class DivGifImageTemplate: TemplateValue { public let paddings: Field? public let placeholderColor: Field>? // default value: #14000000 public let preloadRequired: Field>? // default value: false + public let pressEndActions: Field<[DivActionTemplate]>? + public let pressStartActions: Field<[DivActionTemplate]>? public let preview: Field>? public let reuseId: Field>? public let rowSpan: Field>? // constraint: number >= 0 @@ -77,6 +81,8 @@ public final class DivGifImageTemplate: TemplateValue { functions: dictionary.getOptionalArray("functions", templateToType: templateToType), gifUrl: dictionary.getOptionalExpressionField("gif_url", transform: URL.init(string:)), height: dictionary.getOptionalField("height", templateToType: templateToType), + hoverEndActions: dictionary.getOptionalArray("hover_end_actions", templateToType: templateToType), + hoverStartActions: dictionary.getOptionalArray("hover_start_actions", templateToType: templateToType), id: dictionary.getOptionalField("id"), layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), longtapActions: dictionary.getOptionalArray("longtap_actions", templateToType: templateToType), @@ -84,6 +90,8 @@ public final class DivGifImageTemplate: TemplateValue { paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), placeholderColor: dictionary.getOptionalExpressionField("placeholder_color", transform: Color.color(withHexString:)), preloadRequired: dictionary.getOptionalExpressionField("preload_required"), + pressEndActions: dictionary.getOptionalArray("press_end_actions", templateToType: templateToType), + pressStartActions: dictionary.getOptionalArray("press_start_actions", templateToType: templateToType), preview: dictionary.getOptionalExpressionField("preview"), reuseId: dictionary.getOptionalExpressionField("reuse_id"), rowSpan: dictionary.getOptionalExpressionField("row_span"), @@ -127,6 +135,8 @@ public final class DivGifImageTemplate: TemplateValue { functions: Field<[DivFunctionTemplate]>? = nil, gifUrl: Field>? = nil, height: Field? = nil, + hoverEndActions: Field<[DivActionTemplate]>? = nil, + hoverStartActions: Field<[DivActionTemplate]>? = nil, id: Field? = nil, layoutProvider: Field? = nil, longtapActions: Field<[DivActionTemplate]>? = nil, @@ -134,6 +144,8 @@ public final class DivGifImageTemplate: TemplateValue { paddings: Field? = nil, placeholderColor: Field>? = nil, preloadRequired: Field>? = nil, + pressEndActions: Field<[DivActionTemplate]>? = nil, + pressStartActions: Field<[DivActionTemplate]>? = nil, preview: Field>? = nil, reuseId: Field>? = nil, rowSpan: Field>? = nil, @@ -174,6 +186,8 @@ public final class DivGifImageTemplate: TemplateValue { self.functions = functions self.gifUrl = gifUrl self.height = height + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.layoutProvider = layoutProvider self.longtapActions = longtapActions @@ -181,6 +195,8 @@ public final class DivGifImageTemplate: TemplateValue { self.paddings = paddings self.placeholderColor = placeholderColor self.preloadRequired = preloadRequired + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.preview = preview self.reuseId = reuseId self.rowSpan = rowSpan @@ -222,6 +238,8 @@ public final class DivGifImageTemplate: TemplateValue { let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let gifUrlValue = { parent?.gifUrl?.resolveValue(context: context, transform: URL.init(string:)) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverEndActionsValue = { parent?.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverStartActionsValue = { parent?.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let longtapActionsValue = { parent?.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -229,6 +247,8 @@ public final class DivGifImageTemplate: TemplateValue { let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let placeholderColorValue = { parent?.placeholderColor?.resolveOptionalValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() let preloadRequiredValue = { parent?.preloadRequired?.resolveOptionalValue(context: context) ?? .noValue }() + let pressEndActionsValue = { parent?.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressStartActionsValue = { parent?.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let previewValue = { parent?.preview?.resolveOptionalValue(context: context) ?? .noValue }() let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() @@ -268,6 +288,8 @@ public final class DivGifImageTemplate: TemplateValue { functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, gifUrlValue.errorsOrWarnings?.map { .nestedObjectError(field: "gif_url", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, longtapActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "longtap_actions", error: $0) }, @@ -275,6 +297,8 @@ public final class DivGifImageTemplate: TemplateValue { paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, placeholderColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "placeholder_color", error: $0) }, preloadRequiredValue.errorsOrWarnings?.map { .nestedObjectError(field: "preload_required", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, previewValue.errorsOrWarnings?.map { .nestedObjectError(field: "preview", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, @@ -323,6 +347,8 @@ public final class DivGifImageTemplate: TemplateValue { functions: { functionsValue.value }(), gifUrl: { gifUrlNonNil }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), layoutProvider: { layoutProviderValue.value }(), longtapActions: { longtapActionsValue.value }(), @@ -330,6 +356,8 @@ public final class DivGifImageTemplate: TemplateValue { paddings: { paddingsValue.value }(), placeholderColor: { placeholderColorValue.value }(), preloadRequired: { preloadRequiredValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), preview: { previewValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), @@ -376,6 +404,8 @@ public final class DivGifImageTemplate: TemplateValue { var functionsValue: DeserializationResult<[DivFunction]> = .noValue var gifUrlValue: DeserializationResult> = { parent?.gifUrl?.value() ?? .noValue }() var heightValue: DeserializationResult = .noValue + var hoverEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var hoverStartActionsValue: DeserializationResult<[DivAction]> = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() var layoutProviderValue: DeserializationResult = .noValue var longtapActionsValue: DeserializationResult<[DivAction]> = .noValue @@ -383,6 +413,8 @@ public final class DivGifImageTemplate: TemplateValue { var paddingsValue: DeserializationResult = .noValue var placeholderColorValue: DeserializationResult> = { parent?.placeholderColor?.value() ?? .noValue }() var preloadRequiredValue: DeserializationResult> = { parent?.preloadRequired?.value() ?? .noValue }() + var pressEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var pressStartActionsValue: DeserializationResult<[DivAction]> = .noValue var previewValue: DeserializationResult> = { parent?.preview?.value() ?? .noValue }() var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() @@ -510,6 +542,16 @@ public final class DivGifImageTemplate: TemplateValue { heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: heightValue) } }() + _ = { + if key == "hover_end_actions" { + hoverEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverEndActionsValue) + } + }() + _ = { + if key == "hover_start_actions" { + hoverStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverStartActionsValue) + } + }() _ = { if key == "id" { idValue = deserialize(__dictValue).merged(with: idValue) @@ -545,6 +587,16 @@ public final class DivGifImageTemplate: TemplateValue { preloadRequiredValue = deserialize(__dictValue).merged(with: preloadRequiredValue) } }() + _ = { + if key == "press_end_actions" { + pressEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressEndActionsValue) + } + }() + _ = { + if key == "press_start_actions" { + pressStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressStartActionsValue) + } + }() _ = { if key == "preview" { previewValue = deserialize(__dictValue).merged(with: previewValue) @@ -735,6 +787,16 @@ public final class DivGifImageTemplate: TemplateValue { heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) } }() + _ = { + if key == parent?.hoverEndActions?.link { + hoverEndActionsValue = hoverEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.hoverStartActions?.link { + hoverStartActionsValue = hoverStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.id?.link { idValue = idValue.merged(with: { deserialize(__dictValue) }) @@ -770,6 +832,16 @@ public final class DivGifImageTemplate: TemplateValue { preloadRequiredValue = preloadRequiredValue.merged(with: { deserialize(__dictValue) }) } }() + _ = { + if key == parent?.pressEndActions?.link { + pressEndActionsValue = pressEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.pressStartActions?.link { + pressStartActionsValue = pressStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.preview?.link { previewValue = previewValue.merged(with: { deserialize(__dictValue) }) @@ -872,10 +944,14 @@ public final class DivGifImageTemplate: TemplateValue { _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverEndActionsValue = hoverEndActionsValue.merged(with: { parent.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverStartActionsValue = hoverStartActionsValue.merged(with: { parent.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { longtapActionsValue = longtapActionsValue.merged(with: { parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressEndActionsValue = pressEndActionsValue.merged(with: { parent.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressStartActionsValue = pressStartActionsValue.merged(with: { parent.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { tooltipsValue = tooltipsValue.merged(with: { parent.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { transformValue = transformValue.merged(with: { parent.transform?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -910,6 +986,8 @@ public final class DivGifImageTemplate: TemplateValue { functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, gifUrlValue.errorsOrWarnings?.map { .nestedObjectError(field: "gif_url", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, longtapActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "longtap_actions", error: $0) }, @@ -917,6 +995,8 @@ public final class DivGifImageTemplate: TemplateValue { paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, placeholderColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "placeholder_color", error: $0) }, preloadRequiredValue.errorsOrWarnings?.map { .nestedObjectError(field: "preload_required", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, previewValue.errorsOrWarnings?.map { .nestedObjectError(field: "preview", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, @@ -965,6 +1045,8 @@ public final class DivGifImageTemplate: TemplateValue { functions: { functionsValue.value }(), gifUrl: { gifUrlNonNil }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), layoutProvider: { layoutProviderValue.value }(), longtapActions: { longtapActionsValue.value }(), @@ -972,6 +1054,8 @@ public final class DivGifImageTemplate: TemplateValue { paddings: { paddingsValue.value }(), placeholderColor: { placeholderColorValue.value }(), preloadRequired: { preloadRequiredValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), preview: { previewValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), @@ -1023,6 +1107,8 @@ public final class DivGifImageTemplate: TemplateValue { functions: functions ?? mergedParent.functions, gifUrl: gifUrl ?? mergedParent.gifUrl, height: height ?? mergedParent.height, + hoverEndActions: hoverEndActions ?? mergedParent.hoverEndActions, + hoverStartActions: hoverStartActions ?? mergedParent.hoverStartActions, id: id ?? mergedParent.id, layoutProvider: layoutProvider ?? mergedParent.layoutProvider, longtapActions: longtapActions ?? mergedParent.longtapActions, @@ -1030,6 +1116,8 @@ public final class DivGifImageTemplate: TemplateValue { paddings: paddings ?? mergedParent.paddings, placeholderColor: placeholderColor ?? mergedParent.placeholderColor, preloadRequired: preloadRequired ?? mergedParent.preloadRequired, + pressEndActions: pressEndActions ?? mergedParent.pressEndActions, + pressStartActions: pressStartActions ?? mergedParent.pressStartActions, preview: preview ?? mergedParent.preview, reuseId: reuseId ?? mergedParent.reuseId, rowSpan: rowSpan ?? mergedParent.rowSpan, @@ -1076,6 +1164,8 @@ public final class DivGifImageTemplate: TemplateValue { functions: merged.functions?.tryResolveParent(templates: templates), gifUrl: merged.gifUrl, height: merged.height?.tryResolveParent(templates: templates), + hoverEndActions: merged.hoverEndActions?.tryResolveParent(templates: templates), + hoverStartActions: merged.hoverStartActions?.tryResolveParent(templates: templates), id: merged.id, layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), longtapActions: merged.longtapActions?.tryResolveParent(templates: templates), @@ -1083,6 +1173,8 @@ public final class DivGifImageTemplate: TemplateValue { paddings: merged.paddings?.tryResolveParent(templates: templates), placeholderColor: merged.placeholderColor, preloadRequired: merged.preloadRequired, + pressEndActions: merged.pressEndActions?.tryResolveParent(templates: templates), + pressStartActions: merged.pressStartActions?.tryResolveParent(templates: templates), preview: merged.preview, reuseId: merged.reuseId, rowSpan: merged.rowSpan, diff --git a/DivKit/generated_sources/DivGrid.swift b/DivKit/generated_sources/DivGrid.swift index 954dd261..d6f8cbaf 100644 --- a/DivKit/generated_sources/DivGrid.swift +++ b/DivKit/generated_sources/DivGrid.swift @@ -26,12 +26,16 @@ public final class DivGrid: DivBase { public let focus: DivFocus? public let functions: [DivFunction]? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: [DivAction]? + public let hoverStartActions: [DivAction]? public let id: String? public let items: [Div]? public let layoutProvider: DivLayoutProvider? public let longtapActions: [DivAction]? public let margins: DivEdgeInsets? public let paddings: DivEdgeInsets? + public let pressEndActions: [DivAction]? + public let pressStartActions: [DivAction]? public let reuseId: Expression? public let rowSpan: Expression? // constraint: number >= 0 public let selectedActions: [DivAction]? @@ -124,12 +128,16 @@ public final class DivGrid: DivBase { focus: DivFocus?, functions: [DivFunction]?, height: DivSize?, + hoverEndActions: [DivAction]?, + hoverStartActions: [DivAction]?, id: String?, items: [Div]?, layoutProvider: DivLayoutProvider?, longtapActions: [DivAction]?, margins: DivEdgeInsets?, paddings: DivEdgeInsets?, + pressEndActions: [DivAction]?, + pressStartActions: [DivAction]?, reuseId: Expression?, rowSpan: Expression?, selectedActions: [DivAction]?, @@ -166,12 +174,16 @@ public final class DivGrid: DivBase { self.focus = focus self.functions = functions self.height = height ?? .divWrapContentSize(DivWrapContentSize()) + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.items = items self.layoutProvider = layoutProvider self.longtapActions = longtapActions self.margins = margins self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.reuseId = reuseId self.rowSpan = rowSpan self.selectedActions = selectedActions @@ -238,53 +250,61 @@ extension DivGrid: Equatable { guard lhs.functions == rhs.functions, lhs.height == rhs.height, - lhs.id == rhs.id + lhs.hoverEndActions == rhs.hoverEndActions + else { + return false + } + guard + lhs.hoverStartActions == rhs.hoverStartActions, + lhs.id == rhs.id, + lhs.items == rhs.items else { return false } guard - lhs.items == rhs.items, lhs.layoutProvider == rhs.layoutProvider, - lhs.longtapActions == rhs.longtapActions + lhs.longtapActions == rhs.longtapActions, + lhs.margins == rhs.margins else { return false } guard - lhs.margins == rhs.margins, lhs.paddings == rhs.paddings, - lhs.reuseId == rhs.reuseId + lhs.pressEndActions == rhs.pressEndActions, + lhs.pressStartActions == rhs.pressStartActions else { return false } guard + lhs.reuseId == rhs.reuseId, lhs.rowSpan == rhs.rowSpan, - lhs.selectedActions == rhs.selectedActions, - lhs.tooltips == rhs.tooltips + lhs.selectedActions == rhs.selectedActions else { return false } guard + lhs.tooltips == rhs.tooltips, lhs.transform == rhs.transform, - lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn + lhs.transitionChange == rhs.transitionChange else { return false } guard + lhs.transitionIn == rhs.transitionIn, lhs.transitionOut == rhs.transitionOut, - lhs.transitionTriggers == rhs.transitionTriggers, - lhs.variableTriggers == rhs.variableTriggers + lhs.transitionTriggers == rhs.transitionTriggers else { return false } guard + lhs.variableTriggers == rhs.variableTriggers, lhs.variables == rhs.variables, - lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction + lhs.visibility == rhs.visibility else { return false } guard + lhs.visibilityAction == rhs.visibilityAction, lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { @@ -319,12 +339,16 @@ extension DivGrid: Serializable { result["focus"] = focus?.toDictionary() result["functions"] = functions?.map { $0.toDictionary() } result["height"] = height.toDictionary() + result["hover_end_actions"] = hoverEndActions?.map { $0.toDictionary() } + result["hover_start_actions"] = hoverStartActions?.map { $0.toDictionary() } result["id"] = id result["items"] = items?.map { $0.toDictionary() } result["layout_provider"] = layoutProvider?.toDictionary() result["longtap_actions"] = longtapActions?.map { $0.toDictionary() } result["margins"] = margins?.toDictionary() result["paddings"] = paddings?.toDictionary() + result["press_end_actions"] = pressEndActions?.map { $0.toDictionary() } + result["press_start_actions"] = pressStartActions?.map { $0.toDictionary() } result["reuse_id"] = reuseId?.toValidSerializationValue() result["row_span"] = rowSpan?.toValidSerializationValue() result["selected_actions"] = selectedActions?.map { $0.toDictionary() } diff --git a/DivKit/generated_sources/DivGridTemplate.swift b/DivKit/generated_sources/DivGridTemplate.swift index 3a0e024e..4e292d66 100644 --- a/DivKit/generated_sources/DivGridTemplate.swift +++ b/DivKit/generated_sources/DivGridTemplate.swift @@ -27,12 +27,16 @@ public final class DivGridTemplate: TemplateValue { public let focus: Field? public let functions: Field<[DivFunctionTemplate]>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: Field<[DivActionTemplate]>? + public let hoverStartActions: Field<[DivActionTemplate]>? public let id: Field? public let items: Field<[DivTemplate]>? public let layoutProvider: Field? public let longtapActions: Field<[DivActionTemplate]>? public let margins: Field? public let paddings: Field? + public let pressEndActions: Field<[DivActionTemplate]>? + public let pressStartActions: Field<[DivActionTemplate]>? public let reuseId: Field>? public let rowSpan: Field>? // constraint: number >= 0 public let selectedActions: Field<[DivActionTemplate]>? @@ -72,12 +76,16 @@ public final class DivGridTemplate: TemplateValue { focus: dictionary.getOptionalField("focus", templateToType: templateToType), functions: dictionary.getOptionalArray("functions", templateToType: templateToType), height: dictionary.getOptionalField("height", templateToType: templateToType), + hoverEndActions: dictionary.getOptionalArray("hover_end_actions", templateToType: templateToType), + hoverStartActions: dictionary.getOptionalArray("hover_start_actions", templateToType: templateToType), id: dictionary.getOptionalField("id"), items: dictionary.getOptionalArray("items", templateToType: templateToType), layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), longtapActions: dictionary.getOptionalArray("longtap_actions", templateToType: templateToType), margins: dictionary.getOptionalField("margins", templateToType: templateToType), paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), + pressEndActions: dictionary.getOptionalArray("press_end_actions", templateToType: templateToType), + pressStartActions: dictionary.getOptionalArray("press_start_actions", templateToType: templateToType), reuseId: dictionary.getOptionalExpressionField("reuse_id"), rowSpan: dictionary.getOptionalExpressionField("row_span"), selectedActions: dictionary.getOptionalArray("selected_actions", templateToType: templateToType), @@ -118,12 +126,16 @@ public final class DivGridTemplate: TemplateValue { focus: Field? = nil, functions: Field<[DivFunctionTemplate]>? = nil, height: Field? = nil, + hoverEndActions: Field<[DivActionTemplate]>? = nil, + hoverStartActions: Field<[DivActionTemplate]>? = nil, id: Field? = nil, items: Field<[DivTemplate]>? = nil, layoutProvider: Field? = nil, longtapActions: Field<[DivActionTemplate]>? = nil, margins: Field? = nil, paddings: Field? = nil, + pressEndActions: Field<[DivActionTemplate]>? = nil, + pressStartActions: Field<[DivActionTemplate]>? = nil, reuseId: Field>? = nil, rowSpan: Field>? = nil, selectedActions: Field<[DivActionTemplate]>? = nil, @@ -161,12 +173,16 @@ public final class DivGridTemplate: TemplateValue { self.focus = focus self.functions = functions self.height = height + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.items = items self.layoutProvider = layoutProvider self.longtapActions = longtapActions self.margins = margins self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.reuseId = reuseId self.rowSpan = rowSpan self.selectedActions = selectedActions @@ -205,12 +221,16 @@ public final class DivGridTemplate: TemplateValue { let focusValue = { parent?.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverEndActionsValue = { parent?.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverStartActionsValue = { parent?.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() let itemsValue = { parent?.items?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let longtapActionsValue = { parent?.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let marginsValue = { parent?.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressEndActionsValue = { parent?.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressStartActionsValue = { parent?.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() let selectedActionsValue = { parent?.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -247,12 +267,16 @@ public final class DivGridTemplate: TemplateValue { focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, itemsValue.errorsOrWarnings?.map { .nestedObjectError(field: "items", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, longtapActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "longtap_actions", error: $0) }, marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, @@ -298,12 +322,16 @@ public final class DivGridTemplate: TemplateValue { focus: { focusValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), items: { itemsValue.value }(), layoutProvider: { layoutProviderValue.value }(), longtapActions: { longtapActionsValue.value }(), margins: { marginsValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), selectedActions: { selectedActionsValue.value }(), @@ -347,12 +375,16 @@ public final class DivGridTemplate: TemplateValue { var focusValue: DeserializationResult = .noValue var functionsValue: DeserializationResult<[DivFunction]> = .noValue var heightValue: DeserializationResult = .noValue + var hoverEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var hoverStartActionsValue: DeserializationResult<[DivAction]> = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() var itemsValue: DeserializationResult<[Div]> = .noValue var layoutProviderValue: DeserializationResult = .noValue var longtapActionsValue: DeserializationResult<[DivAction]> = .noValue var marginsValue: DeserializationResult = .noValue var paddingsValue: DeserializationResult = .noValue + var pressEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var pressStartActionsValue: DeserializationResult<[DivAction]> = .noValue var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() var selectedActionsValue: DeserializationResult<[DivAction]> = .noValue @@ -473,6 +505,16 @@ public final class DivGridTemplate: TemplateValue { heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: heightValue) } }() + _ = { + if key == "hover_end_actions" { + hoverEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverEndActionsValue) + } + }() + _ = { + if key == "hover_start_actions" { + hoverStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverStartActionsValue) + } + }() _ = { if key == "id" { idValue = deserialize(__dictValue).merged(with: idValue) @@ -503,6 +545,16 @@ public final class DivGridTemplate: TemplateValue { paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) } }() + _ = { + if key == "press_end_actions" { + pressEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressEndActionsValue) + } + }() + _ = { + if key == "press_start_actions" { + pressStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressStartActionsValue) + } + }() _ = { if key == "reuse_id" { reuseIdValue = deserialize(__dictValue).merged(with: reuseIdValue) @@ -678,6 +730,16 @@ public final class DivGridTemplate: TemplateValue { heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) } }() + _ = { + if key == parent?.hoverEndActions?.link { + hoverEndActionsValue = hoverEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.hoverStartActions?.link { + hoverStartActionsValue = hoverStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.id?.link { idValue = idValue.merged(with: { deserialize(__dictValue) }) @@ -708,6 +770,16 @@ public final class DivGridTemplate: TemplateValue { paddingsValue = paddingsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self) }) } }() + _ = { + if key == parent?.pressEndActions?.link { + pressEndActionsValue = pressEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.pressStartActions?.link { + pressStartActionsValue = pressStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.reuseId?.link { reuseIdValue = reuseIdValue.merged(with: { deserialize(__dictValue) }) @@ -799,11 +871,15 @@ public final class DivGridTemplate: TemplateValue { _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverEndActionsValue = hoverEndActionsValue.merged(with: { parent.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverStartActionsValue = hoverStartActionsValue.merged(with: { parent.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { itemsValue = itemsValue.merged(with: { parent.items?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { longtapActionsValue = longtapActionsValue.merged(with: { parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressEndActionsValue = pressEndActionsValue.merged(with: { parent.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressStartActionsValue = pressStartActionsValue.merged(with: { parent.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { tooltipsValue = tooltipsValue.merged(with: { parent.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { transformValue = transformValue.merged(with: { parent.transform?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -837,12 +913,16 @@ public final class DivGridTemplate: TemplateValue { focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, itemsValue.errorsOrWarnings?.map { .nestedObjectError(field: "items", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, longtapActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "longtap_actions", error: $0) }, marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, @@ -888,12 +968,16 @@ public final class DivGridTemplate: TemplateValue { focus: { focusValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), items: { itemsValue.value }(), layoutProvider: { layoutProviderValue.value }(), longtapActions: { longtapActionsValue.value }(), margins: { marginsValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), selectedActions: { selectedActionsValue.value }(), @@ -942,12 +1026,16 @@ public final class DivGridTemplate: TemplateValue { focus: focus ?? mergedParent.focus, functions: functions ?? mergedParent.functions, height: height ?? mergedParent.height, + hoverEndActions: hoverEndActions ?? mergedParent.hoverEndActions, + hoverStartActions: hoverStartActions ?? mergedParent.hoverStartActions, id: id ?? mergedParent.id, items: items ?? mergedParent.items, layoutProvider: layoutProvider ?? mergedParent.layoutProvider, longtapActions: longtapActions ?? mergedParent.longtapActions, margins: margins ?? mergedParent.margins, paddings: paddings ?? mergedParent.paddings, + pressEndActions: pressEndActions ?? mergedParent.pressEndActions, + pressStartActions: pressStartActions ?? mergedParent.pressStartActions, reuseId: reuseId ?? mergedParent.reuseId, rowSpan: rowSpan ?? mergedParent.rowSpan, selectedActions: selectedActions ?? mergedParent.selectedActions, @@ -991,12 +1079,16 @@ public final class DivGridTemplate: TemplateValue { focus: merged.focus?.tryResolveParent(templates: templates), functions: merged.functions?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), + hoverEndActions: merged.hoverEndActions?.tryResolveParent(templates: templates), + hoverStartActions: merged.hoverStartActions?.tryResolveParent(templates: templates), id: merged.id, items: merged.items?.tryResolveParent(templates: templates), layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), longtapActions: merged.longtapActions?.tryResolveParent(templates: templates), margins: merged.margins?.tryResolveParent(templates: templates), paddings: merged.paddings?.tryResolveParent(templates: templates), + pressEndActions: merged.pressEndActions?.tryResolveParent(templates: templates), + pressStartActions: merged.pressStartActions?.tryResolveParent(templates: templates), reuseId: merged.reuseId, rowSpan: merged.rowSpan, selectedActions: merged.selectedActions?.tryResolveParent(templates: templates), diff --git a/DivKit/generated_sources/DivImage.swift b/DivKit/generated_sources/DivImage.swift index cb7e6fa2..063d5e7c 100644 --- a/DivKit/generated_sources/DivImage.swift +++ b/DivKit/generated_sources/DivImage.swift @@ -29,6 +29,8 @@ public final class DivImage: DivBase { public let functions: [DivFunction]? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let highPriorityPreviewShow: Expression // default value: false + public let hoverEndActions: [DivAction]? + public let hoverStartActions: [DivAction]? public let id: String? public let imageUrl: Expression public let layoutProvider: DivLayoutProvider? @@ -37,6 +39,8 @@ public final class DivImage: DivBase { public let paddings: DivEdgeInsets? public let placeholderColor: Expression // default value: #14000000 public let preloadRequired: Expression // default value: false + public let pressEndActions: [DivAction]? + public let pressStartActions: [DivAction]? public let preview: Expression? public let reuseId: Expression? public let rowSpan: Expression? // constraint: number >= 0 @@ -161,6 +165,8 @@ public final class DivImage: DivBase { functions: [DivFunction]? = nil, height: DivSize? = nil, highPriorityPreviewShow: Expression? = nil, + hoverEndActions: [DivAction]? = nil, + hoverStartActions: [DivAction]? = nil, id: String? = nil, imageUrl: Expression, layoutProvider: DivLayoutProvider? = nil, @@ -169,6 +175,8 @@ public final class DivImage: DivBase { paddings: DivEdgeInsets? = nil, placeholderColor: Expression? = nil, preloadRequired: Expression? = nil, + pressEndActions: [DivAction]? = nil, + pressStartActions: [DivAction]? = nil, preview: Expression? = nil, reuseId: Expression? = nil, rowSpan: Expression? = nil, @@ -212,6 +220,8 @@ public final class DivImage: DivBase { self.functions = functions self.height = height ?? .divWrapContentSize(DivWrapContentSize()) self.highPriorityPreviewShow = highPriorityPreviewShow ?? .value(false) + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.imageUrl = imageUrl self.layoutProvider = layoutProvider @@ -220,6 +230,8 @@ public final class DivImage: DivBase { self.paddings = paddings self.placeholderColor = placeholderColor ?? .value(Color.colorWithARGBHexCode(0x14000000)) self.preloadRequired = preloadRequired ?? .value(false) + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.preview = preview self.reuseId = reuseId self.rowSpan = rowSpan @@ -297,67 +309,75 @@ extension DivImage: Equatable { guard lhs.height == rhs.height, lhs.highPriorityPreviewShow == rhs.highPriorityPreviewShow, - lhs.id == rhs.id + lhs.hoverEndActions == rhs.hoverEndActions + else { + return false + } + guard + lhs.hoverStartActions == rhs.hoverStartActions, + lhs.id == rhs.id, + lhs.imageUrl == rhs.imageUrl else { return false } guard - lhs.imageUrl == rhs.imageUrl, lhs.layoutProvider == rhs.layoutProvider, - lhs.longtapActions == rhs.longtapActions + lhs.longtapActions == rhs.longtapActions, + lhs.margins == rhs.margins else { return false } guard - lhs.margins == rhs.margins, lhs.paddings == rhs.paddings, - lhs.placeholderColor == rhs.placeholderColor + lhs.placeholderColor == rhs.placeholderColor, + lhs.preloadRequired == rhs.preloadRequired else { return false } guard - lhs.preloadRequired == rhs.preloadRequired, - lhs.preview == rhs.preview, - lhs.reuseId == rhs.reuseId + lhs.pressEndActions == rhs.pressEndActions, + lhs.pressStartActions == rhs.pressStartActions, + lhs.preview == rhs.preview else { return false } guard + lhs.reuseId == rhs.reuseId, lhs.rowSpan == rhs.rowSpan, - lhs.scale == rhs.scale, - lhs.selectedActions == rhs.selectedActions + lhs.scale == rhs.scale else { return false } guard + lhs.selectedActions == rhs.selectedActions, lhs.tintColor == rhs.tintColor, - lhs.tintMode == rhs.tintMode, - lhs.tooltips == rhs.tooltips + lhs.tintMode == rhs.tintMode else { return false } guard + lhs.tooltips == rhs.tooltips, lhs.transform == rhs.transform, - lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn + lhs.transitionChange == rhs.transitionChange else { return false } guard + lhs.transitionIn == rhs.transitionIn, lhs.transitionOut == rhs.transitionOut, - lhs.transitionTriggers == rhs.transitionTriggers, - lhs.variableTriggers == rhs.variableTriggers + lhs.transitionTriggers == rhs.transitionTriggers else { return false } guard + lhs.variableTriggers == rhs.variableTriggers, lhs.variables == rhs.variables, - lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction + lhs.visibility == rhs.visibility else { return false } guard + lhs.visibilityAction == rhs.visibilityAction, lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { @@ -395,6 +415,8 @@ extension DivImage: Serializable { result["functions"] = functions?.map { $0.toDictionary() } result["height"] = height.toDictionary() result["high_priority_preview_show"] = highPriorityPreviewShow.toValidSerializationValue() + result["hover_end_actions"] = hoverEndActions?.map { $0.toDictionary() } + result["hover_start_actions"] = hoverStartActions?.map { $0.toDictionary() } result["id"] = id result["image_url"] = imageUrl.toValidSerializationValue() result["layout_provider"] = layoutProvider?.toDictionary() @@ -403,6 +425,8 @@ extension DivImage: Serializable { result["paddings"] = paddings?.toDictionary() result["placeholder_color"] = placeholderColor.toValidSerializationValue() result["preload_required"] = preloadRequired.toValidSerializationValue() + result["press_end_actions"] = pressEndActions?.map { $0.toDictionary() } + result["press_start_actions"] = pressStartActions?.map { $0.toDictionary() } result["preview"] = preview?.toValidSerializationValue() result["reuse_id"] = reuseId?.toValidSerializationValue() result["row_span"] = rowSpan?.toValidSerializationValue() diff --git a/DivKit/generated_sources/DivImageTemplate.swift b/DivKit/generated_sources/DivImageTemplate.swift index 2a96f79c..5fde4c38 100644 --- a/DivKit/generated_sources/DivImageTemplate.swift +++ b/DivKit/generated_sources/DivImageTemplate.swift @@ -30,6 +30,8 @@ public final class DivImageTemplate: TemplateValue { public let functions: Field<[DivFunctionTemplate]>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let highPriorityPreviewShow: Field>? // default value: false + public let hoverEndActions: Field<[DivActionTemplate]>? + public let hoverStartActions: Field<[DivActionTemplate]>? public let id: Field? public let imageUrl: Field>? public let layoutProvider: Field? @@ -38,6 +40,8 @@ public final class DivImageTemplate: TemplateValue { public let paddings: Field? public let placeholderColor: Field>? // default value: #14000000 public let preloadRequired: Field>? // default value: false + public let pressEndActions: Field<[DivActionTemplate]>? + public let pressStartActions: Field<[DivActionTemplate]>? public let preview: Field>? public let reuseId: Field>? public let rowSpan: Field>? // constraint: number >= 0 @@ -84,6 +88,8 @@ public final class DivImageTemplate: TemplateValue { functions: dictionary.getOptionalArray("functions", templateToType: templateToType), height: dictionary.getOptionalField("height", templateToType: templateToType), highPriorityPreviewShow: dictionary.getOptionalExpressionField("high_priority_preview_show"), + hoverEndActions: dictionary.getOptionalArray("hover_end_actions", templateToType: templateToType), + hoverStartActions: dictionary.getOptionalArray("hover_start_actions", templateToType: templateToType), id: dictionary.getOptionalField("id"), imageUrl: dictionary.getOptionalExpressionField("image_url", transform: URL.init(string:)), layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), @@ -92,6 +98,8 @@ public final class DivImageTemplate: TemplateValue { paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), placeholderColor: dictionary.getOptionalExpressionField("placeholder_color", transform: Color.color(withHexString:)), preloadRequired: dictionary.getOptionalExpressionField("preload_required"), + pressEndActions: dictionary.getOptionalArray("press_end_actions", templateToType: templateToType), + pressStartActions: dictionary.getOptionalArray("press_start_actions", templateToType: templateToType), preview: dictionary.getOptionalExpressionField("preview"), reuseId: dictionary.getOptionalExpressionField("reuse_id"), rowSpan: dictionary.getOptionalExpressionField("row_span"), @@ -139,6 +147,8 @@ public final class DivImageTemplate: TemplateValue { functions: Field<[DivFunctionTemplate]>? = nil, height: Field? = nil, highPriorityPreviewShow: Field>? = nil, + hoverEndActions: Field<[DivActionTemplate]>? = nil, + hoverStartActions: Field<[DivActionTemplate]>? = nil, id: Field? = nil, imageUrl: Field>? = nil, layoutProvider: Field? = nil, @@ -147,6 +157,8 @@ public final class DivImageTemplate: TemplateValue { paddings: Field? = nil, placeholderColor: Field>? = nil, preloadRequired: Field>? = nil, + pressEndActions: Field<[DivActionTemplate]>? = nil, + pressStartActions: Field<[DivActionTemplate]>? = nil, preview: Field>? = nil, reuseId: Field>? = nil, rowSpan: Field>? = nil, @@ -191,6 +203,8 @@ public final class DivImageTemplate: TemplateValue { self.functions = functions self.height = height self.highPriorityPreviewShow = highPriorityPreviewShow + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.imageUrl = imageUrl self.layoutProvider = layoutProvider @@ -199,6 +213,8 @@ public final class DivImageTemplate: TemplateValue { self.paddings = paddings self.placeholderColor = placeholderColor self.preloadRequired = preloadRequired + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.preview = preview self.reuseId = reuseId self.rowSpan = rowSpan @@ -244,6 +260,8 @@ public final class DivImageTemplate: TemplateValue { let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let highPriorityPreviewShowValue = { parent?.highPriorityPreviewShow?.resolveOptionalValue(context: context) ?? .noValue }() + let hoverEndActionsValue = { parent?.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverStartActionsValue = { parent?.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() let imageUrlValue = { parent?.imageUrl?.resolveValue(context: context, transform: URL.init(string:)) ?? .noValue }() let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -252,6 +270,8 @@ public final class DivImageTemplate: TemplateValue { let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let placeholderColorValue = { parent?.placeholderColor?.resolveOptionalValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() let preloadRequiredValue = { parent?.preloadRequired?.resolveOptionalValue(context: context) ?? .noValue }() + let pressEndActionsValue = { parent?.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressStartActionsValue = { parent?.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let previewValue = { parent?.preview?.resolveOptionalValue(context: context) ?? .noValue }() let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() @@ -295,6 +315,8 @@ public final class DivImageTemplate: TemplateValue { functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, highPriorityPreviewShowValue.errorsOrWarnings?.map { .nestedObjectError(field: "high_priority_preview_show", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, imageUrlValue.errorsOrWarnings?.map { .nestedObjectError(field: "image_url", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, @@ -303,6 +325,8 @@ public final class DivImageTemplate: TemplateValue { paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, placeholderColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "placeholder_color", error: $0) }, preloadRequiredValue.errorsOrWarnings?.map { .nestedObjectError(field: "preload_required", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, previewValue.errorsOrWarnings?.map { .nestedObjectError(field: "preview", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, @@ -355,6 +379,8 @@ public final class DivImageTemplate: TemplateValue { functions: { functionsValue.value }(), height: { heightValue.value }(), highPriorityPreviewShow: { highPriorityPreviewShowValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), imageUrl: { imageUrlNonNil }(), layoutProvider: { layoutProviderValue.value }(), @@ -363,6 +389,8 @@ public final class DivImageTemplate: TemplateValue { paddings: { paddingsValue.value }(), placeholderColor: { placeholderColorValue.value }(), preloadRequired: { preloadRequiredValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), preview: { previewValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), @@ -413,6 +441,8 @@ public final class DivImageTemplate: TemplateValue { var functionsValue: DeserializationResult<[DivFunction]> = .noValue var heightValue: DeserializationResult = .noValue var highPriorityPreviewShowValue: DeserializationResult> = { parent?.highPriorityPreviewShow?.value() ?? .noValue }() + var hoverEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var hoverStartActionsValue: DeserializationResult<[DivAction]> = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() var imageUrlValue: DeserializationResult> = { parent?.imageUrl?.value() ?? .noValue }() var layoutProviderValue: DeserializationResult = .noValue @@ -421,6 +451,8 @@ public final class DivImageTemplate: TemplateValue { var paddingsValue: DeserializationResult = .noValue var placeholderColorValue: DeserializationResult> = { parent?.placeholderColor?.value() ?? .noValue }() var preloadRequiredValue: DeserializationResult> = { parent?.preloadRequired?.value() ?? .noValue }() + var pressEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var pressStartActionsValue: DeserializationResult<[DivAction]> = .noValue var previewValue: DeserializationResult> = { parent?.preview?.value() ?? .noValue }() var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() @@ -560,6 +592,16 @@ public final class DivImageTemplate: TemplateValue { highPriorityPreviewShowValue = deserialize(__dictValue).merged(with: highPriorityPreviewShowValue) } }() + _ = { + if key == "hover_end_actions" { + hoverEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverEndActionsValue) + } + }() + _ = { + if key == "hover_start_actions" { + hoverStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverStartActionsValue) + } + }() _ = { if key == "id" { idValue = deserialize(__dictValue).merged(with: idValue) @@ -600,6 +642,16 @@ public final class DivImageTemplate: TemplateValue { preloadRequiredValue = deserialize(__dictValue).merged(with: preloadRequiredValue) } }() + _ = { + if key == "press_end_actions" { + pressEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressEndActionsValue) + } + }() + _ = { + if key == "press_start_actions" { + pressStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressStartActionsValue) + } + }() _ = { if key == "preview" { previewValue = deserialize(__dictValue).merged(with: previewValue) @@ -810,6 +862,16 @@ public final class DivImageTemplate: TemplateValue { highPriorityPreviewShowValue = highPriorityPreviewShowValue.merged(with: { deserialize(__dictValue) }) } }() + _ = { + if key == parent?.hoverEndActions?.link { + hoverEndActionsValue = hoverEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.hoverStartActions?.link { + hoverStartActionsValue = hoverStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.id?.link { idValue = idValue.merged(with: { deserialize(__dictValue) }) @@ -850,6 +912,16 @@ public final class DivImageTemplate: TemplateValue { preloadRequiredValue = preloadRequiredValue.merged(with: { deserialize(__dictValue) }) } }() + _ = { + if key == parent?.pressEndActions?.link { + pressEndActionsValue = pressEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.pressStartActions?.link { + pressStartActionsValue = pressStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.preview?.link { previewValue = previewValue.merged(with: { deserialize(__dictValue) }) @@ -964,10 +1036,14 @@ public final class DivImageTemplate: TemplateValue { _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverEndActionsValue = hoverEndActionsValue.merged(with: { parent.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverStartActionsValue = hoverStartActionsValue.merged(with: { parent.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { longtapActionsValue = longtapActionsValue.merged(with: { parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressEndActionsValue = pressEndActionsValue.merged(with: { parent.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressStartActionsValue = pressStartActionsValue.merged(with: { parent.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { tooltipsValue = tooltipsValue.merged(with: { parent.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { transformValue = transformValue.merged(with: { parent.transform?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -1004,6 +1080,8 @@ public final class DivImageTemplate: TemplateValue { functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, highPriorityPreviewShowValue.errorsOrWarnings?.map { .nestedObjectError(field: "high_priority_preview_show", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, imageUrlValue.errorsOrWarnings?.map { .nestedObjectError(field: "image_url", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, @@ -1012,6 +1090,8 @@ public final class DivImageTemplate: TemplateValue { paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, placeholderColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "placeholder_color", error: $0) }, preloadRequiredValue.errorsOrWarnings?.map { .nestedObjectError(field: "preload_required", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, previewValue.errorsOrWarnings?.map { .nestedObjectError(field: "preview", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, @@ -1064,6 +1144,8 @@ public final class DivImageTemplate: TemplateValue { functions: { functionsValue.value }(), height: { heightValue.value }(), highPriorityPreviewShow: { highPriorityPreviewShowValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), imageUrl: { imageUrlNonNil }(), layoutProvider: { layoutProviderValue.value }(), @@ -1072,6 +1154,8 @@ public final class DivImageTemplate: TemplateValue { paddings: { paddingsValue.value }(), placeholderColor: { placeholderColorValue.value }(), preloadRequired: { preloadRequiredValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), preview: { previewValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), @@ -1127,6 +1211,8 @@ public final class DivImageTemplate: TemplateValue { functions: functions ?? mergedParent.functions, height: height ?? mergedParent.height, highPriorityPreviewShow: highPriorityPreviewShow ?? mergedParent.highPriorityPreviewShow, + hoverEndActions: hoverEndActions ?? mergedParent.hoverEndActions, + hoverStartActions: hoverStartActions ?? mergedParent.hoverStartActions, id: id ?? mergedParent.id, imageUrl: imageUrl ?? mergedParent.imageUrl, layoutProvider: layoutProvider ?? mergedParent.layoutProvider, @@ -1135,6 +1221,8 @@ public final class DivImageTemplate: TemplateValue { paddings: paddings ?? mergedParent.paddings, placeholderColor: placeholderColor ?? mergedParent.placeholderColor, preloadRequired: preloadRequired ?? mergedParent.preloadRequired, + pressEndActions: pressEndActions ?? mergedParent.pressEndActions, + pressStartActions: pressStartActions ?? mergedParent.pressStartActions, preview: preview ?? mergedParent.preview, reuseId: reuseId ?? mergedParent.reuseId, rowSpan: rowSpan ?? mergedParent.rowSpan, @@ -1185,6 +1273,8 @@ public final class DivImageTemplate: TemplateValue { functions: merged.functions?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), highPriorityPreviewShow: merged.highPriorityPreviewShow, + hoverEndActions: merged.hoverEndActions?.tryResolveParent(templates: templates), + hoverStartActions: merged.hoverStartActions?.tryResolveParent(templates: templates), id: merged.id, imageUrl: merged.imageUrl, layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), @@ -1193,6 +1283,8 @@ public final class DivImageTemplate: TemplateValue { paddings: merged.paddings?.tryResolveParent(templates: templates), placeholderColor: merged.placeholderColor, preloadRequired: merged.preloadRequired, + pressEndActions: merged.pressEndActions?.tryResolveParent(templates: templates), + pressStartActions: merged.pressStartActions?.tryResolveParent(templates: templates), preview: merged.preview, reuseId: merged.reuseId, rowSpan: merged.rowSpan, diff --git a/DivKit/generated_sources/DivSeparator.swift b/DivKit/generated_sources/DivSeparator.swift index c1f861bd..a404fab5 100644 --- a/DivKit/generated_sources/DivSeparator.swift +++ b/DivKit/generated_sources/DivSeparator.swift @@ -51,11 +51,15 @@ public final class DivSeparator: DivBase { public let focus: DivFocus? public let functions: [DivFunction]? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: [DivAction]? + public let hoverStartActions: [DivAction]? public let id: String? public let layoutProvider: DivLayoutProvider? public let longtapActions: [DivAction]? public let margins: DivEdgeInsets? public let paddings: DivEdgeInsets? + public let pressEndActions: [DivAction]? + public let pressStartActions: [DivAction]? public let reuseId: Expression? public let rowSpan: Expression? // constraint: number >= 0 public let selectedActions: [DivAction]? @@ -131,11 +135,15 @@ public final class DivSeparator: DivBase { focus: DivFocus? = nil, functions: [DivFunction]? = nil, height: DivSize? = nil, + hoverEndActions: [DivAction]? = nil, + hoverStartActions: [DivAction]? = nil, id: String? = nil, layoutProvider: DivLayoutProvider? = nil, longtapActions: [DivAction]? = nil, margins: DivEdgeInsets? = nil, paddings: DivEdgeInsets? = nil, + pressEndActions: [DivAction]? = nil, + pressStartActions: [DivAction]? = nil, reuseId: Expression? = nil, rowSpan: Expression? = nil, selectedActions: [DivAction]? = nil, @@ -170,11 +178,15 @@ public final class DivSeparator: DivBase { self.focus = focus self.functions = functions self.height = height ?? .divWrapContentSize(DivWrapContentSize()) + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.layoutProvider = layoutProvider self.longtapActions = longtapActions self.margins = margins self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.reuseId = reuseId self.rowSpan = rowSpan self.selectedActions = selectedActions @@ -239,48 +251,56 @@ extension DivSeparator: Equatable { return false } guard - lhs.id == rhs.id, + lhs.hoverEndActions == rhs.hoverEndActions, + lhs.hoverStartActions == rhs.hoverStartActions, + lhs.id == rhs.id + else { + return false + } + guard lhs.layoutProvider == rhs.layoutProvider, - lhs.longtapActions == rhs.longtapActions + lhs.longtapActions == rhs.longtapActions, + lhs.margins == rhs.margins else { return false } guard - lhs.margins == rhs.margins, lhs.paddings == rhs.paddings, - lhs.reuseId == rhs.reuseId + lhs.pressEndActions == rhs.pressEndActions, + lhs.pressStartActions == rhs.pressStartActions else { return false } guard + lhs.reuseId == rhs.reuseId, lhs.rowSpan == rhs.rowSpan, - lhs.selectedActions == rhs.selectedActions, - lhs.tooltips == rhs.tooltips + lhs.selectedActions == rhs.selectedActions else { return false } guard + lhs.tooltips == rhs.tooltips, lhs.transform == rhs.transform, - lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn + lhs.transitionChange == rhs.transitionChange else { return false } guard + lhs.transitionIn == rhs.transitionIn, lhs.transitionOut == rhs.transitionOut, - lhs.transitionTriggers == rhs.transitionTriggers, - lhs.variableTriggers == rhs.variableTriggers + lhs.transitionTriggers == rhs.transitionTriggers else { return false } guard + lhs.variableTriggers == rhs.variableTriggers, lhs.variables == rhs.variables, - lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction + lhs.visibility == rhs.visibility else { return false } guard + lhs.visibilityAction == rhs.visibilityAction, lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { @@ -313,11 +333,15 @@ extension DivSeparator: Serializable { result["focus"] = focus?.toDictionary() result["functions"] = functions?.map { $0.toDictionary() } result["height"] = height.toDictionary() + result["hover_end_actions"] = hoverEndActions?.map { $0.toDictionary() } + result["hover_start_actions"] = hoverStartActions?.map { $0.toDictionary() } result["id"] = id result["layout_provider"] = layoutProvider?.toDictionary() result["longtap_actions"] = longtapActions?.map { $0.toDictionary() } result["margins"] = margins?.toDictionary() result["paddings"] = paddings?.toDictionary() + result["press_end_actions"] = pressEndActions?.map { $0.toDictionary() } + result["press_start_actions"] = pressStartActions?.map { $0.toDictionary() } result["reuse_id"] = reuseId?.toValidSerializationValue() result["row_span"] = rowSpan?.toValidSerializationValue() result["selected_actions"] = selectedActions?.map { $0.toDictionary() } diff --git a/DivKit/generated_sources/DivSeparatorTemplate.swift b/DivKit/generated_sources/DivSeparatorTemplate.swift index 08246627..3ba4b761 100644 --- a/DivKit/generated_sources/DivSeparatorTemplate.swift +++ b/DivKit/generated_sources/DivSeparatorTemplate.swift @@ -113,11 +113,15 @@ public final class DivSeparatorTemplate: TemplateValue { public let focus: Field? public let functions: Field<[DivFunctionTemplate]>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: Field<[DivActionTemplate]>? + public let hoverStartActions: Field<[DivActionTemplate]>? public let id: Field? public let layoutProvider: Field? public let longtapActions: Field<[DivActionTemplate]>? public let margins: Field? public let paddings: Field? + public let pressEndActions: Field<[DivActionTemplate]>? + public let pressStartActions: Field<[DivActionTemplate]>? public let reuseId: Field>? public let rowSpan: Field>? // constraint: number >= 0 public let selectedActions: Field<[DivActionTemplate]>? @@ -155,11 +159,15 @@ public final class DivSeparatorTemplate: TemplateValue { focus: dictionary.getOptionalField("focus", templateToType: templateToType), functions: dictionary.getOptionalArray("functions", templateToType: templateToType), height: dictionary.getOptionalField("height", templateToType: templateToType), + hoverEndActions: dictionary.getOptionalArray("hover_end_actions", templateToType: templateToType), + hoverStartActions: dictionary.getOptionalArray("hover_start_actions", templateToType: templateToType), id: dictionary.getOptionalField("id"), layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), longtapActions: dictionary.getOptionalArray("longtap_actions", templateToType: templateToType), margins: dictionary.getOptionalField("margins", templateToType: templateToType), paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), + pressEndActions: dictionary.getOptionalArray("press_end_actions", templateToType: templateToType), + pressStartActions: dictionary.getOptionalArray("press_start_actions", templateToType: templateToType), reuseId: dictionary.getOptionalExpressionField("reuse_id"), rowSpan: dictionary.getOptionalExpressionField("row_span"), selectedActions: dictionary.getOptionalArray("selected_actions", templateToType: templateToType), @@ -198,11 +206,15 @@ public final class DivSeparatorTemplate: TemplateValue { focus: Field? = nil, functions: Field<[DivFunctionTemplate]>? = nil, height: Field? = nil, + hoverEndActions: Field<[DivActionTemplate]>? = nil, + hoverStartActions: Field<[DivActionTemplate]>? = nil, id: Field? = nil, layoutProvider: Field? = nil, longtapActions: Field<[DivActionTemplate]>? = nil, margins: Field? = nil, paddings: Field? = nil, + pressEndActions: Field<[DivActionTemplate]>? = nil, + pressStartActions: Field<[DivActionTemplate]>? = nil, reuseId: Field>? = nil, rowSpan: Field>? = nil, selectedActions: Field<[DivActionTemplate]>? = nil, @@ -238,11 +250,15 @@ public final class DivSeparatorTemplate: TemplateValue { self.focus = focus self.functions = functions self.height = height + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.layoutProvider = layoutProvider self.longtapActions = longtapActions self.margins = margins self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.reuseId = reuseId self.rowSpan = rowSpan self.selectedActions = selectedActions @@ -279,11 +295,15 @@ public final class DivSeparatorTemplate: TemplateValue { let focusValue = { parent?.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverEndActionsValue = { parent?.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverStartActionsValue = { parent?.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let longtapActionsValue = { parent?.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let marginsValue = { parent?.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressEndActionsValue = { parent?.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressStartActionsValue = { parent?.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() let selectedActionsValue = { parent?.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -318,11 +338,15 @@ public final class DivSeparatorTemplate: TemplateValue { focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, longtapActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "longtap_actions", error: $0) }, marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, @@ -358,11 +382,15 @@ public final class DivSeparatorTemplate: TemplateValue { focus: { focusValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), layoutProvider: { layoutProviderValue.value }(), longtapActions: { longtapActionsValue.value }(), margins: { marginsValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), selectedActions: { selectedActionsValue.value }(), @@ -404,11 +432,15 @@ public final class DivSeparatorTemplate: TemplateValue { var focusValue: DeserializationResult = .noValue var functionsValue: DeserializationResult<[DivFunction]> = .noValue var heightValue: DeserializationResult = .noValue + var hoverEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var hoverStartActionsValue: DeserializationResult<[DivAction]> = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() var layoutProviderValue: DeserializationResult = .noValue var longtapActionsValue: DeserializationResult<[DivAction]> = .noValue var marginsValue: DeserializationResult = .noValue var paddingsValue: DeserializationResult = .noValue + var pressEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var pressStartActionsValue: DeserializationResult<[DivAction]> = .noValue var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() var selectedActionsValue: DeserializationResult<[DivAction]> = .noValue @@ -519,6 +551,16 @@ public final class DivSeparatorTemplate: TemplateValue { heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: heightValue) } }() + _ = { + if key == "hover_end_actions" { + hoverEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverEndActionsValue) + } + }() + _ = { + if key == "hover_start_actions" { + hoverStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverStartActionsValue) + } + }() _ = { if key == "id" { idValue = deserialize(__dictValue).merged(with: idValue) @@ -544,6 +586,16 @@ public final class DivSeparatorTemplate: TemplateValue { paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) } }() + _ = { + if key == "press_end_actions" { + pressEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressEndActionsValue) + } + }() + _ = { + if key == "press_start_actions" { + pressStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressStartActionsValue) + } + }() _ = { if key == "reuse_id" { reuseIdValue = deserialize(__dictValue).merged(with: reuseIdValue) @@ -709,6 +761,16 @@ public final class DivSeparatorTemplate: TemplateValue { heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) } }() + _ = { + if key == parent?.hoverEndActions?.link { + hoverEndActionsValue = hoverEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.hoverStartActions?.link { + hoverStartActionsValue = hoverStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.id?.link { idValue = idValue.merged(with: { deserialize(__dictValue) }) @@ -734,6 +796,16 @@ public final class DivSeparatorTemplate: TemplateValue { paddingsValue = paddingsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self) }) } }() + _ = { + if key == parent?.pressEndActions?.link { + pressEndActionsValue = pressEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.pressStartActions?.link { + pressStartActionsValue = pressStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.reuseId?.link { reuseIdValue = reuseIdValue.merged(with: { deserialize(__dictValue) }) @@ -826,10 +898,14 @@ public final class DivSeparatorTemplate: TemplateValue { _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverEndActionsValue = hoverEndActionsValue.merged(with: { parent.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverStartActionsValue = hoverStartActionsValue.merged(with: { parent.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { longtapActionsValue = longtapActionsValue.merged(with: { parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressEndActionsValue = pressEndActionsValue.merged(with: { parent.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressStartActionsValue = pressStartActionsValue.merged(with: { parent.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { tooltipsValue = tooltipsValue.merged(with: { parent.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { transformValue = transformValue.merged(with: { parent.transform?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -861,11 +937,15 @@ public final class DivSeparatorTemplate: TemplateValue { focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, longtapActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "longtap_actions", error: $0) }, marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, @@ -901,11 +981,15 @@ public final class DivSeparatorTemplate: TemplateValue { focus: { focusValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), layoutProvider: { layoutProviderValue.value }(), longtapActions: { longtapActionsValue.value }(), margins: { marginsValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), selectedActions: { selectedActionsValue.value }(), @@ -952,11 +1036,15 @@ public final class DivSeparatorTemplate: TemplateValue { focus: focus ?? mergedParent.focus, functions: functions ?? mergedParent.functions, height: height ?? mergedParent.height, + hoverEndActions: hoverEndActions ?? mergedParent.hoverEndActions, + hoverStartActions: hoverStartActions ?? mergedParent.hoverStartActions, id: id ?? mergedParent.id, layoutProvider: layoutProvider ?? mergedParent.layoutProvider, longtapActions: longtapActions ?? mergedParent.longtapActions, margins: margins ?? mergedParent.margins, paddings: paddings ?? mergedParent.paddings, + pressEndActions: pressEndActions ?? mergedParent.pressEndActions, + pressStartActions: pressStartActions ?? mergedParent.pressStartActions, reuseId: reuseId ?? mergedParent.reuseId, rowSpan: rowSpan ?? mergedParent.rowSpan, selectedActions: selectedActions ?? mergedParent.selectedActions, @@ -998,11 +1086,15 @@ public final class DivSeparatorTemplate: TemplateValue { focus: merged.focus?.tryResolveParent(templates: templates), functions: merged.functions?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), + hoverEndActions: merged.hoverEndActions?.tryResolveParent(templates: templates), + hoverStartActions: merged.hoverStartActions?.tryResolveParent(templates: templates), id: merged.id, layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), longtapActions: merged.longtapActions?.tryResolveParent(templates: templates), margins: merged.margins?.tryResolveParent(templates: templates), paddings: merged.paddings?.tryResolveParent(templates: templates), + pressEndActions: merged.pressEndActions?.tryResolveParent(templates: templates), + pressStartActions: merged.pressStartActions?.tryResolveParent(templates: templates), reuseId: merged.reuseId, rowSpan: merged.rowSpan, selectedActions: merged.selectedActions?.tryResolveParent(templates: templates), diff --git a/DivKit/generated_sources/DivSlider.swift b/DivKit/generated_sources/DivSlider.swift index c294018d..f85202e7 100644 --- a/DivKit/generated_sources/DivSlider.swift +++ b/DivKit/generated_sources/DivSlider.swift @@ -101,6 +101,7 @@ public final class DivSlider: DivBase { public let functions: [DivFunction]? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let id: String? + public let isEnabled: Expression // default value: true public let layoutProvider: DivLayoutProvider? public let margins: DivEdgeInsets? public let maxValue: Expression // default value: 100 @@ -150,6 +151,10 @@ public final class DivSlider: DivBase { resolver.resolveNumeric(columnSpan) } + public func resolveIsEnabled(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(isEnabled) ?? true + } + public func resolveMaxValue(_ resolver: ExpressionResolver) -> Int { resolver.resolveNumeric(maxValue) ?? 100 } @@ -197,6 +202,7 @@ public final class DivSlider: DivBase { functions: [DivFunction]? = nil, height: DivSize? = nil, id: String? = nil, + isEnabled: Expression? = nil, layoutProvider: DivLayoutProvider? = nil, margins: DivEdgeInsets? = nil, maxValue: Expression? = nil, @@ -244,6 +250,7 @@ public final class DivSlider: DivBase { self.functions = functions self.height = height ?? .divWrapContentSize(DivWrapContentSize()) self.id = id + self.isEnabled = isEnabled ?? .value(true) self.layoutProvider = layoutProvider self.margins = margins self.maxValue = maxValue ?? .value(100) @@ -313,81 +320,82 @@ extension DivSlider: Equatable { guard lhs.height == rhs.height, lhs.id == rhs.id, - lhs.layoutProvider == rhs.layoutProvider + lhs.isEnabled == rhs.isEnabled else { return false } guard + lhs.layoutProvider == rhs.layoutProvider, lhs.margins == rhs.margins, - lhs.maxValue == rhs.maxValue, - lhs.minValue == rhs.minValue + lhs.maxValue == rhs.maxValue else { return false } guard + lhs.minValue == rhs.minValue, lhs.paddings == rhs.paddings, - lhs.ranges == rhs.ranges, - lhs.reuseId == rhs.reuseId + lhs.ranges == rhs.ranges else { return false } guard + lhs.reuseId == rhs.reuseId, lhs.rowSpan == rhs.rowSpan, - lhs.secondaryValueAccessibility == rhs.secondaryValueAccessibility, - lhs.selectedActions == rhs.selectedActions + lhs.secondaryValueAccessibility == rhs.secondaryValueAccessibility else { return false } guard + lhs.selectedActions == rhs.selectedActions, lhs.thumbSecondaryStyle == rhs.thumbSecondaryStyle, - lhs.thumbSecondaryTextStyle == rhs.thumbSecondaryTextStyle, - lhs.thumbSecondaryValueVariable == rhs.thumbSecondaryValueVariable + lhs.thumbSecondaryTextStyle == rhs.thumbSecondaryTextStyle else { return false } guard + lhs.thumbSecondaryValueVariable == rhs.thumbSecondaryValueVariable, lhs.thumbStyle == rhs.thumbStyle, - lhs.thumbTextStyle == rhs.thumbTextStyle, - lhs.thumbValueVariable == rhs.thumbValueVariable + lhs.thumbTextStyle == rhs.thumbTextStyle else { return false } guard + lhs.thumbValueVariable == rhs.thumbValueVariable, lhs.tickMarkActiveStyle == rhs.tickMarkActiveStyle, - lhs.tickMarkInactiveStyle == rhs.tickMarkInactiveStyle, - lhs.tooltips == rhs.tooltips + lhs.tickMarkInactiveStyle == rhs.tickMarkInactiveStyle else { return false } guard + lhs.tooltips == rhs.tooltips, lhs.trackActiveStyle == rhs.trackActiveStyle, - lhs.trackInactiveStyle == rhs.trackInactiveStyle, - lhs.transform == rhs.transform + lhs.trackInactiveStyle == rhs.trackInactiveStyle else { return false } guard + lhs.transform == rhs.transform, lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn, - lhs.transitionOut == rhs.transitionOut + lhs.transitionIn == rhs.transitionIn else { return false } guard + lhs.transitionOut == rhs.transitionOut, lhs.transitionTriggers == rhs.transitionTriggers, - lhs.variableTriggers == rhs.variableTriggers, - lhs.variables == rhs.variables + lhs.variableTriggers == rhs.variableTriggers else { return false } guard + lhs.variables == rhs.variables, lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction, - lhs.visibilityActions == rhs.visibilityActions + lhs.visibilityAction == rhs.visibilityAction else { return false } guard + lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { return false @@ -415,6 +423,7 @@ extension DivSlider: Serializable { result["functions"] = functions?.map { $0.toDictionary() } result["height"] = height.toDictionary() result["id"] = id + result["is_enabled"] = isEnabled.toValidSerializationValue() result["layout_provider"] = layoutProvider?.toDictionary() result["margins"] = margins?.toDictionary() result["max_value"] = maxValue.toValidSerializationValue() diff --git a/DivKit/generated_sources/DivSliderTemplate.swift b/DivKit/generated_sources/DivSliderTemplate.swift index ce81f5dc..ffd24926 100644 --- a/DivKit/generated_sources/DivSliderTemplate.swift +++ b/DivKit/generated_sources/DivSliderTemplate.swift @@ -374,6 +374,7 @@ public final class DivSliderTemplate: TemplateValue { public let functions: Field<[DivFunctionTemplate]>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let id: Field? + public let isEnabled: Field>? // default value: true public let layoutProvider: Field? public let margins: Field? public let maxValue: Field>? // default value: 100 @@ -424,6 +425,7 @@ public final class DivSliderTemplate: TemplateValue { functions: dictionary.getOptionalArray("functions", templateToType: templateToType), height: dictionary.getOptionalField("height", templateToType: templateToType), id: dictionary.getOptionalField("id"), + isEnabled: dictionary.getOptionalExpressionField("is_enabled"), layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), margins: dictionary.getOptionalField("margins", templateToType: templateToType), maxValue: dictionary.getOptionalExpressionField("max_value"), @@ -475,6 +477,7 @@ public final class DivSliderTemplate: TemplateValue { functions: Field<[DivFunctionTemplate]>? = nil, height: Field? = nil, id: Field? = nil, + isEnabled: Field>? = nil, layoutProvider: Field? = nil, margins: Field? = nil, maxValue: Field>? = nil, @@ -523,6 +526,7 @@ public final class DivSliderTemplate: TemplateValue { self.functions = functions self.height = height self.id = id + self.isEnabled = isEnabled self.layoutProvider = layoutProvider self.margins = margins self.maxValue = maxValue @@ -572,6 +576,7 @@ public final class DivSliderTemplate: TemplateValue { let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() + let isEnabledValue = { parent?.isEnabled?.resolveOptionalValue(context: context) ?? .noValue }() let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let marginsValue = { parent?.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let maxValueValue = { parent?.maxValue?.resolveOptionalValue(context: context) ?? .noValue }() @@ -619,6 +624,7 @@ public final class DivSliderTemplate: TemplateValue { functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, maxValueValue.errorsOrWarnings?.map { .nestedObjectError(field: "max_value", error: $0) }, @@ -683,6 +689,7 @@ public final class DivSliderTemplate: TemplateValue { functions: { functionsValue.value }(), height: { heightValue.value }(), id: { idValue.value }(), + isEnabled: { isEnabledValue.value }(), layoutProvider: { layoutProviderValue.value }(), margins: { marginsValue.value }(), maxValue: { maxValueValue.value }(), @@ -737,6 +744,7 @@ public final class DivSliderTemplate: TemplateValue { var functionsValue: DeserializationResult<[DivFunction]> = .noValue var heightValue: DeserializationResult = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() + var isEnabledValue: DeserializationResult> = { parent?.isEnabled?.value() ?? .noValue }() var layoutProviderValue: DeserializationResult = .noValue var marginsValue: DeserializationResult = .noValue var maxValueValue: DeserializationResult> = { parent?.maxValue?.value() ?? .noValue }() @@ -844,6 +852,11 @@ public final class DivSliderTemplate: TemplateValue { idValue = deserialize(__dictValue).merged(with: idValue) } }() + _ = { + if key == "is_enabled" { + isEnabledValue = deserialize(__dictValue).merged(with: isEnabledValue) + } + }() _ = { if key == "layout_provider" { layoutProviderValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivLayoutProviderTemplate.self).merged(with: layoutProviderValue) @@ -1074,6 +1087,11 @@ public final class DivSliderTemplate: TemplateValue { idValue = idValue.merged(with: { deserialize(__dictValue) }) } }() + _ = { + if key == parent?.isEnabled?.link { + isEnabledValue = isEnabledValue.merged(with: { deserialize(__dictValue) }) + } + }() _ = { if key == parent?.layoutProvider?.link { layoutProviderValue = layoutProviderValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivLayoutProviderTemplate.self) }) @@ -1286,6 +1304,7 @@ public final class DivSliderTemplate: TemplateValue { functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, maxValueValue.errorsOrWarnings?.map { .nestedObjectError(field: "max_value", error: $0) }, @@ -1350,6 +1369,7 @@ public final class DivSliderTemplate: TemplateValue { functions: { functionsValue.value }(), height: { heightValue.value }(), id: { idValue.value }(), + isEnabled: { isEnabledValue.value }(), layoutProvider: { layoutProviderValue.value }(), margins: { marginsValue.value }(), maxValue: { maxValueValue.value }(), @@ -1409,6 +1429,7 @@ public final class DivSliderTemplate: TemplateValue { functions: functions ?? mergedParent.functions, height: height ?? mergedParent.height, id: id ?? mergedParent.id, + isEnabled: isEnabled ?? mergedParent.isEnabled, layoutProvider: layoutProvider ?? mergedParent.layoutProvider, margins: margins ?? mergedParent.margins, maxValue: maxValue ?? mergedParent.maxValue, @@ -1463,6 +1484,7 @@ public final class DivSliderTemplate: TemplateValue { functions: merged.functions?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), id: merged.id, + isEnabled: merged.isEnabled, layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), margins: merged.margins?.tryResolveParent(templates: templates), maxValue: merged.maxValue, diff --git a/DivKit/generated_sources/DivState.swift b/DivKit/generated_sources/DivState.swift index c731628c..f5c114e0 100644 --- a/DivKit/generated_sources/DivState.swift +++ b/DivKit/generated_sources/DivState.swift @@ -35,6 +35,7 @@ public final class DivState: DivBase { public let animators: [DivAnimator]? public let background: [DivBackground]? public let border: DivBorder? + public let clipToBounds: Expression // default value: true public let columnSpan: Expression? // constraint: number >= 0 public let defaultStateId: Expression? public let disappearActions: [DivDisappearAction]? @@ -78,6 +79,10 @@ public final class DivState: DivBase { resolver.resolveNumeric(alpha) ?? 1.0 } + public func resolveClipToBounds(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(clipToBounds) ?? true + } + public func resolveColumnSpan(_ resolver: ExpressionResolver) -> Int? { resolver.resolveNumeric(columnSpan) } @@ -125,6 +130,7 @@ public final class DivState: DivBase { animators: [DivAnimator]?, background: [DivBackground]?, border: DivBorder?, + clipToBounds: Expression?, columnSpan: Expression?, defaultStateId: Expression?, disappearActions: [DivDisappearAction]?, @@ -163,6 +169,7 @@ public final class DivState: DivBase { self.animators = animators self.background = background self.border = border + self.clipToBounds = clipToBounds ?? .value(true) self.columnSpan = columnSpan self.defaultStateId = defaultStateId self.disappearActions = disappearActions @@ -215,75 +222,76 @@ extension DivState: Equatable { } guard lhs.border == rhs.border, - lhs.columnSpan == rhs.columnSpan, - lhs.defaultStateId == rhs.defaultStateId + lhs.clipToBounds == rhs.clipToBounds, + lhs.columnSpan == rhs.columnSpan else { return false } guard + lhs.defaultStateId == rhs.defaultStateId, lhs.disappearActions == rhs.disappearActions, - lhs.divId == rhs.divId, - lhs.extensions == rhs.extensions + lhs.divId == rhs.divId else { return false } guard + lhs.extensions == rhs.extensions, lhs.focus == rhs.focus, - lhs.functions == rhs.functions, - lhs.height == rhs.height + lhs.functions == rhs.functions else { return false } guard + lhs.height == rhs.height, lhs.id == rhs.id, - lhs.layoutProvider == rhs.layoutProvider, - lhs.margins == rhs.margins + lhs.layoutProvider == rhs.layoutProvider else { return false } guard + lhs.margins == rhs.margins, lhs.paddings == rhs.paddings, - lhs.reuseId == rhs.reuseId, - lhs.rowSpan == rhs.rowSpan + lhs.reuseId == rhs.reuseId else { return false } guard + lhs.rowSpan == rhs.rowSpan, lhs.selectedActions == rhs.selectedActions, - lhs.stateIdVariable == rhs.stateIdVariable, - lhs.states == rhs.states + lhs.stateIdVariable == rhs.stateIdVariable else { return false } guard + lhs.states == rhs.states, lhs.tooltips == rhs.tooltips, - lhs.transform == rhs.transform, - lhs.transitionAnimationSelector == rhs.transitionAnimationSelector + lhs.transform == rhs.transform else { return false } guard + lhs.transitionAnimationSelector == rhs.transitionAnimationSelector, lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn, - lhs.transitionOut == rhs.transitionOut + lhs.transitionIn == rhs.transitionIn else { return false } guard + lhs.transitionOut == rhs.transitionOut, lhs.transitionTriggers == rhs.transitionTriggers, - lhs.variableTriggers == rhs.variableTriggers, - lhs.variables == rhs.variables + lhs.variableTriggers == rhs.variableTriggers else { return false } guard + lhs.variables == rhs.variables, lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction, - lhs.visibilityActions == rhs.visibilityActions + lhs.visibilityAction == rhs.visibilityAction else { return false } guard + lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { return false @@ -304,6 +312,7 @@ extension DivState: Serializable { result["animators"] = animators?.map { $0.toDictionary() } result["background"] = background?.map { $0.toDictionary() } result["border"] = border?.toDictionary() + result["clip_to_bounds"] = clipToBounds.toValidSerializationValue() result["column_span"] = columnSpan?.toValidSerializationValue() result["default_state_id"] = defaultStateId?.toValidSerializationValue() result["disappear_actions"] = disappearActions?.map { $0.toDictionary() } diff --git a/DivKit/generated_sources/DivStateTemplate.swift b/DivKit/generated_sources/DivStateTemplate.swift index 6c120ea0..58a76c25 100644 --- a/DivKit/generated_sources/DivStateTemplate.swift +++ b/DivKit/generated_sources/DivStateTemplate.swift @@ -190,6 +190,7 @@ public final class DivStateTemplate: TemplateValue { public let animators: Field<[DivAnimatorTemplate]>? public let background: Field<[DivBackgroundTemplate]>? public let border: Field? + public let clipToBounds: Field>? // default value: true public let columnSpan: Field>? // constraint: number >= 0 public let defaultStateId: Field>? public let disappearActions: Field<[DivDisappearActionTemplate]>? @@ -231,6 +232,7 @@ public final class DivStateTemplate: TemplateValue { animators: dictionary.getOptionalArray("animators", templateToType: templateToType), background: dictionary.getOptionalArray("background", templateToType: templateToType), border: dictionary.getOptionalField("border", templateToType: templateToType), + clipToBounds: dictionary.getOptionalExpressionField("clip_to_bounds"), columnSpan: dictionary.getOptionalExpressionField("column_span"), defaultStateId: dictionary.getOptionalExpressionField("default_state_id"), disappearActions: dictionary.getOptionalArray("disappear_actions", templateToType: templateToType), @@ -273,6 +275,7 @@ public final class DivStateTemplate: TemplateValue { animators: Field<[DivAnimatorTemplate]>? = nil, background: Field<[DivBackgroundTemplate]>? = nil, border: Field? = nil, + clipToBounds: Field>? = nil, columnSpan: Field>? = nil, defaultStateId: Field>? = nil, disappearActions: Field<[DivDisappearActionTemplate]>? = nil, @@ -312,6 +315,7 @@ public final class DivStateTemplate: TemplateValue { self.animators = animators self.background = background self.border = border + self.clipToBounds = clipToBounds self.columnSpan = columnSpan self.defaultStateId = defaultStateId self.disappearActions = disappearActions @@ -352,6 +356,7 @@ public final class DivStateTemplate: TemplateValue { let animatorsValue = { parent?.animators?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let backgroundValue = { parent?.background?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let borderValue = { parent?.border?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let clipToBoundsValue = { parent?.clipToBounds?.resolveOptionalValue(context: context) ?? .noValue }() let columnSpanValue = { parent?.columnSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.columnSpanValidator) ?? .noValue }() let defaultStateIdValue = { parent?.defaultStateId?.resolveOptionalValue(context: context) ?? .noValue }() let disappearActionsValue = { parent?.disappearActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -390,6 +395,7 @@ public final class DivStateTemplate: TemplateValue { animatorsValue.errorsOrWarnings?.map { .nestedObjectError(field: "animators", error: $0) }, backgroundValue.errorsOrWarnings?.map { .nestedObjectError(field: "background", error: $0) }, borderValue.errorsOrWarnings?.map { .nestedObjectError(field: "border", error: $0) }, + clipToBoundsValue.errorsOrWarnings?.map { .nestedObjectError(field: "clip_to_bounds", error: $0) }, columnSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "column_span", error: $0) }, defaultStateIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "default_state_id", error: $0) }, disappearActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "disappear_actions", error: $0) }, @@ -437,6 +443,7 @@ public final class DivStateTemplate: TemplateValue { animators: { animatorsValue.value }(), background: { backgroundValue.value }(), border: { borderValue.value }(), + clipToBounds: { clipToBoundsValue.value }(), columnSpan: { columnSpanValue.value }(), defaultStateId: { defaultStateIdValue.value }(), disappearActions: { disappearActionsValue.value }(), @@ -482,6 +489,7 @@ public final class DivStateTemplate: TemplateValue { var animatorsValue: DeserializationResult<[DivAnimator]> = .noValue var backgroundValue: DeserializationResult<[DivBackground]> = .noValue var borderValue: DeserializationResult = .noValue + var clipToBoundsValue: DeserializationResult> = { parent?.clipToBounds?.value() ?? .noValue }() var columnSpanValue: DeserializationResult> = { parent?.columnSpan?.value() ?? .noValue }() var defaultStateIdValue: DeserializationResult> = { parent?.defaultStateId?.value() ?? .noValue }() var disappearActionsValue: DeserializationResult<[DivDisappearAction]> = .noValue @@ -552,6 +560,11 @@ public final class DivStateTemplate: TemplateValue { borderValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBorderTemplate.self).merged(with: borderValue) } }() + _ = { + if key == "clip_to_bounds" { + clipToBoundsValue = deserialize(__dictValue).merged(with: clipToBoundsValue) + } + }() _ = { if key == "column_span" { columnSpanValue = deserialize(__dictValue, validator: ResolvedValue.columnSpanValidator).merged(with: columnSpanValue) @@ -737,6 +750,11 @@ public final class DivStateTemplate: TemplateValue { borderValue = borderValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBorderTemplate.self) }) } }() + _ = { + if key == parent?.clipToBounds?.link { + clipToBoundsValue = clipToBoundsValue.merged(with: { deserialize(__dictValue) }) + } + }() _ = { if key == parent?.columnSpan?.link { columnSpanValue = columnSpanValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.columnSpanValidator) }) @@ -923,6 +941,7 @@ public final class DivStateTemplate: TemplateValue { animatorsValue.errorsOrWarnings?.map { .nestedObjectError(field: "animators", error: $0) }, backgroundValue.errorsOrWarnings?.map { .nestedObjectError(field: "background", error: $0) }, borderValue.errorsOrWarnings?.map { .nestedObjectError(field: "border", error: $0) }, + clipToBoundsValue.errorsOrWarnings?.map { .nestedObjectError(field: "clip_to_bounds", error: $0) }, columnSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "column_span", error: $0) }, defaultStateIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "default_state_id", error: $0) }, disappearActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "disappear_actions", error: $0) }, @@ -970,6 +989,7 @@ public final class DivStateTemplate: TemplateValue { animators: { animatorsValue.value }(), background: { backgroundValue.value }(), border: { borderValue.value }(), + clipToBounds: { clipToBoundsValue.value }(), columnSpan: { columnSpanValue.value }(), defaultStateId: { defaultStateIdValue.value }(), disappearActions: { disappearActionsValue.value }(), @@ -1020,6 +1040,7 @@ public final class DivStateTemplate: TemplateValue { animators: animators ?? mergedParent.animators, background: background ?? mergedParent.background, border: border ?? mergedParent.border, + clipToBounds: clipToBounds ?? mergedParent.clipToBounds, columnSpan: columnSpan ?? mergedParent.columnSpan, defaultStateId: defaultStateId ?? mergedParent.defaultStateId, disappearActions: disappearActions ?? mergedParent.disappearActions, @@ -1065,6 +1086,7 @@ public final class DivStateTemplate: TemplateValue { animators: merged.animators?.tryResolveParent(templates: templates), background: merged.background?.tryResolveParent(templates: templates), border: merged.border?.tryResolveParent(templates: templates), + clipToBounds: merged.clipToBounds, columnSpan: merged.columnSpan, defaultStateId: merged.defaultStateId, disappearActions: merged.disappearActions?.tryResolveParent(templates: templates), diff --git a/DivKit/generated_sources/DivText.swift b/DivKit/generated_sources/DivText.swift index ead8e81d..72d3c37f 100644 --- a/DivKit/generated_sources/DivText.swift +++ b/DivKit/generated_sources/DivText.swift @@ -29,6 +29,12 @@ public final class DivText: DivBase { } public final class Image { + @frozen + public enum IndexingDirection: String, CaseIterable { + case normal = "normal" + case reversed = "reversed" + } + public final class Accessibility { @frozen public enum Kind: String, CaseIterable { @@ -58,6 +64,7 @@ public final class DivText: DivBase { public let accessibility: Accessibility? public let alignmentVertical: Expression // default value: center public let height: DivFixedSize // default value: DivFixedSize(value: .value(20)) + public let indexingDirection: Expression // default value: normal public let preloadRequired: Expression // default value: false public let start: Expression // constraint: number >= 0 public let tintColor: Expression? @@ -69,6 +76,10 @@ public final class DivText: DivBase { resolver.resolveEnum(alignmentVertical) ?? DivTextAlignmentVertical.center } + public func resolveIndexingDirection(_ resolver: ExpressionResolver) -> IndexingDirection { + resolver.resolveEnum(indexingDirection) ?? IndexingDirection.normal + } + public func resolvePreloadRequired(_ resolver: ExpressionResolver) -> Bool { resolver.resolveNumeric(preloadRequired) ?? false } @@ -96,6 +107,7 @@ public final class DivText: DivBase { accessibility: Accessibility? = nil, alignmentVertical: Expression? = nil, height: DivFixedSize? = nil, + indexingDirection: Expression? = nil, preloadRequired: Expression? = nil, start: Expression, tintColor: Expression? = nil, @@ -106,6 +118,7 @@ public final class DivText: DivBase { self.accessibility = accessibility self.alignmentVertical = alignmentVertical ?? .value(.center) self.height = height ?? DivFixedSize(value: .value(20)) + self.indexingDirection = indexingDirection ?? .value(.normal) self.preloadRequired = preloadRequired ?? .value(false) self.start = start self.tintColor = tintColor @@ -119,6 +132,7 @@ public final class DivText: DivBase { public let actions: [DivAction]? public let alignmentVertical: Expression? public let background: DivTextRangeBackground? + public let baselineOffset: Expression // default value: 0 public let border: DivTextRangeBorder? public let end: Expression? // constraint: number > 0 public let fontFamily: Expression? @@ -129,6 +143,7 @@ public final class DivText: DivBase { public let fontWeightValue: Expression? // constraint: number > 0 public let letterSpacing: Expression? public let lineHeight: Expression? // constraint: number >= 0 + public let mask: DivTextRangeMask? public let start: Expression // constraint: number >= 0; default value: 0 public let strike: Expression? public let textColor: Expression? @@ -140,6 +155,10 @@ public final class DivText: DivBase { resolver.resolveEnum(alignmentVertical) } + public func resolveBaselineOffset(_ resolver: ExpressionResolver) -> Double { + resolver.resolveNumeric(baselineOffset) ?? 0 + } + public func resolveEnd(_ resolver: ExpressionResolver) -> Int? { resolver.resolveNumeric(end) } @@ -218,6 +237,7 @@ public final class DivText: DivBase { actions: [DivAction]? = nil, alignmentVertical: Expression? = nil, background: DivTextRangeBackground? = nil, + baselineOffset: Expression? = nil, border: DivTextRangeBorder? = nil, end: Expression? = nil, fontFamily: Expression? = nil, @@ -228,6 +248,7 @@ public final class DivText: DivBase { fontWeightValue: Expression? = nil, letterSpacing: Expression? = nil, lineHeight: Expression? = nil, + mask: DivTextRangeMask? = nil, start: Expression? = nil, strike: Expression? = nil, textColor: Expression? = nil, @@ -238,6 +259,7 @@ public final class DivText: DivBase { self.actions = actions self.alignmentVertical = alignmentVertical self.background = background + self.baselineOffset = baselineOffset ?? .value(0) self.border = border self.end = end self.fontFamily = fontFamily @@ -248,6 +270,7 @@ public final class DivText: DivBase { self.fontWeightValue = fontWeightValue self.letterSpacing = letterSpacing self.lineHeight = lineHeight + self.mask = mask self.start = start ?? .value(0) self.strike = strike self.textColor = textColor @@ -284,6 +307,8 @@ public final class DivText: DivBase { public let fontWeightValue: Expression? // constraint: number > 0 public let functions: [DivFunction]? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: [DivAction]? + public let hoverStartActions: [DivAction]? public let id: String? public let images: [Image]? public let layoutProvider: DivLayoutProvider? @@ -294,6 +319,8 @@ public final class DivText: DivBase { public let maxLines: Expression? // constraint: number >= 0 public let minHiddenLines: Expression? // constraint: number >= 0 public let paddings: DivEdgeInsets? + public let pressEndActions: [DivAction]? + public let pressStartActions: [DivAction]? public let ranges: [Range]? public let reuseId: Expression? public let rowSpan: Expression? // constraint: number >= 0 @@ -483,6 +510,8 @@ public final class DivText: DivBase { fontWeightValue: Expression? = nil, functions: [DivFunction]? = nil, height: DivSize? = nil, + hoverEndActions: [DivAction]? = nil, + hoverStartActions: [DivAction]? = nil, id: String? = nil, images: [Image]? = nil, layoutProvider: DivLayoutProvider? = nil, @@ -493,6 +522,8 @@ public final class DivText: DivBase { maxLines: Expression? = nil, minHiddenLines: Expression? = nil, paddings: DivEdgeInsets? = nil, + pressEndActions: [DivAction]? = nil, + pressStartActions: [DivAction]? = nil, ranges: [Range]? = nil, reuseId: Expression? = nil, rowSpan: Expression? = nil, @@ -546,6 +577,8 @@ public final class DivText: DivBase { self.fontWeightValue = fontWeightValue self.functions = functions self.height = height ?? .divWrapContentSize(DivWrapContentSize()) + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.images = images self.layoutProvider = layoutProvider @@ -556,6 +589,8 @@ public final class DivText: DivBase { self.maxLines = maxLines self.minHiddenLines = minHiddenLines self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.ranges = ranges self.reuseId = reuseId self.rowSpan = rowSpan @@ -647,88 +682,96 @@ extension DivText: Equatable { guard lhs.functions == rhs.functions, lhs.height == rhs.height, - lhs.id == rhs.id + lhs.hoverEndActions == rhs.hoverEndActions + else { + return false + } + guard + lhs.hoverStartActions == rhs.hoverStartActions, + lhs.id == rhs.id, + lhs.images == rhs.images else { return false } guard - lhs.images == rhs.images, lhs.layoutProvider == rhs.layoutProvider, - lhs.letterSpacing == rhs.letterSpacing + lhs.letterSpacing == rhs.letterSpacing, + lhs.lineHeight == rhs.lineHeight else { return false } guard - lhs.lineHeight == rhs.lineHeight, lhs.longtapActions == rhs.longtapActions, - lhs.margins == rhs.margins + lhs.margins == rhs.margins, + lhs.maxLines == rhs.maxLines else { return false } guard - lhs.maxLines == rhs.maxLines, lhs.minHiddenLines == rhs.minHiddenLines, - lhs.paddings == rhs.paddings + lhs.paddings == rhs.paddings, + lhs.pressEndActions == rhs.pressEndActions else { return false } guard + lhs.pressStartActions == rhs.pressStartActions, lhs.ranges == rhs.ranges, - lhs.reuseId == rhs.reuseId, - lhs.rowSpan == rhs.rowSpan + lhs.reuseId == rhs.reuseId else { return false } guard + lhs.rowSpan == rhs.rowSpan, lhs.selectable == rhs.selectable, - lhs.selectedActions == rhs.selectedActions, - lhs.strike == rhs.strike + lhs.selectedActions == rhs.selectedActions else { return false } guard + lhs.strike == rhs.strike, lhs.text == rhs.text, - lhs.textAlignmentHorizontal == rhs.textAlignmentHorizontal, - lhs.textAlignmentVertical == rhs.textAlignmentVertical + lhs.textAlignmentHorizontal == rhs.textAlignmentHorizontal else { return false } guard + lhs.textAlignmentVertical == rhs.textAlignmentVertical, lhs.textColor == rhs.textColor, - lhs.textGradient == rhs.textGradient, - lhs.textShadow == rhs.textShadow + lhs.textGradient == rhs.textGradient else { return false } guard + lhs.textShadow == rhs.textShadow, lhs.tightenWidth == rhs.tightenWidth, - lhs.tooltips == rhs.tooltips, - lhs.transform == rhs.transform + lhs.tooltips == rhs.tooltips else { return false } guard + lhs.transform == rhs.transform, lhs.transitionChange == rhs.transitionChange, - lhs.transitionIn == rhs.transitionIn, - lhs.transitionOut == rhs.transitionOut + lhs.transitionIn == rhs.transitionIn else { return false } guard + lhs.transitionOut == rhs.transitionOut, lhs.transitionTriggers == rhs.transitionTriggers, - lhs.underline == rhs.underline, - lhs.variableTriggers == rhs.variableTriggers + lhs.underline == rhs.underline else { return false } guard + lhs.variableTriggers == rhs.variableTriggers, lhs.variables == rhs.variables, - lhs.visibility == rhs.visibility, - lhs.visibilityAction == rhs.visibilityAction + lhs.visibility == rhs.visibility else { return false } guard + lhs.visibilityAction == rhs.visibilityAction, lhs.visibilityActions == rhs.visibilityActions, lhs.width == rhs.width else { @@ -769,6 +812,8 @@ extension DivText: Serializable { result["font_weight_value"] = fontWeightValue?.toValidSerializationValue() result["functions"] = functions?.map { $0.toDictionary() } result["height"] = height.toDictionary() + result["hover_end_actions"] = hoverEndActions?.map { $0.toDictionary() } + result["hover_start_actions"] = hoverStartActions?.map { $0.toDictionary() } result["id"] = id result["images"] = images?.map { $0.toDictionary() } result["layout_provider"] = layoutProvider?.toDictionary() @@ -779,6 +824,8 @@ extension DivText: Serializable { result["max_lines"] = maxLines?.toValidSerializationValue() result["min_hidden_lines"] = minHiddenLines?.toValidSerializationValue() result["paddings"] = paddings?.toDictionary() + result["press_end_actions"] = pressEndActions?.map { $0.toDictionary() } + result["press_start_actions"] = pressStartActions?.map { $0.toDictionary() } result["ranges"] = ranges?.map { $0.toDictionary() } result["reuse_id"] = reuseId?.toValidSerializationValue() result["row_span"] = rowSpan?.toValidSerializationValue() @@ -854,15 +901,20 @@ extension DivText.Image: Equatable { return false } guard + lhs.indexingDirection == rhs.indexingDirection, lhs.preloadRequired == rhs.preloadRequired, - lhs.start == rhs.start, - lhs.tintColor == rhs.tintColor + lhs.start == rhs.start else { return false } guard + lhs.tintColor == rhs.tintColor, lhs.tintMode == rhs.tintMode, - lhs.url == rhs.url, + lhs.url == rhs.url + else { + return false + } + guard lhs.width == rhs.width else { return false @@ -883,41 +935,43 @@ extension DivText.Range: Equatable { return false } guard + lhs.baselineOffset == rhs.baselineOffset, lhs.border == rhs.border, - lhs.end == rhs.end, - lhs.fontFamily == rhs.fontFamily + lhs.end == rhs.end else { return false } guard + lhs.fontFamily == rhs.fontFamily, lhs.fontFeatureSettings == rhs.fontFeatureSettings, - lhs.fontSize == rhs.fontSize, - lhs.fontSizeUnit == rhs.fontSizeUnit + lhs.fontSize == rhs.fontSize else { return false } guard + lhs.fontSizeUnit == rhs.fontSizeUnit, lhs.fontWeight == rhs.fontWeight, - lhs.fontWeightValue == rhs.fontWeightValue, - lhs.letterSpacing == rhs.letterSpacing + lhs.fontWeightValue == rhs.fontWeightValue else { return false } guard + lhs.letterSpacing == rhs.letterSpacing, lhs.lineHeight == rhs.lineHeight, - lhs.start == rhs.start, - lhs.strike == rhs.strike + lhs.mask == rhs.mask else { return false } guard - lhs.textColor == rhs.textColor, - lhs.textShadow == rhs.textShadow, - lhs.topOffset == rhs.topOffset + lhs.start == rhs.start, + lhs.strike == rhs.strike, + lhs.textColor == rhs.textColor else { return false } guard + lhs.textShadow == rhs.textShadow, + lhs.topOffset == rhs.topOffset, lhs.underline == rhs.underline else { return false @@ -953,6 +1007,7 @@ extension DivText.Image: Serializable { result["accessibility"] = accessibility?.toDictionary() result["alignment_vertical"] = alignmentVertical.toValidSerializationValue() result["height"] = height.toDictionary() + result["indexing_direction"] = indexingDirection.toValidSerializationValue() result["preload_required"] = preloadRequired.toValidSerializationValue() result["start"] = start.toValidSerializationValue() result["tint_color"] = tintColor?.toValidSerializationValue() @@ -969,6 +1024,7 @@ extension DivText.Range: Serializable { result["actions"] = actions?.map { $0.toDictionary() } result["alignment_vertical"] = alignmentVertical?.toValidSerializationValue() result["background"] = background?.toDictionary() + result["baseline_offset"] = baselineOffset.toValidSerializationValue() result["border"] = border?.toDictionary() result["end"] = end?.toValidSerializationValue() result["font_family"] = fontFamily?.toValidSerializationValue() @@ -979,6 +1035,7 @@ extension DivText.Range: Serializable { result["font_weight_value"] = fontWeightValue?.toValidSerializationValue() result["letter_spacing"] = letterSpacing?.toValidSerializationValue() result["line_height"] = lineHeight?.toValidSerializationValue() + result["mask"] = mask?.toDictionary() result["start"] = start.toValidSerializationValue() result["strike"] = strike?.toValidSerializationValue() result["text_color"] = textColor?.toValidSerializationValue() diff --git a/DivKit/generated_sources/DivTextRangeMask.swift b/DivKit/generated_sources/DivTextRangeMask.swift new file mode 100644 index 00000000..e80795bc --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMask.swift @@ -0,0 +1,41 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +@frozen +public enum DivTextRangeMask { + case divTextRangeMaskParticles(DivTextRangeMaskParticles) + case divTextRangeMaskSolid(DivTextRangeMaskSolid) + + public var value: Serializable { + switch self { + case let .divTextRangeMaskParticles(value): + return value + case let .divTextRangeMaskSolid(value): + return value + } + } +} + +#if DEBUG +extension DivTextRangeMask: Equatable { + public static func ==(lhs: DivTextRangeMask, rhs: DivTextRangeMask) -> Bool { + switch (lhs, rhs) { + case let (.divTextRangeMaskParticles(l), .divTextRangeMaskParticles(r)): + return l == r + case let (.divTextRangeMaskSolid(l), .divTextRangeMaskSolid(r)): + return l == r + default: + return false + } + } +} +#endif + +extension DivTextRangeMask: Serializable { + public func toDictionary() -> [String: ValidSerializationValue] { + return value.toDictionary() + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskBase.swift b/DivKit/generated_sources/DivTextRangeMaskBase.swift new file mode 100644 index 00000000..12ab2043 --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskBase.swift @@ -0,0 +1,40 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivTextRangeMaskBase { + public let isEnabled: Expression // default value: true + + public func resolveIsEnabled(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(isEnabled) ?? true + } + + init( + isEnabled: Expression? = nil + ) { + self.isEnabled = isEnabled ?? .value(true) + } +} + +#if DEBUG +extension DivTextRangeMaskBase: Equatable { + public static func ==(lhs: DivTextRangeMaskBase, rhs: DivTextRangeMaskBase) -> Bool { + guard + lhs.isEnabled == rhs.isEnabled + else { + return false + } + return true + } +} +#endif + +extension DivTextRangeMaskBase: Serializable { + public func toDictionary() -> [String: ValidSerializationValue] { + var result: [String: ValidSerializationValue] = [:] + result["is_enabled"] = isEnabled.toValidSerializationValue() + return result + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskBaseTemplate.swift b/DivKit/generated_sources/DivTextRangeMaskBaseTemplate.swift new file mode 100644 index 00000000..b5d588f7 --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskBaseTemplate.swift @@ -0,0 +1,71 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivTextRangeMaskBaseTemplate: TemplateValue { + public let isEnabled: Field>? // default value: true + + public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { + self.init( + isEnabled: dictionary.getOptionalExpressionField("is_enabled") + ) + } + + init( + isEnabled: Field>? = nil + ) { + self.isEnabled = isEnabled + } + + private static func resolveOnlyLinks(context: TemplatesContext, parent: DivTextRangeMaskBaseTemplate?) -> DeserializationResult { + let isEnabledValue = { parent?.isEnabled?.resolveOptionalValue(context: context) ?? .noValue }() + let errors = mergeErrors( + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) } + ) + let result = DivTextRangeMaskBase( + isEnabled: { isEnabledValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + public static func resolveValue(context: TemplatesContext, parent: DivTextRangeMaskBaseTemplate?, useOnlyLinks: Bool) -> DeserializationResult { + if useOnlyLinks { + return resolveOnlyLinks(context: context, parent: parent) + } + var isEnabledValue: DeserializationResult> = { parent?.isEnabled?.value() ?? .noValue }() + _ = { + // Each field is parsed in its own lambda to keep the stack size managable + // Otherwise the compiler will allocate stack for each intermediate variable + // upfront even when we don't actually visit a relevant branch + for (key, __dictValue) in context.templateData { + _ = { + if key == "is_enabled" { + isEnabledValue = deserialize(__dictValue).merged(with: isEnabledValue) + } + }() + _ = { + if key == parent?.isEnabled?.link { + isEnabledValue = isEnabledValue.merged(with: { deserialize(__dictValue) }) + } + }() + } + }() + let errors = mergeErrors( + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) } + ) + let result = DivTextRangeMaskBase( + isEnabled: { isEnabledValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + private func mergedWithParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskBaseTemplate { + return self + } + + public func resolveParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskBaseTemplate { + return try mergedWithParent(templates: templates) + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskParticles.swift b/DivKit/generated_sources/DivTextRangeMaskParticles.swift new file mode 100644 index 00000000..4274e6df --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskParticles.swift @@ -0,0 +1,78 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivTextRangeMaskParticles { + public static let type: String = "particles" + public let color: Expression + public let density: Expression // default value: 0.8 + public let isAnimated: Expression // default value: false + public let isEnabled: Expression // default value: true + public let particleSize: DivFixedSize // default value: DivFixedSize(value: .value(1)) + + public func resolveColor(_ resolver: ExpressionResolver) -> Color? { + resolver.resolveColor(color) + } + + public func resolveDensity(_ resolver: ExpressionResolver) -> Double { + resolver.resolveNumeric(density) ?? 0.8 + } + + public func resolveIsAnimated(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(isAnimated) ?? false + } + + public func resolveIsEnabled(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(isEnabled) ?? true + } + + init( + color: Expression, + density: Expression? = nil, + isAnimated: Expression? = nil, + isEnabled: Expression? = nil, + particleSize: DivFixedSize? = nil + ) { + self.color = color + self.density = density ?? .value(0.8) + self.isAnimated = isAnimated ?? .value(false) + self.isEnabled = isEnabled ?? .value(true) + self.particleSize = particleSize ?? DivFixedSize(value: .value(1)) + } +} + +#if DEBUG +extension DivTextRangeMaskParticles: Equatable { + public static func ==(lhs: DivTextRangeMaskParticles, rhs: DivTextRangeMaskParticles) -> Bool { + guard + lhs.color == rhs.color, + lhs.density == rhs.density, + lhs.isAnimated == rhs.isAnimated + else { + return false + } + guard + lhs.isEnabled == rhs.isEnabled, + lhs.particleSize == rhs.particleSize + else { + return false + } + return true + } +} +#endif + +extension DivTextRangeMaskParticles: Serializable { + public func toDictionary() -> [String: ValidSerializationValue] { + var result: [String: ValidSerializationValue] = [:] + result["type"] = Self.type + result["color"] = color.toValidSerializationValue() + result["density"] = density.toValidSerializationValue() + result["is_animated"] = isAnimated.toValidSerializationValue() + result["is_enabled"] = isEnabled.toValidSerializationValue() + result["particle_size"] = particleSize.toDictionary() + return result + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskParticlesTemplate.swift b/DivKit/generated_sources/DivTextRangeMaskParticlesTemplate.swift new file mode 100644 index 00000000..66b65075 --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskParticlesTemplate.swift @@ -0,0 +1,197 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivTextRangeMaskParticlesTemplate: TemplateValue { + public static let type: String = "particles" + public let parent: String? + public let color: Field>? + public let density: Field>? // default value: 0.8 + public let isAnimated: Field>? // default value: false + public let isEnabled: Field>? // default value: true + public let particleSize: Field? // default value: DivFixedSize(value: .value(1)) + + public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { + self.init( + parent: dictionary["type"] as? String, + color: dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:)), + density: dictionary.getOptionalExpressionField("density"), + isAnimated: dictionary.getOptionalExpressionField("is_animated"), + isEnabled: dictionary.getOptionalExpressionField("is_enabled"), + particleSize: dictionary.getOptionalField("particle_size", templateToType: templateToType) + ) + } + + init( + parent: String?, + color: Field>? = nil, + density: Field>? = nil, + isAnimated: Field>? = nil, + isEnabled: Field>? = nil, + particleSize: Field? = nil + ) { + self.parent = parent + self.color = color + self.density = density + self.isAnimated = isAnimated + self.isEnabled = isEnabled + self.particleSize = particleSize + } + + private static func resolveOnlyLinks(context: TemplatesContext, parent: DivTextRangeMaskParticlesTemplate?) -> DeserializationResult { + let colorValue = { parent?.color?.resolveValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() + let densityValue = { parent?.density?.resolveOptionalValue(context: context) ?? .noValue }() + let isAnimatedValue = { parent?.isAnimated?.resolveOptionalValue(context: context) ?? .noValue }() + let isEnabledValue = { parent?.isEnabled?.resolveOptionalValue(context: context) ?? .noValue }() + let particleSizeValue = { parent?.particleSize?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + var errors = mergeErrors( + colorValue.errorsOrWarnings?.map { .nestedObjectError(field: "color", error: $0) }, + densityValue.errorsOrWarnings?.map { .nestedObjectError(field: "density", error: $0) }, + isAnimatedValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_animated", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) }, + particleSizeValue.errorsOrWarnings?.map { .nestedObjectError(field: "particle_size", error: $0) } + ) + if case .noValue = colorValue { + errors.append(.requiredFieldIsMissing(field: "color")) + } + guard + let colorNonNil = colorValue.value + else { + return .failure(NonEmptyArray(errors)!) + } + let result = DivTextRangeMaskParticles( + color: { colorNonNil }(), + density: { densityValue.value }(), + isAnimated: { isAnimatedValue.value }(), + isEnabled: { isEnabledValue.value }(), + particleSize: { particleSizeValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + public static func resolveValue(context: TemplatesContext, parent: DivTextRangeMaskParticlesTemplate?, useOnlyLinks: Bool) -> DeserializationResult { + if useOnlyLinks { + return resolveOnlyLinks(context: context, parent: parent) + } + var colorValue: DeserializationResult> = { parent?.color?.value() ?? .noValue }() + var densityValue: DeserializationResult> = { parent?.density?.value() ?? .noValue }() + var isAnimatedValue: DeserializationResult> = { parent?.isAnimated?.value() ?? .noValue }() + var isEnabledValue: DeserializationResult> = { parent?.isEnabled?.value() ?? .noValue }() + var particleSizeValue: DeserializationResult = .noValue + _ = { + // Each field is parsed in its own lambda to keep the stack size managable + // Otherwise the compiler will allocate stack for each intermediate variable + // upfront even when we don't actually visit a relevant branch + for (key, __dictValue) in context.templateData { + _ = { + if key == "color" { + colorValue = deserialize(__dictValue, transform: Color.color(withHexString:)).merged(with: colorValue) + } + }() + _ = { + if key == "density" { + densityValue = deserialize(__dictValue).merged(with: densityValue) + } + }() + _ = { + if key == "is_animated" { + isAnimatedValue = deserialize(__dictValue).merged(with: isAnimatedValue) + } + }() + _ = { + if key == "is_enabled" { + isEnabledValue = deserialize(__dictValue).merged(with: isEnabledValue) + } + }() + _ = { + if key == "particle_size" { + particleSizeValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFixedSizeTemplate.self).merged(with: particleSizeValue) + } + }() + _ = { + if key == parent?.color?.link { + colorValue = colorValue.merged(with: { deserialize(__dictValue, transform: Color.color(withHexString:)) }) + } + }() + _ = { + if key == parent?.density?.link { + densityValue = densityValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.isAnimated?.link { + isAnimatedValue = isAnimatedValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.isEnabled?.link { + isEnabledValue = isEnabledValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.particleSize?.link { + particleSizeValue = particleSizeValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFixedSizeTemplate.self) }) + } + }() + } + }() + if let parent = parent { + _ = { particleSizeValue = particleSizeValue.merged(with: { parent.particleSize?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + } + var errors = mergeErrors( + colorValue.errorsOrWarnings?.map { .nestedObjectError(field: "color", error: $0) }, + densityValue.errorsOrWarnings?.map { .nestedObjectError(field: "density", error: $0) }, + isAnimatedValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_animated", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) }, + particleSizeValue.errorsOrWarnings?.map { .nestedObjectError(field: "particle_size", error: $0) } + ) + if case .noValue = colorValue { + errors.append(.requiredFieldIsMissing(field: "color")) + } + guard + let colorNonNil = colorValue.value + else { + return .failure(NonEmptyArray(errors)!) + } + let result = DivTextRangeMaskParticles( + color: { colorNonNil }(), + density: { densityValue.value }(), + isAnimated: { isAnimatedValue.value }(), + isEnabled: { isEnabledValue.value }(), + particleSize: { particleSizeValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + private func mergedWithParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskParticlesTemplate { + guard let parent = parent, parent != Self.type else { return self } + guard let parentTemplate = templates[parent] as? DivTextRangeMaskParticlesTemplate else { + throw DeserializationError.unknownType(type: parent) + } + let mergedParent = try parentTemplate.mergedWithParent(templates: templates) + + return DivTextRangeMaskParticlesTemplate( + parent: nil, + color: color ?? mergedParent.color, + density: density ?? mergedParent.density, + isAnimated: isAnimated ?? mergedParent.isAnimated, + isEnabled: isEnabled ?? mergedParent.isEnabled, + particleSize: particleSize ?? mergedParent.particleSize + ) + } + + public func resolveParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskParticlesTemplate { + let merged = try mergedWithParent(templates: templates) + + return DivTextRangeMaskParticlesTemplate( + parent: nil, + color: merged.color, + density: merged.density, + isAnimated: merged.isAnimated, + isEnabled: merged.isEnabled, + particleSize: merged.particleSize?.tryResolveParent(templates: templates) + ) + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskSolid.swift b/DivKit/generated_sources/DivTextRangeMaskSolid.swift new file mode 100644 index 00000000..7d1c105f --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskSolid.swift @@ -0,0 +1,51 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivTextRangeMaskSolid { + public static let type: String = "solid" + public let color: Expression + public let isEnabled: Expression // default value: true + + public func resolveColor(_ resolver: ExpressionResolver) -> Color? { + resolver.resolveColor(color) + } + + public func resolveIsEnabled(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(isEnabled) ?? true + } + + init( + color: Expression, + isEnabled: Expression? = nil + ) { + self.color = color + self.isEnabled = isEnabled ?? .value(true) + } +} + +#if DEBUG +extension DivTextRangeMaskSolid: Equatable { + public static func ==(lhs: DivTextRangeMaskSolid, rhs: DivTextRangeMaskSolid) -> Bool { + guard + lhs.color == rhs.color, + lhs.isEnabled == rhs.isEnabled + else { + return false + } + return true + } +} +#endif + +extension DivTextRangeMaskSolid: Serializable { + public func toDictionary() -> [String: ValidSerializationValue] { + var result: [String: ValidSerializationValue] = [:] + result["type"] = Self.type + result["color"] = color.toValidSerializationValue() + result["is_enabled"] = isEnabled.toValidSerializationValue() + return result + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskSolidTemplate.swift b/DivKit/generated_sources/DivTextRangeMaskSolidTemplate.swift new file mode 100644 index 00000000..fe3cd812 --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskSolidTemplate.swift @@ -0,0 +1,122 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivTextRangeMaskSolidTemplate: TemplateValue { + public static let type: String = "solid" + public let parent: String? + public let color: Field>? + public let isEnabled: Field>? // default value: true + + public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { + self.init( + parent: dictionary["type"] as? String, + color: dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:)), + isEnabled: dictionary.getOptionalExpressionField("is_enabled") + ) + } + + init( + parent: String?, + color: Field>? = nil, + isEnabled: Field>? = nil + ) { + self.parent = parent + self.color = color + self.isEnabled = isEnabled + } + + private static func resolveOnlyLinks(context: TemplatesContext, parent: DivTextRangeMaskSolidTemplate?) -> DeserializationResult { + let colorValue = { parent?.color?.resolveValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() + let isEnabledValue = { parent?.isEnabled?.resolveOptionalValue(context: context) ?? .noValue }() + var errors = mergeErrors( + colorValue.errorsOrWarnings?.map { .nestedObjectError(field: "color", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) } + ) + if case .noValue = colorValue { + errors.append(.requiredFieldIsMissing(field: "color")) + } + guard + let colorNonNil = colorValue.value + else { + return .failure(NonEmptyArray(errors)!) + } + let result = DivTextRangeMaskSolid( + color: { colorNonNil }(), + isEnabled: { isEnabledValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + public static func resolveValue(context: TemplatesContext, parent: DivTextRangeMaskSolidTemplate?, useOnlyLinks: Bool) -> DeserializationResult { + if useOnlyLinks { + return resolveOnlyLinks(context: context, parent: parent) + } + var colorValue: DeserializationResult> = { parent?.color?.value() ?? .noValue }() + var isEnabledValue: DeserializationResult> = { parent?.isEnabled?.value() ?? .noValue }() + _ = { + // Each field is parsed in its own lambda to keep the stack size managable + // Otherwise the compiler will allocate stack for each intermediate variable + // upfront even when we don't actually visit a relevant branch + for (key, __dictValue) in context.templateData { + _ = { + if key == "color" { + colorValue = deserialize(__dictValue, transform: Color.color(withHexString:)).merged(with: colorValue) + } + }() + _ = { + if key == "is_enabled" { + isEnabledValue = deserialize(__dictValue).merged(with: isEnabledValue) + } + }() + _ = { + if key == parent?.color?.link { + colorValue = colorValue.merged(with: { deserialize(__dictValue, transform: Color.color(withHexString:)) }) + } + }() + _ = { + if key == parent?.isEnabled?.link { + isEnabledValue = isEnabledValue.merged(with: { deserialize(__dictValue) }) + } + }() + } + }() + var errors = mergeErrors( + colorValue.errorsOrWarnings?.map { .nestedObjectError(field: "color", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) } + ) + if case .noValue = colorValue { + errors.append(.requiredFieldIsMissing(field: "color")) + } + guard + let colorNonNil = colorValue.value + else { + return .failure(NonEmptyArray(errors)!) + } + let result = DivTextRangeMaskSolid( + color: { colorNonNil }(), + isEnabled: { isEnabledValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + private func mergedWithParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskSolidTemplate { + guard let parent = parent, parent != Self.type else { return self } + guard let parentTemplate = templates[parent] as? DivTextRangeMaskSolidTemplate else { + throw DeserializationError.unknownType(type: parent) + } + let mergedParent = try parentTemplate.mergedWithParent(templates: templates) + + return DivTextRangeMaskSolidTemplate( + parent: nil, + color: color ?? mergedParent.color, + isEnabled: isEnabled ?? mergedParent.isEnabled + ) + } + + public func resolveParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskSolidTemplate { + return try mergedWithParent(templates: templates) + } +} diff --git a/DivKit/generated_sources/DivTextRangeMaskTemplate.swift b/DivKit/generated_sources/DivTextRangeMaskTemplate.swift new file mode 100644 index 00000000..4d947484 --- /dev/null +++ b/DivKit/generated_sources/DivTextRangeMaskTemplate.swift @@ -0,0 +1,110 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +@frozen +public enum DivTextRangeMaskTemplate: TemplateValue { + case divTextRangeMaskParticlesTemplate(DivTextRangeMaskParticlesTemplate) + case divTextRangeMaskSolidTemplate(DivTextRangeMaskSolidTemplate) + + public var value: Any { + switch self { + case let .divTextRangeMaskParticlesTemplate(value): + return value + case let .divTextRangeMaskSolidTemplate(value): + return value + } + } + + public func resolveParent(templates: [TemplateName: Any]) throws -> DivTextRangeMaskTemplate { + switch self { + case let .divTextRangeMaskParticlesTemplate(value): + return .divTextRangeMaskParticlesTemplate(try value.resolveParent(templates: templates)) + case let .divTextRangeMaskSolidTemplate(value): + return .divTextRangeMaskSolidTemplate(try value.resolveParent(templates: templates)) + } + } + + public static func resolveValue(context: TemplatesContext, parent: DivTextRangeMaskTemplate?, useOnlyLinks: Bool) -> DeserializationResult { + guard let parent = parent else { + if useOnlyLinks { + return .failure(NonEmptyArray(.missingType(representation: context.templateData))) + } else { + return resolveUnknownValue(context: context, useOnlyLinks: useOnlyLinks) + } + } + + return { + var result: DeserializationResult! + result = result ?? { + if case let .divTextRangeMaskParticlesTemplate(value) = parent { + let result = value.resolveValue(context: context, useOnlyLinks: useOnlyLinks) + switch result { + case let .success(value): return .success(.divTextRangeMaskParticles(value)) + case let .partialSuccess(value, warnings): return .partialSuccess(.divTextRangeMaskParticles(value), warnings: warnings) + case let .failure(errors): return .failure(errors) + case .noValue: return .noValue + } + } else { return nil } + }() + result = result ?? { + if case let .divTextRangeMaskSolidTemplate(value) = parent { + let result = value.resolveValue(context: context, useOnlyLinks: useOnlyLinks) + switch result { + case let .success(value): return .success(.divTextRangeMaskSolid(value)) + case let .partialSuccess(value, warnings): return .partialSuccess(.divTextRangeMaskSolid(value), warnings: warnings) + case let .failure(errors): return .failure(errors) + case .noValue: return .noValue + } + } else { return nil } + }() + return result + }() + } + + private static func resolveUnknownValue(context: TemplatesContext, useOnlyLinks: Bool) -> DeserializationResult { + guard let type = (context.templateData["type"] as? String).flatMap({ context.templateToType[$0] ?? $0 }) else { + return .failure(NonEmptyArray(.requiredFieldIsMissing(field: "type"))) + } + + return { + var result: DeserializationResult? + result = result ?? { if type == DivTextRangeMaskParticles.type { + let result = { DivTextRangeMaskParticlesTemplate.resolveValue(context: context, useOnlyLinks: useOnlyLinks) }() + switch result { + case let .success(value): return .success(.divTextRangeMaskParticles(value)) + case let .partialSuccess(value, warnings): return .partialSuccess(.divTextRangeMaskParticles(value), warnings: warnings) + case let .failure(errors): return .failure(errors) + case .noValue: return .noValue + } + } else { return nil } }() + result = result ?? { if type == DivTextRangeMaskSolid.type { + let result = { DivTextRangeMaskSolidTemplate.resolveValue(context: context, useOnlyLinks: useOnlyLinks) }() + switch result { + case let .success(value): return .success(.divTextRangeMaskSolid(value)) + case let .partialSuccess(value, warnings): return .partialSuccess(.divTextRangeMaskSolid(value), warnings: warnings) + case let .failure(errors): return .failure(errors) + case .noValue: return .noValue + } + } else { return nil } }() + return result ?? .failure(NonEmptyArray(.requiredFieldIsMissing(field: "type"))) + }() + } +} + +extension DivTextRangeMaskTemplate { + public init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { + let receivedType = try dictionary.getField("type") as String + let blockType = templateToType[receivedType] ?? receivedType + switch blockType { + case DivTextRangeMaskParticlesTemplate.type: + self = .divTextRangeMaskParticlesTemplate(try DivTextRangeMaskParticlesTemplate(dictionary: dictionary, templateToType: templateToType)) + case DivTextRangeMaskSolidTemplate.type: + self = .divTextRangeMaskSolidTemplate(try DivTextRangeMaskSolidTemplate(dictionary: dictionary, templateToType: templateToType)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-text-range-mask_template", representation: dictionary) + } + } +} diff --git a/DivKit/generated_sources/DivTextTemplate.swift b/DivKit/generated_sources/DivTextTemplate.swift index 4029cbae..76938b8b 100644 --- a/DivKit/generated_sources/DivTextTemplate.swift +++ b/DivKit/generated_sources/DivTextTemplate.swift @@ -248,9 +248,12 @@ public final class DivTextTemplate: TemplateValue { } } + public typealias IndexingDirection = DivText.Image.IndexingDirection + public let accessibility: Field? public let alignmentVertical: Field>? // default value: center public let height: Field? // default value: DivFixedSize(value: .value(20)) + public let indexingDirection: Field>? // default value: normal public let preloadRequired: Field>? // default value: false public let start: Field>? // constraint: number >= 0 public let tintColor: Field>? @@ -263,6 +266,7 @@ public final class DivTextTemplate: TemplateValue { accessibility: dictionary.getOptionalField("accessibility", templateToType: templateToType), alignmentVertical: dictionary.getOptionalExpressionField("alignment_vertical"), height: dictionary.getOptionalField("height", templateToType: templateToType), + indexingDirection: dictionary.getOptionalExpressionField("indexing_direction"), preloadRequired: dictionary.getOptionalExpressionField("preload_required"), start: dictionary.getOptionalExpressionField("start"), tintColor: dictionary.getOptionalExpressionField("tint_color", transform: Color.color(withHexString:)), @@ -276,6 +280,7 @@ public final class DivTextTemplate: TemplateValue { accessibility: Field? = nil, alignmentVertical: Field>? = nil, height: Field? = nil, + indexingDirection: Field>? = nil, preloadRequired: Field>? = nil, start: Field>? = nil, tintColor: Field>? = nil, @@ -286,6 +291,7 @@ public final class DivTextTemplate: TemplateValue { self.accessibility = accessibility self.alignmentVertical = alignmentVertical self.height = height + self.indexingDirection = indexingDirection self.preloadRequired = preloadRequired self.start = start self.tintColor = tintColor @@ -298,6 +304,7 @@ public final class DivTextTemplate: TemplateValue { let accessibilityValue = { parent?.accessibility?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let alignmentVerticalValue = { parent?.alignmentVertical?.resolveOptionalValue(context: context) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let indexingDirectionValue = { parent?.indexingDirection?.resolveOptionalValue(context: context) ?? .noValue }() let preloadRequiredValue = { parent?.preloadRequired?.resolveOptionalValue(context: context) ?? .noValue }() let startValue = { parent?.start?.resolveValue(context: context, validator: ResolvedValue.startValidator) ?? .noValue }() let tintColorValue = { parent?.tintColor?.resolveOptionalValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() @@ -308,6 +315,7 @@ public final class DivTextTemplate: TemplateValue { accessibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "accessibility", error: $0) }, alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + indexingDirectionValue.errorsOrWarnings?.map { .nestedObjectError(field: "indexing_direction", error: $0) }, preloadRequiredValue.errorsOrWarnings?.map { .nestedObjectError(field: "preload_required", error: $0) }, startValue.errorsOrWarnings?.map { .nestedObjectError(field: "start", error: $0) }, tintColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "tint_color", error: $0) }, @@ -331,6 +339,7 @@ public final class DivTextTemplate: TemplateValue { accessibility: { accessibilityValue.value }(), alignmentVertical: { alignmentVerticalValue.value }(), height: { heightValue.value }(), + indexingDirection: { indexingDirectionValue.value }(), preloadRequired: { preloadRequiredValue.value }(), start: { startNonNil }(), tintColor: { tintColorValue.value }(), @@ -348,6 +357,7 @@ public final class DivTextTemplate: TemplateValue { var accessibilityValue: DeserializationResult = .noValue var alignmentVerticalValue: DeserializationResult> = { parent?.alignmentVertical?.value() ?? .noValue }() var heightValue: DeserializationResult = .noValue + var indexingDirectionValue: DeserializationResult> = { parent?.indexingDirection?.value() ?? .noValue }() var preloadRequiredValue: DeserializationResult> = { parent?.preloadRequired?.value() ?? .noValue }() var startValue: DeserializationResult> = { parent?.start?.value() ?? .noValue }() var tintColorValue: DeserializationResult> = { parent?.tintColor?.value() ?? .noValue }() @@ -374,6 +384,11 @@ public final class DivTextTemplate: TemplateValue { heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFixedSizeTemplate.self).merged(with: heightValue) } }() + _ = { + if key == "indexing_direction" { + indexingDirectionValue = deserialize(__dictValue).merged(with: indexingDirectionValue) + } + }() _ = { if key == "preload_required" { preloadRequiredValue = deserialize(__dictValue).merged(with: preloadRequiredValue) @@ -419,6 +434,11 @@ public final class DivTextTemplate: TemplateValue { heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFixedSizeTemplate.self) }) } }() + _ = { + if key == parent?.indexingDirection?.link { + indexingDirectionValue = indexingDirectionValue.merged(with: { deserialize(__dictValue) }) + } + }() _ = { if key == parent?.preloadRequired?.link { preloadRequiredValue = preloadRequiredValue.merged(with: { deserialize(__dictValue) }) @@ -460,6 +480,7 @@ public final class DivTextTemplate: TemplateValue { accessibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "accessibility", error: $0) }, alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + indexingDirectionValue.errorsOrWarnings?.map { .nestedObjectError(field: "indexing_direction", error: $0) }, preloadRequiredValue.errorsOrWarnings?.map { .nestedObjectError(field: "preload_required", error: $0) }, startValue.errorsOrWarnings?.map { .nestedObjectError(field: "start", error: $0) }, tintColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "tint_color", error: $0) }, @@ -483,6 +504,7 @@ public final class DivTextTemplate: TemplateValue { accessibility: { accessibilityValue.value }(), alignmentVertical: { alignmentVerticalValue.value }(), height: { heightValue.value }(), + indexingDirection: { indexingDirectionValue.value }(), preloadRequired: { preloadRequiredValue.value }(), start: { startNonNil }(), tintColor: { tintColorValue.value }(), @@ -504,6 +526,7 @@ public final class DivTextTemplate: TemplateValue { accessibility: merged.accessibility?.tryResolveParent(templates: templates), alignmentVertical: merged.alignmentVertical, height: merged.height?.tryResolveParent(templates: templates), + indexingDirection: merged.indexingDirection, preloadRequired: merged.preloadRequired, start: merged.start, tintColor: merged.tintColor, @@ -518,6 +541,7 @@ public final class DivTextTemplate: TemplateValue { public let actions: Field<[DivActionTemplate]>? public let alignmentVertical: Field>? public let background: Field? + public let baselineOffset: Field>? // default value: 0 public let border: Field? public let end: Field>? // constraint: number > 0 public let fontFamily: Field>? @@ -528,6 +552,7 @@ public final class DivTextTemplate: TemplateValue { public let fontWeightValue: Field>? // constraint: number > 0 public let letterSpacing: Field>? public let lineHeight: Field>? // constraint: number >= 0 + public let mask: Field? public let start: Field>? // constraint: number >= 0; default value: 0 public let strike: Field>? public let textColor: Field>? @@ -540,6 +565,7 @@ public final class DivTextTemplate: TemplateValue { actions: dictionary.getOptionalArray("actions", templateToType: templateToType), alignmentVertical: dictionary.getOptionalExpressionField("alignment_vertical"), background: dictionary.getOptionalField("background", templateToType: templateToType), + baselineOffset: dictionary.getOptionalExpressionField("baseline_offset"), border: dictionary.getOptionalField("border", templateToType: templateToType), end: dictionary.getOptionalExpressionField("end"), fontFamily: dictionary.getOptionalExpressionField("font_family"), @@ -550,6 +576,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: dictionary.getOptionalExpressionField("font_weight_value"), letterSpacing: dictionary.getOptionalExpressionField("letter_spacing"), lineHeight: dictionary.getOptionalExpressionField("line_height"), + mask: dictionary.getOptionalField("mask", templateToType: templateToType), start: dictionary.getOptionalExpressionField("start"), strike: dictionary.getOptionalExpressionField("strike"), textColor: dictionary.getOptionalExpressionField("text_color", transform: Color.color(withHexString:)), @@ -563,6 +590,7 @@ public final class DivTextTemplate: TemplateValue { actions: Field<[DivActionTemplate]>? = nil, alignmentVertical: Field>? = nil, background: Field? = nil, + baselineOffset: Field>? = nil, border: Field? = nil, end: Field>? = nil, fontFamily: Field>? = nil, @@ -573,6 +601,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: Field>? = nil, letterSpacing: Field>? = nil, lineHeight: Field>? = nil, + mask: Field? = nil, start: Field>? = nil, strike: Field>? = nil, textColor: Field>? = nil, @@ -583,6 +612,7 @@ public final class DivTextTemplate: TemplateValue { self.actions = actions self.alignmentVertical = alignmentVertical self.background = background + self.baselineOffset = baselineOffset self.border = border self.end = end self.fontFamily = fontFamily @@ -593,6 +623,7 @@ public final class DivTextTemplate: TemplateValue { self.fontWeightValue = fontWeightValue self.letterSpacing = letterSpacing self.lineHeight = lineHeight + self.mask = mask self.start = start self.strike = strike self.textColor = textColor @@ -605,6 +636,7 @@ public final class DivTextTemplate: TemplateValue { let actionsValue = { parent?.actions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let alignmentVerticalValue = { parent?.alignmentVertical?.resolveOptionalValue(context: context) ?? .noValue }() let backgroundValue = { parent?.background?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let baselineOffsetValue = { parent?.baselineOffset?.resolveOptionalValue(context: context) ?? .noValue }() let borderValue = { parent?.border?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let endValue = { parent?.end?.resolveOptionalValue(context: context, validator: ResolvedValue.endValidator) ?? .noValue }() let fontFamilyValue = { parent?.fontFamily?.resolveOptionalValue(context: context) ?? .noValue }() @@ -615,6 +647,7 @@ public final class DivTextTemplate: TemplateValue { let fontWeightValueValue = { parent?.fontWeightValue?.resolveOptionalValue(context: context, validator: ResolvedValue.fontWeightValueValidator) ?? .noValue }() let letterSpacingValue = { parent?.letterSpacing?.resolveOptionalValue(context: context) ?? .noValue }() let lineHeightValue = { parent?.lineHeight?.resolveOptionalValue(context: context, validator: ResolvedValue.lineHeightValidator) ?? .noValue }() + let maskValue = { parent?.mask?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let startValue = { parent?.start?.resolveOptionalValue(context: context, validator: ResolvedValue.startValidator) ?? .noValue }() let strikeValue = { parent?.strike?.resolveOptionalValue(context: context) ?? .noValue }() let textColorValue = { parent?.textColor?.resolveOptionalValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() @@ -625,6 +658,7 @@ public final class DivTextTemplate: TemplateValue { actionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "actions", error: $0) }, alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, backgroundValue.errorsOrWarnings?.map { .nestedObjectError(field: "background", error: $0) }, + baselineOffsetValue.errorsOrWarnings?.map { .nestedObjectError(field: "baseline_offset", error: $0) }, borderValue.errorsOrWarnings?.map { .nestedObjectError(field: "border", error: $0) }, endValue.errorsOrWarnings?.map { .nestedObjectError(field: "end", error: $0) }, fontFamilyValue.errorsOrWarnings?.map { .nestedObjectError(field: "font_family", error: $0) }, @@ -635,6 +669,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValueValue.errorsOrWarnings?.map { .nestedObjectError(field: "font_weight_value", error: $0) }, letterSpacingValue.errorsOrWarnings?.map { .nestedObjectError(field: "letter_spacing", error: $0) }, lineHeightValue.errorsOrWarnings?.map { .nestedObjectError(field: "line_height", error: $0) }, + maskValue.errorsOrWarnings?.map { .nestedObjectError(field: "mask", error: $0) }, startValue.errorsOrWarnings?.map { .nestedObjectError(field: "start", error: $0) }, strikeValue.errorsOrWarnings?.map { .nestedObjectError(field: "strike", error: $0) }, textColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "text_color", error: $0) }, @@ -646,6 +681,7 @@ public final class DivTextTemplate: TemplateValue { actions: { actionsValue.value }(), alignmentVertical: { alignmentVerticalValue.value }(), background: { backgroundValue.value }(), + baselineOffset: { baselineOffsetValue.value }(), border: { borderValue.value }(), end: { endValue.value }(), fontFamily: { fontFamilyValue.value }(), @@ -656,6 +692,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: { fontWeightValueValue.value }(), letterSpacing: { letterSpacingValue.value }(), lineHeight: { lineHeightValue.value }(), + mask: { maskValue.value }(), start: { startValue.value }(), strike: { strikeValue.value }(), textColor: { textColorValue.value }(), @@ -673,6 +710,7 @@ public final class DivTextTemplate: TemplateValue { var actionsValue: DeserializationResult<[DivAction]> = .noValue var alignmentVerticalValue: DeserializationResult> = { parent?.alignmentVertical?.value() ?? .noValue }() var backgroundValue: DeserializationResult = .noValue + var baselineOffsetValue: DeserializationResult> = { parent?.baselineOffset?.value() ?? .noValue }() var borderValue: DeserializationResult = .noValue var endValue: DeserializationResult> = { parent?.end?.value() ?? .noValue }() var fontFamilyValue: DeserializationResult> = { parent?.fontFamily?.value() ?? .noValue }() @@ -683,6 +721,7 @@ public final class DivTextTemplate: TemplateValue { var fontWeightValueValue: DeserializationResult> = { parent?.fontWeightValue?.value() ?? .noValue }() var letterSpacingValue: DeserializationResult> = { parent?.letterSpacing?.value() ?? .noValue }() var lineHeightValue: DeserializationResult> = { parent?.lineHeight?.value() ?? .noValue }() + var maskValue: DeserializationResult = .noValue var startValue: DeserializationResult> = { parent?.start?.value() ?? .noValue }() var strikeValue: DeserializationResult> = { parent?.strike?.value() ?? .noValue }() var textColorValue: DeserializationResult> = { parent?.textColor?.value() ?? .noValue }() @@ -709,6 +748,11 @@ public final class DivTextTemplate: TemplateValue { backgroundValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextRangeBackgroundTemplate.self).merged(with: backgroundValue) } }() + _ = { + if key == "baseline_offset" { + baselineOffsetValue = deserialize(__dictValue).merged(with: baselineOffsetValue) + } + }() _ = { if key == "border" { borderValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextRangeBorderTemplate.self).merged(with: borderValue) @@ -759,6 +803,11 @@ public final class DivTextTemplate: TemplateValue { lineHeightValue = deserialize(__dictValue, validator: ResolvedValue.lineHeightValidator).merged(with: lineHeightValue) } }() + _ = { + if key == "mask" { + maskValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextRangeMaskTemplate.self).merged(with: maskValue) + } + }() _ = { if key == "start" { startValue = deserialize(__dictValue, validator: ResolvedValue.startValidator).merged(with: startValue) @@ -804,6 +853,11 @@ public final class DivTextTemplate: TemplateValue { backgroundValue = backgroundValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextRangeBackgroundTemplate.self) }) } }() + _ = { + if key == parent?.baselineOffset?.link { + baselineOffsetValue = baselineOffsetValue.merged(with: { deserialize(__dictValue) }) + } + }() _ = { if key == parent?.border?.link { borderValue = borderValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextRangeBorderTemplate.self) }) @@ -854,6 +908,11 @@ public final class DivTextTemplate: TemplateValue { lineHeightValue = lineHeightValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.lineHeightValidator) }) } }() + _ = { + if key == parent?.mask?.link { + maskValue = maskValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextRangeMaskTemplate.self) }) + } + }() _ = { if key == parent?.start?.link { startValue = startValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.startValidator) }) @@ -890,12 +949,14 @@ public final class DivTextTemplate: TemplateValue { _ = { actionsValue = actionsValue.merged(with: { parent.actions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { backgroundValue = backgroundValue.merged(with: { parent.background?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { borderValue = borderValue.merged(with: { parent.border?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { maskValue = maskValue.merged(with: { parent.mask?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { textShadowValue = textShadowValue.merged(with: { parent.textShadow?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() } let errors = mergeErrors( actionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "actions", error: $0) }, alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, backgroundValue.errorsOrWarnings?.map { .nestedObjectError(field: "background", error: $0) }, + baselineOffsetValue.errorsOrWarnings?.map { .nestedObjectError(field: "baseline_offset", error: $0) }, borderValue.errorsOrWarnings?.map { .nestedObjectError(field: "border", error: $0) }, endValue.errorsOrWarnings?.map { .nestedObjectError(field: "end", error: $0) }, fontFamilyValue.errorsOrWarnings?.map { .nestedObjectError(field: "font_family", error: $0) }, @@ -906,6 +967,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValueValue.errorsOrWarnings?.map { .nestedObjectError(field: "font_weight_value", error: $0) }, letterSpacingValue.errorsOrWarnings?.map { .nestedObjectError(field: "letter_spacing", error: $0) }, lineHeightValue.errorsOrWarnings?.map { .nestedObjectError(field: "line_height", error: $0) }, + maskValue.errorsOrWarnings?.map { .nestedObjectError(field: "mask", error: $0) }, startValue.errorsOrWarnings?.map { .nestedObjectError(field: "start", error: $0) }, strikeValue.errorsOrWarnings?.map { .nestedObjectError(field: "strike", error: $0) }, textColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "text_color", error: $0) }, @@ -917,6 +979,7 @@ public final class DivTextTemplate: TemplateValue { actions: { actionsValue.value }(), alignmentVertical: { alignmentVerticalValue.value }(), background: { backgroundValue.value }(), + baselineOffset: { baselineOffsetValue.value }(), border: { borderValue.value }(), end: { endValue.value }(), fontFamily: { fontFamilyValue.value }(), @@ -927,6 +990,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: { fontWeightValueValue.value }(), letterSpacing: { letterSpacingValue.value }(), lineHeight: { lineHeightValue.value }(), + mask: { maskValue.value }(), start: { startValue.value }(), strike: { strikeValue.value }(), textColor: { textColorValue.value }(), @@ -948,6 +1012,7 @@ public final class DivTextTemplate: TemplateValue { actions: merged.actions?.tryResolveParent(templates: templates), alignmentVertical: merged.alignmentVertical, background: merged.background?.tryResolveParent(templates: templates), + baselineOffset: merged.baselineOffset, border: merged.border?.tryResolveParent(templates: templates), end: merged.end, fontFamily: merged.fontFamily, @@ -958,6 +1023,7 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: merged.fontWeightValue, letterSpacing: merged.letterSpacing, lineHeight: merged.lineHeight, + mask: merged.mask?.tryResolveParent(templates: templates), start: merged.start, strike: merged.strike, textColor: merged.textColor, @@ -996,6 +1062,8 @@ public final class DivTextTemplate: TemplateValue { public let fontWeightValue: Field>? // constraint: number > 0 public let functions: Field<[DivFunctionTemplate]>? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) + public let hoverEndActions: Field<[DivActionTemplate]>? + public let hoverStartActions: Field<[DivActionTemplate]>? public let id: Field? public let images: Field<[ImageTemplate]>? public let layoutProvider: Field? @@ -1006,6 +1074,8 @@ public final class DivTextTemplate: TemplateValue { public let maxLines: Field>? // constraint: number >= 0 public let minHiddenLines: Field>? // constraint: number >= 0 public let paddings: Field? + public let pressEndActions: Field<[DivActionTemplate]>? + public let pressStartActions: Field<[DivActionTemplate]>? public let ranges: Field<[RangeTemplate]>? public let reuseId: Field>? public let rowSpan: Field>? // constraint: number >= 0 @@ -1062,6 +1132,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: dictionary.getOptionalExpressionField("font_weight_value"), functions: dictionary.getOptionalArray("functions", templateToType: templateToType), height: dictionary.getOptionalField("height", templateToType: templateToType), + hoverEndActions: dictionary.getOptionalArray("hover_end_actions", templateToType: templateToType), + hoverStartActions: dictionary.getOptionalArray("hover_start_actions", templateToType: templateToType), id: dictionary.getOptionalField("id"), images: dictionary.getOptionalArray("images", templateToType: templateToType), layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), @@ -1072,6 +1144,8 @@ public final class DivTextTemplate: TemplateValue { maxLines: dictionary.getOptionalExpressionField("max_lines"), minHiddenLines: dictionary.getOptionalExpressionField("min_hidden_lines"), paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), + pressEndActions: dictionary.getOptionalArray("press_end_actions", templateToType: templateToType), + pressStartActions: dictionary.getOptionalArray("press_start_actions", templateToType: templateToType), ranges: dictionary.getOptionalArray("ranges", templateToType: templateToType), reuseId: dictionary.getOptionalExpressionField("reuse_id"), rowSpan: dictionary.getOptionalExpressionField("row_span"), @@ -1129,6 +1203,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: Field>? = nil, functions: Field<[DivFunctionTemplate]>? = nil, height: Field? = nil, + hoverEndActions: Field<[DivActionTemplate]>? = nil, + hoverStartActions: Field<[DivActionTemplate]>? = nil, id: Field? = nil, images: Field<[ImageTemplate]>? = nil, layoutProvider: Field? = nil, @@ -1139,6 +1215,8 @@ public final class DivTextTemplate: TemplateValue { maxLines: Field>? = nil, minHiddenLines: Field>? = nil, paddings: Field? = nil, + pressEndActions: Field<[DivActionTemplate]>? = nil, + pressStartActions: Field<[DivActionTemplate]>? = nil, ranges: Field<[RangeTemplate]>? = nil, reuseId: Field>? = nil, rowSpan: Field>? = nil, @@ -1193,6 +1271,8 @@ public final class DivTextTemplate: TemplateValue { self.fontWeightValue = fontWeightValue self.functions = functions self.height = height + self.hoverEndActions = hoverEndActions + self.hoverStartActions = hoverStartActions self.id = id self.images = images self.layoutProvider = layoutProvider @@ -1203,6 +1283,8 @@ public final class DivTextTemplate: TemplateValue { self.maxLines = maxLines self.minHiddenLines = minHiddenLines self.paddings = paddings + self.pressEndActions = pressEndActions + self.pressStartActions = pressStartActions self.ranges = ranges self.reuseId = reuseId self.rowSpan = rowSpan @@ -1258,6 +1340,8 @@ public final class DivTextTemplate: TemplateValue { let fontWeightValueValue = { parent?.fontWeightValue?.resolveOptionalValue(context: context, validator: ResolvedValue.fontWeightValueValidator) ?? .noValue }() let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverEndActionsValue = { parent?.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let hoverStartActionsValue = { parent?.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() let imagesValue = { parent?.images?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() @@ -1268,6 +1352,8 @@ public final class DivTextTemplate: TemplateValue { let maxLinesValue = { parent?.maxLines?.resolveOptionalValue(context: context, validator: ResolvedValue.maxLinesValidator) ?? .noValue }() let minHiddenLinesValue = { parent?.minHiddenLines?.resolveOptionalValue(context: context, validator: ResolvedValue.minHiddenLinesValidator) ?? .noValue }() let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressEndActionsValue = { parent?.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let pressStartActionsValue = { parent?.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let rangesValue = { parent?.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() @@ -1321,6 +1407,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValueValue.errorsOrWarnings?.map { .nestedObjectError(field: "font_weight_value", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, imagesValue.errorsOrWarnings?.map { .nestedObjectError(field: "images", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, @@ -1331,6 +1419,8 @@ public final class DivTextTemplate: TemplateValue { maxLinesValue.errorsOrWarnings?.map { .nestedObjectError(field: "max_lines", error: $0) }, minHiddenLinesValue.errorsOrWarnings?.map { .nestedObjectError(field: "min_hidden_lines", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, rangesValue.errorsOrWarnings?.map { .nestedObjectError(field: "ranges", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, @@ -1393,6 +1483,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: { fontWeightValueValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), images: { imagesValue.value }(), layoutProvider: { layoutProviderValue.value }(), @@ -1403,6 +1495,8 @@ public final class DivTextTemplate: TemplateValue { maxLines: { maxLinesValue.value }(), minHiddenLines: { minHiddenLinesValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), ranges: { rangesValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), @@ -1463,6 +1557,8 @@ public final class DivTextTemplate: TemplateValue { var fontWeightValueValue: DeserializationResult> = { parent?.fontWeightValue?.value() ?? .noValue }() var functionsValue: DeserializationResult<[DivFunction]> = .noValue var heightValue: DeserializationResult = .noValue + var hoverEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var hoverStartActionsValue: DeserializationResult<[DivAction]> = .noValue var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() var imagesValue: DeserializationResult<[DivText.Image]> = .noValue var layoutProviderValue: DeserializationResult = .noValue @@ -1473,6 +1569,8 @@ public final class DivTextTemplate: TemplateValue { var maxLinesValue: DeserializationResult> = { parent?.maxLines?.value() ?? .noValue }() var minHiddenLinesValue: DeserializationResult> = { parent?.minHiddenLines?.value() ?? .noValue }() var paddingsValue: DeserializationResult = .noValue + var pressEndActionsValue: DeserializationResult<[DivAction]> = .noValue + var pressStartActionsValue: DeserializationResult<[DivAction]> = .noValue var rangesValue: DeserializationResult<[DivText.Range]> = .noValue var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() @@ -1634,6 +1732,16 @@ public final class DivTextTemplate: TemplateValue { heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: heightValue) } }() + _ = { + if key == "hover_end_actions" { + hoverEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverEndActionsValue) + } + }() + _ = { + if key == "hover_start_actions" { + hoverStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: hoverStartActionsValue) + } + }() _ = { if key == "id" { idValue = deserialize(__dictValue).merged(with: idValue) @@ -1684,6 +1792,16 @@ public final class DivTextTemplate: TemplateValue { paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) } }() + _ = { + if key == "press_end_actions" { + pressEndActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressEndActionsValue) + } + }() + _ = { + if key == "press_start_actions" { + pressStartActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: pressStartActionsValue) + } + }() _ = { if key == "ranges" { rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.RangeTemplate.self).merged(with: rangesValue) @@ -1944,6 +2062,16 @@ public final class DivTextTemplate: TemplateValue { heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) } }() + _ = { + if key == parent?.hoverEndActions?.link { + hoverEndActionsValue = hoverEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.hoverStartActions?.link { + hoverStartActionsValue = hoverStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.id?.link { idValue = idValue.merged(with: { deserialize(__dictValue) }) @@ -1994,6 +2122,16 @@ public final class DivTextTemplate: TemplateValue { paddingsValue = paddingsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self) }) } }() + _ = { + if key == parent?.pressEndActions?.link { + pressEndActionsValue = pressEndActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.pressStartActions?.link { + pressStartActionsValue = pressStartActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() _ = { if key == parent?.ranges?.link { rangesValue = rangesValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.RangeTemplate.self) }) @@ -2141,11 +2279,15 @@ public final class DivTextTemplate: TemplateValue { _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverEndActionsValue = hoverEndActionsValue.merged(with: { parent.hoverEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { hoverStartActionsValue = hoverStartActionsValue.merged(with: { parent.hoverStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { imagesValue = imagesValue.merged(with: { parent.images?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { longtapActionsValue = longtapActionsValue.merged(with: { parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressEndActionsValue = pressEndActionsValue.merged(with: { parent.pressEndActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { pressStartActionsValue = pressStartActionsValue.merged(with: { parent.pressStartActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { rangesValue = rangesValue.merged(with: { parent.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() _ = { textGradientValue = textGradientValue.merged(with: { parent.textGradient?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() @@ -2188,6 +2330,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValueValue.errorsOrWarnings?.map { .nestedObjectError(field: "font_weight_value", error: $0) }, functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + hoverEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_end_actions", error: $0) }, + hoverStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "hover_start_actions", error: $0) }, idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, imagesValue.errorsOrWarnings?.map { .nestedObjectError(field: "images", error: $0) }, layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, @@ -2198,6 +2342,8 @@ public final class DivTextTemplate: TemplateValue { maxLinesValue.errorsOrWarnings?.map { .nestedObjectError(field: "max_lines", error: $0) }, minHiddenLinesValue.errorsOrWarnings?.map { .nestedObjectError(field: "min_hidden_lines", error: $0) }, paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + pressEndActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_end_actions", error: $0) }, + pressStartActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "press_start_actions", error: $0) }, rangesValue.errorsOrWarnings?.map { .nestedObjectError(field: "ranges", error: $0) }, reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, @@ -2260,6 +2406,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: { fontWeightValueValue.value }(), functions: { functionsValue.value }(), height: { heightValue.value }(), + hoverEndActions: { hoverEndActionsValue.value }(), + hoverStartActions: { hoverStartActionsValue.value }(), id: { idValue.value }(), images: { imagesValue.value }(), layoutProvider: { layoutProviderValue.value }(), @@ -2270,6 +2418,8 @@ public final class DivTextTemplate: TemplateValue { maxLines: { maxLinesValue.value }(), minHiddenLines: { minHiddenLinesValue.value }(), paddings: { paddingsValue.value }(), + pressEndActions: { pressEndActionsValue.value }(), + pressStartActions: { pressStartActionsValue.value }(), ranges: { rangesValue.value }(), reuseId: { reuseIdValue.value }(), rowSpan: { rowSpanValue.value }(), @@ -2335,6 +2485,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: fontWeightValue ?? mergedParent.fontWeightValue, functions: functions ?? mergedParent.functions, height: height ?? mergedParent.height, + hoverEndActions: hoverEndActions ?? mergedParent.hoverEndActions, + hoverStartActions: hoverStartActions ?? mergedParent.hoverStartActions, id: id ?? mergedParent.id, images: images ?? mergedParent.images, layoutProvider: layoutProvider ?? mergedParent.layoutProvider, @@ -2345,6 +2497,8 @@ public final class DivTextTemplate: TemplateValue { maxLines: maxLines ?? mergedParent.maxLines, minHiddenLines: minHiddenLines ?? mergedParent.minHiddenLines, paddings: paddings ?? mergedParent.paddings, + pressEndActions: pressEndActions ?? mergedParent.pressEndActions, + pressStartActions: pressStartActions ?? mergedParent.pressStartActions, ranges: ranges ?? mergedParent.ranges, reuseId: reuseId ?? mergedParent.reuseId, rowSpan: rowSpan ?? mergedParent.rowSpan, @@ -2405,6 +2559,8 @@ public final class DivTextTemplate: TemplateValue { fontWeightValue: merged.fontWeightValue, functions: merged.functions?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), + hoverEndActions: merged.hoverEndActions?.tryResolveParent(templates: templates), + hoverStartActions: merged.hoverStartActions?.tryResolveParent(templates: templates), id: merged.id, images: merged.images?.tryResolveParent(templates: templates), layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), @@ -2415,6 +2571,8 @@ public final class DivTextTemplate: TemplateValue { maxLines: merged.maxLines, minHiddenLines: merged.minHiddenLines, paddings: merged.paddings?.tryResolveParent(templates: templates), + pressEndActions: merged.pressEndActions?.tryResolveParent(templates: templates), + pressStartActions: merged.pressStartActions?.tryResolveParent(templates: templates), ranges: merged.ranges?.tryResolveParent(templates: templates), reuseId: merged.reuseId, rowSpan: merged.rowSpan, diff --git a/DivKitExtensions/Animations/AnimatableView.swift b/DivKitExtensions/Animations/AnimatableView.swift index d1ea3a9c..e5f76287 100644 --- a/DivKitExtensions/Animations/AnimatableView.swift +++ b/DivKitExtensions/Animations/AnimatableView.swift @@ -1,18 +1,42 @@ import Foundation - import LayoutKit import VGSL -public protocol AnimatableViewFactory: AnyObject { + +public protocol AsyncSourceAnimatableViewFactory: AnyObject { + func createAsyncSourceAnimatableView(withMode mode: AnimationRepeatMode, repeatCount count: Float) + -> AsyncSourceAnimatableView +} + +/// This protocol is deprecated. Use AsyncSourceAnimatableViewFactory instead. +public protocol AnimatableViewFactory: AnyObject, AsyncSourceAnimatableViewFactory { func createAnimatableView(withMode mode: AnimationRepeatMode, repeatCount count: Float) -> AnimatableView } -public protocol AnimatableView: ViewType { +extension AnimatableViewFactory { + public func createAsyncSourceAnimatableView(withMode mode: AnimationRepeatMode, repeatCount count: Float) + -> AsyncSourceAnimatableView { + createAnimatableView(withMode: mode, repeatCount: count) + } +} + +public protocol AsyncSourceAnimatableView: ViewType { func play() + @MainActor func setSourceAsync(_ source: AnimationSourceType) async +} + +/// This protocol is deprecated. Use AsyncSourceAnimatableView instead. +public protocol AnimatableView: AsyncSourceAnimatableView { func setSource(_ source: AnimationSourceType) } +extension AnimatableView { + @MainActor public func setSourceAsync(_ source: AnimationSourceType) async { + setSource(source) + } +} + @frozen public enum AnimationRepeatMode { case restart diff --git a/DivKitExtensions/Animations/AnimationBlockView+UIViewRenderableBlock.swift b/DivKitExtensions/Animations/AnimationBlockView+UIViewRenderableBlock.swift index 52df7173..168eefee 100644 --- a/DivKitExtensions/Animations/AnimationBlockView+UIViewRenderableBlock.swift +++ b/DivKitExtensions/Animations/AnimationBlockView+UIViewRenderableBlock.swift @@ -1,8 +1,7 @@ import AVFoundation -import UIKit - import DivKit import LayoutKit +import UIKit import VGSL extension LottieAnimationBlock { diff --git a/DivKitExtensions/Animations/AnimationBlockView.swift b/DivKitExtensions/Animations/AnimationBlockView.swift index 05d413f8..4671fa3c 100644 --- a/DivKitExtensions/Animations/AnimationBlockView.swift +++ b/DivKitExtensions/Animations/AnimationBlockView.swift @@ -1,10 +1,9 @@ -import UIKit - import LayoutKit +import UIKit import VGSL final class AnimationBlockView: BlockView { - var animatableView: AnimatableView? { + var animatableView: AsyncSourceAnimatableView? { didSet { if let animatablView = animatableView { oldValue?.removeFrom(self) @@ -29,13 +28,16 @@ final class AnimationBlockView: BlockView { .requestAnimationWithCompletion { [weak self] animationSource in guard let self, newValue === self.animationHolder, - let animationSource else { + let animationSource, + let view = self.animatableView else { return } - self.animatableView?.contentMode = animationContentMode - self.animatableView?.setSource(animationSource) - self.animatableView?.play() + view.contentMode = animationContentMode + Task { @MainActor in + await view.setSourceAsync(animationSource) + view.play() + } } } } diff --git a/DivKitExtensions/Animations/AnimationHolder.swift b/DivKitExtensions/Animations/AnimationHolder.swift index e2f63450..56eb1f7e 100644 --- a/DivKitExtensions/Animations/AnimationHolder.swift +++ b/DivKitExtensions/Animations/AnimationHolder.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKitExtensions/Animations/Lottie/LottieAnimationBlock.swift b/DivKitExtensions/Animations/Lottie/LottieAnimationBlock.swift index e3302e1d..f456c2e4 100644 --- a/DivKitExtensions/Animations/Lottie/LottieAnimationBlock.swift +++ b/DivKitExtensions/Animations/Lottie/LottieAnimationBlock.swift @@ -1,12 +1,11 @@ import CoreGraphics -import Foundation - import DivKit +import Foundation import LayoutKit import VGSL final class LottieAnimationBlock: SizeForwardingBlock { - let animatableView: Lazy + let animatableView: Lazy let animationHolder: AnimationHolder let sizeProvider: Block let scale: DivImageScale @@ -16,7 +15,7 @@ final class LottieAnimationBlock: SizeForwardingBlock { } init( - animatableView: Lazy, + animatableView: Lazy, animationHolder: AnimationHolder, sizeProvider: Block, scale: DivImageScale diff --git a/DivKitExtensions/Animations/Lottie/LottieExtensionHandler.swift b/DivKitExtensions/Animations/Lottie/LottieExtensionHandler.swift index df2a8072..6ff490e5 100644 --- a/DivKitExtensions/Animations/Lottie/LottieExtensionHandler.swift +++ b/DivKitExtensions/Animations/Lottie/LottieExtensionHandler.swift @@ -7,12 +7,12 @@ import VGSL public final class LottieExtensionHandler: DivExtensionHandler { public let id = "lottie" - private let factory: AnimatableViewFactory + private let factory: AsyncSourceAnimatableViewFactory private let requester: URLResourceRequesting private let localAnimationDataProvider: ((URL) -> Data?)? public init( - factory: AnimatableViewFactory, + factory: AsyncSourceAnimatableViewFactory, requester: URLResourceRequesting, localAnimationDataProvider: ((URL) -> Data?)? = nil ) { @@ -49,7 +49,7 @@ public final class LottieExtensionHandler: DivExtensionHandler { return LottieAnimationBlock( animatableView: Lazy( getter: { - self.factory.createAnimatableView( + self.factory.createAsyncSourceAnimatableView( withMode: params.repeatMode, repeatCount: params.repeatCount ) diff --git a/DivKitExtensions/Animations/RemoteAnimationHolder.swift b/DivKitExtensions/Animations/RemoteAnimationHolder.swift index a2ae0974..72ae6fa7 100644 --- a/DivKitExtensions/Animations/RemoteAnimationHolder.swift +++ b/DivKitExtensions/Animations/RemoteAnimationHolder.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public final class RemoteAnimationHolder: AnimationHolder { diff --git a/DivKitExtensions/Animations/Rive/RiveAnimationBlock+UIViewRenderableBlock.swift b/DivKitExtensions/Animations/Rive/RiveAnimationBlock+UIViewRenderableBlock.swift index 73428193..55c11478 100644 --- a/DivKitExtensions/Animations/Rive/RiveAnimationBlock+UIViewRenderableBlock.swift +++ b/DivKitExtensions/Animations/Rive/RiveAnimationBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import Foundation - import LayoutKit import VGSL diff --git a/DivKitExtensions/Animations/Rive/RiveAnimationBlock.swift b/DivKitExtensions/Animations/Rive/RiveAnimationBlock.swift index 72369cbc..6249c47f 100644 --- a/DivKitExtensions/Animations/Rive/RiveAnimationBlock.swift +++ b/DivKitExtensions/Animations/Rive/RiveAnimationBlock.swift @@ -1,11 +1,10 @@ import Foundation - import LayoutKit import VGSL public final class RiveAnimationBlock: BlockWithTraits { let animationHolder: AnimationHolder - let animatableView: Lazy + let animatableView: Lazy public let widthTrait: LayoutTrait public let heightTrait: LayoutTrait @@ -15,7 +14,7 @@ public final class RiveAnimationBlock: BlockWithTraits { public init( animationHolder: AnimationHolder, - animatableView: Lazy, + animatableView: Lazy, widthTrait: LayoutTrait, heightTrait: LayoutTrait ) { diff --git a/DivKitExtensions/DivBackgroundExtensions.swift b/DivKitExtensions/DivBackgroundExtensions.swift index 54ededc2..dd2c82e9 100644 --- a/DivKitExtensions/DivBackgroundExtensions.swift +++ b/DivKitExtensions/DivBackgroundExtensions.swift @@ -1,6 +1,5 @@ -import Foundation - import DivKit +import Foundation extension DivBackground { func resolveImageURL(_ expressionResolver: ExpressionResolver) -> URL? { diff --git a/DivKitExtensions/DivExtensions.swift b/DivKitExtensions/DivExtensions.swift index f5814fdb..65f58679 100644 --- a/DivKitExtensions/DivExtensions.swift +++ b/DivKitExtensions/DivExtensions.swift @@ -1,6 +1,5 @@ -import Foundation - import DivKit +import Foundation extension Div { public func makeImageURLs(with expressionResolver: ExpressionResolver) -> [URL] { diff --git a/DivKitExtensions/ExtensionHandlers/BlurExtensionHandler.swift b/DivKitExtensions/ExtensionHandlers/BlurExtensionHandler.swift index 6b33d81a..4a50cc75 100644 --- a/DivKitExtensions/ExtensionHandlers/BlurExtensionHandler.swift +++ b/DivKitExtensions/ExtensionHandlers/BlurExtensionHandler.swift @@ -1,6 +1,5 @@ -import Foundation - import DivKit +import Foundation import LayoutKit public final class BlurExtensionHandler: DivExtensionHandler { diff --git a/DivKitExtensions/ExtensionHandlers/CustomImagePreviewExtensionHandler.swift b/DivKitExtensions/ExtensionHandlers/CustomImagePreviewExtensionHandler.swift index 6667fdf5..e367a937 100644 --- a/DivKitExtensions/ExtensionHandlers/CustomImagePreviewExtensionHandler.swift +++ b/DivKitExtensions/ExtensionHandlers/CustomImagePreviewExtensionHandler.swift @@ -1,6 +1,5 @@ -import Foundation - import DivKit +import Foundation import LayoutKit import VGSL diff --git a/DivKitExtensions/ExtensionHandlers/ImageThemeExtensionHandler.swift b/DivKitExtensions/ExtensionHandlers/ImageThemeExtensionHandler.swift index 1298b647..c41086bd 100644 --- a/DivKitExtensions/ExtensionHandlers/ImageThemeExtensionHandler.swift +++ b/DivKitExtensions/ExtensionHandlers/ImageThemeExtensionHandler.swift @@ -1,6 +1,5 @@ -import Foundation - import DivKit +import Foundation import LayoutKit import VGSL diff --git a/DivKitExtensions/ExtensionHandlers/InputAccessoryViewExtensionHandler.swift b/DivKitExtensions/ExtensionHandlers/InputAccessoryViewExtensionHandler.swift index 78cf6467..7a7599fd 100644 --- a/DivKitExtensions/ExtensionHandlers/InputAccessoryViewExtensionHandler.swift +++ b/DivKitExtensions/ExtensionHandlers/InputAccessoryViewExtensionHandler.swift @@ -1,7 +1,6 @@ -import UIKit - import DivKit import LayoutKit +import UIKit import VGSL public protocol InputAccessoryViewProvider { diff --git a/DivKitExtensions/ExtensionHandlers/PinchToZoomExtensionHandler.swift b/DivKitExtensions/ExtensionHandlers/PinchToZoomExtensionHandler.swift index b963f319..b1567855 100644 --- a/DivKitExtensions/ExtensionHandlers/PinchToZoomExtensionHandler.swift +++ b/DivKitExtensions/ExtensionHandlers/PinchToZoomExtensionHandler.swift @@ -1,7 +1,6 @@ -import UIKit - import DivKit import LayoutKit +import UIKit public final class PinchToZoomExtensionHandler: DivExtensionHandler { private weak var overlayView: UIView? diff --git a/DivKitExtensions/ExtensionHandlers/VideoDurationExtensionHandler.swift b/DivKitExtensions/ExtensionHandlers/VideoDurationExtensionHandler.swift index b0c2d05a..ad27fd6e 100644 --- a/DivKitExtensions/ExtensionHandlers/VideoDurationExtensionHandler.swift +++ b/DivKitExtensions/ExtensionHandlers/VideoDurationExtensionHandler.swift @@ -1,6 +1,5 @@ -import Foundation - import DivKit +import Foundation import LayoutKit import VGSL diff --git a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewExtension.swift b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewExtension.swift index 30a191cd..7d21515f 100644 --- a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewExtension.swift +++ b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewExtension.swift @@ -1,7 +1,6 @@ -import UIKit - import DivKit import LayoutKit +import UIKit import VGSL public final class ShimmerImagePreviewExtension: DivExtensionHandler { diff --git a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewStyle.swift b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewStyle.swift index 0dc7d94c..32b1f658 100644 --- a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewStyle.swift +++ b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewStyle.swift @@ -1,21 +1,24 @@ import UIKit - import DivKit +import LayoutKit import VGSL public struct ShimmerImagePreviewStyle: Equatable { public let colorsAndLocations: [ColorAndLocation] public let angle: CGFloat public let duration: CGFloat + public let cornerRadius: CornerRadii? public init( colorsAndLocations: [ColorAndLocation], angle: CGFloat, - duration: CGFloat + duration: CGFloat, + cornerRadius: CornerRadii? = nil ) { self.colorsAndLocations = colorsAndLocations self.angle = angle self.duration = duration + self.cornerRadius = cornerRadius } } @@ -44,6 +47,11 @@ extension ShimmerImagePreviewStyle { locationsKey: "locations", expressionResolver: expressionResolver ) ?? defaultColorsAndLocations + + self.cornerRadius = try dictionary.getOptionalCornerRadius( + "corner_radius", + expressionResolver: expressionResolver + ) } } diff --git a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewView.swift b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewView.swift index 4d7c3ebc..eb6a4fb4 100644 --- a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewView.swift +++ b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewView.swift @@ -1,4 +1,5 @@ import UIKit +import VGSLFundamentals final class ShimmerImagePreviewView: UIView { private static let animationKey = "ShimmerEffect" @@ -31,6 +32,24 @@ final class ShimmerImagePreviewView: UIView { override func layoutSubviews() { super.layoutSubviews() + if let cornerRadius = style.cornerRadius { + if let unifiedRadius = cornerRadius.unifiedRadius { + let radius = clamp( + unifiedRadius, + min: 0, + max: bounds.size.minDimension.half + ) + + layer.cornerRadius = radius + layer.masksToBounds = true + } else { + let maskLayer = CAShapeLayer() + maskLayer.path = .roundedRect(size: bounds.size, cornerRadii: cornerRadius) + layer.mask = maskLayer + layer.maskedCorners = .allCorners + } + } + gradientLayer.frame = ShimmerGradientGeometry.frameScaledToAspectFill(for: bounds) animation.apply(style: style) gradientLayer.apply(style: style) diff --git a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewViewProvider.swift b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewViewProvider.swift index 68836590..19c4377d 100644 --- a/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewViewProvider.swift +++ b/DivKitExtensions/Shimmers/Shimmer/ShimmerImagePreviewViewProvider.swift @@ -1,7 +1,6 @@ import Foundation -import UIKit - import LayoutKit +import UIKit import VGSL public final class ShimmerImagePreviewViewProvider: ViewProvider { diff --git a/DivKitExtensions/Shimmers/ShimmerStyle+Serialization.swift b/DivKitExtensions/Shimmers/ShimmerStyle+Serialization.swift index 7cc2eb21..2d557648 100644 --- a/DivKitExtensions/Shimmers/ShimmerStyle+Serialization.swift +++ b/DivKitExtensions/Shimmers/ShimmerStyle+Serialization.swift @@ -1,6 +1,6 @@ import Foundation - import DivKit +import LayoutKit import VGSL public struct ColorAndLocation: Equatable { @@ -120,6 +120,53 @@ extension Dictionary where Key == String { } return zip(colors, locations).map(ColorAndLocation.init) } + + func getOptionalCornerRadius( + _ key: Key, + expressionResolver: ExpressionResolver + ) throws -> CornerRadii? { + return try? getOptionalField(key) { (obj: Any) in + if let corners = obj as? [String: Any] { + let topLeft: Int? = try? getOptionalIntFromDict( + dict: corners, "top-left", + resolver: expressionResolver + ) + let topRight: Int? = try? getOptionalIntFromDict( + dict: corners, "top-right", + resolver: expressionResolver + ) + let bottomLeft: Int? = try? getOptionalIntFromDict( + dict: corners, "bottom-left", + resolver: expressionResolver + ) + let bottomRight: Int? = try? getOptionalIntFromDict( + dict: corners, "bottom-right", + resolver: expressionResolver + ) + + return CornerRadii( + topLeft: CGFloat(topLeft ?? 0), + topRight: CGFloat(topRight ?? 0), + bottomLeft: CGFloat(bottomLeft ?? 0), + bottomRight: CGFloat(bottomRight ?? 0) + ) + } + return nil + } + } + + private func getOptionalIntFromDict( + dict: [String: Any], + _ key: Key, + resolver: ExpressionResolver + ) throws -> Int? { + if let value = dict[key] as? Int { + return value + } else if let expression: String = try dict.getOptionalField(key) { + return resolver.resolveNumeric(expression) + } + return nil + } } private enum ShimmerSerializationError: Error { diff --git a/DivKitExtensions/Shimmers/Shine/ShineBlock+UIViewRenderableBlock.swift b/DivKitExtensions/Shimmers/Shine/ShineBlock+UIViewRenderableBlock.swift index fd994ef9..8fe37f6f 100644 --- a/DivKitExtensions/Shimmers/Shine/ShineBlock+UIViewRenderableBlock.swift +++ b/DivKitExtensions/Shimmers/Shine/ShineBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ -import UIKit - import LayoutKit +import UIKit import VGSL extension ShineBlock { diff --git a/DivKitExtensions/Shimmers/Shine/ShineBlock.swift b/DivKitExtensions/Shimmers/Shine/ShineBlock.swift index 6b413bba..406de452 100644 --- a/DivKitExtensions/Shimmers/Shine/ShineBlock.swift +++ b/DivKitExtensions/Shimmers/Shine/ShineBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import LayoutKit import VGSL @@ -42,7 +41,7 @@ final class ShineBlock: WrapperBlock, LayoutCachingDefaultImpl { extension ShineBlock: Equatable { static func ==(lhs: ShineBlock, rhs: ShineBlock) -> Bool { - lhs.child == rhs.child && + lhs.child == rhs.child && lhs.params == rhs.params && compare(lhs.maskImageHolder, rhs.maskImageHolder) } diff --git a/DivKitExtensions/Shimmers/Shine/ShineExtensionHandler.swift b/DivKitExtensions/Shimmers/Shine/ShineExtensionHandler.swift index 5c983159..2f4e8569 100644 --- a/DivKitExtensions/Shimmers/Shine/ShineExtensionHandler.swift +++ b/DivKitExtensions/Shimmers/Shine/ShineExtensionHandler.swift @@ -1,7 +1,6 @@ -import UIKit - import DivKit import LayoutKit +import UIKit public final class ShineExtensionHandler: DivExtensionHandler { public let id: String = extensionID diff --git a/DivKitExtensions/Shimmers/Shine/ShineExtensionParams.swift b/DivKitExtensions/Shimmers/Shine/ShineExtensionParams.swift index ac10dbe0..fc681cad 100644 --- a/DivKitExtensions/Shimmers/Shine/ShineExtensionParams.swift +++ b/DivKitExtensions/Shimmers/Shine/ShineExtensionParams.swift @@ -1,7 +1,6 @@ -import UIKit - -import LayoutKitInterface import DivKit +import LayoutKitInterface +import UIKit import VGSL struct ShineExtensionParams: Equatable { diff --git a/DivKitExtensions/Shimmers/Shine/ShineView.swift b/DivKitExtensions/Shimmers/Shine/ShineView.swift index 1f5e6313..b1c4ebe3 100644 --- a/DivKitExtensions/Shimmers/Shine/ShineView.swift +++ b/DivKitExtensions/Shimmers/Shine/ShineView.swift @@ -1,6 +1,5 @@ -import UIKit - import LayoutKit +import UIKit import VGSL final class ShineView: UIView { @@ -35,7 +34,7 @@ final class ShineView: UIView { childView.frame = bounds maskLayer.frame = bounds gradientLayer.frame = - ShimmerGradientGeometry.frameScaledToAspectFill(for: bounds) + ShimmerGradientGeometry.frameScaledToAspectFill(for: bounds) } override func didMoveToWindow() { diff --git a/LayoutKit/Interface/UIElementPath.swift b/LayoutKit/Interface/UIElementPath.swift index 95fca83e..39c6db0c 100644 --- a/LayoutKit/Interface/UIElementPath.swift +++ b/LayoutKit/Interface/UIElementPath.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct UIElementPath: CustomStringConvertible, ExpressibleByStringLiteral, Codable { diff --git a/LayoutKit/Interface/UserInterfaceAction.swift b/LayoutKit/Interface/UserInterfaceAction.swift index 0565091f..bf23c236 100644 --- a/LayoutKit/Interface/UserInterfaceAction.swift +++ b/LayoutKit/Interface/UserInterfaceAction.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct UserInterfaceAction: Equatable, Codable { diff --git a/LayoutKit/LayoutKit/Base/UILink.swift b/LayoutKit/LayoutKit/Base/UILink.swift index f7c07c2e..a01c608b 100644 --- a/LayoutKit/LayoutKit/Base/UILink.swift +++ b/LayoutKit/LayoutKit/Base/UILink.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct UILink: Equatable { diff --git a/LayoutKit/LayoutKit/Base/UIViewExtensions.swift b/LayoutKit/LayoutKit/Base/UIViewExtensions.swift index 9c68ac93..77746168 100644 --- a/LayoutKit/LayoutKit/Base/UIViewExtensions.swift +++ b/LayoutKit/LayoutKit/Base/UIViewExtensions.swift @@ -1,5 +1,5 @@ - import UIKit +import VGSL extension UIView { /// Unlinks the view from a given view if it is a superview of the view @@ -11,3 +11,15 @@ extension UIView { } } } + +extension UIView { + func applyAccessibilityFromScratch(_ element: AccessibilityElement?) { + isAccessibilityElement = false + accessibilityLabel = nil + accessibilityTraits = UIAccessibilityTraits() + accessibilityValue = nil + accessibilityHint = nil + + applyAccessibility(element) + } +} diff --git a/LayoutKit/LayoutKit/Binding.swift b/LayoutKit/LayoutKit/Binding.swift index 97f293b0..f7d39982 100644 --- a/LayoutKit/LayoutKit/Binding.swift +++ b/LayoutKit/LayoutKit/Binding.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct Binding: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/ActionLimiter.swift b/LayoutKit/LayoutKit/Blocks/ActionLimiter.swift index 5a9c507c..dcb6a012 100644 --- a/LayoutKit/LayoutKit/Blocks/ActionLimiter.swift +++ b/LayoutKit/LayoutKit/Blocks/ActionLimiter.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct ActionLimiter { diff --git a/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock+UIViewRenderable.swift b/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock+UIViewRenderable.swift index cc9851fc..89bfd44b 100644 --- a/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock+UIViewRenderable.swift +++ b/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock+UIViewRenderable.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension AnchorBlock { diff --git a/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock.swift b/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock.swift index 7770a016..894f28f4 100644 --- a/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class AnchorBlock: BlockWithLayout, BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlockLayout.swift b/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlockLayout.swift index c7747d9e..c965287f 100644 --- a/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlockLayout.swift +++ b/LayoutKit/LayoutKit/Blocks/Anchor/AnchorBlockLayout.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension AnchorBlock.Layout { diff --git a/LayoutKit/LayoutKit/Blocks/AnimatableImageBlock.swift b/LayoutKit/LayoutKit/Blocks/AnimatableImageBlock.swift index 5b4b8d82..39094580 100644 --- a/LayoutKit/LayoutKit/Blocks/AnimatableImageBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/AnimatableImageBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class AnimatableImageBlock: ImageBaseBlock { diff --git a/LayoutKit/LayoutKit/Blocks/BackgroundBlock.swift b/LayoutKit/LayoutKit/Blocks/BackgroundBlock.swift index c990a046..4851c66f 100644 --- a/LayoutKit/LayoutKit/Blocks/BackgroundBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/BackgroundBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class BackgroundBlock: BlockWithLayout, WrapperBlock { diff --git a/LayoutKit/LayoutKit/Blocks/Block+Accessibility.swift b/LayoutKit/LayoutKit/Blocks/Block+Accessibility.swift index 675e8d7d..106c02cf 100644 --- a/LayoutKit/LayoutKit/Blocks/Block+Accessibility.swift +++ b/LayoutKit/LayoutKit/Blocks/Block+Accessibility.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL extension Block { diff --git a/LayoutKit/LayoutKit/Blocks/Block+Debugging.swift b/LayoutKit/LayoutKit/Blocks/Block+Debugging.swift index a6839692..9d17220c 100644 --- a/LayoutKit/LayoutKit/Blocks/Block+Debugging.swift +++ b/LayoutKit/LayoutKit/Blocks/Block+Debugging.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL extension ContainerBlock.LayoutDirection: CustomDebugStringConvertible { diff --git a/LayoutKit/LayoutKit/Blocks/Block.swift b/LayoutKit/LayoutKit/Blocks/Block.swift index 33aa20b1..9d6639c3 100644 --- a/LayoutKit/LayoutKit/Blocks/Block.swift +++ b/LayoutKit/LayoutKit/Blocks/Block.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL #if os(iOS) diff --git a/LayoutKit/LayoutKit/Blocks/BlockAlignment2D.swift b/LayoutKit/LayoutKit/Blocks/BlockAlignment2D.swift index c71ec7d4..f8a71025 100644 --- a/LayoutKit/LayoutKit/Blocks/BlockAlignment2D.swift +++ b/LayoutKit/LayoutKit/Blocks/BlockAlignment2D.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct BlockAlignment2D: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/BlockBorder.swift b/LayoutKit/LayoutKit/Blocks/BlockBorder.swift index 14c30d24..ccc7f441 100644 --- a/LayoutKit/LayoutKit/Blocks/BlockBorder.swift +++ b/LayoutKit/LayoutKit/Blocks/BlockBorder.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public struct BlockBorder: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/BlockTooltip+Layout.swift b/LayoutKit/LayoutKit/Blocks/BlockTooltip+Layout.swift index d4087f83..531db821 100644 --- a/LayoutKit/LayoutKit/Blocks/BlockTooltip+Layout.swift +++ b/LayoutKit/LayoutKit/Blocks/BlockTooltip+Layout.swift @@ -1,13 +1,15 @@ import CoreGraphics - import VGSL extension BlockTooltip { public func calculateFrame( targeting targetRect: CGRect, - constrainedBy bounds: CGRect + constrainedBy bounds: CGRect, + useLegacyWidth: Bool = true ) -> CGRect { - let size = block.intrinsicSize + let size = useLegacyWidth + ? block.intrinsicSize + : block.size(forResizableBlockSize: bounds.size) var result = CGRect( coordinate: targetRect.coordinate(of: position), ofPosition: position.opposite, @@ -16,10 +18,10 @@ extension BlockTooltip { if result.intersection(bounds) == result { return result - } else { - result.move(to: bounds) - return result } + + result.move(to: bounds) + return result } } diff --git a/LayoutKit/LayoutKit/Blocks/BlockTooltip.swift b/LayoutKit/LayoutKit/Blocks/BlockTooltip.swift index bdaa49a3..514e38a9 100644 --- a/LayoutKit/LayoutKit/Blocks/BlockTooltip.swift +++ b/LayoutKit/LayoutKit/Blocks/BlockTooltip.swift @@ -2,9 +2,9 @@ import CoreGraphics import VGSL #if os(iOS) -public typealias TooltipViewFactory = Variable +public typealias TooltipViewFactory = () async -> VisibleBoundsTrackingView? #else -public typealias TooltipViewFactory = Variable +public typealias TooltipViewFactory = () async -> ViewType? #endif public struct BlockTooltip: Equatable { @@ -25,6 +25,7 @@ public struct BlockTooltip: Equatable { public let duration: Duration public let offset: CGPoint public let position: Position + public let useLegacyWidth: Bool public let tooltipViewFactory: TooltipViewFactory? public init( @@ -33,6 +34,7 @@ public struct BlockTooltip: Equatable { duration: Duration, offset: CGPoint, position: BlockTooltip.Position, + useLegacyWidth: Bool = true, tooltipViewFactory: TooltipViewFactory? = nil ) { self.id = id @@ -40,6 +42,7 @@ public struct BlockTooltip: Equatable { self.duration = duration self.offset = offset self.position = position + self.useLegacyWidth = useLegacyWidth self.tooltipViewFactory = tooltipViewFactory } @@ -48,6 +51,7 @@ public struct BlockTooltip: Equatable { lhs.duration == rhs.duration && lhs.offset == rhs.offset && lhs.position == rhs.position && + lhs.useLegacyWidth == rhs.useLegacyWidth && lhs.block.equals(rhs.block) } } diff --git a/LayoutKit/LayoutKit/Blocks/BlockWithLayout.swift b/LayoutKit/LayoutKit/Blocks/BlockWithLayout.swift index 96314af6..1d2597bf 100644 --- a/LayoutKit/LayoutKit/Blocks/BlockWithLayout.swift +++ b/LayoutKit/LayoutKit/Blocks/BlockWithLayout.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL #if os(iOS) diff --git a/LayoutKit/LayoutKit/Blocks/BlocksStateExtensions.swift b/LayoutKit/LayoutKit/Blocks/BlocksStateExtensions.swift index ce5ac75d..940c91c8 100644 --- a/LayoutKit/LayoutKit/Blocks/BlocksStateExtensions.swift +++ b/LayoutKit/LayoutKit/Blocks/BlocksStateExtensions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct PagerPath: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/BoundaryTrait.swift b/LayoutKit/LayoutKit/Blocks/BoundaryTrait.swift index d4e97ed6..fe049f13 100644 --- a/LayoutKit/LayoutKit/Blocks/BoundaryTrait.swift +++ b/LayoutKit/LayoutKit/Blocks/BoundaryTrait.swift @@ -1,6 +1,5 @@ import CoreGraphics import QuartzCore - import VGSL public enum BoundaryTrait: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/BoundaryTraitExtensions.swift b/LayoutKit/LayoutKit/Blocks/BoundaryTraitExtensions.swift index bf0c242b..ef90ef0d 100644 --- a/LayoutKit/LayoutKit/Blocks/BoundaryTraitExtensions.swift +++ b/LayoutKit/LayoutKit/Blocks/BoundaryTraitExtensions.swift @@ -1,5 +1,4 @@ import QuartzCore - import VGSL typealias BoundaryInfo = (radius: CGFloat, corners: CACornerMask, layer: CALayer?) diff --git a/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift b/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift index c21b6507..c7f58a58 100644 --- a/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Container/ContainerBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL #if canImport(UIKit) diff --git a/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockExtensions.swift b/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockExtensions.swift index 35480797..e12488ac 100644 --- a/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockExtensions.swift +++ b/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension ContainerBlock { diff --git a/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockLayout.swift b/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockLayout.swift index 7a372636..90d6688f 100644 --- a/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockLayout.swift +++ b/LayoutKit/LayoutKit/Blocks/Container/ContainerBlockLayout.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL struct ContainerBlockLayout { diff --git a/LayoutKit/LayoutKit/Blocks/Container/WrapLayoutGroups.swift b/LayoutKit/LayoutKit/Blocks/Container/WrapLayoutGroups.swift index 11f12533..ca00f419 100644 --- a/LayoutKit/LayoutKit/Blocks/Container/WrapLayoutGroups.swift +++ b/LayoutKit/LayoutKit/Blocks/Container/WrapLayoutGroups.swift @@ -44,8 +44,8 @@ struct WrapLayoutGroups { private mutating func makeGroups() { addStartLineSeparator() - children.forEach { child in - guard !child.isResizable(for: layoutDirection.opposite) else { return } + for child in children { + guard !child.isResizable(for: layoutDirection.opposite) else { continue } if child.isResizable(for: layoutDirection) { startNewLine() var childSize = child.content.size(forResizableBlockSize: size) @@ -70,7 +70,7 @@ struct WrapLayoutGroups { size[keyPath: keyPath] : .infinity ) if childSize.isEmpty { - return + continue } if offset + childSize[keyPath: keyPath] + separatorOffset > size[keyPath: keyPath] { startNewLine() diff --git a/LayoutKit/LayoutKit/Blocks/CornerRadiiExtensions.swift b/LayoutKit/LayoutKit/Blocks/CornerRadiiExtensions.swift index 3ba06107..ba853af1 100644 --- a/LayoutKit/LayoutKit/Blocks/CornerRadiiExtensions.swift +++ b/LayoutKit/LayoutKit/Blocks/CornerRadiiExtensions.swift @@ -2,7 +2,7 @@ import CoreGraphics import QuartzCore extension CornerRadii { - var unifiedRadius: CGFloat? { + public var unifiedRadius: CGFloat? { let differentRadiuses = [ topLeft, topRight, @@ -16,7 +16,7 @@ extension CornerRadii { } } - var maskedCorners: CACornerMask { + public var maskedCorners: CACornerMask { CACornerMask() .union(topLeft != 0 ? .layerMinXMinYCorner : []) .union(topRight != 0 ? .layerMaxXMinYCorner : []) diff --git a/LayoutKit/LayoutKit/Blocks/DebugInfoBlock.swift b/LayoutKit/LayoutKit/Blocks/DebugInfoBlock.swift index 3694a88c..f92fcc2d 100644 --- a/LayoutKit/LayoutKit/Blocks/DebugInfoBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/DebugInfoBlock.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public final class DebugInfoBlock: WrapperBlock, LayoutCachingDefaultImpl { diff --git a/LayoutKit/LayoutKit/Blocks/Decorations/Block+Decorations.swift b/LayoutKit/LayoutKit/Blocks/Decorations/Block+Decorations.swift index d4bee4c6..7c7bab5a 100644 --- a/LayoutKit/LayoutKit/Blocks/Decorations/Block+Decorations.swift +++ b/LayoutKit/LayoutKit/Blocks/Decorations/Block+Decorations.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL extension Block { @@ -28,7 +27,8 @@ extension Block { tooltips: [BlockTooltip]? = nil, forceWrapping: Bool, accessibilityElement: AccessibilityElement? = nil, - reuseId: String? + reuseId: String?, + path: UIElementPath? ) -> Block { let hasAlpha = alpha != nil && alpha?.isApproximatelyEqualTo(1) != true let anythingToApplyExceptBoundary = @@ -72,7 +72,8 @@ extension Block { visibilityParams: visibilityParams ?? block.visibilityParams, tooltips: [tooltips, block.tooltips].compactMap { $0 }.flatMap { $0 }, accessibilityElement: accessibilityElement, - reuseId: reuseId + reuseId: reuseId, + path: path ) } @@ -97,7 +98,8 @@ extension Block { visibilityParams: visibilityParams, tooltips: tooltips ?? [], accessibilityElement: accessibilityElement, - reuseId: reuseId + reuseId: reuseId, + path: path ) } @@ -126,7 +128,8 @@ extension Block { tooltips: [BlockTooltip]? = nil, forceWrapping: Bool = false, accessibilityElement: AccessibilityElement? = nil, - reuseId: String? = nil + reuseId: String? = nil, + path: UIElementPath? = nil ) -> Block { let decoratedBlock = applyDecoratingBlockProperties( boundary: boundary, @@ -144,7 +147,8 @@ extension Block { tooltips: tooltips, forceWrapping: forceWrapping, accessibilityElement: accessibilityElement, - reuseId: reuseId + reuseId: reuseId, + path: path ) return decoratedBlock.shaded(with: shadow) } diff --git a/LayoutKit/LayoutKit/Blocks/Decorations/ContextMenu.swift b/LayoutKit/LayoutKit/Blocks/Decorations/ContextMenu.swift index d8d90970..72f6e66c 100644 --- a/LayoutKit/LayoutKit/Blocks/Decorations/ContextMenu.swift +++ b/LayoutKit/LayoutKit/Blocks/Decorations/ContextMenu.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct ContextMenu: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/Decorations/DecoratingBlock.swift b/LayoutKit/LayoutKit/Blocks/Decorations/DecoratingBlock.swift index 3ed087be..172fcfae 100644 --- a/LayoutKit/LayoutKit/Blocks/Decorations/DecoratingBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Decorations/DecoratingBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL final class DecoratingBlock: WrapperBlock { @@ -26,6 +25,7 @@ final class DecoratingBlock: WrapperBlock { let tooltips: [BlockTooltip] let accessibilityElement: AccessibilityElement? let reuseId: String + let path: UIElementPath? init( child: Block, @@ -44,7 +44,8 @@ final class DecoratingBlock: WrapperBlock { visibilityParams: VisibilityParams? = nil, tooltips: [BlockTooltip] = [], accessibilityElement: AccessibilityElement? = nil, - reuseId: String? = nil + reuseId: String? = nil, + path: UIElementPath? = nil ) { self.child = child self.backgroundColor = backgroundColor @@ -63,6 +64,7 @@ final class DecoratingBlock: WrapperBlock { self.tooltips = tooltips self.accessibilityElement = accessibilityElement self.reuseId = reuseId ?? DecoratingBlock.defaultReuseId + self.path = path } var intrinsicContentWidth: CGFloat { @@ -148,7 +150,8 @@ extension DecoratingBlock { visibilityParams: VisibilityParams? = nil, tooltips: [BlockTooltip]? = nil, accessibilityElement: AccessibilityElement? = nil, - reuseId: String? = nil + reuseId: String? = nil, + path: UIElementPath? = nil ) -> DecoratingBlock { DecoratingBlock( child: child ?? self.child, @@ -167,7 +170,8 @@ extension DecoratingBlock { visibilityParams: visibilityParams ?? self.visibilityParams, tooltips: tooltips ?? self.tooltips, accessibilityElement: accessibilityElement ?? self.accessibilityElement, - reuseId: reuseId ?? self.reuseId + reuseId: reuseId ?? self.reuseId, + path: path ?? self.path ) } } diff --git a/LayoutKit/LayoutKit/Blocks/Decorations/LongTapActions.swift b/LayoutKit/LayoutKit/Blocks/Decorations/LongTapActions.swift index f39db5c6..07d7af3e 100644 --- a/LayoutKit/LayoutKit/Blocks/Decorations/LongTapActions.swift +++ b/LayoutKit/LayoutKit/Blocks/Decorations/LongTapActions.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public enum LongTapActions: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift b/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift index 531d073f..f7a7aad5 100644 --- a/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/EmptyBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class EmptyBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/GalleryBlock.swift b/LayoutKit/LayoutKit/Blocks/GalleryBlock.swift index 4068b2be..af9ddf43 100644 --- a/LayoutKit/LayoutKit/Blocks/GalleryBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/GalleryBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class GalleryBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/Grid/Grid.swift b/LayoutKit/LayoutKit/Blocks/Grid/Grid.swift index 2de95d5a..aa2a7726 100644 --- a/LayoutKit/LayoutKit/Blocks/Grid/Grid.swift +++ b/LayoutKit/LayoutKit/Blocks/Grid/Grid.swift @@ -2,7 +2,7 @@ import VGSL struct Grid { typealias GridItem = GridBlock.Item - let itemsIndices: [[Int]] + let itemsIndices: [[Int?]] var rowCount: Int { itemsIndices.count } var columnCount: Int { itemsIndices[0].count } @@ -60,14 +60,7 @@ struct Grid { } } - itemsIndices = try result.enumerated().map { rowIdx, row in - try row.enumerated().map { columnIdx, value in - if let result = value { - return result - } - throw BlockError("Grid block error: empty cell at (\(rowIdx), \(columnIdx))") - } - } + itemsIndices = result } } diff --git a/LayoutKit/LayoutKit/Blocks/Grid/GridBlock.swift b/LayoutKit/LayoutKit/Blocks/Grid/GridBlock.swift index 9b826dc4..55a6ade2 100644 --- a/LayoutKit/LayoutKit/Blocks/Grid/GridBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Grid/GridBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class GridBlock: BlockWithTraits, BlockWithLayout { diff --git a/LayoutKit/LayoutKit/Blocks/Grid/GridLayout.swift b/LayoutKit/LayoutKit/Blocks/Grid/GridLayout.swift index 5ea78527..79cf9954 100644 --- a/LayoutKit/LayoutKit/Blocks/Grid/GridLayout.swift +++ b/LayoutKit/LayoutKit/Blocks/Grid/GridLayout.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension GridBlock.Layout { @@ -127,8 +126,9 @@ extension Grid { fileprivate func calculateItemIndexToCoord() -> [Int: (row: Int, column: Int)] { var itemIndexToCoord: [Int: (row: Int, column: Int)] = [:] forEachCell { - let idx = itemsIndices[$0] - itemIndexToCoord[idx] = itemIndexToCoord[idx] ?? $0 + if let idx = itemsIndices[$0] { + itemIndexToCoord[idx] = itemIndexToCoord[idx] ?? $0 + } } return itemIndexToCoord } @@ -294,7 +294,7 @@ private func calculateWeights( direction.selectDimension(from: (row: grid.rowCount, column: grid.columnCount)) var result = [LayoutTrait.Weight?](repeating: nil, times: try! UInt(value: resultCount)) grid.forEachCell { coord in - if let item = weightedItems[grid.itemsIndices[coord]] { + if let index = grid.itemsIndices[coord], let item = weightedItems[index] { let resultIndex = direction.selectDimension(from: coord) let weightPerSpan = item.weight.rawValue / CGFloat(item.span) result[resultIndex] = LayoutTrait.Weight( @@ -368,10 +368,10 @@ private func calculateWeightToIntrinsicSize( ) grid.forEachCell { coord in - let idx = grid.itemsIndices[coord] - guard !checkedItems.contains(idx) else { + guard let idx = grid.itemsIndices[coord], !checkedItems.contains(idx) else { return } + checkedItems.insert(idx) if let item = nonResizableItems[idx] { let dimension = direction.selectDimension(from: coord) diff --git a/LayoutKit/LayoutKit/Blocks/ImageBaseBlock.swift b/LayoutKit/LayoutKit/Blocks/ImageBaseBlock.swift index 2382296b..63332bcd 100644 --- a/LayoutKit/LayoutKit/Blocks/ImageBaseBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/ImageBaseBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public protocol ImageBaseBlock: BlockWithWidthTrait { diff --git a/LayoutKit/LayoutKit/Blocks/ImageBlock.swift b/LayoutKit/LayoutKit/Blocks/ImageBlock.swift index 965d0f05..104b6176 100644 --- a/LayoutKit/LayoutKit/Blocks/ImageBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/ImageBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class ImageBlock: ImageBaseBlock { diff --git a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ContainerBlock+ImageRenderableBlock.swift b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ContainerBlock+ImageRenderableBlock.swift index 9c8055be..078890cd 100644 --- a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ContainerBlock+ImageRenderableBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ContainerBlock+ImageRenderableBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL extension ContainerBlock: ImageRenderableBlock { diff --git a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageBlock+ImageRenderableBlock.swift b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageBlock+ImageRenderableBlock.swift index 885b771b..0e1f5ea9 100644 --- a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageBlock+ImageRenderableBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageBlock+ImageRenderableBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL extension ImageBlock: ImageRenderableBlock { diff --git a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageRenderableBlock.swift b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageRenderableBlock.swift index a212a45f..f674694c 100644 --- a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageRenderableBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/ImageRenderableBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public protocol ImageRenderableBlock: Block { diff --git a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/LayredBlock+ImageRenderableBlock.swift b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/LayredBlock+ImageRenderableBlock.swift index e3ad50ac..99ea3701 100644 --- a/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/LayredBlock+ImageRenderableBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/ImageRenderableBlock/LayredBlock+ImageRenderableBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension LayeredBlock: ImageRenderableBlock { diff --git a/LayoutKit/LayoutKit/Blocks/LaidOutBlock.swift b/LayoutKit/LayoutKit/Blocks/LaidOutBlock.swift index d9d5e79f..18adeebe 100644 --- a/LayoutKit/LayoutKit/Blocks/LaidOutBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/LaidOutBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL final class LaidOutBlock: Block { diff --git a/LayoutKit/LayoutKit/Blocks/LayeredBlock.swift b/LayoutKit/LayoutKit/Blocks/LayeredBlock.swift index cf2bf615..71fde96f 100644 --- a/LayoutKit/LayoutKit/Blocks/LayeredBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/LayeredBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class LayeredBlock: BlockWithTraits, BlockWithLayout { diff --git a/LayoutKit/LayoutKit/Blocks/LayeredBlockLayout.swift b/LayoutKit/LayoutKit/Blocks/LayeredBlockLayout.swift index 58cf652d..6f2d09cb 100644 --- a/LayoutKit/LayoutKit/Blocks/LayeredBlockLayout.swift +++ b/LayoutKit/LayoutKit/Blocks/LayeredBlockLayout.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension LayeredBlock { diff --git a/LayoutKit/LayoutKit/Blocks/MaskedBlock.swift b/LayoutKit/LayoutKit/Blocks/MaskedBlock.swift index fbbdce7a..dd1fb443 100644 --- a/LayoutKit/LayoutKit/Blocks/MaskedBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/MaskedBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class MaskedBlock: SizeForwardingBlock { diff --git a/LayoutKit/LayoutKit/Blocks/PageControlBlock.swift b/LayoutKit/LayoutKit/Blocks/PageControlBlock.swift index e332fed3..0f67d73e 100644 --- a/LayoutKit/LayoutKit/Blocks/PageControlBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/PageControlBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL #if canImport(UIKit) diff --git a/LayoutKit/LayoutKit/Blocks/PagerBlock.swift b/LayoutKit/LayoutKit/Blocks/PagerBlock.swift index e0093e5b..891bcd4e 100644 --- a/LayoutKit/LayoutKit/Blocks/PagerBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/PagerBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class PagerBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/PinchToZoomBlock.swift b/LayoutKit/LayoutKit/Blocks/PinchToZoomBlock.swift index 0a034dbc..311d3c5c 100644 --- a/LayoutKit/LayoutKit/Blocks/PinchToZoomBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/PinchToZoomBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class PinchToZoomBlock: WrapperBlock, LayoutCachingDefaultImpl { diff --git a/LayoutKit/LayoutKit/Blocks/ResizableBlockMeasure.swift b/LayoutKit/LayoutKit/Blocks/ResizableBlockMeasure.swift index e8ea16c7..a3e7374e 100644 --- a/LayoutKit/LayoutKit/Blocks/ResizableBlockMeasure.swift +++ b/LayoutKit/LayoutKit/Blocks/ResizableBlockMeasure.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct ResizableBlockMeasure { diff --git a/LayoutKit/LayoutKit/Blocks/RoundedRect.swift b/LayoutKit/LayoutKit/Blocks/RoundedRect.swift index 08001662..ded8ddb2 100644 --- a/LayoutKit/LayoutKit/Blocks/RoundedRect.swift +++ b/LayoutKit/LayoutKit/Blocks/RoundedRect.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension CGPath { diff --git a/LayoutKit/LayoutKit/Blocks/SeparatorBlock.swift b/LayoutKit/LayoutKit/Blocks/SeparatorBlock.swift index df869465..07baa9d8 100644 --- a/LayoutKit/LayoutKit/Blocks/SeparatorBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/SeparatorBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class SeparatorBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/Shadow/BlockShadow.swift b/LayoutKit/LayoutKit/Blocks/Shadow/BlockShadow.swift index ace3ec10..d4574e2e 100644 --- a/LayoutKit/LayoutKit/Blocks/Shadow/BlockShadow.swift +++ b/LayoutKit/LayoutKit/Blocks/Shadow/BlockShadow.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct BlockShadow: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/Shadow/ShadedBlock.swift b/LayoutKit/LayoutKit/Blocks/Shadow/ShadedBlock.swift index 803544a6..68b952ba 100644 --- a/LayoutKit/LayoutKit/Blocks/Shadow/ShadedBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Shadow/ShadedBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class ShadedBlock { diff --git a/LayoutKit/LayoutKit/Blocks/SizeForwardingBlock.swift b/LayoutKit/LayoutKit/Blocks/SizeForwardingBlock.swift index af941ca3..66c55237 100644 --- a/LayoutKit/LayoutKit/Blocks/SizeForwardingBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/SizeForwardingBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public protocol SizeForwardingBlock: Block { diff --git a/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift b/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift index e166b4fd..4c65f016 100644 --- a/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift +++ b/LayoutKit/LayoutKit/Blocks/Slider/MarksLayer.swift @@ -99,10 +99,11 @@ final class MarksLayer: CALayer { extension MarksConfiguration.RoundedRectangle { fileprivate func render(in ctx: CGContext, with origin: CGPoint = CGPoint(x: 0, y: 0)) { let rect = CGRect(origin: origin, size: size).insetBy(dx: borderWidth / 4, dy: borderWidth / 4) + let radius = min(cornerRadius, rect.height / 2, rect.width / 2) let path = CGPath( roundedRect: rect, - cornerWidth: min(cornerRadius, rect.height / 2), - cornerHeight: min(cornerRadius, rect.height / 2), + cornerWidth: radius, + cornerHeight: radius, transform: nil ) ctx.addPath(path) diff --git a/LayoutKit/LayoutKit/Blocks/Slider/SliderBlock.swift b/LayoutKit/LayoutKit/Blocks/Slider/SliderBlock.swift index f41355a1..1ab6d2f7 100644 --- a/LayoutKit/LayoutKit/Blocks/Slider/SliderBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Slider/SliderBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class SliderBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift b/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift index 95c95c23..7446cbf2 100644 --- a/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift +++ b/LayoutKit/LayoutKit/Blocks/Slider/SliderModel.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL #if canImport(UIKit) diff --git a/LayoutKit/LayoutKit/Blocks/Slider/SliderView.swift b/LayoutKit/LayoutKit/Blocks/Slider/SliderView.swift index b99a4791..65ffb6b6 100644 --- a/LayoutKit/LayoutKit/Blocks/Slider/SliderView.swift +++ b/LayoutKit/LayoutKit/Blocks/Slider/SliderView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class SliderView: BlockView, VisibleBoundsTrackingLeaf { diff --git a/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift b/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift index 720d723e..969098c2 100644 --- a/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class SwitchBlock: Block { diff --git a/LayoutKit/LayoutKit/Blocks/SwitchableContainerBlock.swift b/LayoutKit/LayoutKit/Blocks/SwitchableContainerBlock.swift index 1143ddc0..199f60a9 100644 --- a/LayoutKit/LayoutKit/Blocks/SwitchableContainerBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/SwitchableContainerBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class SwitchableContainerBlock: Block { diff --git a/LayoutKit/LayoutKit/Blocks/TabsBlock.swift b/LayoutKit/LayoutKit/Blocks/TabsBlock.swift index 1505d790..c6045df9 100644 --- a/LayoutKit/LayoutKit/Blocks/TabsBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/TabsBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class TabsBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/TextBlock+Copy.swift b/LayoutKit/LayoutKit/Blocks/TextBlock+Copy.swift index ddb88165..fb09bcc6 100644 --- a/LayoutKit/LayoutKit/Blocks/TextBlock+Copy.swift +++ b/LayoutKit/LayoutKit/Blocks/TextBlock+Copy.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension TextBlock { diff --git a/LayoutKit/LayoutKit/Blocks/TextBlock.swift b/LayoutKit/LayoutKit/Blocks/TextBlock.swift index 02390364..9ddc01a8 100644 --- a/LayoutKit/LayoutKit/Blocks/TextBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/TextBlock.swift @@ -1,7 +1,6 @@ import CoreGraphics import CoreText import Foundation - import VGSL public final class TextBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/TextFieldBlock.swift b/LayoutKit/LayoutKit/Blocks/TextFieldBlock.swift index 9959c422..aff72256 100644 --- a/LayoutKit/LayoutKit/Blocks/TextFieldBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/TextFieldBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class TextFieldBlock: Block { diff --git a/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift b/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift index 7b493128..58ea7611 100644 --- a/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/TextInputBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public typealias TextInputFilter = (String) -> Bool diff --git a/LayoutKit/LayoutKit/Blocks/TransitioningAnimation.swift b/LayoutKit/LayoutKit/Blocks/TransitioningAnimation.swift index 5085a19a..96b5fdfd 100644 --- a/LayoutKit/LayoutKit/Blocks/TransitioningAnimation.swift +++ b/LayoutKit/LayoutKit/Blocks/TransitioningAnimation.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct TransitioningAnimation: Equatable { diff --git a/LayoutKit/LayoutKit/Blocks/TransitioningBlock.swift b/LayoutKit/LayoutKit/Blocks/TransitioningBlock.swift index e05d7169..cf1dec4f 100644 --- a/LayoutKit/LayoutKit/Blocks/TransitioningBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/TransitioningBlock.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public final class TransitioningBlock: BlockWithLayout, WrapperBlock { diff --git a/LayoutKit/LayoutKit/Blocks/Video/DefaultPlayer/DefaultPlayerFactory.swift b/LayoutKit/LayoutKit/Blocks/Video/DefaultPlayer/DefaultPlayerFactory.swift index 16470e85..76f554c7 100644 --- a/LayoutKit/LayoutKit/Blocks/Video/DefaultPlayer/DefaultPlayerFactory.swift +++ b/LayoutKit/LayoutKit/Blocks/Video/DefaultPlayer/DefaultPlayerFactory.swift @@ -1,7 +1,6 @@ import AVFoundation import Foundation import UIKit - import VGSL public final class DefaultPlayerFactory: PlayerFactory { diff --git a/LayoutKit/LayoutKit/Blocks/Video/VideoBlock.swift b/LayoutKit/LayoutKit/Blocks/Video/VideoBlock.swift index 67f71b88..8b6a8f5a 100644 --- a/LayoutKit/LayoutKit/Blocks/Video/VideoBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/Video/VideoBlock.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public final class VideoBlock: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/VideoBlockLegacy.swift b/LayoutKit/LayoutKit/Blocks/VideoBlockLegacy.swift index b828e7c0..8acf615a 100644 --- a/LayoutKit/LayoutKit/Blocks/VideoBlockLegacy.swift +++ b/LayoutKit/LayoutKit/Blocks/VideoBlockLegacy.swift @@ -1,7 +1,6 @@ import AVFoundation import CoreGraphics import Foundation - import VGSL public final class VideoBlockLegacy: BlockWithTraits { diff --git a/LayoutKit/LayoutKit/Blocks/WrapperBlock.swift b/LayoutKit/LayoutKit/Blocks/WrapperBlock.swift index ad22df6d..dcae0e00 100644 --- a/LayoutKit/LayoutKit/Blocks/WrapperBlock.swift +++ b/LayoutKit/LayoutKit/Blocks/WrapperBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public protocol WrapperBlock: SizeForwardingBlock { diff --git a/LayoutKit/LayoutKit/GenericViewBlock.swift b/LayoutKit/LayoutKit/GenericViewBlock.swift index f57642ca..d85ea758 100644 --- a/LayoutKit/LayoutKit/GenericViewBlock.swift +++ b/LayoutKit/LayoutKit/GenericViewBlock.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL #if os(iOS) diff --git a/LayoutKit/LayoutKit/Tooltips/TooltipAnchorView.swift b/LayoutKit/LayoutKit/Tooltips/TooltipAnchorView.swift new file mode 100644 index 00000000..a29398d0 --- /dev/null +++ b/LayoutKit/LayoutKit/Tooltips/TooltipAnchorView.swift @@ -0,0 +1,5 @@ +import VGSL + +public protocol TooltipAnchorView: ViewType { + var tooltips: [BlockTooltip] { get } +} diff --git a/LayoutKit/LayoutKit/Tooltips/TooltipFactory.swift b/LayoutKit/LayoutKit/Tooltips/TooltipFactory.swift index 1e43be68..6aa66cc4 100644 --- a/LayoutKit/LayoutKit/Tooltips/TooltipFactory.swift +++ b/LayoutKit/LayoutKit/Tooltips/TooltipFactory.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public enum TooltipFactory { diff --git a/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift b/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift index 67473c4a..95087f05 100644 --- a/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift +++ b/LayoutKit/LayoutKit/Tooltips/TooltipManager.swift @@ -95,37 +95,41 @@ public class DefaultTooltipManager: TooltipManager { public func showTooltip(info: TooltipInfo) { setupTooltipWindow() - guard let tooltipWindow else { return } + guard let tooltipWindow, + !showingTooltips.keys.contains(info.id) + else { return } let windowBounds = tooltipWindow.bounds.inset(by: tooltipWindow.safeAreaInsets) - guard !showingTooltips.keys.contains(info.id), - let tooltip = existingAnchorViews.compactMap({ - $0?.makeTooltip(id: info.id, in: windowBounds) - }).first - else { return } - let view = TooltipContainerView( - tooltipView: tooltip.view, - handleAction: handleAction, - onCloseAction: { [weak self] in - self?.showingTooltips.removeValue(forKey: tooltip.id) - self?.tooltipWindow?.isHidden = true + Task { @MainActor in + guard let tooltip = await existingAnchorViews.compactMap( + concurrencyLimit: 1, + transform: { await $0?.makeTooltip(id: info.id, in: windowBounds) } + ).first else { return } + let view = TooltipContainerView( + tooltipView: tooltip.view, + handleAction: handleAction, + onCloseAction: { [weak self] in + self?.showingTooltips.removeValue(forKey: tooltip.id) + self?.tooltipWindow?.isHidden = true + } + ) + // Passing the statusBarStyle control to `rootViewController` of the main window + let vc = ProxyViewController( + viewController: UIApplication.shared.delegate?.window?? + .rootViewController ?? UIViewController() + ) + vc.view = view + // Window won't rotate if `rootViewController` is not set + tooltipWindow.rootViewController = vc + tooltipWindow.isHidden = false + tooltipWindow.makeKeyAndVisible() + view.frame = tooltipWindow.bounds + showingTooltips[info.id] = view + if !tooltip.duration.value.isZero { + try await Task.sleep(nanoseconds: UInt64(tooltip.duration.value.nanoseconds)) + hideTooltip(id: tooltip.id) } - ) - // Passing the statusBarStyle control to `rootViewController` of the main window - let vc = ProxyViewController( - viewController: UIApplication.shared.delegate?.window?? - .rootViewController ?? UIViewController() - ) - vc.view = view - // Window won't rotate if `rootViewController` is not set - tooltipWindow.rootViewController = vc - tooltipWindow.isHidden = false - tooltipWindow.makeKeyAndVisible() - view.frame = tooltipWindow.bounds - showingTooltips[info.id] = view - if !tooltip.duration.value.isZero { - after(tooltip.duration.value, block: { self.hideTooltip(id: tooltip.id) }) } } @@ -181,31 +185,32 @@ public class DefaultTooltipManager: TooltipManager { } extension TooltipAnchorView { + @MainActor fileprivate func makeTooltip( id: String, in constraint: CGRect - ) -> DefaultTooltipManager.Tooltip? { - tooltips - .first { $0.id == id } - .flatMap { - let tooltip = $0 - let targetRect = window != nil ? - convert(bounds, to: nil) : - frame - - return DefaultTooltipManager.Tooltip( - id: tooltip.id, - duration: tooltip.duration, - view: { - let tooltipView = tooltip.tooltipViewFactory?.value ?? tooltip.block.makeBlockView() - tooltipView.frame = tooltip.calculateFrame( - targeting: targetRect, - constrainedBy: constraint - ) - return tooltipView - }() - ) - } + ) async -> DefaultTooltipManager.Tooltip? { + guard let tooltip = tooltips.first(where: { $0.id == id }) else { + return nil + } + + let tooltipView = await tooltip.tooltipViewFactory?() ?? tooltip.block.makeBlockView() + + let targetRect = window != nil ? + convert(bounds, to: nil) : + frame + + tooltipView.frame = tooltip.calculateFrame( + targeting: targetRect, + constrainedBy: constraint, + useLegacyWidth: tooltip.useLegacyWidth + ) + + return DefaultTooltipManager.Tooltip( + id: tooltip.id, + duration: tooltip.duration, + view: tooltipView + ) } } diff --git a/LayoutKit/LayoutKit/UI/Actions/AnalyticsClickEventHandling.swift b/LayoutKit/LayoutKit/UI/Actions/AnalyticsClickEventHandling.swift index 2afe9fbc..c9d58290 100644 --- a/LayoutKit/LayoutKit/UI/Actions/AnalyticsClickEventHandling.swift +++ b/LayoutKit/LayoutKit/UI/Actions/AnalyticsClickEventHandling.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public protocol AnalyticsTouchEventHandling { diff --git a/LayoutKit/LayoutKit/UI/Actions/CommonHandlerExtensions.swift b/LayoutKit/LayoutKit/UI/Actions/CommonHandlerExtensions.swift index c56734c9..8a0d295f 100644 --- a/LayoutKit/LayoutKit/UI/Actions/CommonHandlerExtensions.swift +++ b/LayoutKit/LayoutKit/UI/Actions/CommonHandlerExtensions.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension CommonHandler { diff --git a/LayoutKit/LayoutKit/UI/Actions/GalleryEvent/GalleryScrollEventHandling.swift b/LayoutKit/LayoutKit/UI/Actions/GalleryEvent/GalleryScrollEventHandling.swift index 54bfa6d9..3ab42621 100644 --- a/LayoutKit/LayoutKit/UI/Actions/GalleryEvent/GalleryScrollEventHandling.swift +++ b/LayoutKit/LayoutKit/UI/Actions/GalleryEvent/GalleryScrollEventHandling.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public protocol GalleryScrollEventHandling { diff --git a/LayoutKit/LayoutKit/UI/Actions/MenuExtensions.swift b/LayoutKit/LayoutKit/UI/Actions/MenuExtensions.swift index bf8f837e..c867d794 100644 --- a/LayoutKit/LayoutKit/UI/Actions/MenuExtensions.swift +++ b/LayoutKit/LayoutKit/UI/Actions/MenuExtensions.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension Menu { diff --git a/LayoutKit/LayoutKit/UI/Actions/PagerEventHandling.swift b/LayoutKit/LayoutKit/UI/Actions/PagerEventHandling.swift index 55cd67a4..49c581c1 100644 --- a/LayoutKit/LayoutKit/UI/Actions/PagerEventHandling.swift +++ b/LayoutKit/LayoutKit/UI/Actions/PagerEventHandling.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public protocol PagerEventHandling { diff --git a/LayoutKit/LayoutKit/UI/Actions/TooltipEventPerforming.swift b/LayoutKit/LayoutKit/UI/Actions/TooltipEventPerforming.swift index 1938e23d..59661382 100644 --- a/LayoutKit/LayoutKit/UI/Actions/TooltipEventPerforming.swift +++ b/LayoutKit/LayoutKit/UI/Actions/TooltipEventPerforming.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public protocol TooltipEventPerforming { diff --git a/LayoutKit/LayoutKit/UI/Actions/UIActionEventPerformingAdapter.swift b/LayoutKit/LayoutKit/UI/Actions/UIActionEventPerformingAdapter.swift index bce5214d..9e480a43 100644 --- a/LayoutKit/LayoutKit/UI/Actions/UIActionEventPerformingAdapter.swift +++ b/LayoutKit/LayoutKit/UI/Actions/UIActionEventPerformingAdapter.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL public final class UIActionEventPerformingAdapter: UIActionEventPerforming { diff --git a/LayoutKit/LayoutKit/UI/Base/GenericCollectionLayout.swift b/LayoutKit/LayoutKit/UI/Base/GenericCollectionLayout.swift index 838baac5..8a6451b4 100644 --- a/LayoutKit/LayoutKit/UI/Base/GenericCollectionLayout.swift +++ b/LayoutKit/LayoutKit/UI/Base/GenericCollectionLayout.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public struct GenericCollectionLayout { diff --git a/LayoutKit/LayoutKit/UI/Base/GenericCollectionReusableView.swift b/LayoutKit/LayoutKit/UI/Base/GenericCollectionReusableView.swift index 64040b15..072eac5b 100644 --- a/LayoutKit/LayoutKit/UI/Base/GenericCollectionReusableView.swift +++ b/LayoutKit/LayoutKit/UI/Base/GenericCollectionReusableView.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL public final class GenericCollectionReusableView: UICollectionReusableView { diff --git a/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewCell.swift b/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewCell.swift index 3617b200..f318ef2e 100644 --- a/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewCell.swift +++ b/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewCell.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL open class GenericCollectionViewCell: UICollectionViewCell, VisibleBoundsTrackingContainer { @@ -42,7 +41,7 @@ open class GenericCollectionViewCell: UICollectionViewCell, VisibleBoundsTrackin ) } - applyAccessibility(accessibilityElement) + applyAccessibilityFromScratch(accessibilityElement) } public override func layoutSubviews() { diff --git a/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewDataSource.swift b/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewDataSource.swift index 93a55a60..cfda2e34 100644 --- a/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewDataSource.swift +++ b/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewDataSource.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL public typealias CollectionHeaderModel = Block diff --git a/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewLayout.swift b/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewLayout.swift index 53f5c018..59f6b554 100644 --- a/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewLayout.swift +++ b/LayoutKit/LayoutKit/UI/Base/GenericCollectionViewLayout.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL public final class GenericCollectionViewLayout: UICollectionViewLayout { diff --git a/LayoutKit/LayoutKit/UI/Base/PageIndicator/IndicatorState/IndicatorStateAnimator.swift b/LayoutKit/LayoutKit/UI/Base/PageIndicator/IndicatorState/IndicatorStateAnimator.swift index 7dfd4463..eddc2999 100644 --- a/LayoutKit/LayoutKit/UI/Base/PageIndicator/IndicatorState/IndicatorStateAnimator.swift +++ b/LayoutKit/LayoutKit/UI/Base/PageIndicator/IndicatorState/IndicatorStateAnimator.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL struct IndicatorStateAnimator { diff --git a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorConfiguration.swift b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorConfiguration.swift index b3f1e95d..d4ebb4c7 100644 --- a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorConfiguration.swift +++ b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorConfiguration.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct PageIndicatorConfiguration: Equatable { diff --git a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayer.swift b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayer.swift index 92dd6e47..c1478157 100644 --- a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayer.swift +++ b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayer.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL typealias Scale = (x: CGFloat, y: CGFloat) diff --git a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayerParams.swift b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayerParams.swift index 25507c88..12feb6f9 100644 --- a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayerParams.swift +++ b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorLayerParams.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL struct PageIndicatorLayerParams { diff --git a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorView.swift b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorView.swift index 73d9865c..f6fc0a76 100644 --- a/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorView.swift +++ b/LayoutKit/LayoutKit/UI/Base/PageIndicator/PageIndicatorView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class PageIndicatorView: UIView { diff --git a/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager+ScrollDelegate.swift b/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager+ScrollDelegate.swift index dea05944..e337c0d3 100644 --- a/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager+ScrollDelegate.swift +++ b/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager+ScrollDelegate.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension ScrollableContentPager: ScrollDelegate { diff --git a/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager.swift b/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager.swift index 501a3fb8..1767e1de 100644 --- a/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager.swift +++ b/LayoutKit/LayoutKit/UI/Base/ScrollableContentPager.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public final class ScrollableContentPager: NSObject { diff --git a/LayoutKit/LayoutKit/UI/Blocks/AccessibilityBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/AccessibilityBlock+UIViewRenderableBlock.swift index d335d45d..619403fc 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/AccessibilityBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/AccessibilityBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL #if INTERNAL_BUILD diff --git a/LayoutKit/LayoutKit/UI/Blocks/AnimatableImageBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/AnimatableImageBlock+UIViewRenderableBlock.swift index ea653682..d6e8eb80 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/AnimatableImageBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/AnimatableImageBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension AnimatableImageBlock { @@ -18,7 +17,7 @@ extension AnimatableImageBlock { } animatableImageView.imageContentMode = contentMode animatableImageView.isUserInteractionEnabled = false - animatableImageView.applyAccessibility(accessibilityElement) + animatableImageView.applyAccessibilityFromScratch(accessibilityElement) } public func canConfigureBlockView(_ view: BlockView) -> Bool { diff --git a/LayoutKit/LayoutKit/UI/Blocks/Array+UIViewRenderable.swift b/LayoutKit/LayoutKit/UI/Blocks/Array+UIViewRenderable.swift index 13166543..14a714ed 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/Array+UIViewRenderable.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/Array+UIViewRenderable.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension [BlockView] { diff --git a/LayoutKit/LayoutKit/UI/Blocks/BackgroundBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/BackgroundBlock+UIViewRenderableBlock.swift index db190791..2bd5a7d2 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/BackgroundBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/BackgroundBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension BackgroundBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/BlockViewProtocol.swift b/LayoutKit/LayoutKit/UI/Blocks/BlockViewProtocol.swift index 464cc295..524c116d 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/BlockViewProtocol.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/BlockViewProtocol.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public protocol BlockViewProtocol: AnyObject, VisibleBoundsTracking, diff --git a/LayoutKit/LayoutKit/UI/Blocks/ContainerBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/ContainerBlock+UIViewRenderableBlock.swift index 807056d2..793fe185 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/ContainerBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/ContainerBlock+UIViewRenderableBlock.swift @@ -1,7 +1,6 @@ import CoreGraphics import Foundation import UIKit - import VGSL extension ContainerBlock { @@ -98,7 +97,7 @@ private final class ContainerBlockView: UIView, BlockViewProtocol, VisibleBounds return } - applyAccessibility(model.accessibility) + applyAccessibilityFromScratch(model.accessibility) modelAndLastLayoutSize = (model: model, lastLayoutSize: nil) self.observer = observer self.overscrollDelegate = overscrollDelegate diff --git a/LayoutKit/LayoutKit/UI/Blocks/DebugInfoBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/DebugInfoBlock+UIViewRenderableBlock.swift index 366b1bad..2547b72b 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/DebugInfoBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/DebugInfoBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension DebugInfoBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/DecoratingBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/DecoratingBlock+UIViewRenderableBlock.swift index 8c92129c..72484b60 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/DecoratingBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/DecoratingBlock+UIViewRenderableBlock.swift @@ -1,7 +1,6 @@ import CoreGraphics import Foundation import UIKit - import VGSL extension DecoratingBlock { @@ -48,7 +47,8 @@ extension DecoratingBlock { visibilityParams: visibilityParams, tooltips: tooltips, accessibility: accessibilityElement, - reuseId: reuseId + reuseId: reuseId, + path: path ) view.configure( model: model, @@ -122,6 +122,7 @@ private final class DecoratingView: UIControl, BlockViewProtocol, VisibleBoundsT let tooltips: [BlockTooltip] let accessibility: AccessibilityElement? let reuseId: String? + let path: UIElementPath? var hasResponsiveUI: Bool { actions.hasPayload || longTapActions.hasPayload || doubleTapActions.hasPayload @@ -147,6 +148,9 @@ private final class DecoratingView: UIControl, BlockViewProtocol, VisibleBoundsT private var contextMenuDelegate: NSObjectProtocol? + private var animationStartTime: Date? + private let animationMinimalDuration: TimeInterval = 0.125 + private var visibilityActionPerformers: VisibilityActionPerformers? var visibleBoundsTrackingSubviews: [VisibleBoundsTrackingView] { childView.asArray() } var effectiveBackgroundColor: UIColor? { backgroundColor } @@ -258,6 +262,20 @@ private final class DecoratingView: UIControl, BlockViewProtocol, VisibleBoundsT longPressRecognizer?.isEnabled = model.shouldHandleLongTap } + private func checkTouchableArea() { + guard tapRecognizer != nil || doubleTapRecognizer != nil || longPressRecognizer != nil else { + return + } + guard !bounds.size.isApproximatelyEqualTo(.zero) else { return } + if bounds.width < 44 || bounds.height < 44 { + renderingDelegate?.reportRenderingError( + message: "Touchable view is too small: \(bounds.size), \(model.child)", + isWarning: true, + path: model.path ?? UIElementPath("") + ) + } + } + @available(*, unavailable) required init?(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -322,6 +340,8 @@ private final class DecoratingView: UIControl, BlockViewProtocol, VisibleBoundsT blurView?.frame = bounds + checkTouchableArea() + guard let view = childView else { return } let currentTransform = view.transform @@ -368,7 +388,7 @@ private final class DecoratingView: UIControl, BlockViewProtocol, VisibleBoundsT updateContentBackgroundColor(animated: false) updateContentAlpha(animated: false) - applyAccessibility(model.accessibility) + applyAccessibilityFromScratch(model.accessibility) model.actions? .forEach { applyAccessibility($0.accessibilityElement) } @@ -406,7 +426,26 @@ private final class DecoratingView: UIControl, BlockViewProtocol, VisibleBoundsT return updateContentAlpha(animated: animated) } - perform(actionAnimation, animated: animated) + let startAnimation = DispatchWorkItem { [weak self] in + self?.perform(actionAnimation, animated: animated) { + self?.animationStartTime = nil + } + self?.animationStartTime = Date() + } + + if let animationStartTime { + let remainingTime: TimeInterval = max( + 0.0, animationMinimalDuration - Date().timeIntervalSince(animationStartTime) + ) + + DispatchQueue.main.asyncAfter( + deadline: DispatchTime.now() + remainingTime, + execute: startAnimation + ) + + } else { + startAnimation.perform() + } } private func updateContentAlpha(animated: Bool) { diff --git a/LayoutKit/LayoutKit/UI/Blocks/DetachableAnimationBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/DetachableAnimationBlock+UIViewRenderableBlock.swift index 4093638e..5a7238d2 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/DetachableAnimationBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/DetachableAnimationBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension DetachableAnimationBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/EffectiveBackgroundColorProviding.swift b/LayoutKit/LayoutKit/UI/Blocks/EffectiveBackgroundColorProviding.swift index 4305b21a..123c361c 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/EffectiveBackgroundColorProviding.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/EffectiveBackgroundColorProviding.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public protocol EffectiveBackgroundColorProviding { diff --git a/LayoutKit/LayoutKit/UI/Blocks/EmptyBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/EmptyBlock+UIViewRenderableBlock.swift index b4108f92..ba3d5dde 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/EmptyBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/EmptyBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension EmptyBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/GalleryBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/GalleryBlock+UIViewRenderableBlock.swift index dc19f6a7..4f4b894f 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/GalleryBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/GalleryBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension GalleryBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/GenericViewBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/GenericViewBlock+UIViewRenderableBlock.swift index 846e50d1..3965793c 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/GenericViewBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/GenericViewBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension GenericViewBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/GestureBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/GestureBlock+UIViewRenderableBlock.swift index 604d14a8..2885955a 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/GestureBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/GestureBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension GestureBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/GridBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/GridBlock+UIViewRenderableBlock.swift index 8d652d42..f7b661f9 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/GridBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/GridBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension GridBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/ImageBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/ImageBlock+UIViewRenderableBlock.swift index 5db84562..610ac6b9 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/ImageBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/ImageBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension ImageBlock { @@ -32,7 +31,7 @@ extension ImageBlock { remoteImageViewContainer.imageHolder = imageHolder } remoteImageViewContainer.isUserInteractionEnabled = false - remoteImageViewContainer.applyAccessibility(accessibilityElement) + remoteImageViewContainer.applyAccessibilityFromScratch(accessibilityElement) } public func canConfigureBlockView(_ view: BlockView) -> Bool { diff --git a/LayoutKit/LayoutKit/UI/Blocks/LaidOutBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/LaidOutBlock+UIViewRenderableBlock.swift index 18f8d909..c9534b98 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/LaidOutBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/LaidOutBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension LaidOutBlock where T: BlockWithLayout { diff --git a/LayoutKit/LayoutKit/UI/Blocks/LayeredBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/LayeredBlock+UIViewRenderableBlock.swift index 8e30b8af..35af67e5 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/LayeredBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/LayeredBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension LayeredBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/MaskedBlock+UIViewRenderable.swift b/LayoutKit/LayoutKit/UI/Blocks/MaskedBlock+UIViewRenderable.swift index 73ba6e1e..9b5ff9c5 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/MaskedBlock+UIViewRenderable.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/MaskedBlock+UIViewRenderable.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension MaskedBlock: UIViewRenderable { diff --git a/LayoutKit/LayoutKit/UI/Blocks/PageControlBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/PageControlBlock+UIViewRenderableBlock.swift index d297f60f..344edfc7 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/PageControlBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/PageControlBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension PageControlBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/PagerBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/PagerBlock+UIViewRenderableBlock.swift index 11cca8a5..0f8129f8 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/PagerBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/PagerBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension PagerBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/PinchToZoomBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/PinchToZoomBlock+UIViewRenderableBlock.swift index 680b7f90..402b7644 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/PinchToZoomBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/PinchToZoomBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension PinchToZoomBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/RenderingDelegate.swift b/LayoutKit/LayoutKit/UI/Blocks/RenderingDelegate.swift index daefb858..2482ef4e 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/RenderingDelegate.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/RenderingDelegate.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL #if os(iOS) @@ -7,6 +6,7 @@ public protocol RenderingDelegate: AnyObject { func mapView(_ view: BlockView, to id: BlockViewID) func tooltipAnchorViewAdded(anchorView: TooltipAnchorView) func tooltipAnchorViewRemoved(anchorView: TooltipAnchorView) + func reportRenderingError(message: String, isWarning: Bool, path: UIElementPath) } public typealias BlockViewID = Tagged @@ -15,8 +15,8 @@ public protocol DivViewMetaProviding: AnyObject { func subview(with id: BlockViewID) -> BlockView? } -public protocol TooltipAnchorView: ViewType { - var tooltips: [BlockTooltip] { get } +extension RenderingDelegate { + public func reportRenderingError(message _: String, isWarning _: Bool, path _: UIElementPath) {} } #else public protocol RenderingDelegate {} diff --git a/LayoutKit/LayoutKit/UI/Blocks/SeparatorBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/SeparatorBlock+UIViewRenderableBlock.swift index 01952d35..088f28a3 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/SeparatorBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/SeparatorBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension SeparatorBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/ShadedBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/ShadedBlock+UIViewRenderableBlock.swift index efc37723..6c774f66 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/ShadedBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/ShadedBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension ShadedBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/StateBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/StateBlock+UIViewRenderableBlock.swift index f45d5f20..a3a068b2 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/StateBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/StateBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension StateBlock { @@ -69,6 +68,14 @@ private final class SubviewStorage: RenderingDelegate { wrappedRenderingDelegate?.tooltipAnchorViewRemoved(anchorView: anchorView) } + func reportRenderingError(message: String, isWarning: Bool, path: UIElementPath) { + wrappedRenderingDelegate?.reportRenderingError( + message: message, + isWarning: isWarning, + path: path + ) + } + func getView(_ id: BlockViewID) -> DetachableAnimationBlockView? { views.first { $0.id == id }?.view } @@ -199,7 +206,7 @@ private final class StateBlockView: BlockView { override func layoutSubviews() { super.layoutSubviews() - childView?.frame = bounds + childView?.setNonTransformedFrame(bounds) } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { diff --git a/LayoutKit/LayoutKit/UI/Blocks/SwipeContainerBlock+UIViewRenderable.swift b/LayoutKit/LayoutKit/UI/Blocks/SwipeContainerBlock+UIViewRenderable.swift index eb66afb7..cf680db6 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/SwipeContainerBlock+UIViewRenderable.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/SwipeContainerBlock+UIViewRenderable.swift @@ -1,7 +1,6 @@ import CoreGraphics import Foundation import UIKit - import VGSL extension SwipeContainerBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift index 4bef402a..420b1961 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension SwitchBlock { @@ -40,7 +39,7 @@ private final class SwitchBlockView: BlockView, VisibleBoundsTrackingLeaf { aSwitch.isOn = model.on.value aSwitch.isEnabled = model.enabled aSwitch.onTintColor = model.onTintColor?.systemColor - applyAccessibility(model.accessibility) + applyAccessibilityFromScratch(model.accessibility) } } diff --git a/LayoutKit/LayoutKit/UI/Blocks/SwitchableContainerBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/SwitchableContainerBlock+UIViewRenderableBlock.swift index 518aaf2c..b46904bb 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/SwitchableContainerBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/SwitchableContainerBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension SwitchableContainerBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/TabsBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/TabsBlock+UIViewRenderableBlock.swift index 10505572..80e56258 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/TabsBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/TabsBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension TabsBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift index 42728674..ea09b3e0 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/TextBlock+UIViewRenderableBlock.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension TextBlock { @@ -71,7 +70,7 @@ private final class TextBlockContainer: BlockView, VisibleBoundsTrackingLeaf { } textBlockView.model = model isUserInteractionEnabled = model.isUserInteractionEnabled - applyAccessibility(model.accessibility) + applyAccessibilityFromScratch(model.accessibility) } } diff --git a/LayoutKit/LayoutKit/UI/Blocks/TextFieldBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/TextFieldBlock+UIViewRenderableBlock.swift index 3b1a286c..493352cf 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/TextFieldBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/TextFieldBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension TextFieldBlock { @@ -144,7 +143,7 @@ private final class TextFieldBlockView: BlockView, VisibleBoundsTrackingLeaf { var accessibility: AccessibilityElement? { didSet { - textField.applyAccessibility(accessibility) + textField.applyAccessibilityFromScratch(accessibility) } } @@ -163,7 +162,7 @@ private final class TextFieldBlockView: BlockView, VisibleBoundsTrackingLeaf { ) .makeBlockView() controlView.frame = CGRect(origin: .zero, size: control.image.size) - controlView.applyAccessibility(control.accessibilityElement) + controlView.applyAccessibilityFromScratch(control.accessibilityElement) textField.rightView = controlView textField.rightViewMode = .always } else { diff --git a/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift index b0c2d238..889f359e 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/TextInputBlock+UIViewRenderableBlock.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension TextInputBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/TransitioningBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/TransitioningBlock+UIViewRenderableBlock.swift index c54fc937..704b6160 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/TransitioningBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/TransitioningBlock+UIViewRenderableBlock.swift @@ -1,7 +1,6 @@ import CoreGraphics import Foundation import UIKit - import VGSL extension TransitioningBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/UIView+TransitioningAnimation.swift b/LayoutKit/LayoutKit/UI/Blocks/UIView+TransitioningAnimation.swift index 58b1d676..5b929ee5 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/UIView+TransitioningAnimation.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/UIView+TransitioningAnimation.swift @@ -1,7 +1,6 @@ import CoreGraphics import Foundation import UIKit - import VGSL extension UIView { diff --git a/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderable.swift b/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderable.swift index d2fe5b95..fd17b820 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderable.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderable.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL public protocol UIViewRenderable { diff --git a/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderableBlockWithLayout.swift b/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderableBlockWithLayout.swift index defb8577..4c7c4ab2 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderableBlockWithLayout.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/UIViewRenderableBlockWithLayout.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL extension BlockWithLayout { diff --git a/LayoutKit/LayoutKit/UI/Blocks/VideoBlock+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/VideoBlock+UIViewRenderableBlock.swift index 880bf425..5d2ed2a1 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/VideoBlock+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/VideoBlock+UIViewRenderableBlock.swift @@ -1,7 +1,6 @@ import CoreMedia import Foundation import UIKit - import VGSL extension VideoBlock { diff --git a/LayoutKit/LayoutKit/UI/Blocks/VideoBlockLegacy+UIViewRenderableBlock.swift b/LayoutKit/LayoutKit/UI/Blocks/VideoBlockLegacy+UIViewRenderableBlock.swift index d0cd3d10..df60fca3 100644 --- a/LayoutKit/LayoutKit/UI/Blocks/VideoBlockLegacy+UIViewRenderableBlock.swift +++ b/LayoutKit/LayoutKit/UI/Blocks/VideoBlockLegacy+UIViewRenderableBlock.swift @@ -1,7 +1,6 @@ import AVFoundation import Foundation import UIKit - import VGSL extension VideoBlockLegacy { diff --git a/LayoutKit/LayoutKit/UI/Views/AnimatingGradientView.swift b/LayoutKit/LayoutKit/UI/Views/AnimatingGradientView.swift index 2e20e2d5..8c9311e2 100644 --- a/LayoutKit/LayoutKit/UI/Views/AnimatingGradientView.swift +++ b/LayoutKit/LayoutKit/UI/Views/AnimatingGradientView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class AnimatingGradientView: UIView { diff --git a/LayoutKit/LayoutKit/UI/Views/Background+UIViewRendering.swift b/LayoutKit/LayoutKit/UI/Views/Background+UIViewRendering.swift index c008339e..244d1ba3 100644 --- a/LayoutKit/LayoutKit/UI/Views/Background+UIViewRendering.swift +++ b/LayoutKit/LayoutKit/UI/Views/Background+UIViewRendering.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL extension Background: UIViewRenderable { diff --git a/LayoutKit/LayoutKit/UI/Views/BoxShadowView.swift b/LayoutKit/LayoutKit/UI/Views/BoxShadowView.swift index 97095361..4d5869a3 100644 --- a/LayoutKit/LayoutKit/UI/Views/BoxShadowView.swift +++ b/LayoutKit/LayoutKit/UI/Views/BoxShadowView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class BoxShadowView: UIView { diff --git a/LayoutKit/LayoutKit/UI/Views/ContextMenuDelegate.swift b/LayoutKit/LayoutKit/UI/Views/ContextMenuDelegate.swift index 27e15fc8..5eaa9575 100644 --- a/LayoutKit/LayoutKit/UI/Views/ContextMenuDelegate.swift +++ b/LayoutKit/LayoutKit/UI/Views/ContextMenuDelegate.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class ContextMenuDelegate: NSObject, UIContextMenuInteractionDelegate { diff --git a/LayoutKit/LayoutKit/UI/Views/GalleryView.swift b/LayoutKit/LayoutKit/UI/Views/GalleryView.swift index c5659ab1..c219f7ea 100644 --- a/LayoutKit/LayoutKit/UI/Views/GalleryView.swift +++ b/LayoutKit/LayoutKit/UI/Views/GalleryView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL private typealias CellType = GenericCollectionViewCell @@ -308,9 +307,13 @@ extension GalleryView: ScrollDelegate { let contentPosition: GalleryViewState.Position if model.infiniteScroll, let newPosition = InfiniteScroll.getNewPosition( currentOffset: offset, - origins: layout.blockFrames.map { model.direction.isHorizontal ? $0.minX : $0.minY } + origins: layout.blockFrames.map { model.direction.isHorizontal ? $0.minX : $0.minY }, + bufferSize: model.bufferSize, + boundsSize: model.direction.isHorizontal ? bounds.width : bounds.height, + alignment: model.alignment ) { offset = newPosition.offset + scrollStartOffset = offset contentPager.flatMap { compoundScrollDelegate.remove($0) } compoundScrollDelegate.remove(self) updateContentOffset(to: .offset(newPosition.offset), animated: false) diff --git a/LayoutKit/LayoutKit/UI/Views/NinePatchImageView.swift b/LayoutKit/LayoutKit/UI/Views/NinePatchImageView.swift index 6e020973..e5eef10d 100644 --- a/LayoutKit/LayoutKit/UI/Views/NinePatchImageView.swift +++ b/LayoutKit/LayoutKit/UI/Views/NinePatchImageView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class NinePatchImageView: UIView, RemoteImageViewContentProtocol { diff --git a/LayoutKit/LayoutKit/UI/Views/SegmentedProgressView.swift b/LayoutKit/LayoutKit/UI/Views/SegmentedProgressView.swift index e823c85c..51d3500a 100644 --- a/LayoutKit/LayoutKit/UI/Views/SegmentedProgressView.swift +++ b/LayoutKit/LayoutKit/UI/Views/SegmentedProgressView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class SegmentedProgressView: UIView { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift index b94aae12..0359444c 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabContentsView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class TabContentsView: BlockView { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListSelectionDataSourceImpl.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListSelectionDataSourceImpl.swift index c76ad35e..a52310ca 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListSelectionDataSourceImpl.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListSelectionDataSourceImpl.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL final class TabListSelectionDataSourceImpl: TabListSelectionDataSource { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift index a811ef84..6ab299ce 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class TabListView: UIView { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDataSource.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDataSource.swift index 0039a7ad..9c2b0e35 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDataSource.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDataSource.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class TabListViewDataSource: NSObject, UICollectionViewDataSource { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDelegate.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDelegate.swift index 78df8e59..cc8c23c1 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDelegate.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabListViewDelegate.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class TabListViewDelegate: NSObject, UICollectionViewDelegateFlowLayout { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabSelectionWireframe.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabSelectionWireframe.swift index da7f785d..13cc0628 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabSelectionWireframe.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabSelectionWireframe.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL final class TabSelectionWireframe { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabTitlesViewModel.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabTitlesViewModel.swift index 846e9e25..54745956 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabTitlesViewModel.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabTitlesViewModel.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL struct TabTitlesViewModel { diff --git a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift index ae20a940..9585a40b 100644 --- a/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift +++ b/LayoutKit/LayoutKit/UI/Views/TabbedPages/TabbedPagesView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class TabbedPagesView: BlockView, VisibleBoundsTrackingContainer { diff --git a/LayoutKit/LayoutKit/UI/Views/URLActionHandlingView.swift b/LayoutKit/LayoutKit/UI/Views/URLActionHandlingView.swift index 721db20e..91deb84b 100644 --- a/LayoutKit/LayoutKit/UI/Views/URLActionHandlingView.swift +++ b/LayoutKit/LayoutKit/UI/Views/URLActionHandlingView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class URLActionHandlingView: UIView, UIActionEventPerforming { diff --git a/LayoutKit/LayoutKit/UI/Views/ViewWithContentInsets.swift b/LayoutKit/LayoutKit/UI/Views/ViewWithContentInsets.swift index 2e2cf793..d22f0ad3 100644 --- a/LayoutKit/LayoutKit/UI/Views/ViewWithContentInsets.swift +++ b/LayoutKit/LayoutKit/UI/Views/ViewWithContentInsets.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL final class ViewWithContentInsets: UIView { diff --git a/LayoutKit/LayoutKit/UI/Views/ViewWithShadow.swift b/LayoutKit/LayoutKit/UI/Views/ViewWithShadow.swift index 14063824..a601ca38 100644 --- a/LayoutKit/LayoutKit/UI/Views/ViewWithShadow.swift +++ b/LayoutKit/LayoutKit/UI/Views/ViewWithShadow.swift @@ -1,6 +1,5 @@ import Foundation import UIKit - import VGSL open class ViewWithShadow: UIView { diff --git a/LayoutKit/LayoutKit/UI/Views/VisibleBoundsTrackingCollectionView.swift b/LayoutKit/LayoutKit/UI/Views/VisibleBoundsTrackingCollectionView.swift index 8b98812a..9b4d9821 100644 --- a/LayoutKit/LayoutKit/UI/Views/VisibleBoundsTrackingCollectionView.swift +++ b/LayoutKit/LayoutKit/UI/Views/VisibleBoundsTrackingCollectionView.swift @@ -1,5 +1,4 @@ import UIKit - import VGSL public final class VisibleBoundsTrackingCollectionView: NoContentTouchDelaysCollectionView, diff --git a/LayoutKit/LayoutKit/ViewModels/GalleryViewLayout.swift b/LayoutKit/LayoutKit/ViewModels/GalleryViewLayout.swift index bb3eb7ea..c62f4f37 100644 --- a/LayoutKit/LayoutKit/ViewModels/GalleryViewLayout.swift +++ b/LayoutKit/LayoutKit/ViewModels/GalleryViewLayout.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public protocol GalleryViewLayouting { diff --git a/LayoutKit/LayoutKit/ViewModels/GalleryViewMetrics.swift b/LayoutKit/LayoutKit/ViewModels/GalleryViewMetrics.swift index 1f09791e..52d73f7e 100644 --- a/LayoutKit/LayoutKit/ViewModels/GalleryViewMetrics.swift +++ b/LayoutKit/LayoutKit/ViewModels/GalleryViewMetrics.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public struct GalleryViewMetrics: Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/GalleryViewModel.swift b/LayoutKit/LayoutKit/ViewModels/GalleryViewModel.swift index 6f394d81..01263733 100644 --- a/LayoutKit/LayoutKit/ViewModels/GalleryViewModel.swift +++ b/LayoutKit/LayoutKit/ViewModels/GalleryViewModel.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL #if canImport(UIKit) @@ -43,7 +42,9 @@ public struct GalleryViewModel: Equatable { public let metrics: GalleryViewMetrics public let scrollMode: ScrollMode public let path: UIElementPath + public let alignment: Alignment public let direction: ScrollDirection + public let bufferSize: Int public let columnCount: Int public let areEmptySpaceTouchesEnabled: Bool public let alwaysBounceVertical: Bool @@ -58,7 +59,9 @@ public struct GalleryViewModel: Equatable { metrics: GalleryViewMetrics, scrollMode: ScrollMode = .default, path: UIElementPath, + alignment: Alignment = .center, direction: ScrollDirection = .horizontal, + bufferSize: Int = 0, columnCount: Int = 1, crossAlignment: Alignment = .leading, areEmptySpaceTouchesEnabled: Bool = true, @@ -74,7 +77,9 @@ public struct GalleryViewModel: Equatable { metrics: metrics, scrollMode: scrollMode, path: path, + alignment: alignment, direction: direction, + bufferSize: bufferSize, columnCount: columnCount, areEmptySpaceTouchesEnabled: areEmptySpaceTouchesEnabled, alwaysBounceVertical: alwaysBounceVertical, @@ -91,7 +96,9 @@ public struct GalleryViewModel: Equatable { metrics: GalleryViewMetrics, scrollMode: ScrollMode = .default, path: UIElementPath, + alignment: Alignment = .center, direction: ScrollDirection = .horizontal, + bufferSize: Int = 0, columnCount: Int = 1, areEmptySpaceTouchesEnabled: Bool = true, alwaysBounceVertical: Bool = false, @@ -109,7 +116,9 @@ public struct GalleryViewModel: Equatable { self.metrics = metrics self.scrollMode = scrollMode self.path = path + self.alignment = alignment self.direction = direction + self.bufferSize = bufferSize self.columnCount = columnCount self.areEmptySpaceTouchesEnabled = areEmptySpaceTouchesEnabled self.alwaysBounceVertical = alwaysBounceVertical @@ -124,6 +133,7 @@ public struct GalleryViewModel: Equatable { metrics: GalleryViewMetrics? = nil, scrollMode: ScrollMode? = nil, path: UIElementPath? = nil, + bufferSize: Int? = nil, direction: ScrollDirection? = nil, areEmptySpaceTouchesEnabled: Bool? = nil ) -> GalleryViewModel { @@ -133,6 +143,7 @@ public struct GalleryViewModel: Equatable { scrollMode: scrollMode ?? self.scrollMode, path: path ?? self.path, direction: direction ?? self.direction, + bufferSize: bufferSize ?? self.bufferSize, areEmptySpaceTouchesEnabled: areEmptySpaceTouchesEnabled ?? self.areEmptySpaceTouchesEnabled ) } @@ -142,7 +153,7 @@ public struct GalleryViewModel: Equatable { } var infiniteCorrection: Int { - infiniteScroll && items.count > 0 ? 1 : 0 + infiniteScroll && items.count > 0 ? bufferSize : 0 } } diff --git a/LayoutKit/LayoutKit/ViewModels/GalleryViewState.swift b/LayoutKit/LayoutKit/ViewModels/GalleryViewState.swift index 6590250e..7f6197b3 100644 --- a/LayoutKit/LayoutKit/ViewModels/GalleryViewState.swift +++ b/LayoutKit/LayoutKit/ViewModels/GalleryViewState.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public struct GalleryViewState: ElementState, Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/InfiniteScroll.swift b/LayoutKit/LayoutKit/ViewModels/InfiniteScroll.swift index 6fbdda6f..709592cc 100644 --- a/LayoutKit/LayoutKit/ViewModels/InfiniteScroll.swift +++ b/LayoutKit/LayoutKit/ViewModels/InfiniteScroll.swift @@ -1,23 +1,58 @@ import Foundation +import VGSLUI + enum InfiniteScroll { struct Position: Equatable { let offset: CGFloat let page: Int } - static func getNewPosition(currentOffset: CGFloat, origins: [CGFloat]) -> Position? { - guard origins.count > 2 else { - return nil - } + static func getNewPosition( + currentOffset: CGFloat, + origins: [CGFloat], + bufferSize: Int, + boundsSize: CGFloat = 0, + alignment: Alignment = .center + ) -> Position? { + guard origins.count > 2 else { return nil } + let itemsCount = origins.count - let cycleSize = origins[itemsCount - 1] - origins[1] - let jumpOffset = cycleSize / CGFloat((itemsCount - 2) * 2) + origins[0] - if currentOffset < jumpOffset { - return Position(offset: currentOffset + cycleSize, page: itemsCount - 2) - } else if currentOffset > cycleSize + jumpOffset { - return Position(offset: currentOffset - cycleSize, page: 1) + let cycleStartIndex = bufferSize + let cycleEndIndex = itemsCount - bufferSize - 1 + + let cycleSize = origins[cycleEndIndex + 1] - origins[cycleStartIndex] + let correctedOffset = currentOffset + alignment.offset(bounds: boundsSize) + + if correctedOffset < origins[cycleStartIndex] + alignment.correction { + return Position(offset: currentOffset + cycleSize, page: cycleEndIndex) + } else if correctedOffset > origins[cycleEndIndex + 1] + alignment.correction { + return Position(offset: currentOffset - cycleSize, page: cycleStartIndex) } return nil } } + +extension Alignment { + fileprivate var correction: CGFloat { + switch self { + case .leading: + -1 + case .center: + 0 + case .trailing: + 1 + } + } + + fileprivate func offset(bounds: CGFloat) -> CGFloat { + switch self { + case .leading: + 0 + case .center: + bounds / 2 + case .trailing: + bounds + } + } +} diff --git a/LayoutKit/LayoutKit/ViewModels/InsetMode.swift b/LayoutKit/LayoutKit/ViewModels/InsetMode.swift index 5fc94457..95567899 100644 --- a/LayoutKit/LayoutKit/ViewModels/InsetMode.swift +++ b/LayoutKit/LayoutKit/ViewModels/InsetMode.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public enum InsetMode: Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/PagerViewLayout.swift b/LayoutKit/LayoutKit/ViewModels/PagerViewLayout.swift index fb970889..102bf4c6 100644 --- a/LayoutKit/LayoutKit/ViewModels/PagerViewLayout.swift +++ b/LayoutKit/LayoutKit/ViewModels/PagerViewLayout.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public struct PagerViewLayout: GalleryViewLayouting, Equatable { @@ -47,8 +46,7 @@ public struct PagerViewLayout: GalleryViewLayouting, Equatable { blockPages = model.pages( for: blockFrames, fitting: boundsSize, - alignment: alignment, - layoutMode: layoutMode + alignment: alignment ) let contentSize = model.contentSize( @@ -121,8 +119,7 @@ extension GalleryViewModel { fileprivate func pages( for frames: [CGRect], fitting size: CGSize?, - alignment: Alignment, - layoutMode: PagerBlock.LayoutMode + alignment: Alignment ) -> [PagerViewLayout.Page] { let bound = (size ?? .zero).dimension(in: direction) let contentSize = contentSize( diff --git a/LayoutKit/LayoutKit/ViewModels/PagerViewState.swift b/LayoutKit/LayoutKit/ViewModels/PagerViewState.swift index 3b6b63fb..49416826 100644 --- a/LayoutKit/LayoutKit/ViewModels/PagerViewState.swift +++ b/LayoutKit/LayoutKit/ViewModels/PagerViewState.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct PagerViewState: ElementState, Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewLayout.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewLayout.swift index 1f7d064e..5dc1b38c 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewLayout.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewLayout.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL struct TabContentsViewLayout: Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewModel.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewModel.swift index 3a8d6e31..6c447657 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewModel.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabContentsViewModel.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL #if canImport(UIKit) diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabInterimItemExtensions.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabInterimItemExtensions.swift index 339566f2..25375293 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabInterimItemExtensions.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabInterimItemExtensions.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL extension [CGFloat] { diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabListViewModel.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabListViewModel.swift index 2c0122a2..ce9b6582 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabListViewModel.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabListViewModel.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL #if canImport(UIKit) diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabSeparatorStyle.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabSeparatorStyle.swift index 3b500fea..78cf5f2a 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabSeparatorStyle.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabSeparatorStyle.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL #if canImport(UIKit) diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleStyle.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleStyle.swift index 810658df..c2f6a3e5 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleStyle.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleStyle.swift @@ -1,5 +1,4 @@ import CoreGraphics - import VGSL public struct TabTitleStyle: Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleViewModel.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleViewModel.swift index 63397bc1..7d3b3c9b 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleViewModel.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabTitleViewModel.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL final class TabTitleViewModel: Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewModel.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewModel.swift index b176579f..aa4c9420 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewModel.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewModel.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public final class TabViewModel: Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift index 445ac990..ff9d12ae 100644 --- a/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift +++ b/LayoutKit/LayoutKit/ViewModels/TabbedPages/TabViewState.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public struct TabViewState: ElementState, Equatable { diff --git a/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformer.swift b/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformer.swift index 081f77ee..312ad0c1 100644 --- a/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformer.swift +++ b/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformer.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public enum VisibilityActionType: String { diff --git a/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformers.swift b/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformers.swift index 456cef85..15dcc63e 100644 --- a/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformers.swift +++ b/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityActionPerformers.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL final class VisibilityActionPerformers { diff --git a/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityParams.swift b/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityParams.swift index 9ba45dfa..49ffbce1 100644 --- a/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityParams.swift +++ b/LayoutKit/LayoutKit/ViewModels/VisibilityActionPerformer/VisibilityParams.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL public struct VisibilityParams: Equatable { diff --git a/Serialization/DeserializationResult.swift b/Serialization/DeserializationResult.swift index d97b49bc..df64f116 100644 --- a/Serialization/DeserializationResult.swift +++ b/Serialization/DeserializationResult.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL @frozen diff --git a/Serialization/Dictionary+Serialization.swift b/Serialization/Dictionary+Serialization.swift index 399840ee..bb96b125 100644 --- a/Serialization/Dictionary+Serialization.swift +++ b/Serialization/Dictionary+Serialization.swift @@ -1,6 +1,5 @@ import CoreFoundation import Foundation - import VGSL // MARK: Utils @@ -424,7 +423,7 @@ extension Dictionary where Key == String { } public func getObjCCompatibleBool(_ key: Key...) -> Bool? { - (try? self.getField(key, transform: { $0 as NSString }, validator: nil) as NSString)?.boolValue + (try? self.getField(key, transform: { ($0 as NSString).boolValue }, validator: nil)) ?? (try? self.getField(key, transform: { $0 as Bool }, validator: nil) as Bool) } } diff --git a/Serialization/Serializable.swift b/Serialization/Serializable.swift index a34f1454..ed93ef70 100644 --- a/Serialization/Serializable.swift +++ b/Serialization/Serializable.swift @@ -1,6 +1,5 @@ import CoreGraphics import Foundation - import VGSL public protocol ValidSerializationValue {} diff --git a/Serialization/SettingProperty+Serializable.swift b/Serialization/SettingProperty+Serializable.swift index aca208a1..9338f44a 100644 --- a/Serialization/SettingProperty+Serializable.swift +++ b/Serialization/SettingProperty+Serializable.swift @@ -1,5 +1,4 @@ import Foundation - import VGSL extension SettingProperty where T: Serializable & Deserializable { diff --git a/Serialization/Validation.swift b/Serialization/Validation.swift index 3aa98a88..46c04d8d 100644 --- a/Serialization/Validation.swift +++ b/Serialization/Validation.swift @@ -1,7 +1,7 @@ import CoreFoundation import Foundation -public class AnyValueValidator { +public class AnyValueValidator: @unchecked Sendable { private let validate: (T) -> Bool public init(_ isValid: @escaping (T) -> Bool) { @@ -13,7 +13,8 @@ public class AnyValueValidator { } } -public final class AnyArrayValueValidator: AnyValueValidator<[U]> {} +public final class AnyArrayValueValidator: + AnyValueValidator<[T]>, @unchecked Sendable {} public func makeCFStringValidator(minLength: Int) -> AnyValueValidator { AnyValueValidator { CFStringGetLength($0) >= minLength } diff --git a/Serialization/ValueDeserialization.swift b/Serialization/ValueDeserialization.swift index 69a41564..f39e99e9 100644 --- a/Serialization/ValueDeserialization.swift +++ b/Serialization/ValueDeserialization.swift @@ -1,5 +1,4 @@ import CoreFoundation - import VGSL @inlinable diff --git a/Specs/DivKit/30.33.0/DivKit.podspec b/Specs/DivKit/30.33.0/DivKit.podspec new file mode 100644 index 00000000..c2c0a555 --- /dev/null +++ b/Specs/DivKit/30.33.0/DivKit.podspec @@ -0,0 +1,24 @@ +Pod::Spec.new do |s| + s.name = 'DivKit' + s.version = '30.33.0' + s.summary = 'DivKit framework' + s.description = 'DivKit is a backend-driven UI framework' + s.homepage = 'https://divkit.tech' + + s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' } + s.author = { 'divkit' => 'divkit@yandex-team.ru' } + s.source = { :git => 'https://github.com/divkit/divkit-ios.git', :tag => s.version.to_s } + + s.swift_version = '5.9' + s.requires_arc = true + s.prefix_header_file = false + s.platforms = { :ios => '13.0' } + + s.dependency 'DivKit_LayoutKit', s.version.to_s + s.dependency 'DivKit_Serialization', s.version.to_s + s.dependency 'VGSL', '~> 6.0' + + s.source_files = [ + 'DivKit/**/*' + ] +end diff --git a/Specs/DivKitExtensions/30.33.0/DivKitExtensions.podspec b/Specs/DivKitExtensions/30.33.0/DivKitExtensions.podspec new file mode 100644 index 00000000..f9d4d1f9 --- /dev/null +++ b/Specs/DivKitExtensions/30.33.0/DivKitExtensions.podspec @@ -0,0 +1,22 @@ +Pod::Spec.new do |s| + s.name = 'DivKitExtensions' + s.version = '30.33.0' + s.summary = 'DivKit framework extensions' + s.description = 'Part of DivKit framework' + s.homepage = 'https://divkit.tech' + + s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' } + s.author = { 'divkit' => 'divkit@yandex-team.ru' } + s.source = { :git => 'https://github.com/divkit/divkit-ios.git', :tag => s.version.to_s } + + s.swift_version = '5.9' + s.requires_arc = true + s.prefix_header_file = false + s.platforms = { :ios => '13.0' } + + s.dependency 'DivKit', s.version.to_s + + s.source_files = [ + 'DivKitExtensions/**/*' + ] +end diff --git a/Specs/DivKit_LayoutKit/30.33.0/DivKit_LayoutKit.podspec b/Specs/DivKit_LayoutKit/30.33.0/DivKit_LayoutKit.podspec new file mode 100644 index 00000000..efd0c063 --- /dev/null +++ b/Specs/DivKit_LayoutKit/30.33.0/DivKit_LayoutKit.podspec @@ -0,0 +1,24 @@ +Pod::Spec.new do |s| + s.name = 'DivKit_LayoutKit' + s.module_name = 'LayoutKit' + s.version = '30.33.0' + s.summary = 'Part of DivKit framework' + s.description = 'Part of DivKit framework' + s.homepage = 'https://divkit.tech' + + s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' } + s.author = { 'divkit' => 'divkit@yandex-team.ru' } + s.source = { :git => 'https://github.com/divkit/divkit-ios.git', :tag => s.version.to_s } + + s.swift_version = '5.9' + s.requires_arc = true + s.prefix_header_file = false + s.platforms = { :ios => '13.0' } + + s.dependency 'DivKit_LayoutKitInterface', s.version.to_s + s.dependency 'VGSL', '~> 6.0' + + s.source_files = [ + 'LayoutKit/LayoutKit/**/*' + ] +end diff --git a/Specs/DivKit_LayoutKitInterface/30.33.0/DivKit_LayoutKitInterface.podspec b/Specs/DivKit_LayoutKitInterface/30.33.0/DivKit_LayoutKitInterface.podspec new file mode 100644 index 00000000..f7041692 --- /dev/null +++ b/Specs/DivKit_LayoutKitInterface/30.33.0/DivKit_LayoutKitInterface.podspec @@ -0,0 +1,23 @@ +Pod::Spec.new do |s| + s.name = 'DivKit_LayoutKitInterface' + s.module_name = 'LayoutKitInterface' + s.version = '30.33.0' + s.summary = 'Part of DivKit framework' + s.description = 'Part of DivKit framework' + s.homepage = 'https://divkit.tech' + + s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' } + s.author = { 'divkit' => 'divkit@yandex-team.ru' } + s.source = { :git => 'https://github.com/divkit/divkit-ios.git', :tag => s.version.to_s } + + s.swift_version = '5.9' + s.requires_arc = true + s.prefix_header_file = false + s.platforms = { :ios => '13.0' } + + s.dependency 'VGSL', '~> 6.0' + + s.source_files = [ + 'LayoutKit/Interface/**/*' + ] +end diff --git a/Specs/DivKit_Serialization/30.33.0/DivKit_Serialization.podspec b/Specs/DivKit_Serialization/30.33.0/DivKit_Serialization.podspec new file mode 100644 index 00000000..b980c0a7 --- /dev/null +++ b/Specs/DivKit_Serialization/30.33.0/DivKit_Serialization.podspec @@ -0,0 +1,23 @@ +Pod::Spec.new do |s| + s.name = 'DivKit_Serialization' + s.module_name = 'Serialization' + s.version = '30.33.0' + s.summary = 'Part of DivKit framework' + s.description = 'Part of DivKit framework' + s.homepage = 'https://divkit.tech' + + s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' } + s.author = { 'divkit' => 'divkit@yandex-team.ru' } + s.source = { :git => 'https://github.com/divkit/divkit-ios.git', :tag => s.version.to_s } + + s.swift_version = '5.9' + s.requires_arc = true + s.prefix_header_file = false + s.platforms = { :ios => '13.0' } + + s.dependency 'VGSL', '~> 6.0' + + s.source_files = [ + 'Serialization/**/*' + ] +end