diff --git a/bin/unit_tests/assets/html/eepp-ui-background-atlas.webp b/bin/unit_tests/assets/html/eepp-ui-background-atlas.webp index 992b3c4e7..82ae7a50c 100644 Binary files a/bin/unit_tests/assets/html/eepp-ui-background-atlas.webp and b/bin/unit_tests/assets/html/eepp-ui-background-atlas.webp differ diff --git a/bin/unit_tests/assets/html/eepp-ui-border-rendering.webp b/bin/unit_tests/assets/html/eepp-ui-border-rendering.webp index dcbdb989b..1772856a9 100644 Binary files a/bin/unit_tests/assets/html/eepp-ui-border-rendering.webp and b/bin/unit_tests/assets/html/eepp-ui-border-rendering.webp differ diff --git a/bin/unit_tests/assets/html/eepp-uihtmltable-complex-layout.webp b/bin/unit_tests/assets/html/eepp-uihtmltable-complex-layout.webp index c0027e6cd..3ca34f91c 100644 Binary files a/bin/unit_tests/assets/html/eepp-uihtmltable-complex-layout.webp and b/bin/unit_tests/assets/html/eepp-uihtmltable-complex-layout.webp differ diff --git a/include/eepp/ui/uihtmlwidget.hpp b/include/eepp/ui/uihtmlwidget.hpp index 7cc801da1..5ef46ef04 100644 --- a/include/eepp/ui/uihtmlwidget.hpp +++ b/include/eepp/ui/uihtmlwidget.hpp @@ -47,6 +47,8 @@ class EE_API UIHTMLWidget : public UILayout { CSSDisplay getDisplay() const { return mDisplay; } + bool isFlex() const { return mDisplay == CSSDisplay::Flex || mDisplay == CSSDisplay::InlineFlex; } + void setDisplay( CSSDisplay display ); CSSPosition getCSSPosition() const { return mPosition; } diff --git a/src/eepp/ui/blocklayouter.cpp b/src/eepp/ui/blocklayouter.cpp index 3c341dedb..90e74f221 100644 --- a/src/eepp/ui/blocklayouter.cpp +++ b/src/eepp/ui/blocklayouter.cpp @@ -14,8 +14,7 @@ static bool isStretchedFlexItem( UIHTMLWidget* widget ) { if ( !parent || !parent->isWidget() || !parent->isType( UI_TYPE_HTML_WIDGET ) ) return false; UIHTMLWidget* parentHtml = parent->asType(); - if ( parentHtml->getDisplay() != CSSDisplay::Flex && - parentHtml->getDisplay() != CSSDisplay::InlineFlex ) + if ( !parentHtml->isFlex() ) return false; CSSAlignSelf alignSelf = widget->getAlignSelf(); @@ -75,16 +74,9 @@ void BlockLayouter::updateLayout() { if ( rt == nullptr || mPacking ) return; - bool parentIsFlex = false; Node* parentNode = widget->getParent(); - if ( parentNode && parentNode->isWidget() ) { - UIWidget* parentWidget = parentNode->asType(); - if ( parentWidget->isType( UI_TYPE_HTML_WIDGET ) ) { - CSSDisplay parentDisplay = parentWidget->asType()->getDisplay(); - parentIsFlex = - ( parentDisplay == CSSDisplay::Flex || parentDisplay == CSSDisplay::InlineFlex ); - } - } + bool parentIsFlex = parentNode && parentNode->isType( UI_TYPE_HTML_WIDGET ) && + parentNode->asType()->isFlex(); if ( widget->isInline() && !parentIsFlex ) return; diff --git a/src/eepp/ui/uilayoutermanager.cpp b/src/eepp/ui/uilayoutermanager.cpp index 46d32abd1..46ed94c7e 100644 --- a/src/eepp/ui/uilayoutermanager.cpp +++ b/src/eepp/ui/uilayoutermanager.cpp @@ -12,13 +12,8 @@ namespace EE { namespace UI { static bool parentIsFlexContainer( UIWidget* widget ) { Node* parent = widget->getParent(); - if ( !parent || !parent->isWidget() ) - return false; - UIWidget* parentWidget = parent->asType(); - if ( !parentWidget->isType( UI_TYPE_HTML_WIDGET ) ) - return false; - CSSDisplay parentDisplay = parentWidget->asType()->getDisplay(); - return parentDisplay == CSSDisplay::Flex || parentDisplay == CSSDisplay::InlineFlex; + return parent && parent->isType( UI_TYPE_HTML_WIDGET ) && + parent->asType()->isFlex(); } UILayouter* UILayouterManager::create( CSSDisplay display, UIWidget* container ) { diff --git a/src/eepp/ui/uirichtext.cpp b/src/eepp/ui/uirichtext.cpp index 63363a767..18895c977 100644 --- a/src/eepp/ui/uirichtext.cpp +++ b/src/eepp/ui/uirichtext.cpp @@ -1194,16 +1194,9 @@ void UIRichText::rebuildRichText( UILayout* container, RichText& richText, Intri if ( container->isType( UI_TYPE_TEXTSPAN ) ) { UITextSpan* selfSpan = container->asType(); - bool parentIsFlex = false; Node* parentNode = container->getParent(); - if ( parentNode && parentNode->isWidget() ) { - UIWidget* parentWidget = parentNode->asType(); - if ( parentWidget->isType( UI_TYPE_HTML_WIDGET ) ) { - CSSDisplay parentDisplay = parentWidget->asType()->getDisplay(); - parentIsFlex = ( parentDisplay == CSSDisplay::Flex || - parentDisplay == CSSDisplay::InlineFlex ); - } - } + bool parentIsFlex = parentNode->isType( UI_TYPE_HTML_WIDGET ) && + parentNode->asType()->isFlex(); if ( !selfSpan->getText().empty() && ( !selfSpan->isInline() || parentIsFlex ) && NULL != selfSpan->getFontStyleConfig().Font ) { String::View selfText = selfSpan->getText().view(); diff --git a/src/eepp/ui/uitextspan.cpp b/src/eepp/ui/uitextspan.cpp index a9a66d3ef..1a9e87511 100644 --- a/src/eepp/ui/uitextspan.cpp +++ b/src/eepp/ui/uitextspan.cpp @@ -71,20 +71,14 @@ bool UITextSpan::isInlineBlock() const { } void UITextSpan::draw() { - if ( !isInline() ) { + // When a UITextSpan is a flex item it is laid out independently by the + // flex container (blockification per CSS Flexbox §4). In that case the + // parent flex container does NOT render its text via rebuildRichText(), + // so the span must draw itself. + if ( !isInline() || + ( getParent() && getParent()->isType( UI_TYPE_HTML_WIDGET ) && + getParent()->asType()->isFlex() ) ) { UIRichText::draw(); - } else { - // When a UITextSpan is a flex item it is laid out independently by the - // flex container (blockification per CSS Flexbox §4). In that case the - // parent flex container does NOT render its text via rebuildRichText(), - // so the span must draw itself. - Node* parentNode = getParent(); - if ( parentNode && parentNode->isType( UI_TYPE_HTML_WIDGET ) ) { - CSSDisplay parentDisplay = parentNode->asType()->getDisplay(); - if ( parentDisplay == CSSDisplay::Flex || parentDisplay == CSSDisplay::InlineFlex ) { - UIRichText::draw(); - } - } } } diff --git a/src/tests/unit_tests/uihtml_tests.cpp b/src/tests/unit_tests/uihtml_tests.cpp index 42582ce64..1b0dca233 100644 --- a/src/tests/unit_tests/uihtml_tests.cpp +++ b/src/tests/unit_tests/uihtml_tests.cpp @@ -57,7 +57,7 @@ static void init_ui_test() { UTEST( UIHTMLTable, complexLayout ) { auto win = Engine::instance()->createWindow( - WindowSettings( 1024, 656, "HTML Tables Test", WindowStyle::Default, WindowBackend::Default, + WindowSettings( 1024, 653, "HTML Tables Test", WindowStyle::Default, WindowBackend::Default, 32, {}, 1, false, true ), ContextSettings( false, 0, 0, GLv_default, true, false ) ); FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); @@ -2071,7 +2071,7 @@ UTEST( UIHTMLDetails, lobstersInlineBlockCachesWidth ) { UTEST( UIBorder, renderingVariations ) { auto win = Engine::instance()->createWindow( - WindowSettings( 1024, 656, "Border Rendering Test", WindowStyle::Default, + WindowSettings( 1024, 653, "Border Rendering Test", WindowStyle::Default, WindowBackend::Default, 32, {}, 1, false, true ), ContextSettings( false, 0, 0, GLv_default, true, false ) ); FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); @@ -2586,7 +2586,7 @@ UTEST( UIHTML, ContactFormLayout ) { UTEST( UIBackground, imageAtlasPositioning ) { auto win = Engine::instance()->createWindow( - WindowSettings( 1024, 656, "Background Atlas Test", WindowStyle::Default, + WindowSettings( 1024, 653, "Background Atlas Test", WindowStyle::Default, WindowBackend::Default, 32, {}, 1, false, true ), ContextSettings( false, 0, 0, GLv_default, true, false ) ); FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); @@ -3104,29 +3104,8 @@ UTEST( UIHTML, FlexCenterWebViewLikeLayout ) { ASSERT_TRUE( postWrapper != nullptr ); ASSERT_TRUE( post != nullptr ); - auto postWrapperWidget = postWrapper->asType(); auto postWidget = post->asType(); - std::cerr << "[TEST1280] post-wrapper size=" << postWrapperWidget->getPixelsSize().getWidth() - << "x" << postWrapperWidget->getPixelsSize().getHeight() - << " pos=" << postWrapperWidget->getPixelsPosition().x << "," - << postWrapperWidget->getPixelsPosition().y - << " pad=" << postWrapperWidget->getPixelsPadding().Left << "," - << postWrapperWidget->getPixelsPadding().Top << "," - << postWrapperWidget->getPixelsPadding().Right << "," - << postWrapperWidget->getPixelsPadding().Bottom << std::endl; - std::cerr << "[TEST1280] post type=" << postWidget->getType() - << " size=" << postWidget->getPixelsSize().getWidth() << "x" - << postWidget->getPixelsSize().getHeight() - << " pos=" << postWidget->getPixelsPosition().x << "," - << postWidget->getPixelsPosition().y - << " widthPolicy=" << (int)postWidget->getLayoutWidthPolicy() - << " heightPolicy=" << (int)postWidget->getLayoutHeightPolicy() - << " margin=" << postWidget->getLayoutPixelsMargin().Left << "," - << postWidget->getLayoutPixelsMargin().Top << "," - << postWidget->getLayoutPixelsMargin().Right << "," - << postWidget->getLayoutPixelsMargin().Bottom << std::endl; - // In a real browser a div with width:100% inside a column flex container // with align-items:center still spans the full cross axis because 100% // resolves against the container. The item should therefore sit flush with @@ -3170,17 +3149,6 @@ UTEST( UIHTML, FlexCenterNoTextNodeDisplacement ) { Float wrapperW = postWrapperWidget->getPixelsSize().getWidth(); Float postW = postWidget->getPixelsSize().getWidth(); - // Debug: print children of post-wrapper - std::cerr << "[TEST] post-wrapper children:" << std::endl; - Node* c = postWrapper->getFirstChild(); - while ( c ) { - std::cerr << " type=" << c->getType() << " id=" << c->getId() - << ( c->isWidget() ? " widget" : "" ) << std::endl; - c = c->getNextNode(); - } - std::cerr << "[TEST] post pos=" << postX << "," << postY << " size=" << postW << "x" - << postWidget->getPixelsSize().getHeight() << " wrapperW=" << wrapperW << std::endl; - // In a column flex container the first (and only) real flex item should // sit right after the container's top padding plus its own margin-top. EXPECT_NEAR( postY, wrapperTopPadding + postMarginTop, 2.f );