1313#include " core/renderer/dom/element_manager.h"
1414#include " core/renderer/dom/fiber/component_element.h"
1515#include " core/renderer/dom/fiber/view_element.h"
16+ #include " core/renderer/simple_styling/simple_style_node.h"
17+ #include " core/renderer/simple_styling/style_object.h"
1618#include " core/renderer/tasm/react/testing/mock_painting_context.h"
1719#include " core/shell/tasm_operation_queue.h"
1820#include " core/shell/testing/mock_tasm_delegate.h"
@@ -29,6 +31,42 @@ static constexpr double kDefaultPhysicalPixelsPerLayoutUnit = 1.f;
2931
3032using namespace css ;
3133
34+ // Mock implementation of SimpleStyleNode for testing
35+ class MockSimpleStyleNode : public lynx ::style::SimpleStyleNode {
36+ public:
37+ MockSimpleStyleNode () = default ;
38+ ~MockSimpleStyleNode () override = default ;
39+
40+ void SetStyleObjects (std::unique_ptr<lynx::style::StyleObject*,
41+ lynx::style::StyleObjectArrayDeleter>
42+ style_object) override {
43+ // Not needed for this test
44+ }
45+
46+ void UpdateSimpleStyles (const tasm::StyleMap& style_map) override {
47+ current_styles_ = style_map;
48+ }
49+
50+ void UpdateSimpleStyles (tasm::StyleMap&& style_map) override {
51+ current_styles_ = std::move (style_map);
52+ }
53+
54+ void ResetSimpleStyle (tasm::CSSPropertyID id) override {
55+ current_styles_.erase (id);
56+ }
57+
58+ // Helper method to get current styles for verification
59+ const tasm::StyleMap& GetCurrentStyles () const { return current_styles_; }
60+
61+ // Helper method to check if a property exists
62+ bool HasProperty (tasm::CSSPropertyID id) const {
63+ return current_styles_.find (id) != current_styles_.end ();
64+ }
65+
66+ private:
67+ tasm::StyleMap current_styles_;
68+ };
69+
3270class CSSPatchingTest : public ::testing::Test {
3371 public:
3472 CSSPatchingTest () {}
@@ -394,6 +432,145 @@ TEST_F(CSSPatchingTest, CSSSelectorDescendantSelectorScope) {
394432 EXPECT_EQ (new_value.GetPattern (), CSSValuePattern::PX);
395433 EXPECT_EQ (new_value.AsNumber (), 20 );
396434}
435+
436+ TEST_F (CSSPatchingTest, ResolveStyleObjectsBasedOnExistingMap_EmptyOldAndNew) {
437+ // Test case: Both old and new style maps are empty
438+ tasm::StyleMap old_dcl_style;
439+ MockSimpleStyleNode target;
440+ target.UpdateSimpleStyles (old_dcl_style);
441+
442+ StyleResolver resolver;
443+ resolver.ResolveStyleObjectsBasedOnExistingMap (old_dcl_style, nullptr ,
444+ &target);
445+
446+ EXPECT_TRUE (target.GetCurrentStyles ().empty ());
447+ }
448+
449+ TEST_F (CSSPatchingTest, ResolveStyleObjectsBasedOnExistingMap_OnlyOldStyles) {
450+ // Test case: Only old styles exist, new styles are null
451+ tasm::StyleMap old_dcl_style;
452+ old_dcl_style[CSSPropertyID::kPropertyIDFontSize ] =
453+ CSSValue::MakePlainString (" 16px" );
454+ old_dcl_style[CSSPropertyID::kPropertyIDColor ] =
455+ CSSValue::MakePlainString (" red" );
456+
457+ MockSimpleStyleNode target;
458+ target.UpdateSimpleStyles (old_dcl_style);
459+
460+ StyleResolver resolver;
461+ resolver.ResolveStyleObjectsBasedOnExistingMap (old_dcl_style, nullptr ,
462+ &target);
463+
464+ // All old styles should be reset since new styles are null
465+ EXPECT_TRUE (target.GetCurrentStyles ().empty ());
466+ }
467+
468+ TEST_F (CSSPatchingTest, ResolveStyleObjectsBasedOnExistingMap_OnlyNewStyles) {
469+ // Test case: Only new styles exist, old styles are empty
470+ tasm::StyleMap old_dcl_style;
471+
472+ // Create new style objects
473+ tasm::StyleMap new_style_map1;
474+ new_style_map1[CSSPropertyID::kPropertyIDFontSize ] =
475+ CSSValue::MakePlainString (" 18px" );
476+
477+ tasm::StyleMap new_style_map2;
478+ new_style_map2[CSSPropertyID::kPropertyIDColor ] =
479+ CSSValue::MakePlainString (" blue" );
480+ new_style_map2[CSSPropertyID::kPropertyIDWidth ] =
481+ CSSValue::MakePlainString (" 100px" );
482+
483+ auto style_obj1 =
484+ fml::MakeRefCounted<lynx::style::StyleObject>(new_style_map1);
485+ auto style_obj2 =
486+ fml::MakeRefCounted<lynx::style::StyleObject>(new_style_map2);
487+
488+ lynx::style::StyleObject* new_ptr[] = {style_obj1.get (), style_obj2.get (),
489+ nullptr };
490+
491+ MockSimpleStyleNode target;
492+ target.UpdateSimpleStyles (old_dcl_style);
493+
494+ StyleResolver resolver;
495+ resolver.ResolveStyleObjectsBasedOnExistingMap (old_dcl_style, new_ptr,
496+ &target);
497+
498+ // All new styles should be applied
499+ EXPECT_TRUE (target.HasProperty (CSSPropertyID::kPropertyIDFontSize ));
500+ EXPECT_TRUE (target.HasProperty (CSSPropertyID::kPropertyIDColor ));
501+ EXPECT_TRUE (target.HasProperty (CSSPropertyID::kPropertyIDWidth ));
502+ EXPECT_EQ (target.GetCurrentStyles ().size (), 3u );
503+ }
504+
505+ TEST_F (CSSPatchingTest,
506+ ResolveStyleObjectsBasedOnExistingMap_OverlappingStyles) {
507+ // Test case: Both old and new styles exist with some overlapping properties
508+ tasm::StyleMap old_dcl_style;
509+ old_dcl_style[CSSPropertyID::kPropertyIDFontSize ] =
510+ CSSValue::MakePlainString (" 16px" );
511+ old_dcl_style[CSSPropertyID::kPropertyIDColor ] =
512+ CSSValue::MakePlainString (" red" );
513+ old_dcl_style[CSSPropertyID::kPropertyIDHeight ] =
514+ CSSValue::MakePlainString (" 50px" );
515+
516+ // Create new style objects - font-size overlaps, color is new, height is not
517+ // in new styles
518+ tasm::StyleMap new_style_map1;
519+ new_style_map1[CSSPropertyID::kPropertyIDFontSize ] =
520+ CSSValue::MakePlainString (" 18px" ); // Overrides old
521+
522+ tasm::StyleMap new_style_map2;
523+ new_style_map2[CSSPropertyID::kPropertyIDColor ] =
524+ CSSValue::MakePlainString (" blue" ); // Updates existing
525+ new_style_map2[CSSPropertyID::kPropertyIDWidth ] =
526+ CSSValue::MakePlainString (" 100px" ); // New property
527+
528+ auto style_obj1 =
529+ fml::MakeRefCounted<lynx::style::StyleObject>(new_style_map1);
530+ auto style_obj2 =
531+ fml::MakeRefCounted<lynx::style::StyleObject>(new_style_map2);
532+
533+ lynx::style::StyleObject* new_ptr[] = {style_obj1.get (), style_obj2.get (),
534+ nullptr };
535+
536+ MockSimpleStyleNode target;
537+ target.UpdateSimpleStyles (old_dcl_style);
538+
539+ StyleResolver resolver;
540+ resolver.ResolveStyleObjectsBasedOnExistingMap (old_dcl_style, new_ptr,
541+ &target);
542+
543+ // Check that overlapping properties are updated, new properties are added,
544+ // and old ones are reset
545+ EXPECT_TRUE (target.HasProperty (CSSPropertyID::kPropertyIDFontSize ));
546+ EXPECT_TRUE (target.HasProperty (CSSPropertyID::kPropertyIDColor ));
547+ EXPECT_TRUE (target.HasProperty (CSSPropertyID::kPropertyIDWidth ));
548+ EXPECT_FALSE (
549+ target.HasProperty (CSSPropertyID::kPropertyIDHeight )); // Should be reset
550+ EXPECT_EQ (target.GetCurrentStyles ().size (), 3u );
551+ }
552+
553+ TEST_F (CSSPatchingTest, ResolveStyleObjectsBasedOnExistingMap_EmptyNewStyles) {
554+ // Test case: Old styles exist, but new styles array is empty (not null)
555+ tasm::StyleMap old_dcl_style;
556+ old_dcl_style[CSSPropertyID::kPropertyIDFontSize ] =
557+ CSSValue::MakePlainString (" 16px" );
558+ old_dcl_style[CSSPropertyID::kPropertyIDColor ] =
559+ CSSValue::MakePlainString (" red" );
560+
561+ // Empty new styles array (nullptr terminated)
562+ lynx::style::StyleObject* new_ptr[] = {nullptr };
563+
564+ MockSimpleStyleNode target;
565+ target.UpdateSimpleStyles (old_dcl_style);
566+
567+ StyleResolver resolver;
568+ resolver.ResolveStyleObjectsBasedOnExistingMap (old_dcl_style, new_ptr,
569+ &target);
570+
571+ // All old styles should be reset since new styles are empty
572+ EXPECT_TRUE (target.GetCurrentStyles ().empty ());
573+ }
397574} // namespace testing
398575} // namespace tasm
399576} // namespace lynx
0 commit comments