mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 11:10:31 +03:00
Fix in Flex layout interacting with float elements.
This commit is contained in:
@@ -1222,6 +1222,14 @@ void FlexLayouter::updateLayout() {
|
|||||||
if ( widget->isInline() || mPacking )
|
if ( widget->isInline() || mPacking )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
RichText* richText = widget->isType( UI_TYPE_RICHTEXT )
|
||||||
|
? widget->asType<UIRichText>()->getRichTextPtr()
|
||||||
|
: nullptr;
|
||||||
|
bool preserveFloatConstrainedBFCWidth =
|
||||||
|
widget->establishesBlockFormattingContext() &&
|
||||||
|
widget->getLayoutWidthPolicy() == SizePolicy::MatchParent && richText != nullptr &&
|
||||||
|
!richText->getExternalFloatExclusions().empty();
|
||||||
|
|
||||||
mPacking = true;
|
mPacking = true;
|
||||||
|
|
||||||
mContainer->beginAttributesTransaction();
|
mContainer->beginAttributesTransaction();
|
||||||
@@ -1230,7 +1238,7 @@ void FlexLayouter::updateLayout() {
|
|||||||
auto* parent = mContainer->getParent();
|
auto* parent = mContainer->getParent();
|
||||||
bool parentIsFlexContainer = parent && parent->isType( UI_TYPE_HTML_WIDGET ) &&
|
bool parentIsFlexContainer = parent && parent->isType( UI_TYPE_HTML_WIDGET ) &&
|
||||||
static_cast<UIHTMLWidget*>( parent )->isFlex();
|
static_cast<UIHTMLWidget*>( parent )->isFlex();
|
||||||
if ( !parentIsFlexContainer )
|
if ( !parentIsFlexContainer && !preserveFloatConstrainedBFCWidth )
|
||||||
setMatchParentIfNeededVerticalGrowth();
|
setMatchParentIfNeededVerticalGrowth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1333,6 +1341,8 @@ void FlexLayouter::updateLayout() {
|
|||||||
containerPadding.Right );
|
containerPadding.Right );
|
||||||
else if ( widthPolicy == SizePolicy::Fixed )
|
else if ( widthPolicy == SizePolicy::Fixed )
|
||||||
mContainer->setInternalPixelsWidth( containerWidth );
|
mContainer->setInternalPixelsWidth( containerWidth );
|
||||||
|
else if ( preserveFloatConstrainedBFCWidth )
|
||||||
|
mContainer->setInternalPixelsWidth( containerWidth );
|
||||||
else
|
else
|
||||||
mContainer->setInternalPixelsWidth(
|
mContainer->setInternalPixelsWidth(
|
||||||
mContainer->getParent()
|
mContainer->getParent()
|
||||||
@@ -1355,6 +1365,8 @@ void FlexLayouter::updateLayout() {
|
|||||||
mContainer->setInternalPixelsWidth( totW );
|
mContainer->setInternalPixelsWidth( totW );
|
||||||
else if ( widthPolicy == SizePolicy::Fixed )
|
else if ( widthPolicy == SizePolicy::Fixed )
|
||||||
mContainer->setInternalPixelsWidth( containerWidth );
|
mContainer->setInternalPixelsWidth( containerWidth );
|
||||||
|
else if ( preserveFloatConstrainedBFCWidth )
|
||||||
|
mContainer->setInternalPixelsWidth( containerWidth );
|
||||||
else
|
else
|
||||||
mContainer->setInternalPixelsWidth(
|
mContainer->setInternalPixelsWidth(
|
||||||
mContainer->getParent() ? mContainer->getParent()->getPixelsSize().getWidth()
|
mContainer->getParent() ? mContainer->getParent()->getPixelsSize().getWidth()
|
||||||
@@ -1403,6 +1415,13 @@ void FlexLayouter::updateLayout() {
|
|||||||
|
|
||||||
applyLayout( lines, mainAxis, crossAxis, containerPadding, containerWidth, containerHeight,
|
applyLayout( lines, mainAxis, crossAxis, containerPadding, containerWidth, containerHeight,
|
||||||
widthPolicy, heightPolicy );
|
widthPolicy, heightPolicy );
|
||||||
|
if ( preserveFloatConstrainedBFCWidth ) {
|
||||||
|
// The parent RichText stream has already resolved this match-parent BFC against active
|
||||||
|
// floats and placed it into a narrowed atomic fragment. Flex layout still needs to run
|
||||||
|
// using that used width, but its normal match-parent finalization would expand back to
|
||||||
|
// the full parent content box and overlap the float.
|
||||||
|
mContainer->setInternalPixelsWidth( containerWidth );
|
||||||
|
}
|
||||||
|
|
||||||
// CSS Flexbox §8.5: store the container's baseline for use by outer flex containers.
|
// CSS Flexbox §8.5: store the container's baseline for use by outer flex containers.
|
||||||
// For row/row-reverse, baseline = first flex line's baseline offset from content top.
|
// For row/row-reverse, baseline = first flex line's baseline offset from content top.
|
||||||
|
|||||||
@@ -3745,6 +3745,70 @@ UTEST( UIHTML, PaddedHeaderWithNestedFloatsDoesNotOverlapClearedMain ) {
|
|||||||
Engine::destroySingleton();
|
Engine::destroySingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTEST( UIHTML, FlexInfobarAvoidsRightFloat ) {
|
||||||
|
auto win = Engine::instance()->createWindow(
|
||||||
|
WindowSettings( 800, 600, "flex infobar avoids right float", WindowStyle::Default,
|
||||||
|
WindowBackend::Default, 32, {}, 1, false, true ),
|
||||||
|
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||||
|
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||||
|
|
||||||
|
UI::UISceneNode* sceneNode = init_test_inline_block();
|
||||||
|
sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( R"html(
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font: normal 12px verdana;
|
||||||
|
}
|
||||||
|
.side {
|
||||||
|
float: right;
|
||||||
|
width: 300px;
|
||||||
|
height: 120px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
margin: 7px 5px 0 5px;
|
||||||
|
}
|
||||||
|
.infobar {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 124px;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="side" id="side"></div>
|
||||||
|
<div class="content" id="content">
|
||||||
|
<section class="infobar" id="infobar">
|
||||||
|
<a>Welcome to Reddit.</a>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)html" ) );
|
||||||
|
win->getInput()->update();
|
||||||
|
SceneManager::instance()->update();
|
||||||
|
sceneNode->updateDirtyLayouts();
|
||||||
|
sceneNode->updateDirtyLayouts();
|
||||||
|
|
||||||
|
auto* side = sceneNode->getRoot()->find( "side" )->asType<UIHTMLWidget>();
|
||||||
|
auto* infobar = sceneNode->getRoot()->find( "infobar" )->asType<UIHTMLWidget>();
|
||||||
|
ASSERT_TRUE( side != nullptr );
|
||||||
|
ASSERT_TRUE( infobar != nullptr );
|
||||||
|
|
||||||
|
const Float sideLeft = side->convertToWorldSpace( { 0, 0 } ).x;
|
||||||
|
const Float infobarRight =
|
||||||
|
infobar->convertToWorldSpace( { 0, 0 } ).x + infobar->getPixelsSize().getWidth();
|
||||||
|
|
||||||
|
EXPECT_LE( infobarRight, sideLeft + 0.5f );
|
||||||
|
|
||||||
|
Engine::destroySingleton();
|
||||||
|
}
|
||||||
|
|
||||||
UTEST( UIHTML, AnchorsSizing ) {
|
UTEST( UIHTML, AnchorsSizing ) {
|
||||||
auto win = Engine::instance()->createWindow(
|
auto win = Engine::instance()->createWindow(
|
||||||
WindowSettings( 1024, 653, "anchors sizing", WindowStyle::Default, WindowBackend::Default,
|
WindowSettings( 1024, 653, "anchors sizing", WindowStyle::Default, WindowBackend::Default,
|
||||||
|
|||||||
Reference in New Issue
Block a user