@nativescript/core 9.0.21-next.20 → 9.0.21-next.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,29 +1,29 @@
1
1
  import { FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent, FlexboxLayoutBase, FlexBasisPercent, orderProperty, flexGrowProperty, flexShrinkProperty, flexWrapBeforeProperty, alignSelfProperty } from './flexbox-layout-common';
2
2
  import { View } from '../../core/view';
3
3
  import { layout } from '../../../utils';
4
+ import { CoreTypes } from '../../../core-types';
4
5
  export * from './flexbox-layout-common';
5
- var EXACTLY = layout.EXACTLY;
6
- var AT_MOST = layout.AT_MOST;
7
- var UNSPECIFIED = layout.UNSPECIFIED;
8
- var MEASURED_STATE_TOO_SMALL = layout.MEASURED_STATE_TOO_SMALL;
9
- function requestFlexboxLayout(value) {
10
- const flexbox = this.parent;
11
- if (flexbox instanceof FlexboxLayoutBase) {
12
- flexbox.requestLayout();
13
- }
14
- }
6
+ const EXACTLY = layout.EXACTLY;
7
+ const AT_MOST = layout.AT_MOST;
8
+ const UNSPECIFIED = layout.UNSPECIFIED;
9
+ const MEASURED_STATE_TOO_SMALL = layout.MEASURED_STATE_TOO_SMALL;
10
+ const MATCH_PARENT = -1;
11
+ const WRAP_CONTENT = -2;
12
+ const View_sUseZeroUnspecifiedMeasureSpec = true; // NOTE: android version < M
13
+ const makeMeasureSpec = layout.makeMeasureSpec;
14
+ const getMeasureSpecMode = layout.getMeasureSpecMode;
15
+ const getMeasureSpecSize = layout.getMeasureSpecSize;
15
16
  View.prototype[orderProperty.setNative] = requestFlexboxLayout;
16
17
  View.prototype[flexGrowProperty.setNative] = requestFlexboxLayout;
17
18
  View.prototype[flexShrinkProperty.setNative] = requestFlexboxLayout;
18
19
  View.prototype[flexWrapBeforeProperty.setNative] = requestFlexboxLayout;
19
20
  View.prototype[alignSelfProperty.setNative] = requestFlexboxLayout;
20
- const MATCH_PARENT = -1;
21
- const WRAP_CONTENT = -2;
22
- const View_sUseZeroUnspecifiedMeasureSpec = true; // NOTE: android version < M
23
- var makeMeasureSpec = layout.makeMeasureSpec;
24
- var getMeasureSpecMode = layout.getMeasureSpecMode;
25
- var getMeasureSpecSize = layout.getMeasureSpecSize;
26
- import { CoreTypes } from '../../enums';
21
+ function requestFlexboxLayout(_value) {
22
+ const flexbox = this.parent;
23
+ if (flexbox instanceof FlexboxLayoutBase) {
24
+ flexbox.requestLayout();
25
+ }
26
+ }
27
27
  // `eachLayoutChild` iterates over children, and we need more - indexed access.
28
28
  // This class tries to accomodate that by collecting all children in an
29
29
  // array no more than once per measure.
@@ -49,7 +49,7 @@ class FlexLine {
49
49
  this._right = Number.MAX_VALUE;
50
50
  this._bottom = Number.MAX_VALUE;
51
51
  this._mainSize = 0;
52
- this._dividerLengthInMainSize = 0;
52
+ this._gapLengthInMainSize = 0;
53
53
  this._crossSize = 0;
54
54
  this._itemCount = 0;
55
55
  this._goneItemCount = 0;
@@ -99,7 +99,6 @@ class Order {
99
99
  }
100
100
  export class FlexboxLayout extends FlexboxLayoutBase {
101
101
  constructor() {
102
- // Omit divider
103
102
  super(...arguments);
104
103
  this._flexLines = [];
105
104
  }
@@ -142,17 +141,20 @@ export class FlexboxLayout extends FlexboxLayoutBase {
142
141
  const orders = this._createOrders(childCount);
143
142
  return this._sortOrdersIntoReorderedIndices(childCount, orders);
144
143
  }
145
- _sortOrdersIntoReorderedIndices(childCount, orders) {
144
+ _sortOrdersIntoReorderedIndices(_childCount, orders) {
146
145
  orders.sort((a, b) => a.compareTo(b));
147
146
  if (!this._orderCache) {
148
147
  this._orderCache = [];
149
148
  }
150
- this._orderCache.length = 0;
149
+ else {
150
+ this._orderCache.length = 0;
151
+ }
151
152
  const reorderedIndices = [];
152
- orders.forEach((order, i) => {
153
+ for (let i = 0, length = orders.length; i < length; i++) {
154
+ const order = orders[i];
153
155
  reorderedIndices[i] = order.index;
154
- this._orderCache[i] = order.order;
155
- });
156
+ this._orderCache[order.index] = order.order;
157
+ }
156
158
  return reorderedIndices;
157
159
  }
158
160
  _createOrders(childCount) {
@@ -192,91 +194,93 @@ export class FlexboxLayout extends FlexboxLayoutBase {
192
194
  const heightMode = getMeasureSpecMode(heightMeasureSpec);
193
195
  let childState = 0;
194
196
  this._flexLines.length = 0;
195
- (() => {
196
- const childCount = this.measureContext.childrenCount;
197
- const paddingStart = FlexboxLayout.getPaddingStart(this);
198
- const paddingEnd = FlexboxLayout.getPaddingEnd(this);
199
- let largestHeightInRow = Number.MIN_VALUE;
200
- let flexLine = new FlexLine();
201
- let indexInFlexLine = 0;
202
- flexLine._mainSize = paddingStart + paddingEnd;
203
- for (let i = 0; i < childCount; i++) {
204
- const child = this._getReorderedChildAt(i);
205
- if (child === null) {
206
- this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
207
- continue;
208
- }
209
- else if (child.isCollapsed) {
210
- flexLine._itemCount++;
211
- flexLine._goneItemCount++;
212
- this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
213
- continue;
214
- }
215
- child._updateEffectiveLayoutValues(widthSize, widthMode, heightSize, heightMode);
216
- const lp = child; // child.style;
217
- if (FlexboxLayout.getAlignSelf(child) === 'stretch') {
218
- flexLine._indicesAlignSelfStretch.push(i);
219
- }
220
- let childWidth = lp.effectiveWidth;
221
- if (FlexBasisPercent.DEFAULT /*lp.flexBasisPercent*/ !== FlexBasisPercent.DEFAULT && widthMode === EXACTLY) {
222
- childWidth = Math.round(widthSize * FlexBasisPercent.DEFAULT /*lp.flexBasisPercent*/);
223
- }
224
- const childWidthMeasureSpec = FlexboxLayout.getChildMeasureSpec(widthMeasureSpec, lp.effectivePaddingLeft + lp.effectivePaddingRight + lp.effectiveMarginLeft + lp.effectiveMarginRight, childWidth < 0 ? WRAP_CONTENT : childWidth);
225
- const childHeightMeasureSpec = FlexboxLayout.getChildMeasureSpec(heightMeasureSpec, lp.effectivePaddingTop + lp.effectivePaddingBottom + lp.effectiveMarginTop + lp.effectiveMarginBottom, lp.effectiveHeight < 0 ? WRAP_CONTENT : lp.effectiveHeight);
226
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
227
- this._checkSizeConstraints(child);
228
- childState = View.combineMeasuredStates(childState, child.getMeasuredState());
229
- largestHeightInRow = Math.max(largestHeightInRow, child.getMeasuredHeight() + lp.effectiveMarginTop + lp.effectiveMarginBottom);
230
- if (this._isWrapRequired(child, widthMode, widthSize, flexLine._mainSize, child.getMeasuredWidth() + lp.effectiveMarginLeft + lp.effectiveMarginRight, i, indexInFlexLine)) {
231
- if (flexLine.layoutVisibleItemCount > 0) {
232
- this._addFlexLine(flexLine);
233
- }
234
- flexLine = new FlexLine();
235
- flexLine._itemCount = 1;
236
- flexLine._mainSize = paddingStart + paddingEnd;
237
- largestHeightInRow = child.getMeasuredHeight() + lp.effectiveMarginTop + lp.effectiveMarginBottom;
238
- indexInFlexLine = 0;
239
- }
240
- else {
241
- flexLine._itemCount++;
242
- indexInFlexLine++;
243
- }
244
- flexLine._mainSize += child.getMeasuredWidth() + lp.effectiveMarginLeft + lp.effectiveMarginRight;
245
- flexLine._totalFlexGrow += FlexboxLayout.getFlexGrow(child);
246
- flexLine._totalFlexShrink += FlexboxLayout.getFlexShrink(child);
247
- flexLine._crossSize = Math.max(flexLine._crossSize, largestHeightInRow);
248
- // Omit divider
249
- if (this.flexWrap !== FlexWrap.WRAP_REVERSE) {
250
- flexLine._maxBaseline = Math.max(flexLine._maxBaseline, FlexboxLayout.getBaseline(child) + lp.effectiveMarginTop);
251
- }
252
- else {
253
- flexLine._maxBaseline = Math.max(flexLine._maxBaseline, child.getMeasuredHeight() - FlexboxLayout.getBaseline(child) + lp.effectiveMarginBottom);
254
- }
197
+ const childCount = this.measureContext.childrenCount;
198
+ const paddingStart = FlexboxLayout.getPaddingStart(this);
199
+ const paddingEnd = FlexboxLayout.getPaddingEnd(this);
200
+ let largestHeightInRow = Number.MIN_VALUE;
201
+ let flexLine = new FlexLine();
202
+ let indexInFlexLine = 0;
203
+ flexLine._mainSize = paddingStart + paddingEnd;
204
+ for (let i = 0; i < childCount; i++) {
205
+ const child = this._getReorderedChildAt(i);
206
+ if (child === null) {
255
207
  this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
208
+ continue;
209
+ }
210
+ else if (child.isCollapsed) {
211
+ flexLine._itemCount++;
212
+ flexLine._goneItemCount++;
213
+ this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
214
+ continue;
215
+ }
216
+ child._updateEffectiveLayoutValues(widthSize, widthMode, heightSize, heightMode);
217
+ const lp = child; // child.style;
218
+ if (FlexboxLayout.getAlignSelf(child) === 'stretch') {
219
+ flexLine._indicesAlignSelfStretch.push(i);
220
+ }
221
+ let childWidth = lp.effectiveWidth;
222
+ if (FlexBasisPercent.DEFAULT /*lp.flexBasisPercent*/ !== FlexBasisPercent.DEFAULT && widthMode === EXACTLY) {
223
+ childWidth = Math.round(widthSize * FlexBasisPercent.DEFAULT /*lp.flexBasisPercent*/);
224
+ }
225
+ const childWidthMeasureSpec = FlexboxLayout.getChildMeasureSpec(widthMeasureSpec, lp.effectivePaddingLeft + lp.effectivePaddingRight + lp.effectiveMarginLeft + lp.effectiveMarginRight, childWidth < 0 ? WRAP_CONTENT : childWidth);
226
+ const childHeightMeasureSpec = FlexboxLayout.getChildMeasureSpec(heightMeasureSpec, lp.effectivePaddingTop + lp.effectivePaddingBottom + lp.effectiveMarginTop + lp.effectiveMarginBottom, lp.effectiveHeight < 0 ? WRAP_CONTENT : lp.effectiveHeight);
227
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
228
+ this._checkSizeConstraints(child);
229
+ childState = View.combineMeasuredStates(childState, child.getMeasuredState());
230
+ largestHeightInRow = Math.max(largestHeightInRow, child.getMeasuredHeight() + lp.effectiveMarginTop + lp.effectiveMarginBottom);
231
+ if (this._isWrapRequired(child, widthMode, widthSize, flexLine._mainSize, child.getMeasuredWidth() + lp.effectiveMarginLeft + lp.effectiveMarginRight, i, indexInFlexLine)) {
232
+ if (flexLine.layoutVisibleItemCount > 0) {
233
+ this._addFlexLine(flexLine);
234
+ }
235
+ flexLine = new FlexLine();
236
+ flexLine._itemCount = 1;
237
+ flexLine._mainSize = paddingStart + paddingEnd;
238
+ largestHeightInRow = child.getMeasuredHeight() + lp.effectiveMarginTop + lp.effectiveMarginBottom;
239
+ indexInFlexLine = 0;
240
+ }
241
+ else {
242
+ flexLine._itemCount++;
243
+ indexInFlexLine++;
244
+ }
245
+ flexLine._mainSize += child.getMeasuredWidth() + lp.effectiveMarginLeft + lp.effectiveMarginRight;
246
+ flexLine._totalFlexGrow += FlexboxLayout.getFlexGrow(child);
247
+ flexLine._totalFlexShrink += FlexboxLayout.getFlexShrink(child);
248
+ flexLine._crossSize = Math.max(flexLine._crossSize, largestHeightInRow);
249
+ // Check if column gap is required for the flex item
250
+ if (this.effectiveColumnGap > 0 && this._hasPrecedingViews(i, indexInFlexLine)) {
251
+ flexLine._mainSize += this.effectiveColumnGap;
252
+ flexLine._gapLengthInMainSize += this.effectiveColumnGap;
253
+ }
254
+ if (this.flexWrap !== FlexWrap.WRAP_REVERSE) {
255
+ flexLine._maxBaseline = Math.max(flexLine._maxBaseline, FlexboxLayout.getBaseline(child) + lp.effectiveMarginTop);
256
+ }
257
+ else {
258
+ flexLine._maxBaseline = Math.max(flexLine._maxBaseline, child.getMeasuredHeight() - FlexboxLayout.getBaseline(child) + lp.effectiveMarginBottom);
256
259
  }
257
- })();
260
+ this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
261
+ }
258
262
  this._determineMainSize(this.flexDirection, widthMeasureSpec, heightMeasureSpec);
259
263
  if (this.alignItems === AlignItems.BASELINE) {
260
264
  let viewIndex = 0;
261
- this._flexLines.forEach((flexLine) => {
265
+ for (const fl of this._flexLines) {
262
266
  let largestHeightInLine = Number.MIN_VALUE;
263
- for (let i = viewIndex; i < viewIndex + flexLine._itemCount; i++) {
267
+ for (let i = viewIndex; i < viewIndex + fl._itemCount; i++) {
264
268
  const child = this._getReorderedChildAt(i);
265
269
  const lp = child; // .style;
266
270
  if (this.flexWrap !== FlexWrap.WRAP_REVERSE) {
267
- let marginTop = flexLine._maxBaseline - FlexboxLayout.getBaseline(child);
271
+ let marginTop = fl._maxBaseline - FlexboxLayout.getBaseline(child);
268
272
  marginTop = Math.max(marginTop, lp.effectiveMarginTop);
269
273
  largestHeightInLine = Math.max(largestHeightInLine, child.getMeasuredHeight() + marginTop + lp.effectiveMarginBottom);
270
274
  }
271
275
  else {
272
- let marginBottom = flexLine._maxBaseline - child.getMeasuredHeight() + FlexboxLayout.getBaseline(child);
276
+ let marginBottom = fl._maxBaseline - child.getMeasuredHeight() + FlexboxLayout.getBaseline(child);
273
277
  marginBottom = Math.max(marginBottom, lp.effectiveMarginBottom);
274
278
  largestHeightInLine = Math.max(largestHeightInLine, child.getMeasuredHeight() + lp.effectiveMarginTop + marginBottom);
275
279
  }
276
280
  }
277
- flexLine._crossSize = largestHeightInLine;
278
- viewIndex += flexLine.itemCount;
279
- });
281
+ fl._crossSize = largestHeightInLine;
282
+ viewIndex += fl.itemCount;
283
+ }
280
284
  }
281
285
  this._determineCrossSize(this.flexDirection, widthMeasureSpec, heightMeasureSpec, this.effectivePaddingTop + this.effectivePaddingBottom);
282
286
  this._stretchViews(this.flexDirection, this.alignItems);
@@ -342,7 +346,9 @@ export class FlexboxLayout extends FlexboxLayoutBase {
342
346
  flexLine._totalFlexGrow += FlexboxLayout.getFlexGrow(child);
343
347
  flexLine._totalFlexShrink += FlexboxLayout.getFlexShrink(child);
344
348
  flexLine._crossSize = Math.max(flexLine._crossSize, largestWidthInColumn);
345
- // Omit divider
349
+ if (this.effectiveRowGap > 0 && this._hasPrecedingViews(i, indexInFlexLine)) {
350
+ flexLine._mainSize += this.effectiveRowGap;
351
+ }
346
352
  this._addFlexLineIfLastFlexItem(i, childCount, flexLine);
347
353
  }
348
354
  this._determineMainSize(this.flexDirection, widthMeasureSpec, heightMeasureSpec);
@@ -386,7 +392,6 @@ export class FlexboxLayout extends FlexboxLayoutBase {
386
392
  }
387
393
  }
388
394
  _addFlexLine(flexLine) {
389
- // Omit divider
390
395
  this._flexLines.push(flexLine);
391
396
  }
392
397
  _determineMainSize(flexDirection, widthMeasureSpec, heightMeasureSpec) {
@@ -423,14 +428,14 @@ export class FlexboxLayout extends FlexboxLayoutBase {
423
428
  throw new Error('Invalid flex direction: ' + flexDirection);
424
429
  }
425
430
  let childIndex = 0;
426
- this._flexLines.forEach((flexLine) => {
431
+ for (const flexLine of this._flexLines) {
427
432
  if (flexLine.mainSize < mainSize) {
428
433
  childIndex = this._expandFlexItems(flexLine, flexDirection, mainSize, paddingAlongMainAxis, childIndex);
429
434
  }
430
435
  else {
431
436
  childIndex = this._shrinkFlexItems(flexLine, flexDirection, mainSize, paddingAlongMainAxis, childIndex);
432
437
  }
433
- });
438
+ }
434
439
  }
435
440
  _expandFlexItems(flexLine, flexDirection, maxMainSize, paddingAlongMainAxis, startIndex) {
436
441
  let childIndex = startIndex;
@@ -442,7 +447,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
442
447
  let needsReexpand = false;
443
448
  const pendingSpace = maxMainSize - flexLine._mainSize;
444
449
  const unitSpace = pendingSpace / flexLine._totalFlexGrow;
445
- flexLine._mainSize = paddingAlongMainAxis + flexLine._dividerLengthInMainSize;
450
+ flexLine._mainSize = paddingAlongMainAxis + flexLine._gapLengthInMainSize;
446
451
  let accumulatedRoundError = 0;
447
452
  for (let i = 0; i < flexLine.itemCount; i++) {
448
453
  const child = this._getReorderedChildAt(childIndex);
@@ -509,7 +514,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
509
514
  let needsReshrink = false;
510
515
  const unitShrink = (flexLine._mainSize - maxMainSize) / flexLine._totalFlexShrink;
511
516
  let accumulatedRoundError = 0;
512
- flexLine._mainSize = paddingAlongMainAxis + flexLine._dividerLengthInMainSize;
517
+ flexLine._mainSize = paddingAlongMainAxis + flexLine._gapLengthInMainSize;
513
518
  for (let i = 0; i < flexLine.itemCount; i++) {
514
519
  const child = this._getReorderedChildAt(childIndex);
515
520
  if (child === null) {
@@ -602,81 +607,78 @@ export class FlexboxLayout extends FlexboxLayoutBase {
602
607
  }
603
608
  else if (this._flexLines.length >= 2 && totalCrossSize < size) {
604
609
  switch (this.alignContent) {
605
- case AlignContent.STRETCH:
606
- (() => {
607
- const freeSpaceUnit = (size - totalCrossSize) / this._flexLines.length;
608
- let accumulatedError = 0;
609
- for (let i = 0, flexLinesSize = this._flexLines.length; i < flexLinesSize; i++) {
610
- const flexLine = this._flexLines[i];
611
- let newCrossSizeAsFloat = flexLine._crossSize + freeSpaceUnit;
612
- if (i === this._flexLines.length - 1) {
613
- newCrossSizeAsFloat += accumulatedError;
610
+ case AlignContent.STRETCH: {
611
+ const freeSpaceUnit = (size - totalCrossSize) / this._flexLines.length;
612
+ let accumulatedError = 0;
613
+ for (let i = 0, flexLinesSize = this._flexLines.length; i < flexLinesSize; i++) {
614
+ const flexLine = this._flexLines[i];
615
+ let newCrossSizeAsFloat = flexLine._crossSize + freeSpaceUnit;
616
+ if (i === this._flexLines.length - 1) {
617
+ newCrossSizeAsFloat += accumulatedError;
618
+ accumulatedError = 0;
619
+ }
620
+ let newCrossSize = Math.round(newCrossSizeAsFloat);
621
+ accumulatedError += newCrossSizeAsFloat - newCrossSize;
622
+ if (accumulatedError > 1) {
623
+ newCrossSize += 1;
624
+ accumulatedError -= 1;
625
+ }
626
+ else if (accumulatedError < -1) {
627
+ newCrossSize -= 1;
628
+ accumulatedError += 1;
629
+ }
630
+ flexLine._crossSize = newCrossSize;
631
+ }
632
+ break;
633
+ }
634
+ case AlignContent.SPACE_AROUND: {
635
+ let spaceTopAndBottom = size - totalCrossSize;
636
+ const numberOfSpaces = this._flexLines.length * 2;
637
+ const newFlexLines = [];
638
+ const dummySpaceFlexLine = new FlexLine();
639
+ spaceTopAndBottom = spaceTopAndBottom / numberOfSpaces;
640
+ dummySpaceFlexLine._crossSize = spaceTopAndBottom;
641
+ for (const flexLine of this._flexLines) {
642
+ newFlexLines.push(dummySpaceFlexLine);
643
+ newFlexLines.push(flexLine);
644
+ newFlexLines.push(dummySpaceFlexLine);
645
+ }
646
+ this._flexLines = newFlexLines;
647
+ break;
648
+ }
649
+ case AlignContent.SPACE_BETWEEN: {
650
+ let spaceBetweenFlexLine = size - totalCrossSize;
651
+ const numberOfSpaces = this._flexLines.length - 1;
652
+ spaceBetweenFlexLine = spaceBetweenFlexLine / numberOfSpaces;
653
+ let accumulatedError = 0;
654
+ const newFlexLines = [];
655
+ for (let i = 0, flexLineSize = this._flexLines.length; i < flexLineSize; i++) {
656
+ const flexLine = this._flexLines[i];
657
+ newFlexLines.push(flexLine);
658
+ if (i !== this._flexLines.length - 1) {
659
+ const dummySpaceFlexLine = new FlexLine();
660
+ if (i === this._flexLines.length - 2) {
661
+ dummySpaceFlexLine._crossSize = Math.round(spaceBetweenFlexLine + accumulatedError);
614
662
  accumulatedError = 0;
615
663
  }
616
- let newCrossSize = Math.round(newCrossSizeAsFloat);
617
- accumulatedError += newCrossSizeAsFloat - newCrossSize;
664
+ else {
665
+ dummySpaceFlexLine._crossSize = Math.round(spaceBetweenFlexLine);
666
+ }
667
+ accumulatedError += spaceBetweenFlexLine - dummySpaceFlexLine._crossSize;
618
668
  if (accumulatedError > 1) {
619
- newCrossSize += 1;
669
+ dummySpaceFlexLine._crossSize += 1;
620
670
  accumulatedError -= 1;
621
671
  }
622
672
  else if (accumulatedError < -1) {
623
- newCrossSize -= 1;
673
+ dummySpaceFlexLine._crossSize -= 1;
624
674
  accumulatedError += 1;
625
675
  }
626
- flexLine._crossSize = newCrossSize;
627
- }
628
- })();
629
- break;
630
- case AlignContent.SPACE_AROUND:
631
- (() => {
632
- let spaceTopAndBottom = size - totalCrossSize;
633
- const numberOfSpaces = this._flexLines.length * 2;
634
- spaceTopAndBottom = spaceTopAndBottom / numberOfSpaces;
635
- const newFlexLines = [];
636
- const dummySpaceFlexLine = new FlexLine();
637
- dummySpaceFlexLine._crossSize = spaceTopAndBottom;
638
- this._flexLines.forEach((flexLine) => {
639
676
  newFlexLines.push(dummySpaceFlexLine);
640
- newFlexLines.push(flexLine);
641
- newFlexLines.push(dummySpaceFlexLine);
642
- });
643
- this._flexLines = newFlexLines;
644
- })();
645
- break;
646
- case AlignContent.SPACE_BETWEEN:
647
- (() => {
648
- let spaceBetweenFlexLine = size - totalCrossSize;
649
- const numberOfSpaces = this._flexLines.length - 1;
650
- spaceBetweenFlexLine = spaceBetweenFlexLine / numberOfSpaces;
651
- let accumulatedError = 0;
652
- const newFlexLines = [];
653
- for (let i = 0, flexLineSize = this._flexLines.length; i < flexLineSize; i++) {
654
- const flexLine = this._flexLines[i];
655
- newFlexLines.push(flexLine);
656
- if (i !== this._flexLines.length - 1) {
657
- const dummySpaceFlexLine = new FlexLine();
658
- if (i === this._flexLines.length - 2) {
659
- dummySpaceFlexLine._crossSize = Math.round(spaceBetweenFlexLine + accumulatedError);
660
- accumulatedError = 0;
661
- }
662
- else {
663
- dummySpaceFlexLine._crossSize = Math.round(spaceBetweenFlexLine);
664
- }
665
- accumulatedError += spaceBetweenFlexLine - dummySpaceFlexLine._crossSize;
666
- if (accumulatedError > 1) {
667
- dummySpaceFlexLine._crossSize += 1;
668
- accumulatedError -= 1;
669
- }
670
- else if (accumulatedError < -1) {
671
- dummySpaceFlexLine._crossSize -= 1;
672
- accumulatedError += 1;
673
- }
674
- newFlexLines.push(dummySpaceFlexLine);
675
- }
676
677
  }
677
- this._flexLines = newFlexLines;
678
- })();
678
+ }
679
+ this._flexLines = newFlexLines;
679
680
  break;
681
+ }
680
682
  case AlignContent.CENTER: {
681
683
  let spaceAboveAndBottom = size - totalCrossSize;
682
684
  spaceAboveAndBottom = spaceAboveAndBottom / 2;
@@ -710,7 +712,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
710
712
  _stretchViews(flexDirection, alignItems) {
711
713
  if (alignItems === AlignItems.STRETCH) {
712
714
  let viewIndex = 0;
713
- this._flexLines.forEach((flexLine) => {
715
+ for (const flexLine of this._flexLines) {
714
716
  for (let i = 0; i < flexLine.itemCount; i++, viewIndex++) {
715
717
  const view = this._getReorderedChildAt(viewIndex);
716
718
  const alignSelf = FlexboxLayout.getAlignSelf(view);
@@ -730,11 +732,11 @@ export class FlexboxLayout extends FlexboxLayoutBase {
730
732
  throw new Error('Invalid flex direction: ' + flexDirection);
731
733
  }
732
734
  }
733
- });
735
+ }
734
736
  }
735
737
  else {
736
- this._flexLines.forEach((flexLine) => {
737
- flexLine._indicesAlignSelfStretch.forEach((index) => {
738
+ for (const flexLine of this._flexLines) {
739
+ for (const index of flexLine._indicesAlignSelfStretch) {
738
740
  const view = this._getReorderedChildAt(index);
739
741
  switch (flexDirection) {
740
742
  case FlexDirection.ROW:
@@ -748,8 +750,8 @@ export class FlexboxLayout extends FlexboxLayoutBase {
748
750
  default:
749
751
  throw new Error('Invalid flex direction: ' + flexDirection);
750
752
  }
751
- });
752
- });
753
+ }
754
+ }
753
755
  }
754
756
  }
755
757
  _stretchViewVertically(view, crossSize) {
@@ -851,15 +853,34 @@ export class FlexboxLayout extends FlexboxLayoutBase {
851
853
  if (mode === UNSPECIFIED) {
852
854
  return false;
853
855
  }
854
- // Omit divider
856
+ if (this._isMainAxisDirectionHorizontal(this.flexDirection)) {
857
+ if (this.effectiveColumnGap > 0 && this._hasPrecedingViews(childAbsoluteIndex, childRelativeIndexInFlexLine)) {
858
+ childLength += this.effectiveColumnGap;
859
+ }
860
+ }
861
+ else {
862
+ if (this.effectiveRowGap > 0 && this._hasPrecedingViews(childAbsoluteIndex, childRelativeIndexInFlexLine)) {
863
+ childLength += this.effectiveRowGap;
864
+ }
865
+ }
855
866
  return maxSize < currentLength + childLength;
856
867
  }
857
868
  _getLargestMainSize() {
858
869
  return this._flexLines.reduce((max, flexLine) => Math.max(max, flexLine.mainSize), Number.MIN_VALUE);
859
870
  }
860
871
  _getSumOfCrossSize() {
861
- // Omit divider
862
- return this._flexLines.reduce((sum, flexLine) => sum + flexLine._crossSize, 0);
872
+ const isHorizontalDirection = this._isMainAxisDirectionHorizontal(this.flexDirection);
873
+ let sum = 0;
874
+ for (let i = 0, length = this._flexLines.length; i < length; i++) {
875
+ const flexLine = this._flexLines[i];
876
+ const gap = isHorizontalDirection ? this.effectiveRowGap : this.effectiveColumnGap;
877
+ // Judge if gap is required
878
+ if (gap > 0 && this._hasPrecedingFlexLines(i)) {
879
+ sum += gap;
880
+ }
881
+ sum += flexLine._crossSize;
882
+ }
883
+ return sum;
863
884
  }
864
885
  _isMainAxisDirectionHorizontal(flexDirection) {
865
886
  return flexDirection === FlexDirection.ROW || flexDirection === FlexDirection.ROW_REVERSE;
@@ -904,8 +925,12 @@ export class FlexboxLayout extends FlexboxLayoutBase {
904
925
  let childBottom = height - paddingBottom;
905
926
  let childTop = paddingTop;
906
927
  let childRight;
907
- this._flexLines.forEach((flexLine, i) => {
908
- // Omit divider
928
+ for (let i = 0, length = this._flexLines.length; i < length; i++) {
929
+ const flexLine = this._flexLines[i];
930
+ if (this.effectiveRowGap > 0 && this._hasPrecedingFlexLines(i)) {
931
+ childBottom -= this.effectiveRowGap;
932
+ childTop += this.effectiveRowGap;
933
+ }
909
934
  let spaceBetweenItem = 0.0;
910
935
  switch (this.justifyContent) {
911
936
  case JustifyContent.FLEX_START:
@@ -953,7 +978,10 @@ export class FlexboxLayout extends FlexboxLayoutBase {
953
978
  const lp = child; // .style;
954
979
  childLeft += lp.effectiveMarginLeft;
955
980
  childRight -= lp.effectiveMarginRight;
956
- // Omit divider
981
+ if (this.effectiveColumnGap > 0 && this._hasPrecedingViews(currentViewIndex, j)) {
982
+ childLeft += this.effectiveColumnGap;
983
+ childRight -= this.effectiveColumnGap;
984
+ }
957
985
  if (this.flexWrap === FlexWrap.WRAP_REVERSE) {
958
986
  if (isRtl) {
959
987
  this._layoutSingleChildHorizontal(child, flexLine, this.flexWrap, this.alignItems, Math.round(childRight) - child.getMeasuredWidth(), childBottom - child.getMeasuredHeight(), Math.round(childRight), childBottom);
@@ -981,7 +1009,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
981
1009
  }
982
1010
  childTop += flexLine._crossSize;
983
1011
  childBottom -= flexLine._crossSize;
984
- });
1012
+ }
985
1013
  }
986
1014
  _layoutSingleChildHorizontal(view, flexLine, flexWrap, alignItems, left, top, right, bottom) {
987
1015
  const lp = view; // .style;
@@ -1044,8 +1072,12 @@ export class FlexboxLayout extends FlexboxLayoutBase {
1044
1072
  let childRight = width - paddingRight;
1045
1073
  let childTop;
1046
1074
  let childBottom;
1047
- this._flexLines.forEach((flexLine) => {
1048
- // Omit divider.
1075
+ for (let i = 0, length = this._flexLines.length; i < length; i++) {
1076
+ const flexLine = this._flexLines[i];
1077
+ if (this.effectiveColumnGap > 0 && this._hasPrecedingFlexLines(i)) {
1078
+ childLeft += this.effectiveColumnGap;
1079
+ childRight -= this.effectiveColumnGap;
1080
+ }
1049
1081
  let spaceBetweenItem = 0.0;
1050
1082
  switch (this.justifyContent) {
1051
1083
  case JustifyContent.FLEX_START:
@@ -1093,7 +1125,10 @@ export class FlexboxLayout extends FlexboxLayoutBase {
1093
1125
  const lp = child; // .style;
1094
1126
  childTop += lp.effectiveMarginTop;
1095
1127
  childBottom -= lp.effectiveMarginBottom;
1096
- // Omit divider.
1128
+ if (this.effectiveRowGap > 0 && this._hasPrecedingViews(currentViewIndex, j)) {
1129
+ childTop += this.effectiveRowGap;
1130
+ childBottom -= this.effectiveRowGap;
1131
+ }
1097
1132
  if (isRtl) {
1098
1133
  if (fromBottomToTop) {
1099
1134
  this._layoutSingleChildVertical(child, flexLine, true, this.alignItems, childRight - child.getMeasuredWidth(), Math.round(childBottom) - child.getMeasuredHeight(), childRight, Math.round(childBottom));
@@ -1121,7 +1156,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
1121
1156
  }
1122
1157
  childLeft += flexLine.crossSize;
1123
1158
  childRight -= flexLine.crossSize;
1124
- });
1159
+ }
1125
1160
  }
1126
1161
  _layoutSingleChildVertical(view, flexLine, isRtl, alignItems, left, top, right, bottom) {
1127
1162
  const lp = view; // .style;
@@ -1163,7 +1198,26 @@ export class FlexboxLayout extends FlexboxLayoutBase {
1163
1198
  }
1164
1199
  }
1165
1200
  }
1166
- // Omit divider in onDraw(), drawDividersHorizontal, drawDividersVertical, drawVerticalDivider
1201
+ _hasPrecedingViews(childAbsoluteIndex, childRelativeIndexInFlexLine) {
1202
+ for (let i = 1; i <= childRelativeIndexInFlexLine; i++) {
1203
+ const view = this._getReorderedChildAt(childAbsoluteIndex - i);
1204
+ if (view != null && !view.isCollapsed) {
1205
+ return true;
1206
+ }
1207
+ }
1208
+ return false;
1209
+ }
1210
+ _hasPrecedingFlexLines(flexLineIndex) {
1211
+ if (flexLineIndex < 0 || flexLineIndex >= this._flexLines.length) {
1212
+ return false;
1213
+ }
1214
+ for (let i = 0; i < flexLineIndex; i++) {
1215
+ if (this._flexLines[i].layoutVisibleItemCount > 0) {
1216
+ return true;
1217
+ }
1218
+ }
1219
+ return false;
1220
+ }
1167
1221
  // requestLayout on set flexDirection, set flexWrap, set justifyContent, set alignItems, set alignContent
1168
1222
  // NOTE Consider moving to View if frequently used
1169
1223
  static getChildMeasureSpec(spec, padding, childDimension) {