diff --git a/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt b/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt index da4f41626..cd19075d5 100644 --- a/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt +++ b/client/android/div-size-provider/src/main/java/com/yandex/div/sizeprovider/DivSizeProviderVariablesHolder.kt @@ -4,6 +4,7 @@ import com.yandex.div.core.Disposable import com.yandex.div.internal.core.DivVisitor import com.yandex.div.internal.core.ExpressionSubscriber import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.Expression import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div @@ -32,17 +33,17 @@ class DivSizeProviderVariablesHolder : DivVisitor(), ExpressionSubscriber override fun visit(data: Div.Grid, resolver: ExpressionResolver) { defaultVisit(data, resolver) - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } } override fun visit(data: Div.Gallery, resolver: ExpressionResolver) { defaultVisit(data, resolver) - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } } override fun visit(data: Div.Pager, resolver: ExpressionResolver) { defaultVisit(data, resolver) - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } } override fun visit(data: Div.Tabs, resolver: ExpressionResolver) { diff --git a/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt b/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt index 3459ac4c3..95276c59e 100644 --- a/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt +++ b/client/android/div/src/main/java/androidx/recyclerview/widget/DivLinearLayoutManager.kt @@ -9,6 +9,7 @@ import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.gallery.DivGalleryBinder import com.yandex.div.core.view2.divs.gallery.DivGalleryItemHelper import com.yandex.div.core.view2.divs.gallery.ScrollPosition +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.widget.DivLayoutParams import com.yandex.div2.DivGallery @@ -22,7 +23,7 @@ internal class DivLinearLayoutManager( override val childrenToRelayout = HashSet() override val divItems - get() = (view.adapter as? DivGalleryBinder.GalleryAdapter)?.items ?: div.items + get() = (view.adapter as? DivGalleryBinder.GalleryAdapter)?.items ?: div.nonNullItems override fun toLayoutManager() = this diff --git a/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt b/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt index 3e9e743e4..1e1b3d822 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/DivPreloader.kt @@ -12,6 +12,7 @@ import com.yandex.div.core.images.LoadReference import com.yandex.div.core.view2.DivImagePreloader import com.yandex.div.internal.core.DivVisitor import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import java.util.concurrent.atomic.AtomicBoolean @@ -80,17 +81,17 @@ class DivPreloader internal constructor( } override fun visit(data: Div.Grid, resolver: ExpressionResolver) { - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } defaultVisit(data, resolver) } override fun visit(data: Div.Gallery, resolver: ExpressionResolver) { - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } defaultVisit(data, resolver) } override fun visit(data: Div.Pager, resolver: ExpressionResolver) { - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } defaultVisit(data, resolver) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt index 2675bc684..8f2fc695a 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivPatchApply.kt @@ -10,6 +10,7 @@ import com.yandex.div.core.view2.divs.widgets.DivRecyclerView import com.yandex.div.internal.KAssert import com.yandex.div.internal.KLog import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivBase @@ -204,13 +205,16 @@ internal class DivPatchApply(private val patch: DivPatchMap) { ) is DivGrid -> - currentDivValue.items.pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) + currentDivValue.nonNullItems + .pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) is DivGallery -> - currentDivValue.items.pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) + currentDivValue.nonNullItems + .pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) is DivPager -> - currentDivValue.items.pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) + currentDivValue.nonNullItems + .pathToChildWithId(idToFind, resolver, currentPath, builtByBuilder = false) is DivTabs -> { if (currentDivValue.items.any { it.div.value().id == idToFind }) { @@ -274,21 +278,33 @@ internal class DivPatchApply(private val patch: DivPatchMap) { } is DivGrid -> { - getPatchedDivCollection(currentDiv, currentDivValue.items, pathIterator, resolver, + getPatchedDivCollection( + currentDiv, + currentDivValue.nonNullItems, + pathIterator, + resolver, { Div.Grid(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) } is DivGallery -> { - getPatchedDivCollection(currentDiv, currentDivValue.items, pathIterator, resolver, + getPatchedDivCollection( + currentDiv, + currentDivValue.nonNullItems, + pathIterator, + resolver, { Div.Gallery(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) } is DivPager -> { - getPatchedDivCollection(currentDiv, currentDivValue.items, pathIterator, resolver, + getPatchedDivCollection( + currentDiv, + currentDivValue.nonNullItems, + pathIterator, + resolver, { Div.Pager(currentDivValue.copyWithNewProperties(it)) }, { DivPatchApply(patch).applyPatch(currentDivValue, resolver) } ) diff --git a/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt b/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt index 11ccd7d4f..8c538db71 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/player/DivVideoActionHandler.kt @@ -4,6 +4,7 @@ import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.view2.Div2View import com.yandex.div.internal.KAssert import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.DivBase import com.yandex.div2.DivContainer @@ -50,7 +51,7 @@ internal class DivVideoActionHandler @Inject constructor( when (div) { is DivVideo -> return if (div.id == id) div else null is DivGallery -> { - div.items.forEach { item -> + div.nonNullItems.forEach { item -> findDivVideoWithId(item.value(), id, resolver)?.let { return it } @@ -66,7 +67,7 @@ internal class DivVideoActionHandler @Inject constructor( return null } is DivGrid -> { - div.items.forEach { item -> + div.nonNullItems.forEach { item -> findDivVideoWithId(item.value(), id, resolver)?.let { return it } @@ -74,7 +75,7 @@ internal class DivVideoActionHandler @Inject constructor( return null } is DivPager -> { - div.items.forEach { item -> + div.nonNullItems.forEach { item -> findDivVideoWithId(item.value(), id, resolver)?.let { return it } diff --git a/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt b/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt index 4ee7943e9..e6d46f659 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.core.view.children import com.yandex.div.core.view2.divs.widgets.DivStateLayout import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivData @@ -109,9 +110,9 @@ internal object DivPathUtils { } is Div.Tabs -> value.items.map { it.div }.findRecursively(divId, resolver) is Div.Container -> value.buildItems(resolver).findRecursively(divId, resolver) - is Div.Grid -> value.items.findRecursively(divId, resolver) - is Div.Gallery -> value.items.findRecursively(divId, resolver) - is Div.Pager -> value.items.findRecursively(divId, resolver) + is Div.Grid -> value.nonNullItems.findRecursively(divId, resolver) + is Div.Gallery -> value.nonNullItems.findRecursively(divId, resolver) + is Div.Pager -> value.nonNullItems.findRecursively(divId, resolver) is Div.Custom -> value.items?.findRecursively(divId, resolver) is Div.Text -> null is Div.Image -> null diff --git a/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt b/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt index 0277fa2a5..2b5e4317f 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt @@ -1,6 +1,7 @@ package com.yandex.div.core.util import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div @@ -172,9 +173,9 @@ private fun Div.getItems(resolver: ExpressionResolver): List
{ is Div.Select -> emptyList() is Div.Video -> emptyList() is Div.Container -> value.buildItems(resolver) - is Div.Grid -> value.items - is Div.Gallery -> value.items - is Div.Pager -> value.items + is Div.Grid -> value.nonNullItems + is Div.Gallery -> value.nonNullItems + is Div.Pager -> value.nonNullItems is Div.Tabs -> value.items.map { tab -> tab.div } is Div.State -> value.states.mapNotNull { state -> state.div } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt b/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt index f73b0e4cc..de634c37c 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt @@ -13,6 +13,7 @@ import com.yandex.div.core.animation.EaseOutInterpolator import com.yandex.div.core.animation.SpringInterpolator import com.yandex.div.core.view2.divs.dpToPx import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivAnimationInterpolator @@ -132,8 +133,12 @@ internal fun Div.containsStateInnerTransitions(resolver: ExpressionResolver): Bo } } return when (this) { - is Div.Container -> value.buildItems(resolver).map { it.containsStateInnerTransitions(resolver) }.contains(true) - is Div.Grid -> value.items.map { it.containsStateInnerTransitions(resolver) }.contains(true) + is Div.Container -> value.buildItems(resolver) + .map { it.containsStateInnerTransitions(resolver) } + .contains(true) + is Div.Grid -> value.nonNullItems + .map { it.containsStateInnerTransitions(resolver) } + .contains(true) is Div.Text -> false is Div.Image -> false is Div.GifImage -> false diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt index 31191608e..f7ef70506 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivImagePreloader.kt @@ -8,6 +8,7 @@ import com.yandex.div.core.images.DivImagePriority import com.yandex.div.core.images.LoadReference import com.yandex.div.internal.core.DivVisitor import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivBackground @@ -94,21 +95,21 @@ class DivImagePreloader @Inject constructor( override fun visit(data: Div.Grid, resolver: ExpressionResolver) { defaultVisit(data, resolver) if (visitContainers) { - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } } } override fun visit(data: Div.Gallery, resolver: ExpressionResolver) { defaultVisit(data, resolver) if (visitContainers) { - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } } } override fun visit(data: Div.Pager, resolver: ExpressionResolver) { defaultVisit(data, resolver) if (visitContainers) { - data.value.items.forEach { visit(it, resolver) } + data.value.nonNullItems.forEach { visit(it, resolver) } } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivValidator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivValidator.kt index 160709c91..a551dfdad 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivValidator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivValidator.kt @@ -4,6 +4,7 @@ import com.yandex.div.core.annotations.Mockable import com.yandex.div.core.dagger.DivScope import com.yandex.div.core.util.toIntSafely import com.yandex.div.internal.core.DivVisitor +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivSize @@ -19,13 +20,15 @@ internal class DivValidator @Inject constructor() : DivVisitor() { override fun defaultVisit(data: Div, resolver: ExpressionResolver) = true override fun visit(data: Div.Grid, resolver: ExpressionResolver): Boolean { - val columnCount = data.value.columnCount.evaluate(resolver).toIntSafely() + val grid = data.value + val columnCount = grid.columnCount.evaluate(resolver).toIntSafely() val heights = IntArray(columnCount) var column: Int var matchParentWidthCount = 0 var matchParentHeightCount = 0 - data.value.items.forEach { + val items = grid.nonNullItems + items.forEach { val minHeight = heights.minOrNull() ?: 0 column = heights.indexOf(minHeight) for (i in heights.indices) { @@ -46,8 +49,8 @@ internal class DivValidator @Inject constructor() : DivVisitor() { if (div.height is DivSize.MatchParent) matchParentHeightCount++ } - if (data.value.width is DivSize.WrapContent && matchParentWidthCount == data.value.items.size) return false - if (data.value.height is DivSize.WrapContent && matchParentHeightCount == data.value.items.size) return false + if (grid.width is DivSize.WrapContent && matchParentWidthCount == items.size) return false + if (grid.height is DivSize.WrapContent && matchParentHeightCount == items.size) return false return heights.all { it == heights.first() } // the last row filled by cells } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt index c54e1ac33..83a258f17 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt @@ -28,6 +28,7 @@ import com.yandex.div.core.view2.divs.widgets.DivVideoView import com.yandex.div.core.view2.divs.widgets.DivWrapLayout import com.yandex.div.internal.core.DivVisitor import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.viewpool.ViewPool import com.yandex.div.internal.viewpool.ViewPreCreationProfile import com.yandex.div.internal.viewpool.optimization.ViewPreCreationProfileRepository @@ -98,7 +99,7 @@ internal class DivViewCreator @Inject constructor( override fun visit(data: Div.Grid, resolver: ExpressionResolver): View { val view = defaultVisit(data, resolver) as ViewGroup - data.value.items.forEach { childData -> + data.value.nonNullItems.forEach { childData -> view.addView(create(childData, resolver)) } return view diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt index d8f87333c..51ba0f0d3 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt @@ -2,6 +2,7 @@ package com.yandex.div.core.view2.animations import com.yandex.div.core.view2.divs.isWrapContainer import com.yandex.div.internal.core.buildItems +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div import com.yandex.div2.DivBase @@ -79,7 +80,7 @@ internal object DivComparator { private fun extractChildren(div: Div, resolver: ExpressionResolver): List
{ return when (div) { is Div.Container -> div.value.buildItems(resolver) - is Div.Grid -> div.value.items + is Div.Grid -> div.value.nonNullItems is Div.Image -> emptyList() is Div.GifImage -> emptyList() is Div.Text -> emptyList() diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt index 44566b21a..f2328abaa 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivGridBinder.kt @@ -13,6 +13,7 @@ import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.DivViewBinder import com.yandex.div.core.view2.divs.widgets.DivGridLayout import com.yandex.div.internal.core.ExpressionSubscriber +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.widget.DivLayoutParams import com.yandex.div.json.expressions.Expression import com.yandex.div.json.expressions.ExpressionResolver @@ -50,14 +51,15 @@ internal class DivGridBinder @Inject constructor( ) view.observeContentAlignment(div.contentAlignmentHorizontal, div.contentAlignmentVertical, resolver) + val items = div.nonNullItems if (oldDiv != null) { - for (i in div.items.size..oldDiv.items.lastIndex) { + for (i in items.size..oldDiv.nonNullItems.lastIndex) { divView.unbindViewFromDiv(view.getChildAt(i)) } } var viewsPositionDiff = 0 - for (gridIndex in div.items.indices) { - val childDivValue = div.items[gridIndex].value() + for (gridIndex in items.indices) { + val childDivValue = items[gridIndex].value() val childView = view.getChildAt(gridIndex + viewsPositionDiff) val childDivId = childDivValue.id // applying div patch @@ -81,16 +83,16 @@ internal class DivGridBinder @Inject constructor( } } childView.layoutParams = DivLayoutParams(WRAP_CONTENT, WRAP_CONTENT) - divBinder.get().bind(childView, div.items[gridIndex], divView, path) + divBinder.get().bind(childView, items[gridIndex], divView, path) bindLayoutParams(childView, childDivValue, resolver) if (childDivValue.hasSightActions) { - divView.bindViewToDiv(childView, div.items[gridIndex]) + divView.bindViewToDiv(childView, items[gridIndex]) } else { divView.unbindViewFromDiv(childView) } } - view.trackVisibilityActions(div.items, oldDiv?.items, divView) + view.trackVisibilityActions(items, oldDiv?.items, divView) } private fun DivGridLayout.observeContentAlignment( @@ -143,10 +145,11 @@ internal class DivGridBinder @Inject constructor( fun setDataWithoutBinding(view: DivGridLayout, div: DivGrid, resolver: ExpressionResolver) { view.div = div - for (gridIndex in div.items.indices) { + val items = div.nonNullItems + for (gridIndex in items.indices) { divBinder.get().setDataWithoutBinding( view.getChildAt(gridIndex), - div.items[gridIndex], + items[gridIndex], resolver ) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt index 2c0dfadd4..5be9700ab 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/DivPagerBinder.kt @@ -33,6 +33,7 @@ import com.yandex.div.core.view2.divs.widgets.ParentScrollRestrictor import com.yandex.div.core.view2.divs.widgets.ReleaseUtils.releaseAndRemoveChildren import com.yandex.div.core.widget.makeUnspecifiedSpec import com.yandex.div.internal.KAssert +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.widget.DivLayoutParams import com.yandex.div.internal.widget.FrameContainerLayout import com.yandex.div.internal.widget.PageItemDecoration @@ -83,9 +84,9 @@ internal class DivPagerBinder @Inject constructor( val pageTranslations = SparseArray() view.setRecycledViewPool(ReleasingViewPool(divView.releaseViewVisitor)) - var divItems = div.items + var divItems = div.nonNullItems if (div.infiniteScroll.evaluate(resolver)) { - divItems = ArrayList(div.items) + divItems = ArrayList(divItems) val firstItem = divItems.first() val lastItem = divItems.last() divItems.add(0, lastItem) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt index a5fc925b8..d2f90e175 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGalleryBinder.kt @@ -34,6 +34,7 @@ import com.yandex.div.core.view2.divs.widgets.ParentScrollRestrictor import com.yandex.div.core.view2.divs.widgets.ReleaseUtils.releaseAndRemoveChildren import com.yandex.div.core.view2.divs.widgets.visitViewTree import com.yandex.div.core.widget.DivViewWrapper +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.internal.widget.PaddingItemDecoration import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div @@ -62,7 +63,7 @@ internal class DivGalleryBinder @Inject constructor( adapter.applyPatch(view, divPatchCache, divView) adapter.closeAllSubscription() adapter.subscribeOnElements() - bindStates(view, div.items, divView, resolver) + bindStates(view, div.nonNullItems, divView, resolver) return } @@ -89,7 +90,7 @@ internal class DivGalleryBinder @Inject constructor( val itemStateBinder = { itemView: View, div: Div -> bindStates(itemView, listOf(div), divView, resolver) } view.adapter = - GalleryAdapter(div.items, divView, divBinder.get(), viewCreator, itemStateBinder, path) + GalleryAdapter(div.nonNullItems, divView, divBinder.get(), viewCreator, itemStateBinder, path) updateDecorations(view, div, divView, resolver) } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt index da6e56588..1f33dbf46 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/gallery/DivGridLayoutManager.kt @@ -6,6 +6,7 @@ import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.yandex.div.core.util.toIntSafely import com.yandex.div.core.view2.Div2View import com.yandex.div.core.view2.divs.dpToPx +import com.yandex.div.internal.core.nonNullItems import com.yandex.div2.DivGallery import com.yandex.div2.DivSize @@ -22,7 +23,7 @@ internal class DivGridLayoutManager( override val childrenToRelayout = HashSet() override val divItems - get() = (view.adapter as? DivGalleryBinder.GalleryAdapter)?.items ?: div.items + get() = (view.adapter as? DivGalleryBinder.GalleryAdapter)?.items ?: div.nonNullItems private val midPadding get() = div.itemSpacing.evaluate(divView.expressionResolver).dpToPx(view.resources.displayMetrics) @@ -119,7 +120,7 @@ internal class DivGridLayoutManager( override fun getDecoratedMeasuredWidth(child: View): Int { val position = _getPosition(child) - val item = div.items[position].value() + val item = div.nonNullItems[position].value() val isFixedWidth = item.width is DivSize.Fixed val isMultiSpan = spanCount > 1 @@ -129,7 +130,7 @@ internal class DivGridLayoutManager( override fun getDecoratedMeasuredHeight(child: View): Int { val position = _getPosition(child) - val item = div.items[position].value() + val item = div.nonNullItems[position].value() val isFixedHeight = item.height is DivSize.Fixed val isMultiSpan = spanCount > 1 diff --git a/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt b/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt index b649ecb2c..72f924135 100644 --- a/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt +++ b/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt @@ -1,6 +1,16 @@ package com.yandex.div.internal.core import com.yandex.div.json.expressions.ExpressionResolver +import com.yandex.div2.Div import com.yandex.div2.DivContainer +import com.yandex.div2.DivGallery +import com.yandex.div2.DivGrid +import com.yandex.div2.DivPager fun DivContainer.buildItems(resolver: ExpressionResolver) = items ?: emptyList() + +val DivGallery.nonNullItems: List
get() = items ?: emptyList() + +val DivGrid.nonNullItems: List
get() = items ?: emptyList() + +val DivPager.nonNullItems: List
get() = items ?: emptyList() diff --git a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt index 39a79183b..eefbf43f4 100644 --- a/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt +++ b/client/android/div/src/test/java/com/yandex/div/core/view2/divs/DivPagerBinderTest.kt @@ -7,6 +7,7 @@ import com.yandex.div.core.state.PagerState import com.yandex.div.core.view2.DivBinder import com.yandex.div.core.view2.divs.widgets.DivPagerView import com.yandex.div.data.DivParsingEnvironment +import com.yandex.div.internal.core.nonNullItems import com.yandex.div.json.ParsingErrorLogger import com.yandex.div.json.expressions.ExpressionResolver import com.yandex.div2.Div @@ -123,7 +124,7 @@ class DivPagerBinderTest: DivBinderTest() { underTest.changePageCallbackForLogger?.onPageSelected(DEFAULT_ITEM) - verify(divView).bindViewToDiv(divPagerView.viewPager[0], divPager.items[DEFAULT_ITEM]) + verify(divView).bindViewToDiv(divPagerView.viewPager[0], divPager.nonNullItems[DEFAULT_ITEM]) } @Test diff --git a/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift b/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift index 3e410388b..81617478e 100644 --- a/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift +++ b/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift @@ -130,7 +130,7 @@ extension DivContainer { extension DivGallery { fileprivate func applyPatch(_ patch: DivPatch) -> DivGallery { - let patchedItems = items.flatMap { $0.applyMultipleItemsPatch(patch) } + let patchedItems = nonNilItems.flatMap { $0.applyMultipleItemsPatch(patch) } return DivGallery( accessibility: accessibility, alignmentHorizontal: alignmentHorizontal, @@ -174,7 +174,7 @@ extension DivGallery { extension DivGrid { fileprivate func applyPatch(_ patch: DivPatch) -> DivGrid { - let patchedItems = items.flatMap { $0.applyMultipleItemsPatch(patch) } + let patchedItems = nonNilItems.flatMap { $0.applyMultipleItemsPatch(patch) } return DivGrid( accessibility: accessibility, action: action, @@ -217,7 +217,7 @@ extension DivGrid { extension DivPager { fileprivate func applyPatch(_ patch: DivPatch) -> DivPager { - let patchedItems = items.flatMap { $0.applyMultipleItemsPatch(patch) } + let patchedItems = nonNilItems.flatMap { $0.applyMultipleItemsPatch(patch) } return DivPager( accessibility: accessibility, alignmentHorizontal: alignmentHorizontal, diff --git a/client/ios/DivKit/Extensions/DivExtensions.swift b/client/ios/DivKit/Extensions/DivExtensions.swift index 1e74d48dd..844765c7b 100644 --- a/client/ios/DivKit/Extensions/DivExtensions.swift +++ b/client/ios/DivKit/Extensions/DivExtensions.swift @@ -4,9 +4,9 @@ extension Div { var children: [Div] { switch self { case let .divContainer(div): return div.nonNilItems - case let .divGrid(div): return div.items - case let .divGallery(div): return div.items - case let .divPager(div): return div.items + case let .divGrid(div): return div.nonNilItems + case let .divGallery(div): return div.nonNilItems + case let .divPager(div): return div.nonNilItems case let .divTabs(div): return div.items.map(\.div) case let .divCustom(div): return div.items ?? [] case let .divState(div): return div.states.compactMap(\.div) diff --git a/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift b/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift index 201955931..804eb9648 100644 --- a/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift +++ b/client/ios/DivKit/Extensions/DivGallery/DivGalleryProtocol.swift @@ -5,10 +5,14 @@ import CommonCorePublic import LayoutKit protocol DivGalleryProtocol: DivBase { - var items: [Div] { get } + var items: [Div]? { get } } extension DivGalleryProtocol { + var nonNilItems: [Div] { + items ?? [] + } + func makeGalleryModel( context: DivBlockModelingContext, direction: GalleryViewModel.Direction, @@ -22,7 +26,7 @@ extension DivGalleryProtocol { ) throws -> GalleryViewModel { let expressionResolver = context.expressionResolver let childrenContext = context.modifying(errorsStorage: DivErrorsStorage(errors: [])) - var children: [GalleryViewModel.Item] = items.makeBlocks( + var children: [GalleryViewModel.Item] = nonNilItems.makeBlocks( context: childrenContext, sizeModifier: DivGallerySizeModifier( context: context, diff --git a/client/ios/DivKit/Extensions/DivGallery/DivGallerySizeModifier.swift b/client/ios/DivKit/Extensions/DivGallery/DivGallerySizeModifier.swift index 5a3465a46..4ef64fe56 100644 --- a/client/ios/DivKit/Extensions/DivGallery/DivGallerySizeModifier.swift +++ b/client/ios/DivKit/Extensions/DivGallery/DivGallerySizeModifier.swift @@ -15,9 +15,11 @@ struct DivGallerySizeModifier: DivSizeModifier { gallery: DivGalleryProtocol, direction: GalleryViewModel.Direction ) { + let items = gallery.nonNilItems + if direction == .vertical, gallery.getTransformedWidth(context).isIntrinsic, - gallery.items.allHorizontallyMatchParent { + items.allHorizontallyMatchParent { context.addWarning( message: "All items in vertical \(gallery.typeName) with wrap_content width has match_parent width" ) @@ -28,7 +30,7 @@ struct DivGallerySizeModifier: DivSizeModifier { if direction == .horizontal, gallery.getTransformedHeight(context).isIntrinsic, - gallery.items.allVerticallyMatchParent { + items.allVerticallyMatchParent { context.addWarning( message: "All items in horizontal \(gallery.typeName) with wrap_content height has match_parent height" ) diff --git a/client/ios/DivKit/Extensions/DivGridExtensions.swift b/client/ios/DivKit/Extensions/DivGridExtensions.swift index e5f4dd216..7ef9fbf33 100644 --- a/client/ios/DivKit/Extensions/DivGridExtensions.swift +++ b/client/ios/DivKit/Extensions/DivGridExtensions.swift @@ -9,12 +9,16 @@ extension DivGrid: DivBlockModeling { actionsHolder: self ) } + + var nonNilItems: [Div] { + items ?? [] + } private func makeBaseBlock(context: DivBlockModelingContext) throws -> Block { let gridPath = context.parentPath + DivGrid.type let gridContext = context.modifying(parentPath: gridPath) let gridItemsContext = gridContext.modifying(errorsStorage: DivErrorsStorage(errors: [])) - let gridItems = items.enumerated().compactMap { tuple in + let gridItems = nonNilItems.enumerated().compactMap { tuple in let itemContext = gridItemsContext.modifying( parentPath: gridItemsContext.parentPath + tuple.offset ) @@ -27,7 +31,7 @@ extension DivGrid: DivBlockModeling { return nil } } - if items.count != gridItems.count { + if nonNilItems.count != gridItems.count { throw DivBlockModelingError( "Unable to form grid", path: gridPath, diff --git a/client/ios/DivKit/Extensions/DivPagerExtensions.swift b/client/ios/DivKit/Extensions/DivPagerExtensions.swift index 565b04602..09947ce4a 100644 --- a/client/ios/DivKit/Extensions/DivPagerExtensions.swift +++ b/client/ios/DivKit/Extensions/DivPagerExtensions.swift @@ -26,6 +26,7 @@ extension DivPager: DivBlockModeling, DivGalleryProtocol { } return try modifyError({ DivBlockModelingError($0.message, path: pagerPath) }) { + let items = nonNilItems let gallery = try makeGalleryModel( context: itemContext, direction: resolveOrientation(expressionResolver).direction, diff --git a/client/ios/DivKit/generated_sources/DivCustom.swift b/client/ios/DivKit/generated_sources/DivCustom.swift index f366115b6..92b1306bd 100644 --- a/client/ios/DivKit/generated_sources/DivCustom.swift +++ b/client/ios/DivKit/generated_sources/DivCustom.swift @@ -20,7 +20,7 @@ public final class DivCustom: DivBase { public let focus: DivFocus? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let id: String? - public let items: [Div]? // at least 1 elements + public let items: [Div]? public let margins: DivEdgeInsets public let paddings: DivEdgeInsets public let rowSpan: Expression? // constraint: number >= 0 @@ -66,9 +66,6 @@ public final class DivCustom: DivBase { static let columnSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let itemsValidator: AnyArrayValueValidator
= - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) diff --git a/client/ios/DivKit/generated_sources/DivCustomTemplate.swift b/client/ios/DivKit/generated_sources/DivCustomTemplate.swift index f635a34b6..827a131bf 100644 --- a/client/ios/DivKit/generated_sources/DivCustomTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivCustomTemplate.swift @@ -21,7 +21,7 @@ public final class DivCustomTemplate: TemplateValue { public let focus: Field? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let id: Field? - public let items: Field<[DivTemplate]>? // at least 1 elements + public let items: Field<[DivTemplate]>? public let margins: Field? public let paddings: Field? public let rowSpan: Field>? // constraint: number >= 0 @@ -155,7 +155,7 @@ public final class DivCustomTemplate: TemplateValue { let focusValue = parent?.focus?.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 itemsValue = parent?.items?.resolveOptionalValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true) ?? .noValue + let itemsValue = parent?.items?.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 rowSpanValue = parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue @@ -307,7 +307,7 @@ public final class DivCustomTemplate: TemplateValue { case "id": idValue = deserialize(__dictValue).merged(with: idValue) case "items": - itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self).merged(with: itemsValue) + itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self).merged(with: itemsValue) case "margins": marginsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: marginsValue) case "paddings": @@ -365,7 +365,7 @@ public final class DivCustomTemplate: TemplateValue { case parent?.id?.link: idValue = idValue.merged(with: deserialize(__dictValue)) case parent?.items?.link: - itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self)) + itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self)) case parent?.margins?.link: marginsValue = marginsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self)) case parent?.paddings?.link: @@ -405,7 +405,7 @@ public final class DivCustomTemplate: TemplateValue { extensionsValue = extensionsValue.merged(with: parent.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true)) focusValue = focusValue.merged(with: parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true)) heightValue = heightValue.merged(with: parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true)) - itemsValue = itemsValue.merged(with: parent.items?.resolveOptionalValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true)) + itemsValue = itemsValue.merged(with: parent.items?.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)) selectedActionsValue = selectedActionsValue.merged(with: parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) diff --git a/client/ios/DivKit/generated_sources/DivFocus.swift b/client/ios/DivKit/generated_sources/DivFocus.swift index 224657573..021eeab65 100644 --- a/client/ios/DivKit/generated_sources/DivFocus.swift +++ b/client/ios/DivKit/generated_sources/DivFocus.swift @@ -47,15 +47,12 @@ public final class DivFocus { } } - public let background: [DivBackground]? // at least 1 elements + public let background: [DivBackground]? public let border: DivBorder public let nextFocusIds: NextFocusIds? public let onBlur: [DivAction]? public let onFocus: [DivAction]? - static let backgroundValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - init( background: [DivBackground]? = nil, border: DivBorder? = nil, diff --git a/client/ios/DivKit/generated_sources/DivFocusTemplate.swift b/client/ios/DivKit/generated_sources/DivFocusTemplate.swift index 016519033..36c5e3697 100644 --- a/client/ios/DivKit/generated_sources/DivFocusTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivFocusTemplate.swift @@ -119,7 +119,7 @@ public final class DivFocusTemplate: TemplateValue { } } - public let background: Field<[DivBackgroundTemplate]>? // at least 1 elements + public let background: Field<[DivBackgroundTemplate]>? public let border: Field? public let nextFocusIds: Field? public let onBlur: Field<[DivActionTemplate]>? @@ -150,7 +150,7 @@ public final class DivFocusTemplate: TemplateValue { } private static func resolveOnlyLinks(context: TemplatesContext, parent: DivFocusTemplate?) -> DeserializationResult { - let backgroundValue = parent?.background?.resolveOptionalValue(context: context, validator: ResolvedValue.backgroundValidator, useOnlyLinks: true) ?? .noValue + let backgroundValue = parent?.background?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let borderValue = parent?.border?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let nextFocusIdsValue = parent?.nextFocusIds?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let onBlurValue = parent?.onBlur?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue @@ -184,7 +184,7 @@ public final class DivFocusTemplate: TemplateValue { context.templateData.forEach { key, __dictValue in switch key { case "background": - backgroundValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.backgroundValidator, type: DivBackgroundTemplate.self).merged(with: backgroundValue) + backgroundValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBackgroundTemplate.self).merged(with: backgroundValue) case "border": borderValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBorderTemplate.self).merged(with: borderValue) case "next_focus_ids": @@ -194,7 +194,7 @@ public final class DivFocusTemplate: TemplateValue { case "on_focus": onFocusValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: onFocusValue) case parent?.background?.link: - backgroundValue = backgroundValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.backgroundValidator, type: DivBackgroundTemplate.self)) + backgroundValue = backgroundValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBackgroundTemplate.self)) case parent?.border?.link: borderValue = borderValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBorderTemplate.self)) case parent?.nextFocusIds?.link: @@ -207,7 +207,7 @@ public final class DivFocusTemplate: TemplateValue { } } if let parent = parent { - backgroundValue = backgroundValue.merged(with: parent.background?.resolveOptionalValue(context: context, validator: ResolvedValue.backgroundValidator, useOnlyLinks: true)) + backgroundValue = backgroundValue.merged(with: parent.background?.resolveOptionalValue(context: context, useOnlyLinks: true)) borderValue = borderValue.merged(with: parent.border?.resolveOptionalValue(context: context, useOnlyLinks: true)) nextFocusIdsValue = nextFocusIdsValue.merged(with: parent.nextFocusIds?.resolveOptionalValue(context: context, useOnlyLinks: true)) onBlurValue = onBlurValue.merged(with: parent.onBlur?.resolveOptionalValue(context: context, useOnlyLinks: true)) diff --git a/client/ios/DivKit/generated_sources/DivGallery.swift b/client/ios/DivKit/generated_sources/DivGallery.swift index 0f303313c..0f477dab3 100644 --- a/client/ios/DivKit/generated_sources/DivGallery.swift +++ b/client/ios/DivKit/generated_sources/DivGallery.swift @@ -48,7 +48,7 @@ public final class DivGallery: DivBase { public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let id: String? public let itemSpacing: Expression // constraint: number >= 0; default value: 8 - public let items: [Div] // at least 1 elements + public let items: [Div]? public let margins: DivEdgeInsets public let orientation: Expression // default value: horizontal public let paddings: DivEdgeInsets @@ -146,9 +146,6 @@ public final class DivGallery: DivBase { static let itemSpacingValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let itemsValidator: AnyArrayValueValidator
= - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -173,7 +170,7 @@ public final class DivGallery: DivBase { height: DivSize?, id: String?, itemSpacing: Expression?, - items: [Div], + items: [Div]?, margins: DivEdgeInsets?, orientation: Expression?, paddings: DivEdgeInsets?, @@ -345,7 +342,7 @@ extension DivGallery: Serializable { result["height"] = height.toDictionary() result["id"] = id result["item_spacing"] = itemSpacing.toValidSerializationValue() - result["items"] = items.map { $0.toDictionary() } + result["items"] = items?.map { $0.toDictionary() } result["margins"] = margins.toDictionary() result["orientation"] = orientation.toValidSerializationValue() result["paddings"] = paddings.toDictionary() diff --git a/client/ios/DivKit/generated_sources/DivGalleryTemplate.swift b/client/ios/DivKit/generated_sources/DivGalleryTemplate.swift index 87866cf5d..91992000c 100644 --- a/client/ios/DivKit/generated_sources/DivGalleryTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivGalleryTemplate.swift @@ -32,7 +32,7 @@ public final class DivGalleryTemplate: TemplateValue { public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let id: Field? public let itemSpacing: Field>? // constraint: number >= 0; default value: 8 - public let items: Field<[DivTemplate]>? // at least 1 elements + public let items: Field<[DivTemplate]>? public let margins: Field? public let orientation: Field>? // default value: horizontal public let paddings: Field? @@ -53,49 +53,45 @@ public final class DivGalleryTemplate: TemplateValue { public let width: Field? // default value: .divMatchParentSize(DivMatchParentSize()) public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { - do { - self.init( - parent: try dictionary.getOptionalField("type"), - accessibility: try dictionary.getOptionalField("accessibility", templateToType: templateToType), - alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal"), - alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical"), - alpha: try dictionary.getOptionalExpressionField("alpha"), - background: try dictionary.getOptionalArray("background", templateToType: templateToType), - border: try dictionary.getOptionalField("border", templateToType: templateToType), - columnCount: try dictionary.getOptionalExpressionField("column_count"), - columnSpan: try dictionary.getOptionalExpressionField("column_span"), - crossContentAlignment: try dictionary.getOptionalExpressionField("cross_content_alignment"), - crossSpacing: try dictionary.getOptionalExpressionField("cross_spacing"), - defaultItem: try dictionary.getOptionalExpressionField("default_item"), - disappearActions: try dictionary.getOptionalArray("disappear_actions", templateToType: templateToType), - extensions: try dictionary.getOptionalArray("extensions", templateToType: templateToType), - focus: try dictionary.getOptionalField("focus", templateToType: templateToType), - height: try dictionary.getOptionalField("height", templateToType: templateToType), - id: try dictionary.getOptionalField("id"), - itemSpacing: try dictionary.getOptionalExpressionField("item_spacing"), - items: try dictionary.getOptionalArray("items", templateToType: templateToType), - margins: try dictionary.getOptionalField("margins", templateToType: templateToType), - orientation: try dictionary.getOptionalExpressionField("orientation"), - paddings: try dictionary.getOptionalField("paddings", templateToType: templateToType), - restrictParentScroll: try dictionary.getOptionalExpressionField("restrict_parent_scroll"), - rowSpan: try dictionary.getOptionalExpressionField("row_span"), - scrollMode: try dictionary.getOptionalExpressionField("scroll_mode"), - scrollbar: try dictionary.getOptionalExpressionField("scrollbar"), - selectedActions: try dictionary.getOptionalArray("selected_actions", templateToType: templateToType), - tooltips: try dictionary.getOptionalArray("tooltips", templateToType: templateToType), - transform: try dictionary.getOptionalField("transform", templateToType: templateToType), - transitionChange: try dictionary.getOptionalField("transition_change", templateToType: templateToType), - transitionIn: try dictionary.getOptionalField("transition_in", templateToType: templateToType), - transitionOut: try dictionary.getOptionalField("transition_out", templateToType: templateToType), - transitionTriggers: try dictionary.getOptionalArray("transition_triggers"), - visibility: try dictionary.getOptionalExpressionField("visibility"), - visibilityAction: try dictionary.getOptionalField("visibility_action", templateToType: templateToType), - visibilityActions: try dictionary.getOptionalArray("visibility_actions", templateToType: templateToType), - width: try dictionary.getOptionalField("width", templateToType: templateToType) - ) - } catch let DeserializationError.invalidFieldRepresentation(field: field, representation: representation) { - throw DeserializationError.invalidFieldRepresentation(field: "div-gallery_template." + field, representation: representation) - } + self.init( + parent: try dictionary.getOptionalField("type"), + accessibility: try dictionary.getOptionalField("accessibility", templateToType: templateToType), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal"), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical"), + alpha: try dictionary.getOptionalExpressionField("alpha"), + background: try dictionary.getOptionalArray("background", templateToType: templateToType), + border: try dictionary.getOptionalField("border", templateToType: templateToType), + columnCount: try dictionary.getOptionalExpressionField("column_count"), + columnSpan: try dictionary.getOptionalExpressionField("column_span"), + crossContentAlignment: try dictionary.getOptionalExpressionField("cross_content_alignment"), + crossSpacing: try dictionary.getOptionalExpressionField("cross_spacing"), + defaultItem: try dictionary.getOptionalExpressionField("default_item"), + disappearActions: try dictionary.getOptionalArray("disappear_actions", templateToType: templateToType), + extensions: try dictionary.getOptionalArray("extensions", templateToType: templateToType), + focus: try dictionary.getOptionalField("focus", templateToType: templateToType), + height: try dictionary.getOptionalField("height", templateToType: templateToType), + id: try dictionary.getOptionalField("id"), + itemSpacing: try dictionary.getOptionalExpressionField("item_spacing"), + items: try dictionary.getOptionalArray("items", templateToType: templateToType), + margins: try dictionary.getOptionalField("margins", templateToType: templateToType), + orientation: try dictionary.getOptionalExpressionField("orientation"), + paddings: try dictionary.getOptionalField("paddings", templateToType: templateToType), + restrictParentScroll: try dictionary.getOptionalExpressionField("restrict_parent_scroll"), + rowSpan: try dictionary.getOptionalExpressionField("row_span"), + scrollMode: try dictionary.getOptionalExpressionField("scroll_mode"), + scrollbar: try dictionary.getOptionalExpressionField("scrollbar"), + selectedActions: try dictionary.getOptionalArray("selected_actions", templateToType: templateToType), + tooltips: try dictionary.getOptionalArray("tooltips", templateToType: templateToType), + transform: try dictionary.getOptionalField("transform", templateToType: templateToType), + transitionChange: try dictionary.getOptionalField("transition_change", templateToType: templateToType), + transitionIn: try dictionary.getOptionalField("transition_in", templateToType: templateToType), + transitionOut: try dictionary.getOptionalField("transition_out", templateToType: templateToType), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers"), + visibility: try dictionary.getOptionalExpressionField("visibility"), + visibilityAction: try dictionary.getOptionalField("visibility_action", templateToType: templateToType), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", templateToType: templateToType), + width: try dictionary.getOptionalField("width", templateToType: templateToType) + ) } init( @@ -194,7 +190,7 @@ public final class DivGalleryTemplate: TemplateValue { let heightValue = parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let idValue = parent?.id?.resolveOptionalValue(context: context) ?? .noValue let itemSpacingValue = parent?.itemSpacing?.resolveOptionalValue(context: context, validator: ResolvedValue.itemSpacingValidator) ?? .noValue - let itemsValue = parent?.items?.resolveValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true) ?? .noValue + let itemsValue = parent?.items?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue 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 @@ -213,7 +209,7 @@ public final class DivGalleryTemplate: TemplateValue { let visibilityActionValue = parent?.visibilityAction?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let visibilityActionsValue = parent?.visibilityActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let widthValue = parent?.width?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue - var errors = mergeErrors( + let errors = mergeErrors( accessibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "accessibility", error: $0) }, alignmentHorizontalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_horizontal", error: $0) }, alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, @@ -251,14 +247,6 @@ public final class DivGalleryTemplate: TemplateValue { visibilityActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_actions", error: $0) }, widthValue.errorsOrWarnings?.map { .nestedObjectError(field: "width", error: $0) } ) - if case .noValue = itemsValue { - errors.append(.requiredFieldIsMissing(field: "items")) - } - guard - let itemsNonNil = itemsValue.value - else { - return .failure(NonEmptyArray(errors)!) - } let result = DivGallery( accessibility: accessibilityValue.value, alignmentHorizontal: alignmentHorizontalValue.value, @@ -277,7 +265,7 @@ public final class DivGalleryTemplate: TemplateValue { height: heightValue.value, id: idValue.value, itemSpacing: itemSpacingValue.value, - items: itemsNonNil, + items: itemsValue.value, margins: marginsValue.value, orientation: orientationValue.value, paddings: paddingsValue.value, @@ -377,7 +365,7 @@ public final class DivGalleryTemplate: TemplateValue { case "item_spacing": itemSpacingValue = deserialize(__dictValue, validator: ResolvedValue.itemSpacingValidator).merged(with: itemSpacingValue) case "items": - itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self).merged(with: itemsValue) + itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self).merged(with: itemsValue) case "margins": marginsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: marginsValue) case "orientation": @@ -449,7 +437,7 @@ public final class DivGalleryTemplate: TemplateValue { case parent?.itemSpacing?.link: itemSpacingValue = itemSpacingValue.merged(with: deserialize(__dictValue, validator: ResolvedValue.itemSpacingValidator)) case parent?.items?.link: - itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self)) + itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self)) case parent?.margins?.link: marginsValue = marginsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self)) case parent?.orientation?.link: @@ -497,7 +485,7 @@ public final class DivGalleryTemplate: TemplateValue { extensionsValue = extensionsValue.merged(with: parent.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true)) focusValue = focusValue.merged(with: parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true)) heightValue = heightValue.merged(with: parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true)) - itemsValue = itemsValue.merged(with: parent.items?.resolveValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true)) + itemsValue = itemsValue.merged(with: parent.items?.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)) selectedActionsValue = selectedActionsValue.merged(with: parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) @@ -510,7 +498,7 @@ public final class DivGalleryTemplate: TemplateValue { visibilityActionsValue = visibilityActionsValue.merged(with: parent.visibilityActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) widthValue = widthValue.merged(with: parent.width?.resolveOptionalValue(context: context, useOnlyLinks: true)) } - var errors = mergeErrors( + let errors = mergeErrors( accessibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "accessibility", error: $0) }, alignmentHorizontalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_horizontal", error: $0) }, alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, @@ -548,14 +536,6 @@ public final class DivGalleryTemplate: TemplateValue { visibilityActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_actions", error: $0) }, widthValue.errorsOrWarnings?.map { .nestedObjectError(field: "width", error: $0) } ) - if case .noValue = itemsValue { - errors.append(.requiredFieldIsMissing(field: "items")) - } - guard - let itemsNonNil = itemsValue.value - else { - return .failure(NonEmptyArray(errors)!) - } let result = DivGallery( accessibility: accessibilityValue.value, alignmentHorizontal: alignmentHorizontalValue.value, @@ -574,7 +554,7 @@ public final class DivGalleryTemplate: TemplateValue { height: heightValue.value, id: idValue.value, itemSpacing: itemSpacingValue.value, - items: itemsNonNil, + items: itemsValue.value, margins: marginsValue.value, orientation: orientationValue.value, paddings: paddingsValue.value, @@ -667,7 +647,7 @@ public final class DivGalleryTemplate: TemplateValue { height: merged.height?.tryResolveParent(templates: templates), id: merged.id, itemSpacing: merged.itemSpacing, - items: try merged.items?.resolveParent(templates: templates), + items: merged.items?.tryResolveParent(templates: templates), margins: merged.margins?.tryResolveParent(templates: templates), orientation: merged.orientation, paddings: merged.paddings?.tryResolveParent(templates: templates), diff --git a/client/ios/DivKit/generated_sources/DivGrid.swift b/client/ios/DivKit/generated_sources/DivGrid.swift index e8574e67a..8b8540171 100644 --- a/client/ios/DivKit/generated_sources/DivGrid.swift +++ b/client/ios/DivKit/generated_sources/DivGrid.swift @@ -25,7 +25,7 @@ public final class DivGrid: DivBase { public let focus: DivFocus? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let id: String? - public let items: [Div] // at least 1 elements + public let items: [Div]? public let longtapActions: [DivAction]? public let margins: DivEdgeInsets public let paddings: DivEdgeInsets @@ -87,9 +87,6 @@ public final class DivGrid: DivBase { static let columnSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let itemsValidator: AnyArrayValueValidator
= - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -116,7 +113,7 @@ public final class DivGrid: DivBase { focus: DivFocus?, height: DivSize?, id: String?, - items: [Div], + items: [Div]?, longtapActions: [DivAction]?, margins: DivEdgeInsets?, paddings: DivEdgeInsets?, @@ -285,7 +282,7 @@ extension DivGrid: Serializable { result["focus"] = focus?.toDictionary() result["height"] = height.toDictionary() result["id"] = id - result["items"] = items.map { $0.toDictionary() } + result["items"] = items?.map { $0.toDictionary() } result["longtap_actions"] = longtapActions?.map { $0.toDictionary() } result["margins"] = margins.toDictionary() result["paddings"] = paddings.toDictionary() diff --git a/client/ios/DivKit/generated_sources/DivGridTemplate.swift b/client/ios/DivKit/generated_sources/DivGridTemplate.swift index c01479e1c..23aaa455d 100644 --- a/client/ios/DivKit/generated_sources/DivGridTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivGridTemplate.swift @@ -26,7 +26,7 @@ public final class DivGridTemplate: TemplateValue { public let focus: Field? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let id: Field? - public let items: Field<[DivTemplate]>? // at least 1 elements + public let items: Field<[DivTemplate]>? public let longtapActions: Field<[DivActionTemplate]>? public let margins: Field? public let paddings: Field? @@ -184,7 +184,7 @@ public final class DivGridTemplate: TemplateValue { let focusValue = parent?.focus?.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 itemsValue = parent?.items?.resolveValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true) ?? .noValue + let itemsValue = parent?.items?.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 @@ -240,12 +240,8 @@ public final class DivGridTemplate: TemplateValue { if case .noValue = columnCountValue { errors.append(.requiredFieldIsMissing(field: "column_count")) } - if case .noValue = itemsValue { - errors.append(.requiredFieldIsMissing(field: "items")) - } guard - let columnCountNonNil = columnCountValue.value, - let itemsNonNil = itemsValue.value + let columnCountNonNil = columnCountValue.value else { return .failure(NonEmptyArray(errors)!) } @@ -269,7 +265,7 @@ public final class DivGridTemplate: TemplateValue { focus: focusValue.value, height: heightValue.value, id: idValue.value, - items: itemsNonNil, + items: itemsValue.value, longtapActions: longtapActionsValue.value, margins: marginsValue.value, paddings: paddingsValue.value, @@ -369,7 +365,7 @@ public final class DivGridTemplate: TemplateValue { case "id": idValue = deserialize(__dictValue).merged(with: idValue) case "items": - itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self).merged(with: itemsValue) + itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self).merged(with: itemsValue) case "longtap_actions": longtapActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: longtapActionsValue) case "margins": @@ -439,7 +435,7 @@ public final class DivGridTemplate: TemplateValue { case parent?.id?.link: idValue = idValue.merged(with: deserialize(__dictValue)) case parent?.items?.link: - itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self)) + itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self)) case parent?.longtapActions?.link: longtapActionsValue = longtapActionsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self)) case parent?.margins?.link: @@ -485,7 +481,7 @@ public final class DivGridTemplate: TemplateValue { extensionsValue = extensionsValue.merged(with: parent.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true)) focusValue = focusValue.merged(with: parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true)) heightValue = heightValue.merged(with: parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true)) - itemsValue = itemsValue.merged(with: parent.items?.resolveValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true)) + itemsValue = itemsValue.merged(with: parent.items?.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)) @@ -539,12 +535,8 @@ public final class DivGridTemplate: TemplateValue { if case .noValue = columnCountValue { errors.append(.requiredFieldIsMissing(field: "column_count")) } - if case .noValue = itemsValue { - errors.append(.requiredFieldIsMissing(field: "items")) - } guard - let columnCountNonNil = columnCountValue.value, - let itemsNonNil = itemsValue.value + let columnCountNonNil = columnCountValue.value else { return .failure(NonEmptyArray(errors)!) } @@ -568,7 +560,7 @@ public final class DivGridTemplate: TemplateValue { focus: focusValue.value, height: heightValue.value, id: idValue.value, - items: itemsNonNil, + items: itemsValue.value, longtapActions: longtapActionsValue.value, margins: marginsValue.value, paddings: paddingsValue.value, @@ -659,7 +651,7 @@ public final class DivGridTemplate: TemplateValue { focus: merged.focus?.tryResolveParent(templates: templates), height: merged.height?.tryResolveParent(templates: templates), id: merged.id, - items: try merged.items?.resolveParent(templates: templates), + items: merged.items?.tryResolveParent(templates: templates), longtapActions: merged.longtapActions?.tryResolveParent(templates: templates), margins: merged.margins?.tryResolveParent(templates: templates), paddings: merged.paddings?.tryResolveParent(templates: templates), diff --git a/client/ios/DivKit/generated_sources/DivImage.swift b/client/ios/DivKit/generated_sources/DivImage.swift index f244e16e1..22f890a52 100644 --- a/client/ios/DivKit/generated_sources/DivImage.swift +++ b/client/ios/DivKit/generated_sources/DivImage.swift @@ -23,7 +23,7 @@ public final class DivImage: DivBase { public let disappearActions: [DivDisappearAction]? public let doubletapActions: [DivAction]? public let extensions: [DivExtension]? - public let filters: [DivFilter]? // at least 1 elements + public let filters: [DivFilter]? public let focus: DivFocus? public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let highPriorityPreviewShow: Expression // default value: false @@ -121,9 +121,6 @@ public final class DivImage: DivBase { static let columnSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let filtersValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) diff --git a/client/ios/DivKit/generated_sources/DivImageBackground.swift b/client/ios/DivKit/generated_sources/DivImageBackground.swift index 8baa653f7..44241f32e 100644 --- a/client/ios/DivKit/generated_sources/DivImageBackground.swift +++ b/client/ios/DivKit/generated_sources/DivImageBackground.swift @@ -9,7 +9,7 @@ public final class DivImageBackground { public let alpha: Expression // constraint: number >= 0.0 && number <= 1.0; default value: 1.0 public let contentAlignmentHorizontal: Expression // default value: center public let contentAlignmentVertical: Expression // default value: center - public let filters: [DivFilter]? // at least 1 elements + public let filters: [DivFilter]? public let imageUrl: Expression public let preloadRequired: Expression // default value: false public let scale: Expression // default value: fill @@ -41,9 +41,6 @@ public final class DivImageBackground { static let alphaValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0.0 && $0 <= 1.0 }) - static let filtersValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - init( alpha: Expression? = nil, contentAlignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivImageBackgroundTemplate.swift b/client/ios/DivKit/generated_sources/DivImageBackgroundTemplate.swift index e63cedc08..0d9832a40 100644 --- a/client/ios/DivKit/generated_sources/DivImageBackgroundTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivImageBackgroundTemplate.swift @@ -10,7 +10,7 @@ public final class DivImageBackgroundTemplate: TemplateValue { public let alpha: Field>? // constraint: number >= 0.0 && number <= 1.0; default value: 1.0 public let contentAlignmentHorizontal: Field>? // default value: center public let contentAlignmentVertical: Field>? // default value: center - public let filters: Field<[DivFilterTemplate]>? // at least 1 elements + public let filters: Field<[DivFilterTemplate]>? public let imageUrl: Field>? public let preloadRequired: Field>? // default value: false public let scale: Field>? // default value: fill @@ -56,7 +56,7 @@ public final class DivImageBackgroundTemplate: TemplateValue { let alphaValue = parent?.alpha?.resolveOptionalValue(context: context, validator: ResolvedValue.alphaValidator) ?? .noValue let contentAlignmentHorizontalValue = parent?.contentAlignmentHorizontal?.resolveOptionalValue(context: context) ?? .noValue let contentAlignmentVerticalValue = parent?.contentAlignmentVertical?.resolveOptionalValue(context: context) ?? .noValue - let filtersValue = parent?.filters?.resolveOptionalValue(context: context, validator: ResolvedValue.filtersValidator, useOnlyLinks: true) ?? .noValue + let filtersValue = parent?.filters?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let imageUrlValue = parent?.imageUrl?.resolveValue(context: context, transform: URL.init(string:)) ?? .noValue let preloadRequiredValue = parent?.preloadRequired?.resolveOptionalValue(context: context) ?? .noValue let scaleValue = parent?.scale?.resolveOptionalValue(context: context) ?? .noValue @@ -109,7 +109,7 @@ public final class DivImageBackgroundTemplate: TemplateValue { case "content_alignment_vertical": contentAlignmentVerticalValue = deserialize(__dictValue).merged(with: contentAlignmentVerticalValue) case "filters": - filtersValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.filtersValidator, type: DivFilterTemplate.self).merged(with: filtersValue) + filtersValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFilterTemplate.self).merged(with: filtersValue) case "image_url": imageUrlValue = deserialize(__dictValue, transform: URL.init(string:)).merged(with: imageUrlValue) case "preload_required": @@ -123,7 +123,7 @@ public final class DivImageBackgroundTemplate: TemplateValue { case parent?.contentAlignmentVertical?.link: contentAlignmentVerticalValue = contentAlignmentVerticalValue.merged(with: deserialize(__dictValue)) case parent?.filters?.link: - filtersValue = filtersValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.filtersValidator, type: DivFilterTemplate.self)) + filtersValue = filtersValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFilterTemplate.self)) case parent?.imageUrl?.link: imageUrlValue = imageUrlValue.merged(with: deserialize(__dictValue, transform: URL.init(string:))) case parent?.preloadRequired?.link: @@ -134,7 +134,7 @@ public final class DivImageBackgroundTemplate: TemplateValue { } } if let parent = parent { - filtersValue = filtersValue.merged(with: parent.filters?.resolveOptionalValue(context: context, validator: ResolvedValue.filtersValidator, useOnlyLinks: true)) + filtersValue = filtersValue.merged(with: parent.filters?.resolveOptionalValue(context: context, useOnlyLinks: true)) } var errors = mergeErrors( alphaValue.errorsOrWarnings?.map { .nestedObjectError(field: "alpha", error: $0) }, diff --git a/client/ios/DivKit/generated_sources/DivImageTemplate.swift b/client/ios/DivKit/generated_sources/DivImageTemplate.swift index c904cf874..07362d8cf 100644 --- a/client/ios/DivKit/generated_sources/DivImageTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivImageTemplate.swift @@ -24,7 +24,7 @@ public final class DivImageTemplate: TemplateValue { public let disappearActions: Field<[DivDisappearActionTemplate]>? public let doubletapActions: Field<[DivActionTemplate]>? public let extensions: Field<[DivExtensionTemplate]>? - public let filters: Field<[DivFilterTemplate]>? // at least 1 elements + public let filters: Field<[DivFilterTemplate]>? public let focus: Field? public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let highPriorityPreviewShow: Field>? // default value: false @@ -218,7 +218,7 @@ public final class DivImageTemplate: TemplateValue { let disappearActionsValue = parent?.disappearActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let doubletapActionsValue = parent?.doubletapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let extensionsValue = parent?.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue - let filtersValue = parent?.filters?.resolveOptionalValue(context: context, validator: ResolvedValue.filtersValidator, useOnlyLinks: true) ?? .noValue + let filtersValue = parent?.filters?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let focusValue = parent?.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let heightValue = parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let highPriorityPreviewShowValue = parent?.highPriorityPreviewShow?.resolveOptionalValue(context: context) ?? .noValue @@ -433,7 +433,7 @@ public final class DivImageTemplate: TemplateValue { case "extensions": extensionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivExtensionTemplate.self).merged(with: extensionsValue) case "filters": - filtersValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.filtersValidator, type: DivFilterTemplate.self).merged(with: filtersValue) + filtersValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFilterTemplate.self).merged(with: filtersValue) case "focus": focusValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFocusTemplate.self).merged(with: focusValue) case "height": @@ -521,7 +521,7 @@ public final class DivImageTemplate: TemplateValue { case parent?.extensions?.link: extensionsValue = extensionsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivExtensionTemplate.self)) case parent?.filters?.link: - filtersValue = filtersValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.filtersValidator, type: DivFilterTemplate.self)) + filtersValue = filtersValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFilterTemplate.self)) case parent?.focus?.link: focusValue = focusValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFocusTemplate.self)) case parent?.height?.link: @@ -589,7 +589,7 @@ public final class DivImageTemplate: TemplateValue { disappearActionsValue = disappearActionsValue.merged(with: parent.disappearActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) doubletapActionsValue = doubletapActionsValue.merged(with: parent.doubletapActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) extensionsValue = extensionsValue.merged(with: parent.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true)) - filtersValue = filtersValue.merged(with: parent.filters?.resolveOptionalValue(context: context, validator: ResolvedValue.filtersValidator, useOnlyLinks: true)) + filtersValue = filtersValue.merged(with: parent.filters?.resolveOptionalValue(context: context, useOnlyLinks: true)) focusValue = focusValue.merged(with: parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true)) heightValue = heightValue.merged(with: parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true)) longtapActionsValue = longtapActionsValue.merged(with: parent.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) diff --git a/client/ios/DivKit/generated_sources/DivPager.swift b/client/ios/DivKit/generated_sources/DivPager.swift index 3f19487ed..e511dac1c 100644 --- a/client/ios/DivKit/generated_sources/DivPager.swift +++ b/client/ios/DivKit/generated_sources/DivPager.swift @@ -27,7 +27,7 @@ public final class DivPager: DivBase { public let id: String? public let infiniteScroll: Expression // default value: false public let itemSpacing: DivFixedSize // default value: DivFixedSize(value: .value(0)) - public let items: [Div] // at least 1 elements + public let items: [Div]? public let layoutMode: DivPagerLayoutMode public let margins: DivEdgeInsets public let orientation: Expression // default value: horizontal @@ -95,9 +95,6 @@ public final class DivPager: DivBase { static let defaultItemValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let itemsValidator: AnyArrayValueValidator
= - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -120,7 +117,7 @@ public final class DivPager: DivBase { id: String?, infiniteScroll: Expression?, itemSpacing: DivFixedSize?, - items: [Div], + items: [Div]?, layoutMode: DivPagerLayoutMode, margins: DivEdgeInsets?, orientation: Expression?, @@ -279,7 +276,7 @@ extension DivPager: Serializable { result["id"] = id result["infinite_scroll"] = infiniteScroll.toValidSerializationValue() result["item_spacing"] = itemSpacing.toDictionary() - result["items"] = items.map { $0.toDictionary() } + result["items"] = items?.map { $0.toDictionary() } result["layout_mode"] = layoutMode.toDictionary() result["margins"] = margins.toDictionary() result["orientation"] = orientation.toValidSerializationValue() diff --git a/client/ios/DivKit/generated_sources/DivPagerTemplate.swift b/client/ios/DivKit/generated_sources/DivPagerTemplate.swift index faae372fa..4867ceab4 100644 --- a/client/ios/DivKit/generated_sources/DivPagerTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivPagerTemplate.swift @@ -24,7 +24,7 @@ public final class DivPagerTemplate: TemplateValue { public let id: Field? public let infiniteScroll: Field>? // default value: false public let itemSpacing: Field? // default value: DivFixedSize(value: .value(0)) - public let items: Field<[DivTemplate]>? // at least 1 elements + public let items: Field<[DivTemplate]>? public let layoutMode: Field? public let margins: Field? public let orientation: Field>? // default value: horizontal @@ -174,7 +174,7 @@ public final class DivPagerTemplate: TemplateValue { let idValue = parent?.id?.resolveOptionalValue(context: context) ?? .noValue let infiniteScrollValue = parent?.infiniteScroll?.resolveOptionalValue(context: context) ?? .noValue let itemSpacingValue = parent?.itemSpacing?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue - let itemsValue = parent?.items?.resolveValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true) ?? .noValue + let itemsValue = parent?.items?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let layoutModeValue = parent?.layoutMode?.resolveValue(context: context, useOnlyLinks: true) ?? .noValue let marginsValue = parent?.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let orientationValue = parent?.orientation?.resolveOptionalValue(context: context) ?? .noValue @@ -227,14 +227,10 @@ public final class DivPagerTemplate: TemplateValue { visibilityActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_actions", error: $0) }, widthValue.errorsOrWarnings?.map { .nestedObjectError(field: "width", error: $0) } ) - if case .noValue = itemsValue { - errors.append(.requiredFieldIsMissing(field: "items")) - } if case .noValue = layoutModeValue { errors.append(.requiredFieldIsMissing(field: "layout_mode")) } guard - let itemsNonNil = itemsValue.value, let layoutModeNonNil = layoutModeValue.value else { return .failure(NonEmptyArray(errors)!) @@ -255,7 +251,7 @@ public final class DivPagerTemplate: TemplateValue { id: idValue.value, infiniteScroll: infiniteScrollValue.value, itemSpacing: itemSpacingValue.value, - items: itemsNonNil, + items: itemsValue.value, layoutMode: layoutModeNonNil, margins: marginsValue.value, orientation: orientationValue.value, @@ -347,7 +343,7 @@ public final class DivPagerTemplate: TemplateValue { case "item_spacing": itemSpacingValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFixedSizeTemplate.self).merged(with: itemSpacingValue) case "items": - itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self).merged(with: itemsValue) + itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self).merged(with: itemsValue) case "layout_mode": layoutModeValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivPagerLayoutModeTemplate.self).merged(with: layoutModeValue) case "margins": @@ -413,7 +409,7 @@ public final class DivPagerTemplate: TemplateValue { case parent?.itemSpacing?.link: itemSpacingValue = itemSpacingValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFixedSizeTemplate.self)) case parent?.items?.link: - itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self)) + itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self)) case parent?.layoutMode?.link: layoutModeValue = layoutModeValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivPagerLayoutModeTemplate.self)) case parent?.margins?.link: @@ -460,7 +456,7 @@ public final class DivPagerTemplate: TemplateValue { focusValue = focusValue.merged(with: parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true)) heightValue = heightValue.merged(with: parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true)) itemSpacingValue = itemSpacingValue.merged(with: parent.itemSpacing?.resolveOptionalValue(context: context, useOnlyLinks: true)) - itemsValue = itemsValue.merged(with: parent.items?.resolveValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true)) + itemsValue = itemsValue.merged(with: parent.items?.resolveOptionalValue(context: context, useOnlyLinks: true)) layoutModeValue = layoutModeValue.merged(with: parent.layoutMode?.resolveValue(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)) @@ -509,14 +505,10 @@ public final class DivPagerTemplate: TemplateValue { visibilityActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_actions", error: $0) }, widthValue.errorsOrWarnings?.map { .nestedObjectError(field: "width", error: $0) } ) - if case .noValue = itemsValue { - errors.append(.requiredFieldIsMissing(field: "items")) - } if case .noValue = layoutModeValue { errors.append(.requiredFieldIsMissing(field: "layout_mode")) } guard - let itemsNonNil = itemsValue.value, let layoutModeNonNil = layoutModeValue.value else { return .failure(NonEmptyArray(errors)!) @@ -537,7 +529,7 @@ public final class DivPagerTemplate: TemplateValue { id: idValue.value, infiniteScroll: infiniteScrollValue.value, itemSpacing: itemSpacingValue.value, - items: itemsNonNil, + items: itemsValue.value, layoutMode: layoutModeNonNil, margins: marginsValue.value, orientation: orientationValue.value, @@ -624,7 +616,7 @@ public final class DivPagerTemplate: TemplateValue { id: merged.id, infiniteScroll: merged.infiniteScroll, itemSpacing: merged.itemSpacing?.tryResolveParent(templates: templates), - items: try merged.items?.resolveParent(templates: templates), + items: merged.items?.tryResolveParent(templates: templates), layoutMode: try merged.layoutMode?.resolveParent(templates: templates), margins: merged.margins?.tryResolveParent(templates: templates), orientation: merged.orientation, diff --git a/client/ios/DivKit/generated_sources/DivPatch.swift b/client/ios/DivKit/generated_sources/DivPatch.swift index 759f5586e..d15aa4ce3 100644 --- a/client/ios/DivKit/generated_sources/DivPatch.swift +++ b/client/ios/DivKit/generated_sources/DivPatch.swift @@ -13,10 +13,7 @@ public final class DivPatch { public final class Change { public let id: String - public let items: [Div]? // at least 1 elements - - static let itemsValidator: AnyArrayValueValidator
= - makeArrayValidator(minItems: 1) + public let items: [Div]? init( id: String, diff --git a/client/ios/DivKit/generated_sources/DivPatchTemplate.swift b/client/ios/DivKit/generated_sources/DivPatchTemplate.swift index 4b1c81338..590043953 100644 --- a/client/ios/DivKit/generated_sources/DivPatchTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivPatchTemplate.swift @@ -7,7 +7,7 @@ import Serialization public final class DivPatchTemplate: TemplateValue { public final class ChangeTemplate: TemplateValue { public let id: Field? - public let items: Field<[DivTemplate]>? // at least 1 elements + public let items: Field<[DivTemplate]>? public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { do { @@ -30,7 +30,7 @@ public final class DivPatchTemplate: TemplateValue { private static func resolveOnlyLinks(context: TemplatesContext, parent: ChangeTemplate?) -> DeserializationResult { let idValue = parent?.id?.resolveValue(context: context) ?? .noValue - let itemsValue = parent?.items?.resolveOptionalValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true) ?? .noValue + let itemsValue = parent?.items?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue var errors = mergeErrors( idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, itemsValue.errorsOrWarnings?.map { .nestedObjectError(field: "items", error: $0) } @@ -61,16 +61,16 @@ public final class DivPatchTemplate: TemplateValue { case "id": idValue = deserialize(__dictValue).merged(with: idValue) case "items": - itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self).merged(with: itemsValue) + itemsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self).merged(with: itemsValue) case parent?.id?.link: idValue = idValue.merged(with: deserialize(__dictValue)) case parent?.items?.link: - itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.itemsValidator, type: DivTemplate.self)) + itemsValue = itemsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTemplate.self)) default: break } } if let parent = parent { - itemsValue = itemsValue.merged(with: parent.items?.resolveOptionalValue(context: context, validator: ResolvedValue.itemsValidator, useOnlyLinks: true)) + itemsValue = itemsValue.merged(with: parent.items?.resolveOptionalValue(context: context, useOnlyLinks: true)) } var errors = mergeErrors( idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, diff --git a/client/ios/DivKit/generated_sources/DivSlider.swift b/client/ios/DivKit/generated_sources/DivSlider.swift index 8b44b5d23..e51451152 100644 --- a/client/ios/DivKit/generated_sources/DivSlider.swift +++ b/client/ios/DivKit/generated_sources/DivSlider.swift @@ -93,7 +93,7 @@ public final class DivSlider: DivBase { public let maxValue: Expression // default value: 100 public let minValue: Expression // default value: 0 public let paddings: DivEdgeInsets - public let ranges: [Range]? // at least 1 elements + public let ranges: [Range]? public let rowSpan: Expression? // constraint: number >= 0 public let secondaryValueAccessibility: DivAccessibility public let selectedActions: [DivAction]? @@ -156,9 +156,6 @@ public final class DivSlider: DivBase { static let columnSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let rangesValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) diff --git a/client/ios/DivKit/generated_sources/DivSliderTemplate.swift b/client/ios/DivKit/generated_sources/DivSliderTemplate.swift index 3bee7caba..c35e0f573 100644 --- a/client/ios/DivKit/generated_sources/DivSliderTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivSliderTemplate.swift @@ -295,7 +295,7 @@ public final class DivSliderTemplate: TemplateValue { public let maxValue: Field>? // default value: 100 public let minValue: Field>? // default value: 0 public let paddings: Field? - public let ranges: Field<[RangeTemplate]>? // at least 1 elements + public let ranges: Field<[RangeTemplate]>? public let rowSpan: Field>? // constraint: number >= 0 public let secondaryValueAccessibility: Field? public let selectedActions: Field<[DivActionTemplate]>? @@ -473,7 +473,7 @@ public final class DivSliderTemplate: TemplateValue { let maxValueValue = parent?.maxValue?.resolveOptionalValue(context: context) ?? .noValue let minValueValue = parent?.minValue?.resolveOptionalValue(context: context) ?? .noValue let paddingsValue = parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue - let rangesValue = parent?.ranges?.resolveOptionalValue(context: context, validator: ResolvedValue.rangesValidator, useOnlyLinks: true) ?? .noValue + let rangesValue = parent?.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let rowSpanValue = parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue let secondaryValueAccessibilityValue = parent?.secondaryValueAccessibility?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let selectedActionsValue = parent?.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue @@ -679,7 +679,7 @@ public final class DivSliderTemplate: TemplateValue { case "paddings": paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) case "ranges": - rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.rangesValidator, type: DivSliderTemplate.RangeTemplate.self).merged(with: rangesValue) + rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSliderTemplate.RangeTemplate.self).merged(with: rangesValue) case "row_span": rowSpanValue = deserialize(__dictValue, validator: ResolvedValue.rowSpanValidator).merged(with: rowSpanValue) case "secondary_value_accessibility": @@ -759,7 +759,7 @@ public final class DivSliderTemplate: TemplateValue { case parent?.paddings?.link: paddingsValue = paddingsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self)) case parent?.ranges?.link: - rangesValue = rangesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.rangesValidator, type: DivSliderTemplate.RangeTemplate.self)) + rangesValue = rangesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSliderTemplate.RangeTemplate.self)) case parent?.rowSpan?.link: rowSpanValue = rowSpanValue.merged(with: deserialize(__dictValue, validator: ResolvedValue.rowSpanValidator)) case parent?.secondaryValueAccessibility?.link: @@ -819,7 +819,7 @@ public final class DivSliderTemplate: TemplateValue { heightValue = heightValue.merged(with: parent.height?.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)) - rangesValue = rangesValue.merged(with: parent.ranges?.resolveOptionalValue(context: context, validator: ResolvedValue.rangesValidator, useOnlyLinks: true)) + rangesValue = rangesValue.merged(with: parent.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true)) secondaryValueAccessibilityValue = secondaryValueAccessibilityValue.merged(with: parent.secondaryValueAccessibility?.resolveOptionalValue(context: context, useOnlyLinks: true)) selectedActionsValue = selectedActionsValue.merged(with: parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true)) thumbSecondaryStyleValue = thumbSecondaryStyleValue.merged(with: parent.thumbSecondaryStyle?.resolveOptionalValue(context: context, useOnlyLinks: true)) diff --git a/client/ios/DivKit/generated_sources/DivText.swift b/client/ios/DivKit/generated_sources/DivText.swift index 4a661605c..cbd3f87d6 100644 --- a/client/ios/DivKit/generated_sources/DivText.swift +++ b/client/ios/DivKit/generated_sources/DivText.swift @@ -7,20 +7,14 @@ import Serialization public final class DivText: DivBase { public final class Ellipsis { public let actions: [DivAction]? - public let images: [Image]? // at least 1 elements - public let ranges: [Range]? // at least 1 elements + public let images: [Image]? + public let ranges: [Range]? public let text: Expression public func resolveText(_ resolver: ExpressionResolver) -> String? { resolver.resolveStringBasedValue(expression: text, initializer: { $0 }) } - static let imagesValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - - static let rangesValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - init( actions: [DivAction]? = nil, images: [Image]? = nil, @@ -220,7 +214,7 @@ public final class DivText: DivBase { public let fontWeight: Expression // default value: regular public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) public let id: String? - public let images: [Image]? // at least 1 elements + public let images: [Image]? public let letterSpacing: Expression // default value: 0 public let lineHeight: Expression? // constraint: number >= 0 public let longtapActions: [DivAction]? @@ -228,7 +222,7 @@ 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 ranges: [Range]? // at least 1 elements + public let ranges: [Range]? public let rowSpan: Expression? // constraint: number >= 0 public let selectable: Expression // default value: false public let selectedActions: [DivAction]? @@ -352,9 +346,6 @@ public final class DivText: DivBase { static let fontSizeValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let imagesValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - static let lineHeightValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) @@ -364,9 +355,6 @@ public final class DivText: DivBase { static let minHiddenLinesValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) - static let rangesValidator: AnyArrayValueValidator = - makeArrayValidator(minItems: 1) - static let rowSpanValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) diff --git a/client/ios/DivKit/generated_sources/DivTextTemplate.swift b/client/ios/DivKit/generated_sources/DivTextTemplate.swift index 6dd567bc1..1d2087cd7 100644 --- a/client/ios/DivKit/generated_sources/DivTextTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivTextTemplate.swift @@ -7,8 +7,8 @@ import Serialization public final class DivTextTemplate: TemplateValue { public final class EllipsisTemplate: TemplateValue { public let actions: Field<[DivActionTemplate]>? - public let images: Field<[ImageTemplate]>? // at least 1 elements - public let ranges: Field<[RangeTemplate]>? // at least 1 elements + public let images: Field<[ImageTemplate]>? + public let ranges: Field<[RangeTemplate]>? public let text: Field>? public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { @@ -38,8 +38,8 @@ public final class DivTextTemplate: TemplateValue { private static func resolveOnlyLinks(context: TemplatesContext, parent: EllipsisTemplate?) -> DeserializationResult { let actionsValue = parent?.actions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue - let imagesValue = parent?.images?.resolveOptionalValue(context: context, validator: ResolvedValue.imagesValidator, useOnlyLinks: true) ?? .noValue - let rangesValue = parent?.ranges?.resolveOptionalValue(context: context, validator: ResolvedValue.rangesValidator, useOnlyLinks: true) ?? .noValue + let imagesValue = parent?.images?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue + let rangesValue = parent?.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let textValue = parent?.text?.resolveValue(context: context) ?? .noValue var errors = mergeErrors( actionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "actions", error: $0) }, @@ -77,17 +77,17 @@ public final class DivTextTemplate: TemplateValue { case "actions": actionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: actionsValue) case "images": - imagesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.imagesValidator, type: DivTextTemplate.ImageTemplate.self).merged(with: imagesValue) + imagesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.ImageTemplate.self).merged(with: imagesValue) case "ranges": - rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.rangesValidator, type: DivTextTemplate.RangeTemplate.self).merged(with: rangesValue) + rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.RangeTemplate.self).merged(with: rangesValue) case "text": textValue = deserialize(__dictValue).merged(with: textValue) case parent?.actions?.link: actionsValue = actionsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self)) case parent?.images?.link: - imagesValue = imagesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.imagesValidator, type: DivTextTemplate.ImageTemplate.self)) + imagesValue = imagesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.ImageTemplate.self)) case parent?.ranges?.link: - rangesValue = rangesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.rangesValidator, type: DivTextTemplate.RangeTemplate.self)) + rangesValue = rangesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.RangeTemplate.self)) case parent?.text?.link: textValue = textValue.merged(with: deserialize(__dictValue)) default: break @@ -95,8 +95,8 @@ public final class DivTextTemplate: TemplateValue { } if let parent = parent { actionsValue = actionsValue.merged(with: parent.actions?.resolveOptionalValue(context: context, useOnlyLinks: true)) - imagesValue = imagesValue.merged(with: parent.images?.resolveOptionalValue(context: context, validator: ResolvedValue.imagesValidator, useOnlyLinks: true)) - rangesValue = rangesValue.merged(with: parent.ranges?.resolveOptionalValue(context: context, validator: ResolvedValue.rangesValidator, useOnlyLinks: true)) + imagesValue = imagesValue.merged(with: parent.images?.resolveOptionalValue(context: context, useOnlyLinks: true)) + rangesValue = rangesValue.merged(with: parent.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true)) } var errors = mergeErrors( actionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "actions", error: $0) }, @@ -652,7 +652,7 @@ public final class DivTextTemplate: TemplateValue { public let fontWeight: Field>? // default value: regular public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) public let id: Field? - public let images: Field<[ImageTemplate]>? // at least 1 elements + public let images: Field<[ImageTemplate]>? public let letterSpacing: Field>? // default value: 0 public let lineHeight: Field>? // constraint: number >= 0 public let longtapActions: Field<[DivActionTemplate]>? @@ -660,7 +660,7 @@ 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 ranges: Field<[RangeTemplate]>? // at least 1 elements + public let ranges: Field<[RangeTemplate]>? public let rowSpan: Field>? // constraint: number >= 0 public let selectable: Field>? // default value: false public let selectedActions: Field<[DivActionTemplate]>? @@ -882,7 +882,7 @@ public final class DivTextTemplate: TemplateValue { let fontWeightValue = parent?.fontWeight?.resolveOptionalValue(context: context) ?? .noValue let heightValue = parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let idValue = parent?.id?.resolveOptionalValue(context: context) ?? .noValue - let imagesValue = parent?.images?.resolveOptionalValue(context: context, validator: ResolvedValue.imagesValidator, useOnlyLinks: true) ?? .noValue + let imagesValue = parent?.images?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let letterSpacingValue = parent?.letterSpacing?.resolveOptionalValue(context: context) ?? .noValue let lineHeightValue = parent?.lineHeight?.resolveOptionalValue(context: context, validator: ResolvedValue.lineHeightValidator) ?? .noValue let longtapActionsValue = parent?.longtapActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue @@ -890,7 +890,7 @@ 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 rangesValue = parent?.ranges?.resolveOptionalValue(context: context, validator: ResolvedValue.rangesValidator, useOnlyLinks: true) ?? .noValue + let rangesValue = parent?.ranges?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue let rowSpanValue = parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue let selectableValue = parent?.selectable?.resolveOptionalValue(context: context) ?? .noValue let selectedActionsValue = parent?.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue @@ -1139,7 +1139,7 @@ public final class DivTextTemplate: TemplateValue { case "id": idValue = deserialize(__dictValue).merged(with: idValue) case "images": - imagesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.imagesValidator, type: DivTextTemplate.ImageTemplate.self).merged(with: imagesValue) + imagesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.ImageTemplate.self).merged(with: imagesValue) case "letter_spacing": letterSpacingValue = deserialize(__dictValue).merged(with: letterSpacingValue) case "line_height": @@ -1155,7 +1155,7 @@ public final class DivTextTemplate: TemplateValue { case "paddings": paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) case "ranges": - rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.rangesValidator, type: DivTextTemplate.RangeTemplate.self).merged(with: rangesValue) + rangesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.RangeTemplate.self).merged(with: rangesValue) case "row_span": rowSpanValue = deserialize(__dictValue, validator: ResolvedValue.rowSpanValidator).merged(with: rowSpanValue) case "selectable": @@ -1245,7 +1245,7 @@ public final class DivTextTemplate: TemplateValue { case parent?.id?.link: idValue = idValue.merged(with: deserialize(__dictValue)) case parent?.images?.link: - imagesValue = imagesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.imagesValidator, type: DivTextTemplate.ImageTemplate.self)) + imagesValue = imagesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.ImageTemplate.self)) case parent?.letterSpacing?.link: letterSpacingValue = letterSpacingValue.merged(with: deserialize(__dictValue)) case parent?.lineHeight?.link: @@ -1261,7 +1261,7 @@ public final class DivTextTemplate: TemplateValue { case parent?.paddings?.link: paddingsValue = paddingsValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self)) case parent?.ranges?.link: - rangesValue = rangesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, validator: ResolvedValue.rangesValidator, type: DivTextTemplate.RangeTemplate.self)) + rangesValue = rangesValue.merged(with: deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTextTemplate.RangeTemplate.self)) case parent?.rowSpan?.link: rowSpanValue = rowSpanValue.merged(with: deserialize(__dictValue, validator: ResolvedValue.rowSpanValidator)) case parent?.selectable?.link: @@ -1320,11 +1320,11 @@ public final class DivTextTemplate: TemplateValue { extensionsValue = extensionsValue.merged(with: parent.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true)) focusValue = focusValue.merged(with: parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true)) heightValue = heightValue.merged(with: parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true)) - imagesValue = imagesValue.merged(with: parent.images?.resolveOptionalValue(context: context, validator: ResolvedValue.imagesValidator, useOnlyLinks: true)) + imagesValue = imagesValue.merged(with: parent.images?.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)) - rangesValue = rangesValue.merged(with: parent.ranges?.resolveOptionalValue(context: context, validator: ResolvedValue.rangesValidator, 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)) textShadowValue = textShadowValue.merged(with: parent.textShadow?.resolveOptionalValue(context: context, useOnlyLinks: true)) diff --git a/client/ios/DivKitTests/DivDeserializationErrorsTests.swift b/client/ios/DivKitTests/DivDeserializationErrorsTests.swift index 5e61003ab..0490ae94c 100644 --- a/client/ios/DivKitTests/DivDeserializationErrorsTests.swift +++ b/client/ios/DivKitTests/DivDeserializationErrorsTests.swift @@ -65,7 +65,7 @@ private let dictWithInvalidField: [String: Any] = [ "states": [ [ "div": [ - "type": "gallery", + "type": "tabs", "items": [] as [Any], ] as [String: Any], "state_id": 0, diff --git a/json-builder/python/tests/test_ref_types.py b/json-builder/python/tests/test_ref_types.py index 44e63ba74..55b61302f 100644 --- a/json-builder/python/tests/test_ref_types.py +++ b/json-builder/python/tests/test_ref_types.py @@ -7,7 +7,6 @@ from pydivkit import ( DivAction, DivBorder, DivContainer, - DivGallery, DivGifImage, DivImage, DivText, @@ -72,17 +71,6 @@ def test_union_type(): assert "card" in make_div(images) -def test_ref_collections_error_simple_type(): - with pytest.raises(TypeError): - class ImageItems(DivGallery): - image_items: str = Field() - items = [ - DivGallery( - items=Ref(image_items), - ), - ] - - def test_optional_expr(): class CategoriesItem(DivContainer): corner_radius: int = Field() diff --git a/schema/div-custom.json b/schema/div-custom.json index 00b36b60d..211475e1a 100644 --- a/schema/div-custom.json +++ b/schema/div-custom.json @@ -18,7 +18,6 @@ "items": { "$ref": "div.json" }, - "minItems": 1, "$description": "translations.json#/div_custom_items" }, "custom_type": { diff --git a/schema/div-focus.json b/schema/div-focus.json index 4072c4fc3..b2e8df326 100644 --- a/schema/div-focus.json +++ b/schema/div-focus.json @@ -7,7 +7,6 @@ "items": { "$ref": "div-background.json" }, - "minItems": 1, "$description": "translations.json#/div_focus_background" }, "border": { diff --git a/schema/div-gallery.json b/schema/div-gallery.json index 138a67a5c..56963db99 100644 --- a/schema/div-gallery.json +++ b/schema/div-gallery.json @@ -61,7 +61,6 @@ "items": { "$ref": "div.json" }, - "minItems": 1, "$description": "translations.json#/div_gallery_items" }, "orientation": { @@ -104,7 +103,6 @@ } ], "required": [ - "type", - "items" + "type" ] } diff --git a/schema/div-grid.json b/schema/div-grid.json index 22b98606b..ce11f8362 100644 --- a/schema/div-grid.json +++ b/schema/div-grid.json @@ -35,7 +35,6 @@ "items": { "$ref": "div.json" }, - "minItems": 1, "$description": "translations.json#/div_grid_items" }, "column_count": { @@ -52,7 +51,6 @@ } ], "required": [ - "items", "column_count", "type" ] diff --git a/schema/div-image-background.json b/schema/div-image-background.json index 1ba8b1431..fcb86b01c 100644 --- a/schema/div-image-background.json +++ b/schema/div-image-background.json @@ -40,7 +40,6 @@ "items": { "$ref": "div-filter.json" }, - "minItems": 1, "$description": "translations.json#/div_filter" }, "type": { diff --git a/schema/div-image.json b/schema/div-image.json index f9196d16f..48713f2bd 100644 --- a/schema/div-image.json +++ b/schema/div-image.json @@ -57,7 +57,6 @@ "items": { "$ref": "div-filter.json" }, - "minItems": 1, "$description": "translations.json#/div_filter" } } diff --git a/schema/div-pager.json b/schema/div-pager.json index 13e43a3be..f4c03995c 100644 --- a/schema/div-pager.json +++ b/schema/div-pager.json @@ -37,7 +37,6 @@ "items": { "$ref": "div.json" }, - "minItems": 1, "$description": "translations.json#/div_pager_items" }, "orientation": { @@ -73,7 +72,6 @@ ], "required": [ "type", - "items", "layout_mode" ] } diff --git a/schema/div-patch.json b/schema/div-patch.json index 27913531e..16932ea1b 100644 --- a/schema/div-patch.json +++ b/schema/div-patch.json @@ -14,7 +14,6 @@ "items": { "$ref": "div.json" }, - "minItems": 1, "$description": "translations.json#/div_patch_change_items" } }, diff --git a/schema/div-slider.json b/schema/div-slider.json index 920176172..858199687 100644 --- a/schema/div-slider.json +++ b/schema/div-slider.json @@ -129,7 +129,6 @@ "items": { "$ref": "#/definitions/range" }, - "minItems": 1, "$description": "translations.json#/div_slider_ranges", "platforms": [ "android", diff --git a/schema/div-text.json b/schema/div-text.json index b0d38ac87..333be2a4d 100644 --- a/schema/div-text.json +++ b/schema/div-text.json @@ -154,7 +154,6 @@ "items": { "$ref": "#/definitions/range" }, - "minItems": 1, "$description": "translations.json#/div_text_ellipsis_ranges" }, "images": { @@ -162,7 +161,6 @@ "items": { "$ref": "#/definitions/image" }, - "minItems": 1, "$description": "translations.json#/div_text_ellipsis_images" } }, @@ -288,7 +286,6 @@ "items": { "$ref": "#/definitions/range" }, - "minItems": 1, "$description": "translations.json#/div_text_ranges" }, "images": { @@ -296,7 +293,6 @@ "items": { "$ref": "#/definitions/image" }, - "minItems": 1, "$description": "translations.json#/div_text_images" }, "ellipsis": {