blob: c6b6cb455602a5254f12b60805cb99b8678f63c4 [file]
// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/fxcrt/css/cfx_cssdeclaration.h"
#include <stdint.h>
#include <optional>
#include "core/fxcrt/css/cfx_csscolorvalue.h"
#include "core/fxcrt/css/cfx_csscomputedstyle.h"
#include "core/fxcrt/css/cfx_cssstyleselector.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/widestring.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(CFXCSSDeclarationTest, HexEncodingParsing) {
std::optional<CFX_CSSColor> maybe_color;
// Length value invalid.
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSColor(L"#00"));
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSColor(L"#0000"));
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSColor(L"#0000000"));
// Invalid characters
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"#zxytlm");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF000000u, maybe_color.value());
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"#000");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF000000u, maybe_color.value());
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"#FFF");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFFFFFFFFu, maybe_color.value());
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"#F0F0F0");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFFF0F0F0u, maybe_color.value());
// Upper and lower case characters.
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"#1b2F3c");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF1B2F3Cu, maybe_color.value());
}
TEST(CFXCSSDeclarationTest, RGBEncodingParsing) {
std::optional<CFX_CSSColor> maybe_color;
// Invalid input for rgb() syntax.
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSColor(L"blahblahblah"));
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"rgb(0, 0, 0)");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF000000u, maybe_color.value());
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"rgb(128,255,48)");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF80FF30u, maybe_color.value());
}
TEST(CFXCSSDeclarationTest, NamedColorParsing) {
std::optional<CFX_CSSColor> maybe_color =
CFX_CSSDeclaration::ParseCSSColor(L"red");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFFFF0000u, maybe_color.value());
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"green");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF008000u, maybe_color.value());
maybe_color = CFX_CSSDeclaration::ParseCSSColor(L"blue");
ASSERT_TRUE(maybe_color.has_value());
EXPECT_EQ(0xFF0000FFu, maybe_color.value());
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSColor(L"notacolor"));
}
TEST(CFXCSSDeclarationTest, ParseCSSString) {
EXPECT_EQ(L"Double Quoted",
CFX_CSSDeclaration::ParseCSSString(L"\"Double Quoted\""));
EXPECT_EQ(L"Single Quoted",
CFX_CSSDeclaration::ParseCSSString(L"'Single Quoted'"));
EXPECT_EQ(L"Unquoted", CFX_CSSDeclaration::ParseCSSString(L"Unquoted"));
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSString(L"\"\"").has_value());
EXPECT_FALSE(CFX_CSSDeclaration::ParseCSSString(L"").has_value());
}
TEST(CFXCSSDeclarationTest, AddProperty) {
CFX_CSSDeclaration decl;
EXPECT_TRUE(decl.empty());
bool important = false;
decl.AddProperty(CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::Color),
L"red");
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::Color, &important));
EXPECT_FALSE(important);
important = false;
decl.AddProperty(CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::FontSize),
L"16pt !important");
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::FontSize, &important));
EXPECT_TRUE(important);
important = false;
decl.AddProperty(CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::FontStyle),
L"italic");
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::FontStyle, &important));
EXPECT_FALSE(important);
important = false;
decl.AddProperty(CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::FontWeight),
L"bold");
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::FontWeight, &important));
EXPECT_FALSE(important);
important = false;
decl.AddProperty(CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::TextAlign),
L"center");
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::TextAlign, &important));
EXPECT_FALSE(important);
decl.AddProperty(CFX_CSSData::GetPropertyByEnum(CFX_CSSProperty::Border),
L"1px");
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::BorderLeftWidth, &important));
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::BorderTopWidth, &important));
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::BorderRightWidth, &important));
EXPECT_TRUE(decl.GetProperty(CFX_CSSProperty::BorderBottomWidth, &important));
decl.AddProperty(L"--custom", L"custom_value");
EXPECT_FALSE(decl.empty());
EXPECT_EQ(1, std::distance(decl.custom_begin(), decl.custom_end()));
}
TEST(CFXCSSDeclarationTest, CustomPropertiesInInlineStyle) {
CFX_CSSStyleSelector selector;
RetainPtr<CFX_CSSComputedStyle> style = selector.CreateComputedStyle(nullptr);
selector.ComputeStyle(
{}, L"color: #ff0000; xfa-spacerun: yes; tab-interval: 24pt", L"",
style.Get());
EXPECT_EQ(0xFFFF0000u, style->GetColor());
WideString value;
EXPECT_TRUE(style->GetCustomStyle(L"xfa-spacerun", &value));
EXPECT_EQ(L"yes", value);
EXPECT_TRUE(style->GetCustomStyle(L"tab-interval", &value));
EXPECT_EQ(L"24pt", value);
EXPECT_FALSE(style->GetCustomStyle(L"nonexistent", &value));
}