less 1.2.21 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -3
- data/.gitmodules +6 -0
- data/Gemfile +3 -0
- data/README.md +39 -46
- data/Rakefile +5 -50
- data/bin/lessc +1 -100
- data/less.gemspec +21 -125
- data/lib/less.rb +11 -30
- data/{LICENSE → lib/less/js/LICENSE} +1 -1
- data/lib/less/js/Makefile +56 -0
- data/lib/less/js/README.md +20 -0
- data/lib/less/js/benchmark/benchmark.less +3979 -0
- data/lib/less/js/benchmark/less-benchmark.js +49 -0
- data/lib/less/js/bin/lessc +105 -0
- data/lib/less/js/build/ecma-5.js +120 -0
- data/lib/less/js/build/header.js +7 -0
- data/lib/less/js/build/require.js +7 -0
- data/lib/less/js/dist/less-1.0.44.js +2655 -0
- data/lib/less/js/dist/less-1.1.0.js +2695 -0
- data/lib/less/js/dist/less-1.1.0.min.js +16 -0
- data/lib/less/js/dist/less-1.1.1.js +2710 -0
- data/lib/less/js/dist/less-1.1.1.min.js +16 -0
- data/lib/less/js/dist/less-1.1.2.js +2712 -0
- data/lib/less/js/dist/less-1.1.2.min.js +16 -0
- data/lib/less/js/dist/less-1.1.3.js +2721 -0
- data/lib/less/js/dist/less-1.1.3.min.js +16 -0
- data/lib/less/js/lib/less/browser.js +369 -0
- data/lib/less/js/lib/less/functions.js +174 -0
- data/lib/less/js/lib/less/index.js +137 -0
- data/lib/less/js/lib/less/parser.js +1098 -0
- data/lib/less/js/lib/less/tree.js +13 -0
- data/lib/less/js/lib/less/tree/alpha.js +17 -0
- data/lib/less/js/lib/less/tree/anonymous.js +13 -0
- data/lib/less/js/lib/less/tree/call.js +45 -0
- data/lib/less/js/lib/less/tree/color.js +98 -0
- data/lib/less/js/lib/less/tree/comment.js +14 -0
- data/lib/less/js/lib/less/tree/dimension.js +34 -0
- data/lib/less/js/lib/less/tree/directive.js +33 -0
- data/lib/less/js/lib/less/tree/element.js +32 -0
- data/lib/less/js/lib/less/tree/expression.js +23 -0
- data/lib/less/js/lib/less/tree/import.js +77 -0
- data/lib/less/js/lib/less/tree/javascript.js +51 -0
- data/lib/less/js/lib/less/tree/keyword.js +9 -0
- data/lib/less/js/lib/less/tree/mixin.js +106 -0
- data/lib/less/js/lib/less/tree/operation.js +32 -0
- data/lib/less/js/lib/less/tree/quoted.js +29 -0
- data/lib/less/js/lib/less/tree/rule.js +38 -0
- data/lib/less/js/lib/less/tree/ruleset.js +179 -0
- data/lib/less/js/lib/less/tree/selector.js +28 -0
- data/lib/less/js/lib/less/tree/url.js +25 -0
- data/lib/less/js/lib/less/tree/value.js +24 -0
- data/lib/less/js/lib/less/tree/variable.js +24 -0
- data/lib/less/js/package.json +13 -0
- data/lib/less/js/test/css/colors.css +42 -0
- data/lib/less/js/test/css/comments.css +52 -0
- data/lib/less/js/test/css/css-3.css +42 -0
- data/lib/less/js/test/css/css-escapes.css +20 -0
- data/lib/less/js/test/css/css.css +82 -0
- data/lib/less/js/test/css/functions.css +30 -0
- data/{spec → lib/less/js/test}/css/import.css +4 -2
- data/lib/less/js/test/css/javascript.css +22 -0
- data/lib/less/js/test/css/lazy-eval.css +3 -0
- data/lib/less/js/test/css/media.css +21 -0
- data/lib/less/js/test/css/mixins-args.css +61 -0
- data/lib/less/js/test/css/mixins-closure.css +9 -0
- data/lib/less/js/test/css/mixins-nested.css +14 -0
- data/lib/less/js/test/css/mixins-pattern.css +49 -0
- data/lib/less/js/test/css/mixins.css +50 -0
- data/{spec → lib/less/js/test}/css/operations.css +20 -2
- data/{spec → lib/less/js/test}/css/parens.css +0 -0
- data/lib/less/js/test/css/rulesets.css +29 -0
- data/{spec → lib/less/js/test}/css/scope.css +6 -2
- data/lib/less/js/test/css/selectors.css +32 -0
- data/lib/less/js/test/css/strings.css +38 -0
- data/lib/less/js/test/css/variables.css +24 -0
- data/lib/less/js/test/css/whitespace.css +36 -0
- data/lib/less/js/test/less-test.js +75 -0
- data/{spec → lib/less/js/test}/less/colors.less +13 -2
- data/{spec → lib/less/js/test}/less/comments.less +19 -2
- data/{spec → lib/less/js/test}/less/css-3.less +4 -1
- data/lib/less/js/test/less/css-escapes.less +28 -0
- data/{spec → lib/less/js/test}/less/css.less +10 -18
- data/lib/less/js/test/less/functions.less +35 -0
- data/{spec → lib/less/js/test}/less/import.less +1 -1
- data/{spec → lib/less/js/test}/less/import/import-test-a.less +0 -0
- data/{spec → lib/less/js/test}/less/import/import-test-b.less +0 -0
- data/{spec → lib/less/js/test}/less/import/import-test-c.less +0 -0
- data/{spec → lib/less/js/test}/less/import/import-test-d.css +0 -0
- data/lib/less/js/test/less/javascript.less +27 -0
- data/{spec → lib/less/js/test}/less/lazy-eval.less +0 -0
- data/lib/less/js/test/less/media.less +25 -0
- data/lib/less/js/test/less/mixins-args.less +118 -0
- data/lib/less/js/test/less/mixins-closure.less +26 -0
- data/lib/less/js/test/less/mixins-nested.less +22 -0
- data/lib/less/js/test/less/mixins-pattern.less +96 -0
- data/{spec → lib/less/js/test}/less/mixins.less +8 -4
- data/{spec → lib/less/js/test}/less/operations.less +19 -0
- data/{spec → lib/less/js/test}/less/parens.less +0 -0
- data/{spec → lib/less/js/test}/less/rulesets.less +2 -2
- data/{spec → lib/less/js/test}/less/scope.less +1 -1
- data/{spec → lib/less/js/test}/less/selectors.less +1 -1
- data/lib/less/js/test/less/strings.less +49 -0
- data/lib/less/js/test/less/variables.less +50 -0
- data/{spec → lib/less/js/test}/less/whitespace.less +3 -0
- data/lib/less/loader.rb +67 -0
- data/lib/less/parser.rb +46 -0
- data/lib/less/version.rb +3 -0
- data/spec/less/one/one.less +1 -0
- data/spec/less/parser_spec.rb +30 -0
- data/spec/less/two/two.less +1 -0
- data/spec/spec_helper.rb +2 -7
- metadata +156 -106
- data/CHANGELOG +0 -62
- data/VERSION +0 -1
- data/lib/less/command.rb +0 -110
- data/lib/less/engine.rb +0 -52
- data/lib/less/engine/grammar/common.tt +0 -29
- data/lib/less/engine/grammar/entity.tt +0 -144
- data/lib/less/engine/grammar/less.tt +0 -341
- data/lib/less/engine/nodes.rb +0 -9
- data/lib/less/engine/nodes/element.rb +0 -281
- data/lib/less/engine/nodes/entity.rb +0 -79
- data/lib/less/engine/nodes/function.rb +0 -93
- data/lib/less/engine/nodes/literal.rb +0 -171
- data/lib/less/engine/nodes/property.rb +0 -232
- data/lib/less/engine/nodes/ruleset.rb +0 -12
- data/lib/less/engine/nodes/selector.rb +0 -44
- data/lib/less/ext.rb +0 -60
- data/spec/command_spec.rb +0 -102
- data/spec/css/accessors.css +0 -18
- data/spec/css/big.css +0 -3768
- data/spec/css/colors.css +0 -14
- data/spec/css/comments.css +0 -9
- data/spec/css/css-3.css +0 -21
- data/spec/css/css.css +0 -50
- data/spec/css/dash-prefix.css +0 -12
- data/spec/css/functions.css +0 -6
- data/spec/css/import-with-extra-paths.css +0 -8
- data/spec/css/import-with-partial-in-extra-path.css +0 -6
- data/spec/css/lazy-eval.css +0 -1
- data/spec/css/mixins-args.css +0 -32
- data/spec/css/mixins.css +0 -28
- data/spec/css/rulesets.css +0 -17
- data/spec/css/selectors.css +0 -13
- data/spec/css/strings.css +0 -12
- data/spec/css/variables.css +0 -8
- data/spec/css/whitespace.css +0 -7
- data/spec/engine_spec.rb +0 -127
- data/spec/less/accessors.less +0 -20
- data/spec/less/big.less +0 -1264
- data/spec/less/dash-prefix.less +0 -21
- data/spec/less/exceptions/mixed-units-error.less +0 -3
- data/spec/less/exceptions/name-error-1.0.less +0 -3
- data/spec/less/exceptions/syntax-error-1.0.less +0 -3
- data/spec/less/extra_import_path/extra.less +0 -1
- data/spec/less/extra_import_path/import/import-test-a.css +0 -1
- data/spec/less/extra_import_path/import/import-test-a.less +0 -4
- data/spec/less/functions.less +0 -6
- data/spec/less/hidden.less +0 -25
- data/spec/less/import-with-extra-paths.less +0 -4
- data/spec/less/literal-css.less +0 -11
- data/spec/less/mixins-args.less +0 -59
- data/spec/less/strings.less +0 -14
- data/spec/less/variables.less +0 -29
- data/spec/spec.css +0 -50
data/lib/less/engine/nodes.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)
|
2
|
-
|
3
|
-
require 'engine/nodes/entity'
|
4
|
-
require 'engine/nodes/function'
|
5
|
-
require 'engine/nodes/ruleset'
|
6
|
-
require 'engine/nodes/element'
|
7
|
-
require 'engine/nodes/property'
|
8
|
-
require 'engine/nodes/literal'
|
9
|
-
require 'engine/nodes/selector'
|
@@ -1,281 +0,0 @@
|
|
1
|
-
module Less
|
2
|
-
module Node
|
3
|
-
#
|
4
|
-
# Element
|
5
|
-
#
|
6
|
-
# div {...}
|
7
|
-
#
|
8
|
-
# TODO: Look into making @rules its own hash-like class
|
9
|
-
# TODO: Look into whether selector should be child by default
|
10
|
-
#
|
11
|
-
class Element
|
12
|
-
include Enumerable
|
13
|
-
include Entity
|
14
|
-
|
15
|
-
attr_accessor :rules, :selector, :file,
|
16
|
-
:set, :imported, :name
|
17
|
-
|
18
|
-
def initialize name = "", selector = ''
|
19
|
-
@name = name
|
20
|
-
@set, @imported = [], []
|
21
|
-
@rules = [] # Holds all the nodes under this element's hierarchy
|
22
|
-
@selector = Selector[selector.strip].new # descendant | child | adjacent
|
23
|
-
end
|
24
|
-
|
25
|
-
def class?; name =~ /^\./ end
|
26
|
-
def id?; name =~ /^#/ end
|
27
|
-
def universal?; name == '*' end
|
28
|
-
|
29
|
-
def tag?
|
30
|
-
not id? || class? || universal?
|
31
|
-
end
|
32
|
-
|
33
|
-
# Top-most node?
|
34
|
-
def root?
|
35
|
-
parent.nil?
|
36
|
-
end
|
37
|
-
|
38
|
-
def empty?
|
39
|
-
@rules.empty?
|
40
|
-
end
|
41
|
-
|
42
|
-
def leaf?
|
43
|
-
elements.empty?
|
44
|
-
end
|
45
|
-
|
46
|
-
# Group similar rulesets together
|
47
|
-
# This is horrible, horrible code,
|
48
|
-
# but it'll have to do until I find
|
49
|
-
# a proper way to do it.
|
50
|
-
def group
|
51
|
-
elements = self.elements.reject {|e| e.is_a?(Mixin::Def) }
|
52
|
-
return self unless elements.size > 1
|
53
|
-
|
54
|
-
stack, result, matched = elements.dup, [], false
|
55
|
-
|
56
|
-
elements.each do
|
57
|
-
e = stack.first
|
58
|
-
result << e unless matched
|
59
|
-
|
60
|
-
matched = stack[1..-1].each do |ee|
|
61
|
-
if e.equiv? ee and e.elements.size == 0
|
62
|
-
self[e].set << ee
|
63
|
-
stack.shift
|
64
|
-
else
|
65
|
-
stack.shift
|
66
|
-
break false
|
67
|
-
end
|
68
|
-
end if stack.size > 1
|
69
|
-
end
|
70
|
-
@rules -= (elements - result)
|
71
|
-
self
|
72
|
-
end
|
73
|
-
|
74
|
-
#
|
75
|
-
# Accessors for the different nodes in @rules
|
76
|
-
#
|
77
|
-
def identifiers; @rules.select {|r| r.kind_of? Property } end
|
78
|
-
def properties; @rules.select {|r| r.instance_of? Property } end
|
79
|
-
def variables; @rules.select {|r| r.instance_of? Variable } end
|
80
|
-
def elements; @rules.select {|r| r.kind_of? Element } end
|
81
|
-
def mixins; @rules.select {|r| r.instance_of? Mixin::Call} end
|
82
|
-
def parameters; [] end
|
83
|
-
|
84
|
-
# Select a child element
|
85
|
-
# TODO: Implement full selector syntax & merge with descend()
|
86
|
-
def [] key
|
87
|
-
case key
|
88
|
-
when Entity
|
89
|
-
@rules.find {|i| i.eql? key }
|
90
|
-
when String
|
91
|
-
@rules.find {|i| i.to_s == key }
|
92
|
-
else raise ArgumentError
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def == other
|
97
|
-
name == other.name
|
98
|
-
end
|
99
|
-
|
100
|
-
def eql? other
|
101
|
-
super and self.equiv? other
|
102
|
-
end
|
103
|
-
|
104
|
-
def equiv? other
|
105
|
-
rules.size == other.rules.size and
|
106
|
-
!rules.zip(other.rules).map do |a, b|
|
107
|
-
a.to_css == b.to_css
|
108
|
-
end.include?(false)
|
109
|
-
end
|
110
|
-
|
111
|
-
# Same as above, except with a specific selector
|
112
|
-
# TODO: clean this up or implement it differently
|
113
|
-
def descend selector, element
|
114
|
-
if selector.is_a? Child
|
115
|
-
s = self[element.name].selector
|
116
|
-
self[element.name] if s.is_a? Child or s.is_a? Descendant
|
117
|
-
elsif selector.is_a? Descendant
|
118
|
-
self[element.name]
|
119
|
-
else
|
120
|
-
self[element.name] if self[element.name].selector.class == selector.class
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
#
|
125
|
-
# Add an arbitrary node to this element
|
126
|
-
#
|
127
|
-
def << obj
|
128
|
-
if obj.kind_of? Node::Entity
|
129
|
-
obj.parent = self
|
130
|
-
@rules << obj
|
131
|
-
else
|
132
|
-
raise ArgumentError, "argument can't be a #{obj.class}"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def last; elements.last end
|
137
|
-
def first; elements.first end
|
138
|
-
def to_s; root?? '*' : name end
|
139
|
-
|
140
|
-
#
|
141
|
-
# Entry point for the css conversion
|
142
|
-
#
|
143
|
-
def to_css path = [], env = nil
|
144
|
-
path << @selector.to_css << name unless root?
|
145
|
-
|
146
|
-
# puts "to_css env: #{env ? env.variables : "nil"}"
|
147
|
-
content = @rules.select do |r|
|
148
|
-
r.is_a?(Mixin::Call) || r.instance_of?(Property)
|
149
|
-
end.map do |i|
|
150
|
-
' ' * 2 + i.to_css(env)
|
151
|
-
end.compact.reject(&:empty?) * "\n"
|
152
|
-
|
153
|
-
content = content.include?("\n") ? "\n#{content}\n" : " #{content.strip} "
|
154
|
-
|
155
|
-
ruleset = if is_a?(Mixin::Def)
|
156
|
-
content.strip
|
157
|
-
else
|
158
|
-
!content.strip.empty??
|
159
|
-
"#{[path.reject(&:empty?).join.strip,
|
160
|
-
*@set.map(&:name)].uniq * ', '} {#{content}}\n" : ""
|
161
|
-
end
|
162
|
-
|
163
|
-
ruleset + elements.reject {|e| e.is_a?(Mixin::Def) }.map do |i|
|
164
|
-
i.to_css(path, env)
|
165
|
-
end.reject(&:empty?).join
|
166
|
-
|
167
|
-
ensure
|
168
|
-
2.times { path.pop }
|
169
|
-
end
|
170
|
-
|
171
|
-
#
|
172
|
-
# Find the nearest node in the hierarchy or raise a NameError
|
173
|
-
#
|
174
|
-
def nearest ident, type = nil
|
175
|
-
ary = type || ident =~ /^[.#]/ ? :elements : :variables
|
176
|
-
path.map do |node|
|
177
|
-
node.send(ary).find {|i| i.to_s == ident }
|
178
|
-
end.compact.first.tap do |result|
|
179
|
-
raise VariableNameError, ("#{ident} in #{self.to_s}") if result.nil? && type != :mixin
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
#
|
184
|
-
# Traverse the whole tree, returning each leaf (recursive)
|
185
|
-
#
|
186
|
-
def each path = [], &blk
|
187
|
-
elements.each do |element|
|
188
|
-
path << element
|
189
|
-
yield element, path if element.leaf?
|
190
|
-
element.each path, &blk
|
191
|
-
path.pop
|
192
|
-
end
|
193
|
-
self
|
194
|
-
end
|
195
|
-
|
196
|
-
def inspect depth = 0
|
197
|
-
indent = lambda {|i| '. ' * i }
|
198
|
-
put = lambda {|ary| ary.map {|i| indent[ depth + 1 ] + i.inspect } * "\n"}
|
199
|
-
|
200
|
-
(root?? "\n" : "") + [
|
201
|
-
indent[ depth ] + self.to_s,
|
202
|
-
put[ variables ],
|
203
|
-
put[ properties ],
|
204
|
-
put[ mixins ],
|
205
|
-
elements.map {|i| i.inspect( depth + 1 ) } * "\n"
|
206
|
-
].reject(&:empty?).join("\n") + "\n" + indent[ depth ]
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
module Mixin
|
211
|
-
class Call
|
212
|
-
include Entity
|
213
|
-
|
214
|
-
def initialize mixin, params, parent
|
215
|
-
# puts "Initializing a Mixin::Call #{mixin}"
|
216
|
-
@mixin = mixin
|
217
|
-
self.parent = parent
|
218
|
-
@params = params.each do |e|
|
219
|
-
e.parent = self.parent
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def to_css env = nil
|
224
|
-
# puts "\n\n"
|
225
|
-
# puts "call .#{@mixin.name} #{@params} <#{@params.class}>"
|
226
|
-
@mixin.call(@params.map {|e| e.evaluate(env) })
|
227
|
-
end
|
228
|
-
|
229
|
-
def inspect
|
230
|
-
"#{@mixin.to_s} (#{@params})"
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
class Def < Element
|
235
|
-
attr_accessor :params
|
236
|
-
|
237
|
-
def initialize name, params = []
|
238
|
-
super name
|
239
|
-
@params = params.each do |param|
|
240
|
-
param.parent = self
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
def call args = []
|
245
|
-
if e = @rules.find {|r| r.is_a? Element }
|
246
|
-
raise CompileError, "#{e} in #{self.inspect}: can't nest selectors inside a dynamic mixin."
|
247
|
-
end
|
248
|
-
|
249
|
-
env = Element.new
|
250
|
-
|
251
|
-
@params.zip(args).each do |param, val|
|
252
|
-
env << (val ? Variable.new(param.to_s, Expression.new([val])) : param)
|
253
|
-
end
|
254
|
-
|
255
|
-
#b ? Node::Variable.new(a.to_s, Expression.new([b])) : a
|
256
|
-
|
257
|
-
# puts "#{self.inspect}"
|
258
|
-
# puts "env: #{env.variables} root?: #{env.root?}"
|
259
|
-
# puts "\nTOCSS"
|
260
|
-
to_css([], env)
|
261
|
-
end
|
262
|
-
|
263
|
-
def variables
|
264
|
-
params + super
|
265
|
-
end
|
266
|
-
|
267
|
-
def to_s
|
268
|
-
'.' + name
|
269
|
-
end
|
270
|
-
|
271
|
-
def inspect
|
272
|
-
".#{name}()"
|
273
|
-
end
|
274
|
-
|
275
|
-
def to_css path, env
|
276
|
-
super(path, env)
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module Less
|
2
|
-
#
|
3
|
-
# Node::Entity
|
4
|
-
#
|
5
|
-
# Everything in the tree is an Entity
|
6
|
-
#
|
7
|
-
# Mixin/Class hierarchy
|
8
|
-
#
|
9
|
-
# - Entity
|
10
|
-
# - Element
|
11
|
-
# - Entity
|
12
|
-
# - Function
|
13
|
-
# - Keyword
|
14
|
-
# - Literal
|
15
|
-
# - Color
|
16
|
-
# - Number
|
17
|
-
# - String
|
18
|
-
# - FontFamily
|
19
|
-
# - Property
|
20
|
-
# - Variable
|
21
|
-
#
|
22
|
-
# TODO: Use delegate class -> @rules
|
23
|
-
#
|
24
|
-
module Node
|
25
|
-
module Entity
|
26
|
-
attr_accessor :parent
|
27
|
-
|
28
|
-
def initialize value, parent = nil
|
29
|
-
super value
|
30
|
-
@parent = parent
|
31
|
-
end
|
32
|
-
|
33
|
-
#
|
34
|
-
# Returns the path from any given node, to the root
|
35
|
-
#
|
36
|
-
# ex: ['color', 'p', '#header', 'body', '*']
|
37
|
-
#
|
38
|
-
def path node = self
|
39
|
-
path = []
|
40
|
-
while node do
|
41
|
-
path << node
|
42
|
-
node = node.parent
|
43
|
-
end
|
44
|
-
path
|
45
|
-
end
|
46
|
-
|
47
|
-
def root
|
48
|
-
path.last
|
49
|
-
end
|
50
|
-
|
51
|
-
def inspect; to_s end
|
52
|
-
def to_css; to_s end
|
53
|
-
def to_s; super end
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# An anonymous node, for all the 'other' stuff
|
58
|
-
# which doesn't need any specific functionality.
|
59
|
-
#
|
60
|
-
class Anonymous < String
|
61
|
-
include Entity
|
62
|
-
end
|
63
|
-
|
64
|
-
#
|
65
|
-
# + * - /
|
66
|
-
#
|
67
|
-
class Operator < String
|
68
|
-
def to_ruby
|
69
|
-
self
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
class Paren < String
|
74
|
-
def to_ruby
|
75
|
-
self
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
module Less
|
2
|
-
#
|
3
|
-
# Functions useable from within the style-sheet go here
|
4
|
-
#
|
5
|
-
module Functions
|
6
|
-
def rgb *rgb
|
7
|
-
rgba rgb, 1.0
|
8
|
-
end
|
9
|
-
|
10
|
-
def hsl *args
|
11
|
-
hsla *[args, 1.0].flatten
|
12
|
-
end
|
13
|
-
|
14
|
-
#
|
15
|
-
# RGBA to Node::Color
|
16
|
-
#
|
17
|
-
def rgba *rgba
|
18
|
-
Node::Color.new *rgba.flatten
|
19
|
-
end
|
20
|
-
|
21
|
-
#
|
22
|
-
# HSLA to RGBA
|
23
|
-
#
|
24
|
-
def hsla h, s, l, a = 1.0
|
25
|
-
m2 = ( l <= 0.5 ) ? l * ( s + 1 ) : l + s - l * s
|
26
|
-
m1 = l * 2 - m2;
|
27
|
-
|
28
|
-
hue = lambda do |h|
|
29
|
-
h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h)
|
30
|
-
if h * 6 < 1 then m1 + (m2 - m1) * h * 6
|
31
|
-
elsif h * 2 < 1 then m2
|
32
|
-
elsif h * 3 < 2 then m1 + (m2 - m1) * (2/3 - h) * 6
|
33
|
-
else m1
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
rgba hue[ h + 1/3 ], hue[ h ], hue[ h - 1/3 ], a
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.available
|
41
|
-
self.instance_methods.map(&:to_sym)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
module Node
|
46
|
-
#
|
47
|
-
# A CSS function, like rgb() or url()
|
48
|
-
#
|
49
|
-
# it calls functions from the Functions module
|
50
|
-
#
|
51
|
-
class Function < String
|
52
|
-
include Entity
|
53
|
-
include Functions
|
54
|
-
|
55
|
-
def initialize name, args
|
56
|
-
@args = if args.is_a? Array
|
57
|
-
args.map {|e| e.is_a?(Expression) ? e : Expression.new(e, self)}
|
58
|
-
else
|
59
|
-
[args]
|
60
|
-
end
|
61
|
-
|
62
|
-
super name
|
63
|
-
end
|
64
|
-
|
65
|
-
def to_css env = nil
|
66
|
-
self.evaluate(env).to_css
|
67
|
-
end
|
68
|
-
|
69
|
-
def nearest node
|
70
|
-
parent.nearest node
|
71
|
-
end
|
72
|
-
|
73
|
-
#
|
74
|
-
# Call the function
|
75
|
-
#
|
76
|
-
# If the function isn't found, we just print it out,
|
77
|
-
# this is the case for url(), for example,
|
78
|
-
#
|
79
|
-
def evaluate context = nil
|
80
|
-
if Functions.available.include? self.to_sym
|
81
|
-
send to_sym, *@args
|
82
|
-
else
|
83
|
-
args = @args.map { |e|
|
84
|
-
e.parent = self.parent
|
85
|
-
e = e.evaluate(context) if e.respond_to?(:evaluate)
|
86
|
-
e.to_css
|
87
|
-
} * ', '
|
88
|
-
Node::Anonymous.new("#{to_sym}(#{args})")
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|