diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h')
-rw-r--r-- | chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h new file mode 100644 index 00000000000..9a49e2c72d2 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h @@ -0,0 +1,107 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_ + +#include "base/logging.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h" + +namespace blink { + +// The origin and importance criteria are evaluated together [1], hence we +// encode both into a single integer which will do the right thing when compared +// to another such encoded integer. See CascadeOrigin for more information on +// how that works. +// +// [1] https://www.w3.org/TR/css-cascade-3/#cascade-origin +inline uint64_t EncodeOriginImportance(CascadeOrigin origin, bool important) { + uint8_t important_xor = (static_cast<uint8_t>(!important) - 1) & 0xF; + return static_cast<uint64_t>(origin) ^ important_xor; +} + +// Tree order bits are flipped for important declarations to reverse the +// priority [1]. +// +// [1] https://drafts.csswg.org/css-scoping/#shadow-cascading +inline uint64_t EncodeTreeOrder(uint16_t tree_order, bool important) { + uint16_t important_xor = static_cast<uint16_t>(!important) - 1; + return static_cast<uint64_t>(tree_order) ^ important_xor; +} + +// The CascadePriority class encapsulates a subset of the cascading criteria +// described by css-cascade [1], and provides a way to compare priorities +// quickly by encoding all the information in a single integer. +// +// It encompasses, from most significant to least significant: +// Origin/importance; tree order, which is a number representing the +// shadow-including tree order [2]; position, which contains the index (or +// indices) required to lookup a declaration in the underlying structure (e.g. a +// MatchResult); and finally generation, which is a monotonically increasing +// number generated by StyleCascade for each call to StyleCascade::Apply. +// +// [1] https://drafts.csswg.org/css-cascade/#cascading +// [2] https://drafts.csswg.org/css-scoping/#shadow-cascading +class CORE_EXPORT CascadePriority { + public: + // The declaration is important if this bit is set on the encoded priority. + static constexpr uint64_t kImportantBit = 55; + static constexpr uint64_t kOriginImportanceOffset = 52; + static constexpr uint64_t kTreeOrderOffset = 36; + + CascadePriority() : bits_(0) {} + CascadePriority(CascadeOrigin origin) + : CascadePriority(origin, false, 0, 0) {} + CascadePriority(CascadeOrigin origin, bool important) + : CascadePriority(origin, important, 0, 0) {} + CascadePriority(CascadeOrigin origin, bool important, uint16_t tree_order) + : CascadePriority(origin, important, tree_order, 0) {} + // For an explanation of 'tree_order', see css-scoping: + // https://drafts.csswg.org/css-scoping/#shadow-cascading + CascadePriority(CascadeOrigin origin, + bool important, + uint16_t tree_order, + uint32_t position) + : bits_(static_cast<uint64_t>(position) << 4 | + EncodeTreeOrder(tree_order, important) << kTreeOrderOffset | + EncodeOriginImportance(origin, important) + << kOriginImportanceOffset) {} + // See StyleCascade.generation_. + CascadePriority(CascadePriority o, uint8_t generation) + : bits_((o.bits_ & ~static_cast<uint8_t>(0xF)) | generation) { + DCHECK_LE(generation, 0xF); + } + + bool IsImportant() const { return (bits_ >> kImportantBit) & 1; } + CascadeOrigin GetOrigin() const { + uint64_t important_xor = (((~bits_ >> kImportantBit) & 1) - 1) & 0xF; + return static_cast<CascadeOrigin>((bits_ >> kOriginImportanceOffset) ^ + important_xor); + } + bool HasOrigin() const { return GetOrigin() != CascadeOrigin::kNone; } + uint32_t GetPosition() const { return (bits_ >> 4) & 0xFFFFFFFF; } + uint8_t GetGeneration() const { return bits_ & 0xF; } + + bool operator>=(const CascadePriority& o) const { return bits_ >= o.bits_; } + bool operator<(const CascadePriority& o) const { return bits_ < o.bits_; } + bool operator==(const CascadePriority& o) const { return bits_ == o.bits_; } + bool operator!=(const CascadePriority& o) const { return bits_ != o.bits_; } + + private: + friend class StyleCascade; + friend class StyleCascadeTest; + + CascadePriority(uint64_t bits) : bits_(bits) {} + + // Bit 0-3 : generation + // Bit 4-35: position + // Bit 36-51: tree_order (encoded) + // Bit 52-59: origin/importance (encoded) + uint64_t bits_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_ |