Summary:
Import latest master from css-layout.

This includes the following pull requests:
https://github.com/facebook/css-layout/pull/192
https://github.com/facebook/css-layout/pull/193
https://github.com/facebook/css-layout/pull/195
https://github.com/facebook/css-layout/pull/196

Reviewed By: javache

Differential Revision: D3411535

fbshipit-source-id: 95bee9bd0282f98f6fafa15335b910b644395ad3
This commit is contained in:
Emil Sjolander 2016-06-13 07:52:14 -07:00 коммит произвёл Facebook Github Bot 2
Родитель 97cfacb5ba
Коммит 8afcaa36e6
8 изменённых файлов: 383 добавлений и 150 удалений

Просмотреть файл

@ -871,6 +871,25 @@
}
}
// If child has no defined size in the cross axis and is set to stretch, set the cross
// axis to be measured exactly with the available inner width
if (!isMainAxisRow &&
!isUndefined(availableInnerWidth) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
if (isMainAxisRow &&
!isUndefined(availableInnerHeight) &&
!isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
}
// Measure the child
layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure");
@ -1080,7 +1099,13 @@
childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) {
if (!isUndefined(availableInnerCrossDim) &&
!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
@ -1091,7 +1116,13 @@
childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);
childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) {
if (!isUndefined(availableInnerCrossDim) &&
!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
} else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
} else {
@ -1528,35 +1559,80 @@
return performLayout? kLayoutModeNames[mode] : kMeasureModeNames[mode];
}
static bool canUseCachedMeasurement(float availableWidth, float availableHeight,
float marginRow, float marginColumn,
css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode,
css_cached_measurement_t cachedLayout) {
static bool canUseCachedMeasurement(
bool is_text_node,
float available_width,
float available_height,
float margin_row,
float margin_column,
css_measure_mode_t width_measure_mode,
css_measure_mode_t height_measure_mode,
css_cached_measurement_t cached_layout) {
// Is it an exact match?
if (eq(cachedLayout.available_width, availableWidth) &&
eq(cachedLayout.available_height, availableHeight) &&
cachedLayout.width_measure_mode == widthMeasureMode &&
cachedLayout.height_measure_mode == heightMeasureMode) {
bool is_height_same =
(cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) ||
(cached_layout.height_measure_mode == height_measure_mode && eq(cached_layout.available_height, available_height));
bool is_width_same =
(cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) ||
(cached_layout.width_measure_mode == width_measure_mode && eq(cached_layout.available_width, available_width));
if (is_height_same && is_width_same) {
return true;
}
// If the width is an exact match, try a fuzzy match on the height.
if (cachedLayout.width_measure_mode == widthMeasureMode &&
eq(cachedLayout.available_width, availableWidth) &&
heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
eq(availableHeight - marginColumn, cachedLayout.computed_height)) {
bool is_height_valid =
(cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_height <= (available_height - margin_column)) ||
(height_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_height, available_height - margin_column));
if (is_width_same && is_height_valid) {
return true;
}
// If the height is an exact match, try a fuzzy match on the width.
if (cachedLayout.height_measure_mode == heightMeasureMode &&
eq(cachedLayout.available_height, availableHeight) &&
widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
eq(availableWidth - marginRow, cachedLayout.computed_width)) {
bool is_width_valid =
(cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_width <= (available_width - margin_row)) ||
(width_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_width, available_width - margin_row));
if (is_height_same && is_width_valid) {
return true;
}
if (is_height_valid && is_width_valid) {
return true;
}
// We know this to be text so we can apply some more specialized heuristics.
if (is_text_node) {
if (is_width_same) {
if (height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) {
// Width is the same and height is not restricted. Re-use cahced value.
return true;
}
if (height_measure_mode == CSS_MEASURE_MODE_AT_MOST &&
cached_layout.computed_height < (available_height - margin_column)) {
// Width is the same and height restriction is greater than the cached height. Re-use cached value.
return true;
}
// Width is the same but height restriction imposes smaller height than previously measured.
// Update the cached value to respect the new height restriction.
cached_layout.computed_height = available_height - margin_column;
return true;
}
if (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) {
if (width_measure_mode == CSS_MEASURE_MODE_UNDEFINED ||
(width_measure_mode == CSS_MEASURE_MODE_AT_MOST &&
cached_layout.computed_width <= (available_width - margin_row))) {
// Previsouly this text was measured with no width restriction, if width is now restricted
// but to a larger value than the previsouly measured width we can re-use the measurement
// as we know it will fit.
return true;
}
}
}
return false;
}
@ -1598,13 +1674,13 @@
float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);
// First, try to use the layout cache.
if (canUseCachedMeasurement(availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
widthMeasureMode, heightMeasureMode, layout->cached_layout)) {
cachedResults = &layout->cached_layout;
} else {
// Try to use the measurement cache.
for (int i = 0; i < layout->next_cached_measurements_index; i++) {
if (canUseCachedMeasurement(availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
widthMeasureMode, heightMeasureMode, layout->cached_measurements[i])) {
cachedResults = &layout->cached_measurements[i];
break;

Просмотреть файл

@ -188,6 +188,7 @@
void (*print)(void *context);
struct css_node* (*get_child)(void *context, int i);
bool (*is_dirty)(void *context);
bool (*is_text_node)(void *context);
void *context;
};

Просмотреть файл

@ -7,7 +7,7 @@
*/
// NOTE: this file is auto-copied from https://github.com/facebook/css-layout
// @generated SignedSource<<fe2172034939f4e8919ad4b533f27703>>
// @generated SignedSource<<7463b170625c103400318b8a42378786>>
package com.facebook.csslayout;

Просмотреть файл

@ -7,7 +7,7 @@
*/
// NOTE: this file is auto-copied from https://github.com/facebook/css-layout
// @generated SignedSource<<4ed6ae4c11cdd41f5db380e3b9a06f23>>
// @generated SignedSource<<af6ef8054f37d4745903e857b95fe01f>>
package com.facebook.csslayout;

Просмотреть файл

@ -7,7 +7,7 @@
*/
// NOTE: this file is auto-copied from https://github.com/facebook/css-layout
// @generated SignedSource<<67fbba6df7c2472877c7b04327fb1863>>
// @generated SignedSource<<da35a9f6c5a59af0d73da3e46ee60a9a>>
package com.facebook.csslayout;
@ -72,6 +72,7 @@ public class CSSNode {
private @Nullable CSSNode mParent;
private @Nullable MeasureFunction mMeasureFunction = null;
private LayoutState mLayoutState = LayoutState.DIRTY;
private boolean mIsTextNode = false;
public int getChildCount() {
return mChildren == null ? 0 : mChildren.size();
@ -127,6 +128,14 @@ public class CSSNode {
return mMeasureFunction != null;
}
public void setIsTextNode(boolean isTextNode) {
mIsTextNode = isTextNode;
}
public boolean isTextNode() {
return mIsTextNode;
}
/*package*/ MeasureOutput measure(MeasureOutput measureOutput, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) {
if (!isMeasureDefined()) {
throw new RuntimeException("Measure function isn't defined!");
@ -450,6 +459,62 @@ public class CSSNode {
}
}
/**
* Get this node's max width, as defined in the style
*/
public float getStyleMaxWidth() {
return style.maxWidth;
}
public void setStyleMaxWidth(float maxWidth) {
if (!valuesEqual(style.maxWidth, maxWidth)) {
style.maxWidth = maxWidth;
dirty();
}
}
/**
* Get this node's min width, as defined in the style
*/
public float getStyleMinWidth() {
return style.minWidth;
}
public void setStyleMinWidth(float minWidth) {
if (!valuesEqual(style.minWidth, minWidth)) {
style.minWidth = minWidth;
dirty();
}
}
/**
* Get this node's max height, as defined in the style
*/
public float getStyleMaxHeight() {
return style.maxHeight;
}
public void setStyleMaxHeight(float maxHeight) {
if (!valuesEqual(style.maxHeight, maxHeight)) {
style.maxHeight = maxHeight;
dirty();
}
}
/**
* Get this node's min height, as defined in the style
*/
public float getStyleMinHeight() {
return style.minHeight;
}
public void setStyleMinHeight(float minHeight) {
if (!valuesEqual(style.minHeight, minHeight)) {
style.minHeight = minHeight;
dirty();
}
}
public float getLayoutX() {
return layout.position[POSITION_LEFT];
}
@ -479,6 +544,20 @@ public class CSSNode {
}
}
/**
* Get this node's overflow property, as defined in the style
*/
public CSSOverflow getOverflow() {
return style.overflow;
}
public void setOverflow(CSSOverflow overflow) {
if (style.overflow != overflow) {
style.overflow = overflow;
dirty();
}
}
/**
* Resets this instance to its default state. This method is meant to be used when
* recycling {@link CSSNode} instances.

Просмотреть файл

@ -7,7 +7,7 @@
*/
// NOTE: this file is auto-copied from https://github.com/facebook/css-layout
// @generated SignedSource<<9165e7546c964b47cb01be9ff8070aa8>>
// @generated SignedSource<<c5a4eadcd6d93bc6d989cba73caa12a7>>
package com.facebook.csslayout;
@ -253,34 +253,80 @@ public class LayoutEngine {
}
}
/*package*/ static boolean canUseCachedMeasurement(float availableWidth, float availableHeight,
float marginRow, float marginColumn,
CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode,
/*package*/ static boolean canUseCachedMeasurement(
boolean isTextNode,
float availableWidth,
float availableHeight,
float marginRow,
float marginColumn,
CSSMeasureMode widthMeasureMode,
CSSMeasureMode heightMeasureMode,
CSSCachedMeasurement cachedLayout) {
// Is it an exact match?
if (FloatUtil.floatsEqual(cachedLayout.availableWidth, availableWidth) &&
FloatUtil.floatsEqual(cachedLayout.availableHeight, availableHeight) &&
cachedLayout.widthMeasureMode == widthMeasureMode &&
cachedLayout.heightMeasureMode == heightMeasureMode) {
boolean isHeightSame =
(cachedLayout.heightMeasureMode == CSSMeasureMode.UNDEFINED && heightMeasureMode == CSSMeasureMode.UNDEFINED) ||
(cachedLayout.heightMeasureMode == heightMeasureMode && FloatUtil.floatsEqual(cachedLayout.availableHeight, availableHeight));
boolean isWidthSame =
(cachedLayout.widthMeasureMode == CSSMeasureMode.UNDEFINED && widthMeasureMode == CSSMeasureMode.UNDEFINED) ||
(cachedLayout.widthMeasureMode == widthMeasureMode && FloatUtil.floatsEqual(cachedLayout.availableWidth, availableWidth));
if (isHeightSame && isWidthSame) {
return true;
}
// If the width is an exact match, try a fuzzy match on the height.
if (FloatUtil.floatsEqual(cachedLayout.availableWidth, availableWidth) &&
cachedLayout.widthMeasureMode == widthMeasureMode &&
heightMeasureMode == CSSMeasureMode.EXACTLY &&
FloatUtil.floatsEqual(availableHeight - marginColumn, cachedLayout.computedHeight)) {
boolean isHeightValid =
(cachedLayout.heightMeasureMode == CSSMeasureMode.UNDEFINED && heightMeasureMode == CSSMeasureMode.AT_MOST && cachedLayout.computedHeight <= (availableHeight - marginColumn)) ||
(heightMeasureMode == CSSMeasureMode.EXACTLY && FloatUtil.floatsEqual(cachedLayout.computedHeight, availableHeight - marginColumn));
if (isWidthSame && isHeightValid) {
return true;
}
// If the height is an exact match, try a fuzzy match on the width.
if (FloatUtil.floatsEqual(cachedLayout.availableHeight, availableHeight) &&
cachedLayout.heightMeasureMode == heightMeasureMode &&
widthMeasureMode == CSSMeasureMode.EXACTLY &&
FloatUtil.floatsEqual(availableWidth - marginRow, cachedLayout.computedWidth)) {
boolean isWidthValid =
(cachedLayout.widthMeasureMode == CSSMeasureMode.UNDEFINED && widthMeasureMode == CSSMeasureMode.AT_MOST && cachedLayout.computedWidth <= (availableWidth - marginRow)) ||
(widthMeasureMode == CSSMeasureMode.EXACTLY && FloatUtil.floatsEqual(cachedLayout.computedWidth, availableWidth - marginRow));
if (isHeightSame && isWidthValid) {
return true;
}
if (isHeightValid && isWidthValid) {
return true;
}
// We know this to be text so we can apply some more specialized heuristics.
if (isTextNode) {
if (isWidthSame) {
if (heightMeasureMode == CSSMeasureMode.UNDEFINED) {
// Width is the same and height is not restricted. Re-use cahced value.
return true;
}
if (heightMeasureMode == CSSMeasureMode.AT_MOST &&
cachedLayout.computedHeight < (availableHeight - marginColumn)) {
// Width is the same and height restriction is greater than the cached height. Re-use cached value.
return true;
}
// Width is the same but height restriction imposes smaller height than previously measured.
// Update the cached value to respect the new height restriction.
cachedLayout.computedHeight = availableHeight - marginColumn;
return true;
}
if (cachedLayout.widthMeasureMode == CSSMeasureMode.UNDEFINED) {
if (widthMeasureMode == CSSMeasureMode.UNDEFINED ||
(widthMeasureMode == CSSMeasureMode.AT_MOST &&
cachedLayout.computedWidth <= (availableWidth - marginRow))) {
// Previsouly this text was measured with no width restriction, if width is now restricted
// but to a larger value than the previsouly measured width we can re-use the measurement
// as we know it will fit.
return true;
}
}
}
return false;
}
@ -332,13 +378,13 @@ public class LayoutEngine {
node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]);
// First, try to use the layout cache.
if (canUseCachedMeasurement(availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
if (canUseCachedMeasurement(node.isTextNode(), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
widthMeasureMode, heightMeasureMode, layout.cachedLayout)) {
cachedResults = layout.cachedLayout;
} else {
// Try to use the measurement cache.
for (int i = 0; i < layout.nextCachedMeasurementsIndex; i++) {
if (canUseCachedMeasurement(availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
if (canUseCachedMeasurement(node.isTextNode(), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) {
cachedResults = layout.cachedMeasurements[i];
break;
@ -702,6 +748,25 @@ public class LayoutEngine {
}
}
// If child has no defined size in the cross axis and is set to stretch, set the cross
// axis to be measured exactly with the available inner width
if (!isMainAxisRow &&
!Float.isNaN(availableInnerWidth) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) &&
widthMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, child) == CSSAlign.STRETCH) {
childWidth = availableInnerWidth;
childWidthMeasureMode = CSSMeasureMode.EXACTLY;
}
if (isMainAxisRow &&
!Float.isNaN(availableInnerHeight) &&
!(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) &&
heightMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, child) == CSSAlign.STRETCH) {
childHeight = availableInnerHeight;
childHeightMeasureMode = CSSMeasureMode.EXACTLY;
}
// Measure the child
layoutNodeInternal(layoutContext, child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure");
@ -911,7 +976,13 @@ public class LayoutEngine {
childWidth = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]));
childWidthMeasureMode = CSSMeasureMode.EXACTLY;
if (!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
if (!Float.isNaN(availableInnerCrossDim) &&
!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) &&
heightMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, currentRelativeChild) == CSSAlign.STRETCH) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = CSSMeasureMode.EXACTLY;
} else if (!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) {
childHeight = availableInnerCrossDim;
childHeightMeasureMode = Float.isNaN(childHeight) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.AT_MOST;
} else {
@ -922,7 +993,13 @@ public class LayoutEngine {
childHeight = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]));
childHeightMeasureMode = CSSMeasureMode.EXACTLY;
if (!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
if (!Float.isNaN(availableInnerCrossDim) &&
!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) &&
widthMeasureMode == CSSMeasureMode.EXACTLY &&
getAlignItem(node, currentRelativeChild) == CSSAlign.STRETCH) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = CSSMeasureMode.EXACTLY;
} else if (!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) {
childWidth = availableInnerCrossDim;
childWidthMeasureMode = Float.isNaN(childWidth) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.AT_MOST;
} else {

Просмотреть файл

@ -1,7 +1,7 @@
The source of truth for css-layout is: https://github.com/facebook/css-layout
The code here should be kept in sync with GitHub.
HEAD at the time this code was synced: https://github.com/facebook/css-layout/commit/16f43dac87ace8b60e0e4c07a798a558c22bd21b
HEAD at the time this code was synced: https://github.com/facebook/css-layout/commit/383d8a6b3dcbdb978e012e29040e1a43157765c6
There is generated code in:
- README (this file)

Просмотреть файл

@ -1,7 +1,7 @@
The source of truth for css-layout is: https://github.com/facebook/css-layout
The code here should be kept in sync with GitHub.
HEAD at the time this code was synced: https://github.com/facebook/css-layout/commit/16f43dac87ace8b60e0e4c07a798a558c22bd21b
HEAD at the time this code was synced: https://github.com/facebook/css-layout/commit/383d8a6b3dcbdb978e012e29040e1a43157765c6
There is generated code in:
- README.facebook (this file)