Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: layout wrapping space #856

Merged
merged 2 commits into from
Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions integration_tests/specs/css/css-display/inline-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,49 @@ describe('Display inline-block', () => {

await snapshot();
});

it('text not wrap when inline-block width exceeds its container', async() => {
const container = createElement('div', {
style: {
"display": "inline-block",
"padding": "10px 300px",
backgroundColor: 'yellow'
}
}, [
createText('11111'),
]);

document.body.appendChild(container);
await snapshot();
});

it('element wrap when inline-block width exceeds its container', async() => {
const container = createElement('div', {
style: {
"display": "inline-block",
"padding": "10px 300px",
backgroundColor: 'green'
}
}, [
createElement('div', {
style: {
display: 'inline-block',
width: '50px',
height: '50px',
backgroundColor: 'yellow'
}
}),
createElement('div', {
style: {
display: 'inline-block',
width: '50px',
height: '50px',
backgroundColor: 'red'
}
})
]);

document.body.appendChild(container);
await snapshot();
});
});
42 changes: 27 additions & 15 deletions kraken/lib/src/css/render_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,18 @@ class RenderStyle
}
}

/// Get max constraint width from style, use width or max-width exists if exists,
/// otherwise calculated from its ancestors
double getMaxConstraintWidth() {
double maxConstraintWidth = double.infinity;
// Max constraints width of content, used in calculating the remaining space for line wrapping
// in the stage of layout.
double get contentMaxConstraintsWidth {
// If renderBoxModel definite content constraints, use it as max constrains width of content.
BoxConstraints? contentConstraints = renderBoxModel!.contentConstraints;
if (contentConstraints != null && contentConstraints.maxWidth != double.infinity) {
return contentConstraints.maxWidth;
}

// If renderBoxModel has no logical content width (eg display is inline-block/inline-flex and
// has no width), find its ancestors with logical width set to calculate the remaining space.
double contentMaxConstraintsWidth = double.infinity;
double cropWidth = 0;

RenderStyle currentRenderStyle = this;
Expand All @@ -441,9 +449,9 @@ class RenderStyle
if (effectiveDisplay != CSSDisplay.inline &&
(currentRenderStyle.width.isNotAuto || currentRenderStyle.maxWidth.isNotNone)) {
// Get the min width between width and max-width
maxConstraintWidth = math.min(
(currentRenderStyle.width.isAuto ? null : currentRenderStyle.width.computedValue) ?? double.infinity,
(currentRenderStyle.maxWidth.isNone ? null : currentRenderStyle.maxWidth.computedValue) ?? double.infinity
contentMaxConstraintsWidth = math.min(
(currentRenderStyle.width.isAuto ? null : currentRenderStyle.width.computedValue) ?? double.infinity,
(currentRenderStyle.maxWidth.isNone ? null : currentRenderStyle.maxWidth.computedValue) ?? double.infinity
);
cropWidth = _getCropWidthByPaddingBorder(currentRenderStyle, cropWidth);
break;
Expand All @@ -458,17 +466,21 @@ class RenderStyle
}
}

if (maxConstraintWidth != double.infinity) {
maxConstraintWidth = maxConstraintWidth - cropWidth;
if (contentMaxConstraintsWidth != double.infinity) {
contentMaxConstraintsWidth = contentMaxConstraintsWidth - cropWidth;
}

return maxConstraintWidth;
}
// Set contentMaxConstraintsWidth to 0 when it is negative in the case of
// renderBoxModel's width exceeds its ancestors.
// <div style="width: 300px;">
// <div style="display: inline-block; padding: 0 200px;">
// </div>
// </div>
if (contentMaxConstraintsWidth < 0) {
contentMaxConstraintsWidth = 0;
}

// Max constraints width calculated from renderStyle tree.
// @TODO: add cache to avoid recalculate every time.
double get maxConstraintsWidth {
return getMaxConstraintWidth();
return contentMaxConstraintsWidth;
}

// Content width calculated from renderStyle tree.
Expand Down
5 changes: 1 addition & 4 deletions kraken/lib/src/rendering/flex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -883,10 +883,7 @@ class RenderFlexLayout extends RenderLayoutBox {
RenderBoxModel? containerBox =
isScrollingContentBox ? parent as RenderBoxModel? : this;
if (_isHorizontalFlexDirection) {
flexLineLimit = containerBox!.contentConstraints!.maxWidth;
if (flexLineLimit == double.infinity) {
flexLineLimit = containerBox.renderStyle.getMaxConstraintWidth();
}
flexLineLimit = renderStyle.contentMaxConstraintsWidth;
} else {
flexLineLimit = containerBox!.contentConstraints!.maxHeight;
}
Expand Down
5 changes: 1 addition & 4 deletions kraken/lib/src/rendering/flow.dart
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,7 @@ class RenderFlowLayout extends RenderLayoutBox {
isScrollingContentBox ? parent as RenderBoxModel? : this;
switch (direction) {
case Axis.horizontal:
mainAxisLimit = containerBox!.contentConstraints!.maxWidth;
if (mainAxisLimit == double.infinity) {
mainAxisLimit = containerBox.renderStyle.getMaxConstraintWidth();
}
mainAxisLimit = renderStyle.contentMaxConstraintsWidth;
if (textDirection == TextDirection.rtl) flipMainAxis = true;
if (verticalDirection == VerticalDirection.up) flipCrossAxis = true;
break;
Expand Down
10 changes: 9 additions & 1 deletion kraken/lib/src/rendering/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,15 @@ class RenderTextBox extends RenderBox
if (parentParentData.isPositioned) {
maxConstraintWidth = double.infinity;
} else {
maxConstraintWidth = parentRenderBoxModel.renderStyle.getMaxConstraintWidth();
maxConstraintWidth = parentRenderBoxModel.renderStyle.contentMaxConstraintsWidth;
// @FIXME: Each character in the text will be placed in a new line when remaining space of
// parent is 0 cause word-break behavior can not be specified in flutter.
// https://github.com/flutter/flutter/issues/61081
// This behavior is not desirable compared to the default word-break:break-word value in the browser.
// So we choose to not do wrapping for text in this case.
if (maxConstraintWidth == 0) {
maxConstraintWidth = double.infinity;
}
}
} else {
EdgeInsets borderEdge = parentRenderBoxModel.renderStyle.border;
Expand Down