blob: 60f978ea81d5fdf0544d2858d546ce7efe0e729f [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.
#ifndef COBALT_CSSOM_CASCADE_PRECEDENCE_H_
#define COBALT_CSSOM_CASCADE_PRECEDENCE_H_
#include <string>
#include "base/basictypes.h"
#include "base/logging.h"
#include "cobalt/cssom/specificity.h"
namespace cobalt {
namespace cssom {
// The enum origin here includes both origin and importance in the spec. The
// origin of a declaration is based on where it comes from and its importance
// is whether or not it is declared !important.
// https://www.w3.org/TR/css-cascade-3/#cascade-origin
// The origin with higher precedence appears later in the enum, and is therefore
// with higher value.
enum Origin {
kNormalUserAgent,
kNormalAuthor,
kNormalOverride,
kImportantMin, // The lowest important origin.
kImportantAuthor = kImportantMin,
kImportantOverride,
kImportantUserAgent,
kImportantMax = kImportantUserAgent,
};
// Appearance is the position of the declaration in the document.
// https://www.w3.org/TR/css-cascade-3/#cascade-order
class Appearance {
public:
static const int kUnattached = -1;
Appearance() : style_sheet_index_(kUnattached), rule_index_(kUnattached) {}
Appearance(int style_sheet_index, int rule_index)
: style_sheet_index_(style_sheet_index), rule_index_(rule_index) {
DCHECK_GE(style_sheet_index, kUnattached) << "Wrong style sheet index.";
DCHECK_GE(rule_index, kUnattached) << "Wrong rule index.";
}
// Earlier appearance is smaller. The fields are compared lexicographically.
bool operator<(const Appearance& rhs) const {
return style_sheet_index_ < rhs.style_sheet_index_ ||
(style_sheet_index_ == rhs.style_sheet_index_ &&
rule_index_ < rhs.rule_index_);
}
bool operator==(const Appearance& rhs) const {
return style_sheet_index_ == rhs.style_sheet_index_ &&
rule_index_ == rhs.rule_index_;
}
private:
int style_sheet_index_;
int rule_index_;
};
// Cascade precedence is the value that is used in sorting the declarations in
// the cascade.
// https://www.w3.org/TR/css-cascade-3/#cascade
// In Cobalt the cascade precedence includes origin, specificity and appearance,
// which is compared lexicographically.
class CascadePrecedence {
public:
explicit CascadePrecedence(Origin origin) : origin_(origin) {}
CascadePrecedence(Origin origin, const Specificity& specificity,
const Appearance& appearance)
: origin_(origin), specificity_(specificity), appearance_(appearance) {}
Origin origin() const { return origin_; }
const Specificity& specificity() const { return specificity_; }
const Appearance& appearance() const { return appearance_; }
void SetImportant() {
switch (origin_) {
case kNormalUserAgent: {
origin_ = kImportantUserAgent;
break;
}
case kNormalAuthor: {
origin_ = kImportantAuthor;
break;
}
case kNormalOverride: {
origin_ = kImportantOverride;
break;
}
case kImportantAuthor:
case kImportantOverride:
case kImportantUserAgent:
NOTREACHED();
}
}
bool operator<(const CascadePrecedence& rhs) const {
return origin_ < rhs.origin_ ||
(origin_ == rhs.origin_ && (specificity_ < rhs.specificity_ ||
(specificity_ == rhs.specificity_ &&
appearance_ < rhs.appearance_)));
}
bool operator==(const CascadePrecedence& rhs) const {
return origin_ == rhs.origin_ && specificity_ == rhs.specificity_ &&
appearance_ == rhs.appearance_;
}
private:
Origin origin_;
Specificity specificity_;
Appearance appearance_;
};
} // namespace cssom
} // namespace cobalt
#endif // COBALT_CSSOM_CASCADE_PRECEDENCE_H_