We already did this optimization when there wasn't any
available horizontal space. Now we're covering the
vertical space case as well.
This optimization assumes that, for a node with a
measure function, if there isn't any available
horizontal or vertical space, then we don't need to
measure the node and can assume that the node is 0x0.
Introduced heuristics that enable css-layout to avoid
calling measure functions under a number of conditions.
This enables us to save time by skipping unnecessary
measurements.
We found a case where a flexible item with a max width that was supposed
to be centered was positioned in the wrong location.
The problem was with our 2 pass approach for sizing flexible items with
a min/max width/height. Items sized in the first pass were being double
counted when calculating the remainingFreeSpace. Specifically, their
sizes were being subtracted from remainingFreeSpace in both the first
and second passes.
I also noticed a second unrelated bug. We weren't correctly calculating
deltaFreeSpace in the first pass. When calculating deltaFreeSpace, we
need to take into account the flex basis like we do in the second pass.
Consequently, in the first pass I changed this:
deltaFreeSpace -= boundMainSize;
To this:
deltaFreeSpace -= boundMainSize - childFlexBasis;
The problem there was that we'd end up double counting childFlexBasis
in the remainingFreeSpace.
The primary goals of this change are:
- Better conformance to the W3C flexbox standard (https://www.w3.org/TR/css-flexbox-1/)
and a clear articulation of the areas where it deviates from the spec.
- Support for flex-shrink.
- Conformance with layout effects of "overflow: hidden".
Specifically, here are the limitations of this implementation as compared to the W3C
flexbox standard (this is also documented in Layout.js):
- Display property is always assumed to be 'flex' except for Text nodes, which
are assumed to be 'inline-flex'.
- The 'zIndex' property (or any form of z ordering) is not supported. Nodes are
stacked in document order.
- The 'order' property is not supported. The order of flex items is always defined
by document order.
- The 'visibility' property is always assumed to be 'visible'. Values of 'collapse'
and 'hidden' are not supported.
- The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The
rarely-used 'wrap-reverse' is not supported.
- Rather than allowing arbitrary combinations of flexGrow, flexShrink and
flexBasis, this algorithm supports only the three most common combinations:
- flex: 0 is equiavlent to flex: 0 0 auto
- flex: n (where n is a positive value) is equivalent to flex: n 0 0
- flex: -1 (or any negative value) is equivalent to flex: 0 1 auto
- Margins cannot be specified as 'auto'. They must be specified in terms of pixel
values, and the default value is 0.
- The 'baseline' value is not supported for alignItems and alignSelf properties.
- Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be
specified as pixel values, not as percentages.
- There is no support for calculation of dimensions based on intrinsic aspect ratios
(e.g. images).
- There is no support for forced breaks.
- It does not support vertical inline directions (top-to-bottom or bottom-to-top text).
And here is how the implementation deviates from the standard (this is also documented in
Layout.js):
- Section 4.5 of the spec indicates that all flex items have a default minimum
main size. For text blocks, for example, this is the width of the widest word.
Calculating the minimum width is expensive, so we forego it and assume a default
minimum main size of 0.
- Min/Max sizes in the main axis are not honored when resolving flexible lengths.
- The spec indicates that the default value for 'flexDirection' is 'row', but
the algorithm below assumes a default of 'column'.
This diff:
* adds height as another parameter passed to the measure function, computed the same way width is
* adds tests for this extension, which has involved adding a new measure function to all of js, c, java and c# tests