diff --git a/bin/unit_tests/assets/html/reddit_inline_order_deferred.css b/bin/unit_tests/assets/html/reddit_inline_order_deferred.css new file mode 100644 index 000000000..4489ddc7e --- /dev/null +++ b/bin/unit_tests/assets/html/reddit_inline_order_deferred.css @@ -0,0 +1,20 @@ +.entry .buttons { + display: block; +} + +.entry .float-marker { + float: left; + height: 1px; + width: 1px; +} + +.entry .buttons li { + display: inline-block; + border: none; + padding: 0 4px; + white-space: nowrap; +} + +.entry .buttons li a { + display: inline; +} diff --git a/src/eepp/graphics/richtext.cpp b/src/eepp/graphics/richtext.cpp index e19da0623..1344d9f53 100644 --- a/src/eepp/graphics/richtext.cpp +++ b/src/eepp/graphics/richtext.cpp @@ -1328,13 +1328,12 @@ class RichTextInlineLayouter { addInlineSpacingToCurrentLine( result, curX, startSpacing ); Float effW = metrics.isBlock ? maxLayoutWidth : effectiveMaxWidthAt( curY ); - if ( metrics.isBlockFormattingContext ) { + if ( metrics.isBlockFormattingContext && metrics.isBlock ) { le = floatLeftEdge( curY ); Float re = floatRightEdge( curY ); Float availableWidth = re - le; if ( availableWidth > 0 && availableWidth < 1e9f ) { - if ( metrics.isBlock && - metrics.size.getWidth() > availableWidth + 0.01f ) + if ( metrics.size.getWidth() > availableWidth + 0.01f ) metrics.size.setWidth( availableWidth ); curX = le; effW = availableWidth; diff --git a/src/tests/unit_tests/uihtml_tests.cpp b/src/tests/unit_tests/uihtml_tests.cpp index b34530cd5..fc9674bca 100644 --- a/src/tests/unit_tests/uihtml_tests.cpp +++ b/src/tests/unit_tests/uihtml_tests.cpp @@ -300,6 +300,8 @@ UTEST( UIHTML, redditOldThreadWebViewSmoke ) { auto selftextMd = documentRoot->querySelector( ".link .usertext-body .md" ); auto selftextFirstP = documentRoot->querySelector( ".link .usertext-body .md p" ); auto postTitle = documentRoot->querySelector( ".link .top-matter > p.title" ); + auto postTitleAnchor = documentRoot->querySelector( ".link .top-matter > p.title > a.title" ); + auto postDomain = documentRoot->querySelector( ".link .top-matter > p.title > .domain" ); auto postTagline = documentRoot->querySelector( ".link .top-matter > p.tagline" ); auto postExpando = documentRoot->querySelector( ".link .expando" ); auto postUsertext = documentRoot->querySelector( ".link .expando > form.usertext" ); @@ -310,6 +312,8 @@ UTEST( UIHTML, redditOldThreadWebViewSmoke ) { auto commentHelpToggle = documentRoot->querySelector( ".commentarea .help-toggle" ); auto commentContentPolicy = documentRoot->querySelector( ".commentarea a.reddiquette" ); auto flairCheckbox = documentRoot->find( "flair_enabled" ); + auto commentButtons = + documentRoot->querySelector( "#thing_t1_on791mh > .entry > .flat-list.buttons" ); ASSERT_TRUE( side != nullptr ); ASSERT_TRUE( siteTable != nullptr ); @@ -328,6 +332,8 @@ UTEST( UIHTML, redditOldThreadWebViewSmoke ) { ASSERT_TRUE( selftextMd != nullptr ); ASSERT_TRUE( selftextFirstP != nullptr ); ASSERT_TRUE( postTitle != nullptr ); + ASSERT_TRUE( postTitleAnchor != nullptr ); + ASSERT_TRUE( postDomain != nullptr ); ASSERT_TRUE( postTagline != nullptr ); ASSERT_TRUE( postExpando != nullptr ); ASSERT_TRUE( postUsertext != nullptr ); @@ -338,6 +344,15 @@ UTEST( UIHTML, redditOldThreadWebViewSmoke ) { ASSERT_TRUE( commentHelpToggle != nullptr ); ASSERT_TRUE( commentContentPolicy != nullptr ); ASSERT_TRUE( flairCheckbox != nullptr ); + ASSERT_TRUE( commentButtons != nullptr ); + Float commentButtonRight = 0.f; + for ( auto* li : commentButtons->findAllByTag( "li" ) ) { + ASSERT_TRUE( li->findByTag( "a" ) != nullptr ); + EXPECT_GE( li->getPixelsPosition().x, commentButtonRight ); + commentButtonRight = li->getPixelsPosition().x + li->getPixelsSize().getWidth(); + } + EXPECT_GE( postDomain->getPixelsPosition().x, postTitleAnchor->getPixelsPosition().x + + postTitleAnchor->getPixelsSize().getWidth() ); UIWidget* content = siteTable->getParent()->isWidget() ? siteTable->getParent()->asType() : nullptr; @@ -2847,6 +2862,61 @@ ul > li { Engine::destroySingleton(); } +UTEST( UIHTML, InlineAnchorsInsideInlineBlockSiblingsKeepDocumentOrder ) { + init_ui_test(); + UISceneNode* sceneNode = SceneManager::instance()->getUISceneNode(); + sceneNode->setThreadPool( ThreadPool::createShared( 1 ) ); + sceneNode->setURI( "file://" + Sys::getProcessPath() + "assets/html/" ); + + sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( R"html( + + + + + Low-level coding dataset + (self.cpp) + + + permalinkembedsave + reportreply + + + + )html" ) ); + + UIWidget* buttons = nullptr; + for ( int i = 0; i < 200; ++i ) { + SceneManager::instance()->update(); + buttons = sceneNode->getRoot()->find( "comment-buttons" )->asType(); + if ( buttons ) { + auto items = buttons->findAllByTag( "li" ); + if ( !items.empty() && + items.front()->asType()->getDisplay() == CSSDisplay::InlineBlock ) + break; + } + Sys::sleep( Milliseconds( 1 ) ); + } + + auto* postTitle = sceneNode->getRoot()->find( "post-title" )->asType(); + auto* domain = sceneNode->getRoot()->find( "domain" )->asType(); + ASSERT_TRUE( postTitle != nullptr ); + ASSERT_TRUE( domain != nullptr ); + ASSERT_TRUE( buttons != nullptr ); + EXPECT_GE( domain->getPixelsPosition().x, + postTitle->getPixelsPosition().x + postTitle->getPixelsSize().getWidth() ); + + auto listItems = buttons->findAllByTag( "li" ); + ASSERT_EQ( listItems.size(), (size_t)5 ); + Float previousRight = listItems.front()->getPixelsPosition().x; + for ( auto* listItem : listItems ) { + EXPECT_GE( listItem->getPixelsPosition().x, previousRight ); + EXPECT_GT( listItem->getPixelsSize().getWidth(), 0.f ); + previousRight = listItem->getPixelsPosition().x + listItem->getPixelsSize().getWidth(); + } + + Engine::destroySingleton(); +} + UTEST( UIHTML, StyleSheetTraversalBoundaries ) { Engine::instance()->createWindow( WindowSettings( 1024, 768, "CSS Traversal Test", WindowStyle::Default, WindowBackend::Default,
Low-level coding dataset + (self.cpp)