Skip to content

Commit

Permalink
Release 31.4.0
Browse files Browse the repository at this point in the history
commit_hash:c9da53d5b9f7ff9c09528efe3347b0765e59ec78
  • Loading branch information
robot-divkit committed Feb 24, 2025
1 parent 1bf4af4 commit 171c07e
Show file tree
Hide file tree
Showing 33 changed files with 884 additions and 127 deletions.
12 changes: 12 additions & 0 deletions .mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,12 @@
"DivKit/generated_sources/DivStretchIndicatorItemPlacement.swift":"divkit/public-ios/DivKit/generated_sources/DivStretchIndicatorItemPlacement.swift",
"DivKit/generated_sources/DivStretchIndicatorItemPlacementTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivStretchIndicatorItemPlacementTemplate.swift",
"DivKit/generated_sources/DivStroke.swift":"divkit/public-ios/DivKit/generated_sources/DivStroke.swift",
"DivKit/generated_sources/DivStrokeStyle.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeStyle.swift",
"DivKit/generated_sources/DivStrokeStyleDashed.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeStyleDashed.swift",
"DivKit/generated_sources/DivStrokeStyleDashedTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeStyleDashedTemplate.swift",
"DivKit/generated_sources/DivStrokeStyleSolid.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeStyleSolid.swift",
"DivKit/generated_sources/DivStrokeStyleSolidTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeStyleSolidTemplate.swift",
"DivKit/generated_sources/DivStrokeStyleTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeStyleTemplate.swift",
"DivKit/generated_sources/DivStrokeTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivStrokeTemplate.swift",
"DivKit/generated_sources/DivSwitch.swift":"divkit/public-ios/DivKit/generated_sources/DivSwitch.swift",
"DivKit/generated_sources/DivSwitchTemplate.swift":"divkit/public-ios/DivKit/generated_sources/DivSwitchTemplate.swift",
Expand Down Expand Up @@ -627,6 +633,7 @@
"LayoutKit/LayoutKit/Blocks/BlockError.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlockError.swift",
"LayoutKit/LayoutKit/Blocks/BlockTooltip+Layout.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlockTooltip+Layout.swift",
"LayoutKit/LayoutKit/Blocks/BlockTooltip.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlockTooltip.swift",
"LayoutKit/LayoutKit/Blocks/BlockTooltipParams.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlockTooltipParams.swift",
"LayoutKit/LayoutKit/Blocks/BlockWithLayout.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlockWithLayout.swift",
"LayoutKit/LayoutKit/Blocks/BlockWithTraits.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlockWithTraits.swift",
"LayoutKit/LayoutKit/Blocks/BlocksStateExtensions.swift":"divkit/public-ios/LayoutKit/LayoutKit/Blocks/BlocksStateExtensions.swift",
Expand Down Expand Up @@ -1040,6 +1047,7 @@
"Specs/DivKit/31.1.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/31.1.0/DivKit.podspec",
"Specs/DivKit/31.2.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/31.2.0/DivKit.podspec",
"Specs/DivKit/31.3.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/31.3.0/DivKit.podspec",
"Specs/DivKit/31.4.0/DivKit.podspec":"divkit/public-ios/Specs/DivKit/31.4.0/DivKit.podspec",
"Specs/DivKitExtensions/24.3.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/24.3.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/25.0.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/25.0.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/25.1.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/25.1.0/DivKitExtensions.podspec",
Expand Down Expand Up @@ -1129,6 +1137,7 @@
"Specs/DivKitExtensions/31.1.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/31.1.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/31.2.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/31.2.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/31.3.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/31.3.0/DivKitExtensions.podspec",
"Specs/DivKitExtensions/31.4.0/DivKitExtensions.podspec":"divkit/public-ios/Specs/DivKitExtensions/31.4.0/DivKitExtensions.podspec",
"Specs/DivKit_LayoutKit/28.0.1/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.0.1/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.1.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.1.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/28.10.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/28.10.0/DivKit_LayoutKit.podspec",
Expand Down Expand Up @@ -1200,6 +1209,7 @@
"Specs/DivKit_LayoutKit/31.1.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/31.1.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/31.2.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/31.2.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/31.3.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/31.3.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKit/31.4.0/DivKit_LayoutKit.podspec":"divkit/public-ios/Specs/DivKit_LayoutKit/31.4.0/DivKit_LayoutKit.podspec",
"Specs/DivKit_LayoutKitInterface/28.0.1/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.0.1/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.1.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.1.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/28.10.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/28.10.0/DivKit_LayoutKitInterface.podspec",
Expand Down Expand Up @@ -1271,6 +1281,7 @@
"Specs/DivKit_LayoutKitInterface/31.1.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/31.1.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/31.2.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/31.2.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/31.3.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/31.3.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_LayoutKitInterface/31.4.0/DivKit_LayoutKitInterface.podspec":"divkit/public-ios/Specs/DivKit_LayoutKitInterface/31.4.0/DivKit_LayoutKitInterface.podspec",
"Specs/DivKit_Serialization/28.0.1/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.0.1/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.1.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.1.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/28.10.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/28.10.0/DivKit_Serialization.podspec",
Expand Down Expand Up @@ -1342,6 +1353,7 @@
"Specs/DivKit_Serialization/31.1.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/31.1.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/31.2.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/31.2.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/31.3.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/31.3.0/DivKit_Serialization.podspec",
"Specs/DivKit_Serialization/31.4.0/DivKit_Serialization.podspec":"divkit/public-ios/Specs/DivKit_Serialization/31.4.0/DivKit_Serialization.podspec",
"Specs/LayoutKit/24.3.0/LayoutKit.podspec":"divkit/public-ios/Specs/LayoutKit/24.3.0/LayoutKit.podspec",
"Specs/LayoutKit/25.0.0/LayoutKit.podspec":"divkit/public-ios/Specs/LayoutKit/25.0.0/LayoutKit.podspec",
"Specs/LayoutKit/25.1.0/LayoutKit.podspec":"divkit/public-ios/Specs/LayoutKit/25.1.0/LayoutKit.podspec",
Expand Down
2 changes: 1 addition & 1 deletion DivKit/DivKitInfo.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
public enum DivKitInfo {
public static let version = "31.3.0"
public static let version = "31.4.0"
}
19 changes: 19 additions & 0 deletions DivKit/Expressions/Serialization/FieldExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,23 @@ extension Field {
}
return result
}

@inlinable
func resolveOptionalValue<U: ValidSerializationValue, E>(
context: TemplatesContext,
transform: (U) -> E?,
validator: AnyArrayValueValidator<Expression<E>>
) -> DeserializationResult<T> where T == [Expression<E>] {
let result = resolveValue(
context: context,
transform: transform,
validator: validator
)
if case let .failure(errors) = result,
errors.count == 1,
case .noData = errors.first {
return .noValue
}
return result
}
}
5 changes: 1 addition & 4 deletions DivKit/Extensions/DivBackgroundExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ extension DivBackground {
let expressionResolver = context.expressionResolver
switch self {
case let .divLinearGradient(gradient):
return Gradient.Linear(
colors: gradient.resolveColors(expressionResolver) ?? [],
angle: gradient.resolveAngle(expressionResolver)
).map { .gradient(.linear($0)) }
return gradient.makeBlockLinearGradient(context).map { .gradient(.linear($0)) }
case let .divRadialGradient(gradient):
return Gradient.Radial(
colors: gradient.resolveColors(expressionResolver) ?? [],
Expand Down
10 changes: 10 additions & 0 deletions DivKit/Extensions/DivBase/DivBaseExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ extension DivBorder {
return nil
}
return BlockBorder(
style: stroke.resolveStyle(expressionResolver),
color: stroke.resolveColor(expressionResolver) ?? .black,
width: stroke.resolveUnit(expressionResolver)
.makeScaledValue(stroke.resolveWidth(expressionResolver))
Expand Down Expand Up @@ -440,6 +441,15 @@ extension DivBorder {
}
}

extension DivStroke {
fileprivate func resolveStyle(_: ExpressionResolver) -> BlockBorder.Style {
switch style {
case .divStrokeStyleDashed: BlockBorder.Style.dashed
case .divStrokeStyleSolid: BlockBorder.Style.solid
}
}
}

extension DivBlockModelingContext {
fileprivate func makeVisibilityParams(
actions: [VisibilityAction],
Expand Down
27 changes: 13 additions & 14 deletions DivKit/Extensions/DivTextExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ extension DivText: DivBlockModeling {
widthTrait: resolveContentWidthTrait(context),
heightTrait: resolveContentHeightTrait(context),
text: attributedString,
textGradient: resolveGradient(expressionResolver),
textGradient: resolveGradient(context),
verticalAlignment: resolveTextAlignmentVertical(expressionResolver).alignment,
maxIntrinsicNumberOfLines: resolveMaxLines(expressionResolver) ?? .max,
minNumberOfHiddenLines: resolveMinHiddenLines(expressionResolver) ?? 0,
Expand All @@ -120,7 +120,8 @@ extension DivText: DivBlockModeling {
additionalTextInsets: additionalTextInsets,
canSelect: resolveSelectable(expressionResolver),
tightenWidth: resolveTightenWidth(expressionResolver),
autoEllipsize: resolveAutoEllipsize(expressionResolver) ?? context.flagsInfo.defaultTextAutoEllipsize
autoEllipsize: resolveAutoEllipsize(expressionResolver) ?? context.flagsInfo
.defaultTextAutoEllipsize
)
}

Expand Down Expand Up @@ -152,11 +153,11 @@ extension DivText: DivBlockModeling {
guard let text else {
return []
}
return (images ?? []).compactMap {
return (images ?? []).compactMap {
$0.makeImage(
context: context,
context: context,
textLength: CFAttributedStringGetLength(text)
)
)
}
}

Expand Down Expand Up @@ -231,16 +232,14 @@ extension DivText: DivBlockModeling {
}
}

private func resolveGradient(_ expressionResolver: ExpressionResolver) -> Gradient? {
private func resolveGradient(_ context: DivBlockModelingContext) -> Gradient? {
let expressionResolver = context.expressionResolver
guard let textGradient else {
return nil
}
switch textGradient {
case let .divLinearGradient(gradient):
return Gradient.Linear(
colors: gradient.resolveColors(expressionResolver) ?? [],
angle: gradient.resolveAngle(expressionResolver)
).map { .linear($0) }
return gradient.makeBlockLinearGradient(context).map { .linear($0) }
case let .divRadialGradient(gradient):
return Gradient.Radial(
colors: gradient.resolveColors(expressionResolver) ?? [],
Expand Down Expand Up @@ -317,19 +316,19 @@ extension DivText.Image {
) -> TextBlock.InlineImage? {
let expressionResolver = context.expressionResolver
let start = resolveStart(expressionResolver) ?? 0

guard start <= textLength else {
return nil
}

let indexingDirection = resolveIndexingDirection(expressionResolver)
let location = switch indexingDirection {
case .normal:
case .normal:
start
case .reversed:
textLength - start
}

return TextBlock.InlineImage(
size: CGSize(
width: CGFloat(width.resolveValue(expressionResolver) ?? 0),
Expand Down
14 changes: 8 additions & 6 deletions DivKit/Extensions/DivTooltipExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,19 @@ extension DivTooltip {
}

return try BlockTooltip(
id: id,
// Legacy behavior. Views should be created with tooltipViewFactory.
block: div.value.makeBlock(context: context),
duration: TimeInterval(milliseconds: resolveDuration(expressionResolver)),
params: BlockTooltipParams(
id: id,
mode: mode,
duration: TimeInterval(milliseconds: resolveDuration(expressionResolver)),
closeByTapOutside: resolveCloseByTapOutside(expressionResolver),
tapOutsideActions: tapOutsideActions?.uiActions(context: context) ?? []
),
offset: offset?.resolve(expressionResolver) ?? .zero,
position: position,
useLegacyWidth: context.flagsInfo.useTooltipLegacyWidth,
tooltipViewFactory: tooltipViewFactory,
closeByTapOutside: resolveCloseByTapOutside(expressionResolver),
tapOutsideActions: tapOutsideActions?.uiActions(context: context) ?? [],
mode: mode
tooltipViewFactory: tooltipViewFactory
)
}
}
Expand Down
48 changes: 48 additions & 0 deletions DivKit/Extensions/GradientExtentions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ import Foundation
import VGSL

extension Gradient.Linear {
init?(points: [Gradient.Point], angle: Int) {
guard points.count >= 2 else { return nil }
let sortedPoints = points.stableSort(isLessOrEqual: { $0.location <= $1.location })

guard let start = sortedPoints.first, let end = sortedPoints.last
else { return nil }

self.init(
startColor: start.color,
intermediatePoints: sortedPoints,
endColor: end.color,
direction: .init(angle: angle)
)
}

init?(colors: [Color], angle: Int) {
guard colors.count >= 2 else {
return nil
Expand Down Expand Up @@ -65,6 +80,39 @@ extension Gradient.Radial {
}
}

extension DivLinearGradient {
func makeBlockLinearGradient(
_ context: DivBlockModelingContext
) -> Gradient.Linear? {
let expressionResolver = context.expressionResolver

if let colorMap {
let points: [Gradient.Point] = colorMap.compactMap { positionedColor -> Gradient.Point? in
if let color = positionedColor.resolveColor(expressionResolver),
let position = positionedColor.resolvePosition(expressionResolver) {
return (color: color, location: CGFloat(position))
}
return nil
}

return Gradient.Linear(
points: points,
angle: resolveAngle(expressionResolver)
)
} else if let colors = resolveColors(expressionResolver) {
return Gradient.Linear(
colors: colors,
angle: resolveAngle(expressionResolver)
)
} else {
context.addError(
message: "No colors specified in the linear gradient in the `colors` or `color_map` fields"
)
return nil
}
}
}

extension DivRadialGradient {
func resolveRadius(_ resolver: ExpressionResolver) -> Gradient.Radial.Radius {
switch radius {
Expand Down
63 changes: 59 additions & 4 deletions DivKit/generated_sources/DivLinearGradient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,59 @@ import Serialization
import VGSL

public final class DivLinearGradient: Sendable {
public final class ColorPoint: Sendable {
public let color: Expression<Color>
public let position: Expression<Double> // constraint: number >= 0.0 && number <= 1.0

public func resolveColor(_ resolver: ExpressionResolver) -> Color? {
resolver.resolveColor(color)
}

public func resolvePosition(_ resolver: ExpressionResolver) -> Double? {
resolver.resolveNumeric(position)
}

static let positionValidator: AnyValueValidator<Double> =
makeValueValidator(valueValidator: { $0 >= 0.0 && $0 <= 1.0 })

init(
color: Expression<Color>,
position: Expression<Double>
) {
self.color = color
self.position = position
}
}

public static let type: String = "gradient"
public let angle: Expression<Int> // constraint: number >= 0 && number <= 360; default value: 0
public let colors: [Expression<Color>] // at least 2 elements
public let colorMap: [ColorPoint]? // at least 2 elements
public let colors: [Expression<Color>]? // at least 2 elements

public func resolveAngle(_ resolver: ExpressionResolver) -> Int {
resolver.resolveNumeric(angle) ?? 0
}

public func resolveColors(_ resolver: ExpressionResolver) -> [Color]? {
colors.map { resolver.resolveColor($0) }.compactMap { $0 }
colors?.map { resolver.resolveColor($0) }.compactMap { $0 }
}

static let angleValidator: AnyValueValidator<Int> =
makeValueValidator(valueValidator: { $0 >= 0 && $0 <= 360 })

static let colorMapValidator: AnyArrayValueValidator<DivLinearGradient.ColorPoint> =
makeArrayValidator(minItems: 2)

static let colorsValidator: AnyArrayValueValidator<Expression<Color>> =
makeArrayValidator(minItems: 2)

init(
angle: Expression<Int>? = nil,
colors: [Expression<Color>]
colorMap: [ColorPoint]? = nil,
colors: [Expression<Color>]? = nil
) {
self.angle = angle ?? .value(0)
self.colorMap = colorMap
self.colors = colors
}
}
Expand All @@ -37,6 +67,7 @@ extension DivLinearGradient: Equatable {
public static func ==(lhs: DivLinearGradient, rhs: DivLinearGradient) -> Bool {
guard
lhs.angle == rhs.angle,
lhs.colorMap == rhs.colorMap,
lhs.colors == rhs.colors
else {
return false
Expand All @@ -51,7 +82,31 @@ extension DivLinearGradient: Serializable {
var result: [String: ValidSerializationValue] = [:]
result["type"] = Self.type
result["angle"] = angle.toValidSerializationValue()
result["colors"] = colors.map { $0.toValidSerializationValue() }
result["color_map"] = colorMap?.map { $0.toDictionary() }
result["colors"] = colors?.map { $0.toValidSerializationValue() }
return result
}
}

#if DEBUG
extension DivLinearGradient.ColorPoint: Equatable {
public static func ==(lhs: DivLinearGradient.ColorPoint, rhs: DivLinearGradient.ColorPoint) -> Bool {
guard
lhs.color == rhs.color,
lhs.position == rhs.position
else {
return false
}
return true
}
}
#endif

extension DivLinearGradient.ColorPoint: Serializable {
public func toDictionary() -> [String: ValidSerializationValue] {
var result: [String: ValidSerializationValue] = [:]
result["color"] = color.toValidSerializationValue()
result["position"] = position.toValidSerializationValue()
return result
}
}
Loading

0 comments on commit 171c07e

Please sign in to comment.