blob: e91a653c29000903ef1db7b6ae01e144c78c4465 [file] [log] [blame]
// Copyright 2015 The Cobalt Authors. 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/css_font_face_rule.h"
#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "cobalt/base/source_location.h"
#include "cobalt/cssom/css_declaration_util.h"
#include "cobalt/cssom/css_parser.h"
#include "cobalt/cssom/css_rule_visitor.h"
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/cssom/style_sheet_list.h"
namespace cobalt {
namespace cssom {
namespace {
struct NonTrivialStaticFields {
NonTrivialStaticFields()
: location(base::SourceLocation(CSSFontFaceRule::GetSourceLocationName(),
1, 1)) {}
const base::SourceLocation location;
private:
DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};
// |non_trivial_static_fields| will be lazily created on the first time it's
// accessed.
base::LazyInstance<NonTrivialStaticFields>::DestructorAtExit
non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER;
} // namespace
CSSFontFaceRule::CSSFontFaceRule() : data_(new CSSFontFaceDeclarationData) {}
CSSFontFaceRule::CSSFontFaceRule(
const scoped_refptr<CSSFontFaceDeclarationData>& data)
: data_(data) {
DCHECK(data_.get());
}
std::string CSSFontFaceRule::css_text(
script::ExceptionState* exception_state) const {
std::string css_text;
AppendPropertyDeclaration(GetPropertyName(kFontFamilyProperty),
data_->family(), &css_text);
AppendPropertyDeclaration(GetPropertyName(kSrcProperty), data_->src(),
&css_text);
AppendPropertyDeclaration(GetPropertyName(kFontStyleProperty), data_->style(),
&css_text);
AppendPropertyDeclaration(GetPropertyName(kFontWeightProperty),
data_->weight(), &css_text);
AppendPropertyDeclaration(GetPropertyName(kUnicodeRangeProperty),
data_->unicode_range(), &css_text);
return css_text;
}
void CSSFontFaceRule::set_css_text(const std::string& css_text,
script::ExceptionState* exception_state) {
DCHECK(parent_style_sheet());
scoped_refptr<CSSFontFaceDeclarationData> declaration =
parent_style_sheet()->css_parser()->ParseFontFaceDeclarationList(
css_text, non_trivial_static_fields.Get().location);
if (declaration) {
data_ = declaration;
RecordMutation();
}
}
std::string CSSFontFaceRule::family() const {
return data_->family() ? data_->family()->ToString() : "";
}
void CSSFontFaceRule::set_family(const std::string& family) {
SetPropertyValue(GetPropertyName(kFontFamilyProperty), family);
}
std::string CSSFontFaceRule::src() const {
return data_->src() ? data_->src()->ToString() : "";
}
void CSSFontFaceRule::set_src(const std::string& src) {
SetPropertyValue(GetPropertyName(kSrcProperty), src);
}
std::string CSSFontFaceRule::style() const {
return data_->style() ? data_->style()->ToString() : "";
}
void CSSFontFaceRule::set_style(const std::string& style) {
SetPropertyValue(GetPropertyName(kFontStyleProperty), style);
}
std::string CSSFontFaceRule::weight() const {
return data_->weight() ? data_->weight()->ToString() : "";
}
void CSSFontFaceRule::set_weight(const std::string& weight) {
SetPropertyValue(GetPropertyName(kFontWeightProperty), weight);
}
std::string CSSFontFaceRule::unicode_range() const {
return data_->unicode_range() ? data_->unicode_range()->ToString() : "";
}
void CSSFontFaceRule::set_unicode_range(const std::string& unicode_range) {
SetPropertyValue(GetPropertyName(kUnicodeRangeProperty), unicode_range);
}
void CSSFontFaceRule::Accept(CSSRuleVisitor* visitor) {
visitor->VisitCSSFontFaceRule(this);
}
void CSSFontFaceRule::AttachToCSSStyleSheet(CSSStyleSheet* style_sheet) {
set_parent_style_sheet(style_sheet);
}
std::string CSSFontFaceRule::GetPropertyValue(PropertyKey key) {
return data_->GetPropertyValue(key) ? data_->GetPropertyValue(key)->ToString()
: "";
}
void CSSFontFaceRule::SetPropertyValue(const std::string& property_name,
const std::string& property_value) {
DCHECK(parent_style_sheet());
parent_style_sheet()->css_parser()->ParsePropertyIntoDeclarationData(
property_name, property_value,
base::SourceLocation(non_trivial_static_fields.Get().location),
data_.get());
RecordMutation();
}
// font-family and src are required for an @font-face rule to be valid:
// https://www.w3.org/TR/css3-fonts/#descdef-font-family
// https://www.w3.org/TR/css3-fonts/#descdef-src
bool CSSFontFaceRule::IsValid() const {
return !family().empty() && !src().empty();
}
CSSFontFaceRule::~CSSFontFaceRule() {}
void CSSFontFaceRule::RecordMutation() {
DCHECK(parent_style_sheet());
DCHECK(parent_style_sheet()->ParentStyleSheetList());
// Trigger layout update.
parent_style_sheet()->ParentStyleSheetList()->OnCSSMutation();
}
} // namespace cssom
} // namespace cobalt