| // Copyright 2015 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "cobalt/cssom/cascaded_style.h" |
| |
| #include "cobalt/css_parser/parser.h" |
| #include "cobalt/cssom/cascade_precedence.h" |
| #include "cobalt/cssom/css_computed_style_data.h" |
| #include "cobalt/cssom/css_declaration_data.h" |
| #include "cobalt/cssom/css_declared_style_data.h" |
| #include "cobalt/cssom/css_rule_style_declaration.h" |
| #include "cobalt/cssom/css_style_rule.h" |
| #include "cobalt/cssom/css_style_sheet.h" |
| #include "cobalt/cssom/keyword_value.h" |
| #include "googleurl/src/gurl.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace cobalt { |
| namespace cssom { |
| |
| TEST(CascadedStyleTest, PromoteToCascadedStyle) { |
| scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create(); |
| scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData(); |
| RulesWithCascadePrecedence rules_with_cascade_precedence; |
| GURLMap property_key_to_base_url_map; |
| |
| style->SetPropertyValueAndImportance(kVerticalAlignProperty, |
| KeywordValue::GetBottom(), true); |
| style->SetPropertyValueAndImportance(kTextAlignProperty, |
| KeywordValue::GetLeft(), false); |
| |
| // The order of cascade precedence of the following rules: |
| // rule 2 > rule 3 > rule 1. |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_1 = |
| css_parser->ParseRule( |
| "div {" |
| " left: 100px !important;" |
| " right: 100px;" |
| " width: 100px;" |
| " height: 100px;" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_1(kNormalUserAgent); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_1, cascade_precedence_1)); |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_2 = |
| css_parser->ParseRule( |
| "div {" |
| " left: 200px;" |
| " right: 200px !important;" |
| " width: 200px;" |
| " height: 200px;" |
| " vertical-align: top !important;" |
| " text-align: center !important;" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_2(kNormalOverride); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_2, cascade_precedence_2)); |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_3 = |
| css_parser->ParseRule( |
| "div {" |
| " left: 300px;" |
| " right: 300px;" |
| " width: 300px !important;" |
| " height: 300px;" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_3(kNormalAuthor); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_3, cascade_precedence_3)); |
| |
| scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle( |
| style, &rules_with_cascade_precedence, &property_key_to_base_url_map); |
| |
| EXPECT_EQ( |
| computed_style->left(), |
| css_style_rule_1->declared_style_data()->GetPropertyValue(kLeftProperty)); |
| EXPECT_EQ(computed_style->right(), |
| css_style_rule_2->declared_style_data()->GetPropertyValue( |
| kRightProperty)); |
| EXPECT_EQ(computed_style->width(), |
| css_style_rule_3->declared_style_data()->GetPropertyValue( |
| kWidthProperty)); |
| EXPECT_EQ(computed_style->height(), |
| css_style_rule_2->declared_style_data()->GetPropertyValue( |
| kHeightProperty)); |
| EXPECT_EQ(computed_style->vertical_align(), |
| style->GetPropertyValue(kVerticalAlignProperty)); |
| EXPECT_EQ(computed_style->text_align(), |
| css_style_rule_2->declared_style_data()->GetPropertyValue( |
| kTextAlignProperty)); |
| } |
| |
| TEST(CascadedStyleTest, PromoteToCascadedStyleWithBackgroundImage) { |
| scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create(); |
| scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData(); |
| RulesWithCascadePrecedence rules_with_cascade_precedence; |
| GURLMap property_key_to_base_url_map; |
| |
| // The order of cascade precedence of the following rules: |
| // rule 2 > rule 1. |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_1 = |
| css_parser->ParseRule( |
| "div {" |
| " left: 100px !important;" |
| " right: 100px;" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_1(kNormalUserAgent); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_1, cascade_precedence_1)); |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_2 = |
| css_parser->ParseRule( |
| "div {" |
| " left: 200px;" |
| " right: 200px !important;" |
| " background-image: url(foo.png);" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_2(kNormalOverride); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_2, cascade_precedence_2)); |
| |
| scoped_refptr<CSSStyleSheet> parent_style_sheet(new CSSStyleSheet()); |
| parent_style_sheet->SetOriginClean(true); |
| parent_style_sheet->SetLocationUrl(GURL("https:///www.youtube.com/tv/img")); |
| css_style_rule_2->set_parent_style_sheet(parent_style_sheet.get()); |
| |
| scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle( |
| style, &rules_with_cascade_precedence, &property_key_to_base_url_map); |
| |
| EXPECT_EQ( |
| computed_style->left(), |
| css_style_rule_1->declared_style_data()->GetPropertyValue(kLeftProperty)); |
| EXPECT_EQ(computed_style->right(), |
| css_style_rule_2->declared_style_data()->GetPropertyValue( |
| kRightProperty)); |
| EXPECT_EQ(computed_style->background_image(), |
| css_style_rule_2->declared_style_data()->GetPropertyValue( |
| kBackgroundImageProperty)); |
| ASSERT_FALSE(property_key_to_base_url_map.empty()); |
| EXPECT_EQ(property_key_to_base_url_map[kBackgroundImageProperty].spec(), |
| "https://www.youtube.com/tv/img"); |
| } |
| |
| TEST(CascadedStyleTest, |
| PromoteToCascadedStyleWithParentStyleSheetLocationUnset) { |
| scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create(); |
| scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData(); |
| RulesWithCascadePrecedence rules_with_cascade_precedence; |
| GURLMap property_key_to_base_url_map; |
| property_key_to_base_url_map[kBackgroundImageProperty] = |
| GURL("https://www.youtube.com/tv/img"); |
| |
| scoped_refptr<CSSStyleRule> css_style_rule = |
| css_parser->ParseRule( |
| "div {" |
| " left: 200px;" |
| " right: 200px !important;" |
| " background-image: url(foo.png);" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence(kNormalOverride); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule, cascade_precedence)); |
| |
| scoped_refptr<CSSStyleSheet> parent_style_sheet(new CSSStyleSheet()); |
| parent_style_sheet->SetOriginClean(true); |
| css_style_rule->set_parent_style_sheet(parent_style_sheet.get()); |
| |
| scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle( |
| style, &rules_with_cascade_precedence, &property_key_to_base_url_map); |
| |
| EXPECT_EQ( |
| computed_style->left(), |
| css_style_rule->declared_style_data()->GetPropertyValue(kLeftProperty)); |
| EXPECT_EQ( |
| computed_style->right(), |
| css_style_rule->declared_style_data()->GetPropertyValue(kRightProperty)); |
| EXPECT_EQ(computed_style->background_image(), |
| css_style_rule->declared_style_data()->GetPropertyValue( |
| kBackgroundImageProperty)); |
| ASSERT_FALSE(property_key_to_base_url_map.empty()); |
| EXPECT_EQ(property_key_to_base_url_map[kBackgroundImageProperty].spec(), |
| "https://www.youtube.com/tv/img"); |
| } |
| |
| TEST(CascadedStyleTest, |
| PromoteToCascadedStyleWithHigherBackgroundImagePriorityInFirstRule) { |
| scoped_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create(); |
| scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData(); |
| RulesWithCascadePrecedence rules_with_cascade_precedence; |
| GURLMap property_key_to_base_url_map; |
| |
| // The order of cascade precedence of the following rules: |
| // rule 2 > rule 1. |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_1 = |
| css_parser->ParseRule( |
| "div {" |
| " right: 100px;" |
| " background-image: url(bar.png) !important;" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_1(kNormalUserAgent); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_1, cascade_precedence_1)); |
| |
| scoped_refptr<CSSStyleSheet> parent_style_sheet_1(new CSSStyleSheet()); |
| parent_style_sheet_1->SetLocationUrl( |
| GURL("https:///www.youtube.com/tv/img1")); |
| css_style_rule_1->set_parent_style_sheet(parent_style_sheet_1.get()); |
| |
| scoped_refptr<CSSStyleRule> css_style_rule_2 = |
| css_parser->ParseRule( |
| "div {" |
| " right: 200px !important;" |
| " background-image: url(foo.png);" |
| "}", |
| base::SourceLocation("[object CascadedStyleTest]", 1, 1)) |
| ->AsCSSStyleRule(); |
| CascadePrecedence cascade_precedence_2(kNormalOverride); |
| rules_with_cascade_precedence.push_back( |
| std::make_pair(css_style_rule_2, cascade_precedence_2)); |
| |
| scoped_refptr<CSSStyleSheet> parent_style_sheet_2(new CSSStyleSheet()); |
| parent_style_sheet_2->SetLocationUrl( |
| GURL("https:///www.youtube.com/tv/img2")); |
| css_style_rule_2->set_parent_style_sheet(parent_style_sheet_2.get()); |
| |
| scoped_refptr<CSSComputedStyleData> computed_style = PromoteToCascadedStyle( |
| style, &rules_with_cascade_precedence, &property_key_to_base_url_map); |
| |
| EXPECT_EQ(computed_style->right(), |
| css_style_rule_2->declared_style_data()->GetPropertyValue( |
| kRightProperty)); |
| EXPECT_EQ(computed_style->background_image(), |
| css_style_rule_1->declared_style_data()->GetPropertyValue( |
| kBackgroundImageProperty)); |
| ASSERT_FALSE(property_key_to_base_url_map.empty()); |
| EXPECT_EQ(property_key_to_base_url_map[kBackgroundImageProperty].spec(), |
| "https://www.youtube.com/tv/img1"); |
| } |
| |
| } // namespace cssom |
| } // namespace cobalt |