Class: Dommy::CSSRule
- Inherits:
-
Object
- Object
- Dommy::CSSRule
- Defined in:
- lib/dommy/css.rb
Overview
CSSRule — one parsed stylesheet rule. cssText round-trips the source
slice verbatim until the rule is mutated. The CSSOM subclass hierarchy
(CSSStyleRule / CSSMediaRule / …) is collapsed into this one class, which
exposes the accessors per type: selectorText + style for style
rules, conditionText + cssRules for grouping rules (@media/@supports).
The selector text and declaration block are derived lazily with
Internal::CSSRuleText (a light scanner; the cascade's correctness still
comes from lexbor).
Constant Summary collapse
- STYLE_RULE =
1- CHARSET_RULE =
2- IMPORT_RULE =
3- MEDIA_RULE =
4- FONT_FACE_RULE =
5- PAGE_RULE =
6- KEYFRAMES_RULE =
7- KEYFRAME_RULE =
8- SUPPORTS_RULE =
12- AT_RULE_TYPES =
{ "media" => MEDIA_RULE, "supports" => SUPPORTS_RULE, "import" => IMPORT_RULE, "charset" => CHARSET_RULE, "font-face" => FONT_FACE_RULE, "page" => PAGE_RULE, "keyframes" => KEYFRAMES_RULE }.freeze
- GROUPING_TYPES =
[MEDIA_RULE, SUPPORTS_RULE].freeze
Instance Attribute Summary collapse
-
#parent_style_sheet ⇒ Object
readonly
Returns the value of attribute parent_style_sheet.
Instance Method Summary collapse
-
#__internal_rebuild_from_style__(block_text) ⇒ Object
Called by RuleStyleDeclaration after a property write: rebuild cssText from the (possibly new) selector and declaration block.
-
#__internal_set_media__(media_text) ⇒ Object
Called by the MediaList when its media text changes: rebuild the @media prelude (keeping the block body) and reflow the cascade.
- #__js_get__(key) ⇒ Object
- #__js_set__(key, value) ⇒ Object
-
#condition_text ⇒ Object
CSSConditionRule#conditionText — the condition text after the at-keyword.
-
#css_rules ⇒ Object
CSSGroupingRule#cssRules — the nested rules of an @media/@supports block.
- #css_text ⇒ Object
- #css_text=(v) ⇒ Object
- #grouping? ⇒ Boolean
-
#initialize(css_text, parent_style_sheet = nil) ⇒ CSSRule
constructor
A new instance of CSSRule.
-
#media ⇒ Object
CSSMediaRule#media — a live MediaList over the @media condition.
- #parent_rule ⇒ Object
-
#selector_text ⇒ Object
CSSStyleRule#selectorText — the rule's selector list ("" for at-rules).
- #selector_text=(value) ⇒ Object
-
#style ⇒ Object
CSSStyleRule#style — a live, mutable declaration block.
- #style_rule? ⇒ Boolean
- #type ⇒ Object
Constructor Details
#initialize(css_text, parent_style_sheet = nil) ⇒ CSSRule
Returns a new instance of CSSRule.
456 457 458 459 |
# File 'lib/dommy/css.rb', line 456 def initialize(css_text, parent_style_sheet = nil) @css_text = css_text.to_s @parent_style_sheet = parent_style_sheet end |
Instance Attribute Details
#parent_style_sheet ⇒ Object (readonly)
Returns the value of attribute parent_style_sheet.
454 455 456 |
# File 'lib/dommy/css.rb', line 454 def parent_style_sheet @parent_style_sheet end |
Instance Method Details
#__internal_rebuild_from_style__(block_text) ⇒ Object
Called by RuleStyleDeclaration after a property write: rebuild cssText from the (possibly new) selector and declaration block.
537 538 539 540 541 542 |
# File 'lib/dommy/css.rb', line 537 def __internal_rebuild_from_style__(block_text) @selector ||= prelude @css_text = block_text.empty? ? "#{@selector} {}" : "#{@selector} { #{block_text} }" @parent_style_sheet&.__internal_notify_rule_changed__ nil end |
#__internal_set_media__(media_text) ⇒ Object
Called by the MediaList when its media text changes: rebuild the @media prelude (keeping the block body) and reflow the cascade.
546 547 548 549 550 551 552 |
# File 'lib/dommy/css.rb', line 546 def __internal_set_media__(media_text) @css_text = "@media #{media_text} { #{body} }" @prelude = nil @media_list = nil @parent_style_sheet&.__internal_notify_rule_changed__ nil end |
#__js_get__(key) ⇒ Object
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/dommy/css.rb', line 554 def __js_get__(key) case key when "cssText" then @css_text when "type" then type when "selectorText" then selector_text when "style" then style when "cssRules" then css_rules when "conditionText" then grouping? ? condition_text : nil when "media" then media when "parentStyleSheet" then @parent_style_sheet when "parentRule" then parent_rule when "STYLE_RULE" then STYLE_RULE when "MEDIA_RULE" then MEDIA_RULE when "IMPORT_RULE" then IMPORT_RULE when "FONT_FACE_RULE" then FONT_FACE_RULE when "PAGE_RULE" then PAGE_RULE when "KEYFRAMES_RULE" then KEYFRAMES_RULE when "KEYFRAME_RULE" then KEYFRAME_RULE when "SUPPORTS_RULE" then SUPPORTS_RULE when "CHARSET_RULE" then CHARSET_RULE else Bridge::ABSENT end end |
#__js_set__(key, value) ⇒ Object
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 |
# File 'lib/dommy/css.rb', line 579 def __js_set__(key, value) case key when "cssText" then self.css_text = value when "selectorText" then self.selector_text = value when "media" # CSSMediaRule#media is settable with a media-text string. __internal_set_media__(value.to_s) if type == MEDIA_RULE else # Signal "not a host property" so the bridge keeps the assignment as a # JS-side expando (WebIDL platform objects allow expandos; WPT's # [SameObject] tests stash a marker on cssRules[i] and read it back). return Bridge::UNHANDLED end nil end |
#condition_text ⇒ Object
CSSConditionRule#conditionText — the condition text after the at-keyword.
518 519 520 |
# File 'lib/dommy/css.rb', line 518 def condition_text grouping? ? prelude.sub(/\A@[-a-z]+/i, "").strip : "" end |
#css_rules ⇒ Object
CSSGroupingRule#cssRules — the nested rules of an @media/@supports block.
505 506 507 508 509 510 511 512 513 514 515 |
# File 'lib/dommy/css.rb', line 505 def css_rules return nil unless grouping? @css_rules ||= begin list = CSSRuleList.new Internal::CSSRuleText.split_rules(body).each_with_index do |slice, i| list.__internal_insert__(i, CSSRule.new(slice, @parent_style_sheet)) end list end end |
#css_text ⇒ Object
461 462 463 |
# File 'lib/dommy/css.rb', line 461 def css_text @css_text end |
#css_text=(v) ⇒ Object
465 466 467 468 |
# File 'lib/dommy/css.rb', line 465 def css_text=(v) @css_text = v.to_s invalidate! end |
#grouping? ⇒ Boolean
479 480 481 |
# File 'lib/dommy/css.rb', line 479 def grouping? GROUPING_TYPES.include?(type) end |
#media ⇒ Object
CSSMediaRule#media — a live MediaList over the @media condition. nil for non-media rules. Mutations rebuild the rule's prelude and reflow the cascade.
525 526 527 528 529 |
# File 'lib/dommy/css.rb', line 525 def media return nil unless type == MEDIA_RULE @media_list ||= MediaList.new(condition_text, on_change: method(:__internal_set_media__)) end |
#parent_rule ⇒ Object
531 532 533 |
# File 'lib/dommy/css.rb', line 531 def parent_rule nil end |
#selector_text ⇒ Object
CSSStyleRule#selectorText — the rule's selector list ("" for at-rules).
484 485 486 |
# File 'lib/dommy/css.rb', line 484 def selector_text style_rule? ? prelude : "" end |
#selector_text=(value) ⇒ Object
488 489 490 491 492 493 |
# File 'lib/dommy/css.rb', line 488 def selector_text=(value) return unless style_rule? @selector = value.to_s rebuild_css_text! end |
#style ⇒ Object
CSSStyleRule#style — a live, mutable declaration block. nil for at-rules
(matching the absent style member on CSSMediaRule etc.). Writes
reserialize cssText and invalidate the document's computed-style cache.
498 499 500 501 502 |
# File 'lib/dommy/css.rb', line 498 def style return nil unless style_rule? @style ||= RuleStyleDeclaration.new(self, Internal::CSSRuleText.split_rule(@css_text).last) end |
#style_rule? ⇒ Boolean
475 476 477 |
# File 'lib/dommy/css.rb', line 475 def style_rule? type == STYLE_RULE end |
#type ⇒ Object
470 471 472 473 |
# File 'lib/dommy/css.rb', line 470 def type keyword = Internal::CSSRuleText.at_keyword(prelude) keyword ? AT_RULE_TYPES.fetch(keyword, STYLE_RULE) : STYLE_RULE end |