Class: CSS::Cascade
- Inherits:
-
Object
- Object
- CSS::Cascade
- Defined in:
- lib/css/cascade.rb
Overview
Resolves the cascade for a Stylesheet against a single element. Returns ‘Hash<String, Declaration>` keyed by property name with the winning declaration after applying:
- `@media` filtering (against a `MediaQueries::Context`)
- selector matching (`Selectors::Matcher`)
- cascade sort: `!important` > origin / inline > specificity > source order
The Stylesheet is compiled once on construction (selectors are pre-parsed, specificities pre-computed, ‘@media` chains are evaluated against the supplied context up-front, and rules are indexed by the rightmost compound’s strongest anchor — id > class > tag > universal). ‘resolve(element)` then visits only the rules whose anchor could match the element.
Cascade layers, ‘@scope` proximity, and Shadow DOM encapsulation are not modeled — `@layer`, `@supports`, `@container`, `@scope`, and `@starting-style` blocks are descended into unconditionally.
Defined Under Namespace
Classes: AnchorKey, Index, Match, RuleEntry
Constant Summary collapse
- TRANSPARENT_AT_RULES =
%w[supports layer scope starting-style container].freeze
Instance Method Summary collapse
-
#initialize(stylesheet, context: MediaQueries::Context.default) ⇒ Cascade
constructor
A new instance of Cascade.
-
#resolve(element, inline_style: nil, state: nil) ⇒ Object
Returns Hash<String, Declaration> of winning declarations.
Constructor Details
#initialize(stylesheet, context: MediaQueries::Context.default) ⇒ Cascade
Returns a new instance of Cascade.
27 28 29 30 31 |
# File 'lib/css/cascade.rb', line 27 def initialize(stylesheet, context: MediaQueries::Context.default) @context = context @entries = compile(stylesheet) @index = build_index(@entries) end |
Instance Method Details
#resolve(element, inline_style: nil, state: nil) ⇒ Object
Returns Hash<String, Declaration> of winning declarations.
‘state:` opts into stateful-pseudo matching — see `Selectors::Matcher#matches?` for the shape. Defaults to the stateless behavior (`:hover`, `:focus`, etc. never match).
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/css/cascade.rb', line 38 def resolve(element, inline_style: nil, state: nil) cache = {} candidates = collect_candidate_indexes(element, cache) order = 0 matches = [] candidates.each do |idx| entry = @entries[idx] spec = best_matching_specificity(element, entry.selector_pairs, cache, state) next if spec.nil? entry.declarations.each do |decl| order += 1 matches << Match.new(declaration: decl, specificity: spec, inline: false, order: order) end end if inline_style inline_declarations(inline_style).each do |decl| order += 1 matches << Match.new(declaration: decl, specificity: Selectors::Specificity::ZERO, inline: true, order: order) end end pick_winners(matches) end |