haml 3.0.0.beta.1 → 3.0.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/README.md +7 -7
- data/REMEMBER +2 -1
- data/Rakefile +6 -4
- data/VERSION +1 -1
- data/lib/haml/exec.rb +119 -24
- data/lib/haml/filters.rb +5 -1
- data/lib/haml/helpers.rb +4 -2
- data/lib/haml/helpers/action_view_mods.rb +2 -3
- data/lib/haml/precompiler.rb +1 -0
- data/lib/sass.rb +1 -1
- data/lib/sass/css.rb +25 -6
- data/lib/sass/engine.rb +23 -7
- data/lib/sass/environment.rb +47 -1
- data/lib/sass/files.rb +9 -10
- data/lib/sass/plugin.rb +6 -27
- data/lib/sass/plugin/merb.rb +1 -0
- data/lib/sass/plugin/rails.rb +1 -0
- data/lib/sass/plugin/staleness_checker.rb +123 -0
- data/lib/sass/script/bool.rb +1 -1
- data/lib/sass/script/color.rb +1 -1
- data/lib/sass/script/css_lexer.rb +1 -4
- data/lib/sass/script/funcall.rb +2 -2
- data/lib/sass/script/functions.rb +102 -7
- data/lib/sass/script/interpolation.rb +5 -5
- data/lib/sass/script/lexer.rb +10 -8
- data/lib/sass/script/literal.rb +11 -1
- data/lib/sass/script/node.rb +10 -1
- data/lib/sass/script/number.rb +25 -10
- data/lib/sass/script/operation.rb +7 -6
- data/lib/sass/script/parser.rb +37 -28
- data/lib/sass/script/string.rb +12 -7
- data/lib/sass/script/string_interpolation.rb +70 -0
- data/lib/sass/script/unary_operation.rb +3 -3
- data/lib/sass/script/variable.rb +2 -2
- data/lib/sass/scss/css_parser.rb +1 -0
- data/lib/sass/scss/parser.rb +58 -44
- data/lib/sass/scss/rx.rb +1 -0
- data/lib/sass/tree/comment_node.rb +3 -2
- data/lib/sass/tree/debug_node.rb +1 -1
- data/lib/sass/tree/for_node.rb +1 -1
- data/lib/sass/tree/if_node.rb +1 -1
- data/lib/sass/tree/import_node.rb +3 -0
- data/lib/sass/tree/mixin_def_node.rb +3 -3
- data/lib/sass/tree/mixin_node.rb +7 -3
- data/lib/sass/tree/node.rb +8 -0
- data/lib/sass/tree/prop_node.rb +21 -16
- data/lib/sass/tree/rule_node.rb +3 -3
- data/lib/sass/tree/variable_node.rb +1 -1
- data/lib/sass/tree/warn_node.rb +41 -0
- data/lib/sass/tree/while_node.rb +1 -1
- data/test/haml/engine_test.rb +9 -0
- data/test/sass/conversion_test.rb +127 -15
- data/test/sass/css2sass_test.rb +34 -3
- data/test/sass/engine_test.rb +82 -5
- data/test/sass/functions_test.rb +31 -0
- data/test/sass/plugin_test.rb +25 -24
- data/test/sass/results/script.css +4 -4
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +43 -1
- data/test/sass/script_test.rb +3 -3
- data/test/sass/scss/css_test.rb +46 -5
- data/test/sass/scss/scss_test.rb +72 -0
- data/test/sass/templates/import.sass +1 -1
- data/test/sass/templates/warn.sass +3 -0
- data/test/sass/templates/warn_imported.sass +4 -0
- metadata +10 -3
data/lib/sass/environment.rb
CHANGED
@@ -23,7 +23,7 @@ module Sass
|
|
23
23
|
@vars = {}
|
24
24
|
@mixins = {}
|
25
25
|
@parent = parent
|
26
|
-
|
26
|
+
@stack = [] unless parent
|
27
27
|
set_var("important", Script::String.new("!important")) unless @parent
|
28
28
|
end
|
29
29
|
|
@@ -35,6 +35,52 @@ module Sass
|
|
35
35
|
@options || (parent && parent.options) || {}
|
36
36
|
end
|
37
37
|
|
38
|
+
# Push a new stack frame onto the mixin/include stack.
|
39
|
+
#
|
40
|
+
# @param frame_info [{Symbol => Object}]
|
41
|
+
# Frame information has the following keys:
|
42
|
+
#
|
43
|
+
# `:filename`
|
44
|
+
# : The name of the file in which the lexical scope changed.
|
45
|
+
#
|
46
|
+
# `:mixin`
|
47
|
+
# : The name of the mixin in which the lexical scope changed,
|
48
|
+
# or `nil` if it wasn't within in a mixin.
|
49
|
+
#
|
50
|
+
# `:line`
|
51
|
+
# : The line of the file on which the lexical scope changed. Never nil.
|
52
|
+
def push_frame(frame_info)
|
53
|
+
if stack.last && stack.last[:prepared]
|
54
|
+
stack.last.delete(:prepared)
|
55
|
+
stack.last.merge!(frame_info)
|
56
|
+
else
|
57
|
+
stack.push(frame_info)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Like \{#push\_frame}, but next time a stack frame is pushed,
|
62
|
+
# it will be merged with this frame.
|
63
|
+
#
|
64
|
+
# @param frame_info [{Symbol => Object}] Same as for \{#push\_frame}.
|
65
|
+
def prepare_frame(frame_info)
|
66
|
+
push_frame(frame_info.merge(:prepared => true))
|
67
|
+
end
|
68
|
+
|
69
|
+
# Pop a stack frame from the mixin/include stack.
|
70
|
+
def pop_frame
|
71
|
+
stack.pop if stack.last[:prepared]
|
72
|
+
stack.pop
|
73
|
+
end
|
74
|
+
|
75
|
+
# A list of stack frames in the mixin/include stack.
|
76
|
+
# The last element in the list is the most deeply-nested frame.
|
77
|
+
#
|
78
|
+
# @return [Array<{Symbol => Object}>] The stack frames,
|
79
|
+
# of the form passed to \{#push\_frame}.
|
80
|
+
def stack
|
81
|
+
@stack ||= @parent.stack
|
82
|
+
end
|
83
|
+
|
38
84
|
class << self
|
39
85
|
private
|
40
86
|
|
data/lib/sass/files.rb
CHANGED
@@ -76,8 +76,11 @@ module Sass
|
|
76
76
|
return filename
|
77
77
|
end
|
78
78
|
|
79
|
-
new_filename
|
80
|
-
|
79
|
+
new_filename = nil
|
80
|
+
load_paths.each do |load_path|
|
81
|
+
new_filename ||= find_full_path("#{filename}.sass", load_path) unless was_scss
|
82
|
+
new_filename ||= find_full_path("#{filename}.scss", load_path) unless was_sass
|
83
|
+
end
|
81
84
|
|
82
85
|
return new_filename if new_filename
|
83
86
|
unless was_sass || was_scss
|
@@ -134,7 +137,7 @@ END
|
|
134
137
|
end
|
135
138
|
end
|
136
139
|
|
137
|
-
def find_full_path(filename,
|
140
|
+
def find_full_path(filename, load_path)
|
138
141
|
partial_name = File.join(File.dirname(filename), "_#{File.basename(filename)}")
|
139
142
|
|
140
143
|
if Pathname.new(filename).absolute?
|
@@ -144,13 +147,9 @@ END
|
|
144
147
|
return nil
|
145
148
|
end
|
146
149
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
if File.readable?(full_path)
|
151
|
-
return full_path
|
152
|
-
end
|
153
|
-
end
|
150
|
+
[partial_name, filename].each do |name|
|
151
|
+
full_path = File.join(load_path, name)
|
152
|
+
return full_path if File.readable?(full_path)
|
154
153
|
end
|
155
154
|
nil
|
156
155
|
end
|
data/lib/sass/plugin.rb
CHANGED
@@ -3,6 +3,7 @@ require 'rbconfig'
|
|
3
3
|
|
4
4
|
require 'sass'
|
5
5
|
require 'sass/callbacks'
|
6
|
+
require 'sass/plugin/staleness_checker'
|
6
7
|
|
7
8
|
module Sass
|
8
9
|
# This module handles the compilation of Sass/SCSS files.
|
@@ -211,6 +212,8 @@ module Sass
|
|
211
212
|
individual_files.each {|t, c| update_stylesheet(t, c)}
|
212
213
|
|
213
214
|
@checked_for_updates = true
|
215
|
+
staleness_checker = StalenessChecker.new
|
216
|
+
|
214
217
|
template_locations.zip(css_locations).each do |template_location, css_location|
|
215
218
|
|
216
219
|
Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).each do |file|
|
@@ -219,7 +222,7 @@ module Sass
|
|
219
222
|
css = css_filename(name, css_location)
|
220
223
|
|
221
224
|
next if forbid_update?(name)
|
222
|
-
if options[:always_update] || stylesheet_needs_update?(css, file)
|
225
|
+
if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
|
223
226
|
update_stylesheet file, css
|
224
227
|
else
|
225
228
|
run_not_updating_stylesheet file, css
|
@@ -374,33 +377,9 @@ module Sass
|
|
374
377
|
name.sub(/^.*\//, '')[0] == ?_
|
375
378
|
end
|
376
379
|
|
380
|
+
# Compass expects this to exist
|
377
381
|
def stylesheet_needs_update?(css_file, template_file)
|
378
|
-
|
379
|
-
|
380
|
-
css_mtime = File.mtime(css_file)
|
381
|
-
File.mtime(template_file) > css_mtime ||
|
382
|
-
dependencies(template_file).any?(&dependency_updated?(css_mtime))
|
383
|
-
end
|
384
|
-
|
385
|
-
def dependency_updated?(css_mtime)
|
386
|
-
lambda do |dep|
|
387
|
-
begin
|
388
|
-
File.mtime(dep) > css_mtime ||
|
389
|
-
dependencies(dep).any?(&dependency_updated?(css_mtime))
|
390
|
-
rescue Sass::SyntaxError
|
391
|
-
# If there's an error finding depenencies, default to recompiling.
|
392
|
-
true
|
393
|
-
end
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
def dependencies(filename)
|
398
|
-
Files.tree_for(filename, engine_options).select {|n| n.is_a?(Tree::ImportNode)}.map do |n|
|
399
|
-
next if n.full_filename =~ /\.css$/
|
400
|
-
n.full_filename
|
401
|
-
end.compact
|
402
|
-
rescue Sass::SyntaxError => e
|
403
|
-
[] # If the file has an error, we assume it has no dependencies
|
382
|
+
StalenessChecker.stylesheet_needs_update?(css_file, template_file)
|
404
383
|
end
|
405
384
|
end
|
406
385
|
end
|
data/lib/sass/plugin/merb.rb
CHANGED
@@ -14,6 +14,7 @@ unless defined?(Sass::MERB_LOADED)
|
|
14
14
|
:css_location => root + '/public/stylesheets',
|
15
15
|
:cache_location => root + '/tmp/sass-cache',
|
16
16
|
:always_check => env != "production",
|
17
|
+
:quiet => env != "production",
|
17
18
|
:full_exception => env != "production")
|
18
19
|
config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {}
|
19
20
|
|
data/lib/sass/plugin/rails.rb
CHANGED
@@ -5,6 +5,7 @@ unless defined?(Sass::RAILS_LOADED)
|
|
5
5
|
:css_location => Haml::Util.rails_root + '/public/stylesheets',
|
6
6
|
:cache_location => Haml::Util.rails_root + '/tmp/sass-cache',
|
7
7
|
:always_check => Haml::Util.rails_env != "production",
|
8
|
+
:quiet => Haml::Util.rails_env != "production",
|
8
9
|
:full_exception => Haml::Util.rails_env != "production")
|
9
10
|
|
10
11
|
if defined?(Rails.configuration) && defined?(Rails.configuration.middleware)
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Sass
|
2
|
+
module Plugin
|
3
|
+
# The class handles `.s[ca]ss` file staleness checks via their mtime timestamps.
|
4
|
+
#
|
5
|
+
# To speed things up two level of caches are employed:
|
6
|
+
#
|
7
|
+
# * A class-level dependency cache which stores @import paths for each file.
|
8
|
+
# This is a long-lived cache that is reused by every StalenessChecker instance.
|
9
|
+
# * Two short-lived instance-level caches, one for file mtimes
|
10
|
+
# and one for whether a file is stale during this particular run.
|
11
|
+
# These are only used by a single StalenessChecker instance.
|
12
|
+
#
|
13
|
+
# Usage:
|
14
|
+
#
|
15
|
+
# * For a one-off staleness check of a single `.s[ca]ss` file,
|
16
|
+
# the class-level {stylesheet_needs_update?} method
|
17
|
+
# should be used.
|
18
|
+
# * For a series of staleness checks (e.g. checking all files for staleness)
|
19
|
+
# a StalenessChecker instance should be created,
|
20
|
+
# and the instance-level \{#stylesheet\_needs\_update?} method should be used.
|
21
|
+
# the caches should make the whole process significantly faster.
|
22
|
+
# *WARNING*: It is important not to retain the instance for too long,
|
23
|
+
# as its instance-level caches are never explicitly expired.
|
24
|
+
class StalenessChecker
|
25
|
+
@dependencies_cache = {}
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# @private
|
29
|
+
attr_accessor :dependencies_cache
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates a new StalenessChecker
|
33
|
+
# for checking the staleness of several stylesheets at once.
|
34
|
+
def initialize
|
35
|
+
@dependencies = self.class.dependencies_cache
|
36
|
+
|
37
|
+
# Entries in the following instance-level caches are never explicitly expired.
|
38
|
+
# Instead they are supposed to automaticaly go out of scope when a series of staleness checks
|
39
|
+
# (this instance of StalenessChecker was created for) is finished.
|
40
|
+
@mtimes, @dependencies_stale = {}, {}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns whether or not a given CSS file is out of date
|
44
|
+
# and needs to be regenerated.
|
45
|
+
#
|
46
|
+
# @param css_file [String] The location of the CSS file to check.
|
47
|
+
# @param template_file [String] The location of the Sass or SCSS template
|
48
|
+
# that is compiled to `css_file`.
|
49
|
+
def stylesheet_needs_update?(css_file, template_file)
|
50
|
+
template_file = File.expand_path(template_file)
|
51
|
+
|
52
|
+
unless File.exists?(css_file) && File.exists?(template_file)
|
53
|
+
@dependencies.delete(template_file)
|
54
|
+
true
|
55
|
+
else
|
56
|
+
css_mtime = mtime(css_file)
|
57
|
+
mtime(template_file) > css_mtime || dependencies_stale?(template_file, css_mtime)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns whether or not a given CSS file is out of date
|
62
|
+
# and needs to be regenerated.
|
63
|
+
#
|
64
|
+
# The distinction between this method and the instance-level \{#stylesheet\_needs\_update?}
|
65
|
+
# is that the instance method preserves mtime and stale-dependency caches,
|
66
|
+
# so it's better to use when checking multiple stylesheets at once.
|
67
|
+
#
|
68
|
+
# @param css_file [String] The location of the CSS file to check.
|
69
|
+
# @param template_file [String] The location of the Sass or SCSS template
|
70
|
+
# that is compiled to `css_file`.
|
71
|
+
def self.stylesheet_needs_update?(css_file, template_file)
|
72
|
+
new.stylesheet_needs_update?(css_file, template_file)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def dependencies_stale?(template_file, css_mtime)
|
78
|
+
timestamps = @dependencies_stale[template_file] ||= {}
|
79
|
+
timestamps.each_pair do |checked_css_mtime, is_stale|
|
80
|
+
if checked_css_mtime <= css_mtime && !is_stale
|
81
|
+
return false
|
82
|
+
elsif checked_css_mtime > css_mtime && is_stale
|
83
|
+
return true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
timestamps[css_mtime] = dependencies(template_file).any?(&dependency_updated?(css_mtime))
|
87
|
+
end
|
88
|
+
|
89
|
+
def mtime(filename)
|
90
|
+
@mtimes[filename] ||= File.mtime(filename)
|
91
|
+
end
|
92
|
+
|
93
|
+
def dependencies(filename)
|
94
|
+
stored_mtime, dependencies = @dependencies[filename]
|
95
|
+
|
96
|
+
if !stored_mtime || stored_mtime < mtime(filename)
|
97
|
+
@dependencies[filename] = [mtime(filename), dependencies = compute_dependencies(filename)]
|
98
|
+
end
|
99
|
+
|
100
|
+
dependencies
|
101
|
+
end
|
102
|
+
|
103
|
+
def dependency_updated?(css_mtime)
|
104
|
+
lambda do |dep|
|
105
|
+
begin
|
106
|
+
mtime(dep) > css_mtime || dependencies_stale?(dep, css_mtime)
|
107
|
+
rescue Sass::SyntaxError
|
108
|
+
# If there's an error finding depenencies, default to recompiling.
|
109
|
+
true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def compute_dependencies(filename)
|
115
|
+
Files.tree_for(filename, Plugin.engine_options).grep(Tree::ImportNode) do |n|
|
116
|
+
File.expand_path(n.full_filename) unless n.full_filename =~ /\.css$/
|
117
|
+
end.compact
|
118
|
+
rescue Sass::SyntaxError => e
|
119
|
+
[] # If the file has an error, we assume it has no dependencies
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/sass/script/bool.rb
CHANGED
data/lib/sass/script/color.rb
CHANGED
@@ -375,7 +375,7 @@ END
|
|
375
375
|
# but if the color has a name that's used instead.
|
376
376
|
#
|
377
377
|
# @return [String] The string representation
|
378
|
-
def to_s
|
378
|
+
def to_s(opts = {})
|
379
379
|
return rgba_str if alpha?
|
380
380
|
return smallest if options[:style] == :compressed
|
381
381
|
return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb]
|
@@ -7,10 +7,7 @@ module Sass
|
|
7
7
|
|
8
8
|
def string(*args)
|
9
9
|
return unless scan(STRING)
|
10
|
-
|
11
|
-
gsub(/\\([^0-9a-f])/, '\1').
|
12
|
-
gsub(/\\([0-9a-f]{1,4})/, "\\\\\\1")
|
13
|
-
[:string, Script::String.new(str, :string)]
|
10
|
+
[:string, Script::String.new((@scanner[1] || @scanner[2]).gsub(/\\(['"])/, '\1'), :string)]
|
14
11
|
end
|
15
12
|
|
16
13
|
def important
|
data/lib/sass/script/funcall.rb
CHANGED
@@ -31,8 +31,8 @@ module Sass
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# @see Node#to_sass
|
34
|
-
def to_sass
|
35
|
-
"#{name}(#{args.map {|a| a.to_sass}.join(', ')})"
|
34
|
+
def to_sass(opts = {})
|
35
|
+
"#{dasherize(name, opts)}(#{args.map {|a| a.to_sass(opts)}.join(', ')})"
|
36
36
|
end
|
37
37
|
|
38
38
|
# Returns the arguments to the function.
|
@@ -105,6 +105,20 @@ module Sass::Script
|
|
105
105
|
# \{#abs}
|
106
106
|
# : Returns the absolute value of a number.
|
107
107
|
#
|
108
|
+
# ## Introspection Functions
|
109
|
+
#
|
110
|
+
# \{#type_of}
|
111
|
+
# : Returns the type of a value.
|
112
|
+
#
|
113
|
+
# \{#unit}
|
114
|
+
# : Returns the units associated with a number.
|
115
|
+
#
|
116
|
+
# \{#unitless}
|
117
|
+
# : Returns whether a number has units or not.
|
118
|
+
#
|
119
|
+
# \{#comparable}
|
120
|
+
# : Returns whether two numbers can be added or compared.
|
121
|
+
#
|
108
122
|
# These functions are described in more detail below.
|
109
123
|
#
|
110
124
|
# ## Adding Custom Functions
|
@@ -388,17 +402,38 @@ module Sass::Script
|
|
388
402
|
Sass::Script::Number.new(color.lightness, ["%"])
|
389
403
|
end
|
390
404
|
|
405
|
+
# Returns the alpha component (opacity) of a color.
|
406
|
+
# This is 1 unless otherwise specified.
|
407
|
+
#
|
408
|
+
# This function also supports the proprietary Microsoft
|
409
|
+
# `alpha(opacity=20)` syntax.
|
410
|
+
#
|
411
|
+
# @overload def alpha(color)
|
412
|
+
# @param color [Color]
|
413
|
+
# @return [Number]
|
414
|
+
# @raise [ArgumentError] If `color` isn't a color
|
415
|
+
def alpha(*args)
|
416
|
+
if args.all? do |a|
|
417
|
+
a.is_a?(Sass::Script::String) && a.type == :identifier &&
|
418
|
+
a.value =~ /^[a-zA-Z]+\s*=/
|
419
|
+
end
|
420
|
+
# Support the proprietary MS alpha() function
|
421
|
+
return Sass::Script::String.new("alpha(#{args.map {|a| a.to_s}.join(", ")})")
|
422
|
+
end
|
423
|
+
|
424
|
+
opacity(*args)
|
425
|
+
end
|
426
|
+
|
391
427
|
# Returns the alpha component (opacity) of a color.
|
392
428
|
# This is 1 unless otherwise specified.
|
393
429
|
#
|
394
430
|
# @param color [Color]
|
395
431
|
# @return [Number]
|
396
432
|
# @raise [ArgumentError] If `color` isn't a color
|
397
|
-
def
|
433
|
+
def opacity(color)
|
398
434
|
assert_type color, :Color
|
399
435
|
Sass::Script::Number.new(color.alpha)
|
400
436
|
end
|
401
|
-
alias_method :opacity, :alpha
|
402
437
|
|
403
438
|
# Makes a color more opaque.
|
404
439
|
# Takes a color and an amount between 0 and 1,
|
@@ -648,6 +683,71 @@ module Sass::Script
|
|
648
683
|
Sass::Script::String.new(str.value, :string)
|
649
684
|
end
|
650
685
|
|
686
|
+
# Inspects the type of the argument, returning it as an unquoted string.
|
687
|
+
# For example:
|
688
|
+
#
|
689
|
+
# type-of(100px) => number
|
690
|
+
# type-of(asdf) => string
|
691
|
+
# type-of("asdf") => string
|
692
|
+
# type-of(true) => bool
|
693
|
+
# type-of(#fff) => color
|
694
|
+
# type-of(blue) => color
|
695
|
+
#
|
696
|
+
# @param obj [Literal] The object to inspect
|
697
|
+
# @return [String] The unquoted string name of the literal's type
|
698
|
+
def type_of(obj)
|
699
|
+
Sass::Script::String.new(obj.class.name.gsub(/Sass::Script::/,'').downcase)
|
700
|
+
end
|
701
|
+
|
702
|
+
# Inspects the unit of the number, returning it as a quoted string.
|
703
|
+
# Complex units are sorted in alphabetical order by numerator and denominator.
|
704
|
+
# For example:
|
705
|
+
#
|
706
|
+
# unit(100) => ""
|
707
|
+
# unit(100px) => "px"
|
708
|
+
# unit(3em) => "em"
|
709
|
+
# unit(10px * 5em) => "em*px"
|
710
|
+
# unit(10px * 5em / 30cm / 1rem) => "em*px/cm*rem"
|
711
|
+
#
|
712
|
+
# @param number [Literal] The number to inspect
|
713
|
+
# @return [String] The unit(s) of the number
|
714
|
+
# @raise [ArgumentError] if `number` isn't a number
|
715
|
+
def unit(number)
|
716
|
+
assert_type number, :Number
|
717
|
+
Sass::Script::String.new(number.unit_str, :string)
|
718
|
+
end
|
719
|
+
|
720
|
+
# Inspects the unit of the number, returning a boolean indicating if it is unitless.
|
721
|
+
# For example:
|
722
|
+
#
|
723
|
+
# unitless(100) => true
|
724
|
+
# unitless(100px) => false
|
725
|
+
#
|
726
|
+
# @param number [Literal] The number to inspect
|
727
|
+
# @return [Bool] Whether or not the number is unitless
|
728
|
+
# @raise [ArgumentError] if `number` isn't a number
|
729
|
+
def unitless(number)
|
730
|
+
assert_type number, :Number
|
731
|
+
Sass::Script::Bool.new(number.unitless?)
|
732
|
+
end
|
733
|
+
|
734
|
+
# Returns true if two numbers are similar enough to be added, subtracted, or compared.
|
735
|
+
# For example:
|
736
|
+
#
|
737
|
+
# comparable(2px, 1px) => true
|
738
|
+
# comparable(100px, 3em) => false
|
739
|
+
# comparable(10cm, 3mm) => true
|
740
|
+
#
|
741
|
+
# @param number1 [Number]
|
742
|
+
# @param number2 [Number]
|
743
|
+
# @return [Bool] indicating if the numbers can be compared.
|
744
|
+
# @raise [ArgumentError] if `number1` or `number2` aren't numbers
|
745
|
+
def comparable(number1, number2)
|
746
|
+
assert_type number1, :Number
|
747
|
+
assert_type number2, :Number
|
748
|
+
Sass::Script::Bool.new(number1.comparable_to?(number2))
|
749
|
+
end
|
750
|
+
|
651
751
|
# Converts a decimal number to a percentage.
|
652
752
|
# For example:
|
653
753
|
#
|
@@ -715,11 +815,6 @@ module Sass::Script
|
|
715
815
|
numeric_transformation(value) {|n| n.abs}
|
716
816
|
end
|
717
817
|
|
718
|
-
def unquote(value)
|
719
|
-
assert_type value, :String
|
720
|
-
Sass::Script::String.new(value.value)
|
721
|
-
end
|
722
|
-
|
723
818
|
private
|
724
819
|
|
725
820
|
# This method implements the pattern of transforming a numeric value into
|