From a2b216a0e72f97c48d75d1ab8297e93a4f07d3b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 3 Jul 2026 16:40:48 -0300 Subject: [PATCH] Fixed a bug introduced in the latest changes that tried to load non urls as external resources. Fixed some sizing issues. --- src/eepp/ui/uinodedrawable.cpp | 5 +- src/eepp/ui/uirichtext.cpp | 4 +- src/tests/unit_tests/uihtml_tests.cpp | 34 ++++++++--- src/tests/unit_tests/uiwebview_tests.cpp | 77 ++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 14 deletions(-) diff --git a/src/eepp/ui/uinodedrawable.cpp b/src/eepp/ui/uinodedrawable.cpp index 39c4a72a9..ebd6a6081 100644 --- a/src/eepp/ui/uinodedrawable.cpp +++ b/src/eepp/ui/uinodedrawable.cpp @@ -670,8 +670,9 @@ bool UINodeDrawable::LayerDrawable::loadRemoteDrawable( const std::string& value FunctionString functionType = FunctionString::parse( value ); std::string path; - if ( !functionType.isEmpty() && functionType.getName() == "url" && - !functionType.getParameters().empty() ) { + if ( !functionType.isEmpty() ) { + if ( functionType.getName() != "url" || functionType.getParameters().empty() ) + return false; path = functionType.getParameters().at( 0 ); } else { path = value; diff --git a/src/eepp/ui/uirichtext.cpp b/src/eepp/ui/uirichtext.cpp index a2e413116..8ff090d7b 100644 --- a/src/eepp/ui/uirichtext.cpp +++ b/src/eepp/ui/uirichtext.cpp @@ -253,11 +253,11 @@ void UIHTMLBody::updateLayout() { if ( mChild && mChild->isWidget() && !mSettingBodyHeight ) { mSettingBodyHeight = true; - updateDocumentContentMinHeightFromChildren(); + bool documentMinHeightChanged = updateDocumentContentMinHeightFromChildren(); mSettingBodyHeight = false; - if ( getParent() && getParent()->isType( UI_TYPE_HTML_HTML ) ) { + if ( documentMinHeightChanged && getParent() && getParent()->isType( UI_TYPE_HTML_HTML ) ) { auto* html = getParent()->asType(); const Float bodyBottom = getPixelsPosition().y + getPixelsSize().getHeight(); if ( bodyBottom > html->getPixelsSize().getHeight() + 0.5f ) { diff --git a/src/tests/unit_tests/uihtml_tests.cpp b/src/tests/unit_tests/uihtml_tests.cpp index 05d556574..7cbc20b13 100644 --- a/src/tests/unit_tests/uihtml_tests.cpp +++ b/src/tests/unit_tests/uihtml_tests.cpp @@ -4245,22 +4245,24 @@ UTEST( UIHTML, BodyNoOpContentHeightChangeDoesNotDirtyHtml ) { )html"; - sceneNode->setURI( "file://body-no-op-content-height-change.html" ); - sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( html ), - webView->getDocumentContainer(), - String::hash( "body-no-op-content-height-change" ) ); + UISceneNode* documentScene = webView->getDocumentSceneNode(); + ASSERT_TRUE( documentScene != nullptr ); + documentScene->setURI( "file://body-no-op-content-height-change.html" ); + documentScene->loadLayoutFromString( HTMLFormatter::HTMLtoXML( html ), + webView->getDocumentContainer(), + String::hash( "body-no-op-content-height-change" ) ); webView->refreshDocumentLayout(); win->getInput()->update(); SceneManager::instance()->update(); - sceneNode->updateDirtyLayouts(); + documentScene->updateDirtyLayouts(); win->getInput()->update(); SceneManager::instance()->update(); - sceneNode->updateDirtyLayouts(); + documentScene->updateDirtyLayouts(); - auto* htmlNode = sceneNode->getRoot()->findByType( UI_TYPE_HTML_HTML )->asType(); - auto* body = sceneNode->getRoot()->findByType( UI_TYPE_HTML_BODY )->asType(); - auto* spacer = sceneNode->getRoot()->find( "spacer" )->asType(); + auto* htmlNode = documentScene->getRoot()->findByType( UI_TYPE_HTML_HTML )->asType(); + auto* body = documentScene->getRoot()->findByType( UI_TYPE_HTML_BODY )->asType(); + auto* spacer = documentScene->getRoot()->find( "spacer" )->asType(); ASSERT_TRUE( htmlNode != nullptr ); ASSERT_TRUE( body != nullptr ); ASSERT_TRUE( spacer != nullptr ); @@ -4272,7 +4274,19 @@ UTEST( UIHTML, BodyNoOpContentHeightChangeDoesNotDirtyHtml ) { EXPECT_FALSE( htmlNode->isLayoutDirty() ); win->getInput()->update(); SceneManager::instance()->update(); - sceneNode->updateDirtyLayouts(); + documentScene->updateDirtyLayouts(); + + UILayout::resetMetrics(); + for ( int i = 0; i < 4; ++i ) { + win->getInput()->update(); + SceneManager::instance()->update(); + documentScene->updateDirtyLayouts(); + } + auto metrics = UILayout::getMetrics(); + UILayout::setMetricsEnabled( false ); + EXPECT_EQ( 0u, metrics.invalidations ); + EXPECT_EQ( 0u, metrics.treeUpdates ); + EXPECT_EQ( 0u, metrics.richTextRebuilds ); Engine::destroySingleton(); } diff --git a/src/tests/unit_tests/uiwebview_tests.cpp b/src/tests/unit_tests/uiwebview_tests.cpp index d3b825fea..78bc3c123 100644 --- a/src/tests/unit_tests/uiwebview_tests.cpp +++ b/src/tests/unit_tests/uiwebview_tests.cpp @@ -10,11 +10,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -1719,6 +1721,81 @@ UTEST( UIWebView, RemoteBackgroundImageIgnoredAfterNavigation ) { Engine::destroySingleton(); } +UTEST( UIWebView, LinearGradientRendersToFramebuffer ) { + auto win = Engine::instance()->createWindow( + WindowSettings( 640, 480, "UIWebView Linear Gradient Render Test", WindowStyle::Default, + WindowBackend::Default, 32, {}, 1, false, true ), + ContextSettings( false, 0, 0, GLv_default, true, false ) ); + FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); + win->setClearColor( Color::Black ); + + FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ); + font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" ); + ASSERT_TRUE( font != nullptr && font->loaded() ); + FontFamily::loadFromRegular( font ); + + UISceneNode* sceneNode = UISceneNode::New(); + SceneManager::instance()->add( sceneNode ); + sceneNode->getUIThemeManager()->setDefaultFont( font ); + + UIWebView* webView = UIWebView::New(); + webView->setParent( sceneNode->getRoot() ); + webView->setPixelsSize( 300, 200 ); + webView->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed ); + webView->setPixelsPosition( 20, 20 ); + + UISceneNode* documentScene = webView->getDocumentSceneNode(); + ASSERT_TRUE( documentScene != nullptr ); + documentScene->setURI( "https://newsblur.com/features/" ); + documentScene->loadLayoutFromString( Tools::HTMLFormatter::HTMLtoXML( R"html( + + + + + +
+ + )html" ), + webView->getDocumentContainer(), + String::hash( "https-linear-gradient" ) ); + webView->refreshDocumentLayout(); + + for ( int i = 0; i < 10; i++ ) { + win->getInput()->update(); + SceneManager::instance()->update( Seconds( 1.f / 60.f ) ); + } + + Node* probeNode = documentScene->getRoot()->find( "probe" ); + ASSERT_TRUE( probeNode != nullptr && probeNode->isUINode() ); + UINode* probe = probeNode->asType(); + ASSERT_TRUE( probe->getBackground() != nullptr ); + auto* layer = probe->getBackground()->getLayer( 0 ); + ASSERT_TRUE( layer != nullptr ); + ASSERT_TRUE( layer->getDrawable() != nullptr ); + EXPECT_EQ( Drawable::LINEARGRADIENT, layer->getDrawable()->getDrawableType() ); + + win->clear(); + sceneNode->draw(); + Image framebuffer = win->getFrontBufferImage(); + Color left = framebuffer.getPixel( 20 + 10 + 12, 20 + 10 + 40 ); + Color right = framebuffer.getPixel( 20 + 10 + 108, 20 + 10 + 40 ); + + EXPECT_GT( left.r, left.b ); + EXPECT_GT( right.b, right.r ); + EXPECT_GT( eeabs( static_cast( left.r ) - static_cast( right.r ) ), 80 ); + EXPECT_GT( eeabs( static_cast( left.b ) - static_cast( right.b ) ), 80 ); + + Engine::destroySingleton(); +} + UTEST( UIWebView, CoalescesViewportResizeDocumentMetrics ) { auto win = Engine::instance()->createWindow( WindowSettings( 800, 600, "UIWebView Resize Metrics Test", WindowStyle::Default,