mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
110 lines
3.1 KiB
Swift
110 lines
3.1 KiB
Swift
import LayoutKit
|
|
import VGSL
|
|
|
|
extension DivGrid: DivBlockModeling {
|
|
public func makeBlock(context: DivBlockModelingContext) throws -> Block {
|
|
let context = modifiedContextParentPath(context)
|
|
return try modifyError({ DivBlockModelingError($0.message, path: context.path) }) {
|
|
try applyBaseProperties(
|
|
to: { try makeBaseBlock(context: context) },
|
|
context: context,
|
|
actionsHolder: self
|
|
)
|
|
}
|
|
}
|
|
|
|
var nonNilItems: [Div] {
|
|
items ?? []
|
|
}
|
|
|
|
private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block {
|
|
let path = context.path
|
|
let itemsContext = context.modifying(errorsStorage: DivErrorsStorage(errors: []))
|
|
let items = nonNilItems.enumerated().compactMap { tuple in
|
|
let itemContext = itemsContext.modifying(
|
|
pathSuffix: String(tuple.offset)
|
|
)
|
|
do {
|
|
return try tuple.element.value.makeGridItem(context: itemContext)
|
|
} catch {
|
|
itemContext.addError(error: error)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
if nonNilItems.count != items.count {
|
|
throw DivBlockModelingError(
|
|
"Unable to form grid",
|
|
path: path,
|
|
causes: itemsContext.errorsStorage.errors
|
|
)
|
|
}
|
|
|
|
if items.isEmpty {
|
|
return EmptyBlock(
|
|
widthTrait: resolveContentWidthTrait(context),
|
|
heightTrait: resolveContentHeightTrait(context)
|
|
)
|
|
}
|
|
|
|
let expressionResolver = context.expressionResolver
|
|
return try GridBlock(
|
|
widthTrait: resolveContentWidthTrait(context),
|
|
heightTrait: resolveContentHeightTrait(context),
|
|
contentAlignment: resolveContentAlignment(
|
|
expressionResolver,
|
|
isRTLLayout: context.layoutDirection == .rightToLeft
|
|
),
|
|
items: items,
|
|
columnCount: resolveColumnCount(expressionResolver) ?? 0,
|
|
path: path
|
|
)
|
|
}
|
|
|
|
private func resolveContentAlignment(
|
|
_ expressionResolver: ExpressionResolver,
|
|
isRTLLayout: Bool
|
|
) -> BlockAlignment2D {
|
|
BlockAlignment2D(
|
|
horizontal: resolveContentAlignmentHorizontal(expressionResolver)
|
|
.alignment(isRTLLayout: isRTLLayout),
|
|
vertical: resolveContentAlignmentVertical(expressionResolver).alignment
|
|
)
|
|
}
|
|
}
|
|
|
|
extension DivBase {
|
|
fileprivate func makeGridItem(
|
|
context: DivBlockModelingContext
|
|
) throws -> GridBlock.Item {
|
|
let block = try makeBlock(context: context)
|
|
let expressionResolver = context.expressionResolver
|
|
return .init(
|
|
span: GridBlock.Span(
|
|
rows: resolveRowSpan(expressionResolver) ?? 1,
|
|
columns: resolveColumnSpan(expressionResolver) ?? 1
|
|
),
|
|
weight: .init(
|
|
column: width.resolveWeight(expressionResolver),
|
|
row: height.resolveWeight(expressionResolver)
|
|
),
|
|
contents: block,
|
|
alignment: resolveAlignment(context, defaultAlignment: .default)
|
|
)
|
|
}
|
|
}
|
|
|
|
extension DivSize {
|
|
fileprivate func resolveWeight(
|
|
_ expressionResolver: ExpressionResolver
|
|
) -> LayoutTrait.Weight? {
|
|
switch self {
|
|
case .divFixedSize, .divWrapContentSize:
|
|
nil
|
|
case let .divMatchParentSize(size):
|
|
size.resolveWeight(expressionResolver)
|
|
.flatMap { LayoutTrait.Weight(floatLiteral: $0) }
|
|
}
|
|
}
|
|
}
|