/usr/lib/ruby/vendor_ruby/sass/media.rb is in ruby-sass 3.4.6-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | # A namespace for the `@media` query parse tree.
module Sass::Media
# A comma-separated list of queries.
#
# media_query [ ',' S* media_query ]*
class QueryList
# The queries contained in this list.
#
# @return [Array<Query>]
attr_accessor :queries
# @param queries [Array<Query>] See \{#queries}
def initialize(queries)
@queries = queries
end
# Merges this query list with another. The returned query list
# queries for the intersection between the two inputs.
#
# Both query lists should be resolved.
#
# @param other [QueryList]
# @return [QueryList?] The merged list, or nil if there is no intersection.
def merge(other)
new_queries = queries.map {|q1| other.queries.map {|q2| q1.merge(q2)}}.flatten.compact
return if new_queries.empty?
QueryList.new(new_queries)
end
# Returns the CSS for the media query list.
#
# @return [String]
def to_css
queries.map {|q| q.to_css}.join(', ')
end
# Returns the Sass/SCSS code for the media query list.
#
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
# @return [String]
def to_src(options)
queries.map {|q| q.to_src(options)}.join(', ')
end
# Returns a representation of the query as an array of strings and
# potentially {Sass::Script::Tree::Node}s (if there's interpolation in it).
# When the interpolation is resolved and the strings are joined together,
# this will be the string representation of this query.
#
# @return [Array<String, Sass::Script::Tree::Node>]
def to_a
Sass::Util.intersperse(queries.map {|q| q.to_a}, ', ').flatten
end
# Returns a deep copy of this query list and all its children.
#
# @return [QueryList]
def deep_copy
QueryList.new(queries.map {|q| q.deep_copy})
end
end
# A single media query.
#
# [ [ONLY | NOT]? S* media_type S* | expression ] [ AND S* expression ]*
class Query
# The modifier for the query.
#
# When parsed as Sass code, this contains strings and SassScript nodes. When
# parsed as CSS, it contains a single string (accessible via
# \{#resolved_modifier}).
#
# @return [Array<String, Sass::Script::Tree::Node>]
attr_accessor :modifier
# The type of the query (e.g. `"screen"` or `"print"`).
#
# When parsed as Sass code, this contains strings and SassScript nodes. When
# parsed as CSS, it contains a single string (accessible via
# \{#resolved_type}).
#
# @return [Array<String, Sass::Script::Tree::Node>]
attr_accessor :type
# The trailing expressions in the query.
#
# When parsed as Sass code, each expression contains strings and SassScript
# nodes. When parsed as CSS, each one contains a single string.
#
# @return [Array<Array<String, Sass::Script::Tree::Node>>]
attr_accessor :expressions
# @param modifier [Array<String, Sass::Script::Tree::Node>] See \{#modifier}
# @param type [Array<String, Sass::Script::Tree::Node>] See \{#type}
# @param expressions [Array<Array<String, Sass::Script::Tree::Node>>] See \{#expressions}
def initialize(modifier, type, expressions)
@modifier = modifier
@type = type
@expressions = expressions
end
# See \{#modifier}.
# @return [String]
def resolved_modifier
# modifier should contain only a single string
modifier.first || ''
end
# See \{#type}.
# @return [String]
def resolved_type
# type should contain only a single string
type.first || ''
end
# Merges this query with another. The returned query queries for
# the intersection between the two inputs.
#
# Both queries should be resolved.
#
# @param other [Query]
# @return [Query?] The merged query, or nil if there is no intersection.
def merge(other)
m1, t1 = resolved_modifier.downcase, resolved_type.downcase
m2, t2 = other.resolved_modifier.downcase, other.resolved_type.downcase
t1 = t2 if t1.empty?
t2 = t1 if t2.empty?
if (m1 == 'not') ^ (m2 == 'not')
return if t1 == t2
type = m1 == 'not' ? t2 : t1
mod = m1 == 'not' ? m2 : m1
elsif m1 == 'not' && m2 == 'not'
# CSS has no way of representing "neither screen nor print"
return unless t1 == t2
type = t1
mod = 'not'
elsif t1 != t2
return
else # t1 == t2, neither m1 nor m2 are "not"
type = t1
mod = m1.empty? ? m2 : m1
end
Query.new([mod], [type], other.expressions + expressions)
end
# Returns the CSS for the media query.
#
# @return [String]
def to_css
css = ''
css << resolved_modifier
css << ' ' unless resolved_modifier.empty?
css << resolved_type
css << ' and ' unless resolved_type.empty? || expressions.empty?
css << expressions.map do |e|
# It's possible for there to be script nodes in Expressions even when
# we're converting to CSS in the case where we parsed the document as
# CSS originally (as in css_test.rb).
e.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.to_sass : c.to_s}.join
end.join(' and ')
css
end
# Returns the Sass/SCSS code for the media query.
#
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
# @return [String]
def to_src(options)
src = ''
src << Sass::Media._interp_to_src(modifier, options)
src << ' ' unless modifier.empty?
src << Sass::Media._interp_to_src(type, options)
src << ' and ' unless type.empty? || expressions.empty?
src << expressions.map do |e|
Sass::Media._interp_to_src(e, options)
end.join(' and ')
src
end
# @see \{MediaQuery#to\_a}
def to_a
res = []
res += modifier
res << ' ' unless modifier.empty?
res += type
res << ' and ' unless type.empty? || expressions.empty?
res += Sass::Util.intersperse(expressions, ' and ').flatten
res
end
# Returns a deep copy of this query and all its children.
#
# @return [Query]
def deep_copy
Query.new(
modifier.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c},
type.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c},
expressions.map {|e| e.map {|c| c.is_a?(Sass::Script::Tree::Node) ? c.deep_copy : c}})
end
end
# Converts an interpolation array to source.
#
# @param interp [Array<String, Sass::Script::Tree::Node>] The interpolation array to convert.
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
# @return [String]
def self._interp_to_src(interp, options)
interp.map {|r| r.is_a?(String) ? r : r.to_sass(options)}.join
end
end
|