1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h"
6 
7 #include <memory>
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
10 #include "third_party/blink/renderer/core/dom/element.h"
11 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
12 #include "third_party/blink/renderer/core/testing/page_test_base.h"
13 #include "third_party/blink/renderer/platform/heap/handle.h"
14 
15 namespace blink {
16 
17 class PrepopulatedComputedStylePropertyMapTest : public PageTestBase {
18  public:
19   PrepopulatedComputedStylePropertyMapTest() = default;
20 
SetElementWithStyle(const String & value)21   void SetElementWithStyle(const String& value) {
22     GetDocument().body()->setInnerHTML("<div id='target' style='" + value +
23                                        "'></div>");
24     UpdateAllLifecyclePhasesForTest();
25   }
26 
GetNativeValue(const CSSPropertyID & property_id)27   const CSSValue* GetNativeValue(const CSSPropertyID& property_id) {
28     Element* node = GetDocument().getElementById("target");
29     return CSSProperty::Get(property_id)
30         .CSSValueFromComputedStyle(node->ComputedStyleRef(),
31                                    nullptr /* layout_object */,
32                                    false /* allow_visited_style */);
33   }
34 
Declaration() const35   CSSComputedStyleDeclaration* Declaration() const {
36     return declaration_.Get();
37   }
38 
SetUp()39   void SetUp() override {
40     PageTestBase::SetUp(IntSize());
41     declaration_ = MakeGarbageCollected<CSSComputedStyleDeclaration>(
42         GetDocument().documentElement());
43   }
44 
PageNode()45   Node* PageNode() { return GetDocument().documentElement(); }
46 
47  private:
48   Persistent<CSSComputedStyleDeclaration> declaration_;
49 };
50 
TEST_F(PrepopulatedComputedStylePropertyMapTest,NativePropertyAccessors)51 TEST_F(PrepopulatedComputedStylePropertyMapTest, NativePropertyAccessors) {
52   Vector<CSSPropertyID> native_properties(
53       {CSSPropertyID::kColor, CSSPropertyID::kAlignItems});
54   Vector<AtomicString> empty_custom_properties;
55 
56   UpdateAllLifecyclePhasesForTest();
57   Node* node = PageNode();
58 
59   PrepopulatedComputedStylePropertyMap* map =
60       MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
61           GetDocument(), node->ComputedStyleRef(), native_properties,
62           empty_custom_properties);
63 
64   DummyExceptionStateForTesting exception_state;
65 
66   map->get(GetDocument().GetExecutionContext(), "color", exception_state);
67   EXPECT_FALSE(exception_state.HadException());
68 
69   map->has(GetDocument().GetExecutionContext(), "color", exception_state);
70   EXPECT_FALSE(exception_state.HadException());
71 
72   map->getAll(GetDocument().GetExecutionContext(), "color", exception_state);
73   EXPECT_FALSE(exception_state.HadException());
74 
75   map->get(GetDocument().GetExecutionContext(), "align-contents",
76            exception_state);
77   EXPECT_TRUE(exception_state.HadException());
78   exception_state.ClearException();
79 
80   map->has(GetDocument().GetExecutionContext(), "align-contents",
81            exception_state);
82   EXPECT_TRUE(exception_state.HadException());
83   exception_state.ClearException();
84 
85   map->getAll(GetDocument().GetExecutionContext(), "align-contents",
86               exception_state);
87   EXPECT_TRUE(exception_state.HadException());
88   exception_state.ClearException();
89 }
90 
TEST_F(PrepopulatedComputedStylePropertyMapTest,CustomPropertyAccessors)91 TEST_F(PrepopulatedComputedStylePropertyMapTest, CustomPropertyAccessors) {
92   Vector<CSSPropertyID> empty_native_properties;
93   Vector<AtomicString> custom_properties({"--foo", "--bar"});
94 
95   UpdateAllLifecyclePhasesForTest();
96   Node* node = PageNode();
97 
98   PrepopulatedComputedStylePropertyMap* map =
99       MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
100           GetDocument(), node->ComputedStyleRef(), empty_native_properties,
101           custom_properties);
102 
103   DummyExceptionStateForTesting exception_state;
104 
105   const CSSStyleValue* foo =
106       map->get(GetDocument().GetExecutionContext(), "--foo", exception_state);
107   ASSERT_NE(nullptr, foo);
108   ASSERT_EQ(CSSStyleValue::kUnparsedType, foo->GetType());
109   EXPECT_FALSE(exception_state.HadException());
110 
111   EXPECT_EQ(true, map->has(GetDocument().GetExecutionContext(), "--foo",
112                            exception_state));
113   EXPECT_FALSE(exception_state.HadException());
114 
115   CSSStyleValueVector fooAll = map->getAll(GetDocument().GetExecutionContext(),
116                                            "--foo", exception_state);
117   EXPECT_EQ(1U, fooAll.size());
118   ASSERT_NE(nullptr, fooAll[0]);
119   ASSERT_EQ(CSSStyleValue::kUnparsedType, fooAll[0]->GetType());
120   EXPECT_FALSE(exception_state.HadException());
121 
122   EXPECT_EQ(nullptr, map->get(GetDocument().GetExecutionContext(), "--quix",
123                               exception_state));
124   EXPECT_FALSE(exception_state.HadException());
125 
126   EXPECT_EQ(false, map->has(GetDocument().GetExecutionContext(), "--quix",
127                             exception_state));
128   EXPECT_FALSE(exception_state.HadException());
129 
130   EXPECT_EQ(CSSStyleValueVector(),
131             map->getAll(GetDocument().GetExecutionContext(), "--quix",
132                         exception_state));
133   EXPECT_FALSE(exception_state.HadException());
134 }
135 
TEST_F(PrepopulatedComputedStylePropertyMapTest,WidthBeingAuto)136 TEST_F(PrepopulatedComputedStylePropertyMapTest, WidthBeingAuto) {
137   SetElementWithStyle("width:auto");
138   const CSSValue* value = GetNativeValue(CSSPropertyID::kWidth);
139   EXPECT_EQ("auto", value->CssText());
140 }
141 
142 }  // namespace blink
143