summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h
diff options
context:
space:
mode:
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.h107
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_