sass 3.1.21 → 3.2.0.alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -4
- data/REVISION +1 -1
- data/Rakefile +6 -15
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass.rb +0 -1
- data/lib/sass/cache_stores/base.rb +1 -3
- data/lib/sass/cache_stores/filesystem.rb +0 -3
- data/lib/sass/css.rb +49 -145
- data/lib/sass/engine.rb +23 -47
- data/lib/sass/environment.rb +5 -30
- data/lib/sass/exec.rb +7 -30
- data/lib/sass/importers/base.rb +1 -2
- data/lib/sass/importers/filesystem.rb +13 -18
- data/lib/sass/less.rb +1 -1
- data/lib/sass/plugin.rb +8 -4
- data/lib/sass/plugin/compiler.rb +67 -93
- data/lib/sass/plugin/configuration.rb +2 -0
- data/lib/sass/plugin/staleness_checker.rb +4 -14
- data/lib/sass/repl.rb +3 -2
- data/lib/sass/script.rb +1 -0
- data/lib/sass/script/color.rb +9 -4
- data/lib/sass/script/funcall.rb +3 -16
- data/lib/sass/script/functions.rb +55 -98
- data/lib/sass/script/interpolation.rb +0 -9
- data/lib/sass/script/lexer.rb +4 -2
- data/lib/sass/script/list.rb +0 -8
- data/lib/sass/script/literal.rb +20 -5
- data/lib/sass/script/node.rb +0 -8
- data/lib/sass/script/number.rb +11 -35
- data/lib/sass/script/operation.rb +0 -16
- data/lib/sass/script/parser.rb +5 -12
- data/lib/sass/script/string_interpolation.rb +0 -9
- data/lib/sass/script/unary_operation.rb +0 -7
- data/lib/sass/script/variable.rb +1 -5
- data/lib/sass/scss/parser.rb +54 -191
- data/lib/sass/scss/rx.rb +3 -15
- data/lib/sass/scss/static_parser.rb +3 -3
- data/lib/sass/selector.rb +3 -15
- data/lib/sass/selector/abstract_sequence.rb +2 -11
- data/lib/sass/selector/comma_sequence.rb +3 -8
- data/lib/sass/selector/sequence.rb +11 -74
- data/lib/sass/selector/simple.rb +1 -7
- data/lib/sass/selector/simple_sequence.rb +8 -28
- data/lib/sass/shared.rb +5 -3
- data/lib/sass/tree/comment_node.rb +12 -25
- data/lib/sass/tree/debug_node.rb +1 -1
- data/lib/sass/tree/directive_node.rb +0 -5
- data/lib/sass/tree/each_node.rb +1 -1
- data/lib/sass/tree/extend_node.rb +1 -1
- data/lib/sass/tree/for_node.rb +2 -2
- data/lib/sass/tree/function_node.rb +1 -1
- data/lib/sass/tree/if_node.rb +14 -1
- data/lib/sass/tree/media_node.rb +4 -4
- data/lib/sass/tree/mixin_def_node.rb +1 -1
- data/lib/sass/tree/mixin_node.rb +2 -2
- data/lib/sass/tree/node.rb +26 -10
- data/lib/sass/tree/return_node.rb +1 -1
- data/lib/sass/tree/root_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +11 -9
- data/lib/sass/tree/variable_node.rb +1 -1
- data/lib/sass/tree/visitors/base.rb +1 -1
- data/lib/sass/tree/visitors/check_nesting.rb +36 -29
- data/lib/sass/tree/visitors/convert.rb +9 -16
- data/lib/sass/tree/visitors/cssize.rb +9 -40
- data/lib/sass/tree/visitors/perform.rb +23 -79
- data/lib/sass/tree/visitors/to_css.rb +21 -23
- data/lib/sass/tree/warn_node.rb +1 -1
- data/lib/sass/tree/while_node.rb +1 -1
- data/lib/sass/util.rb +9 -147
- data/lib/sass/version.rb +0 -14
- data/test/sass/cache_test.rb +0 -15
- data/test/sass/conversion_test.rb +8 -50
- data/test/sass/css2sass_test.rb +0 -33
- data/test/sass/engine_test.rb +32 -283
- data/test/sass/extend_test.rb +0 -315
- data/test/sass/functions_test.rb +23 -60
- data/test/sass/importer_test.rb +0 -110
- data/test/sass/more_results/more_import.css +2 -2
- data/test/sass/plugin_test.rb +13 -40
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/import_charset.css +0 -1
- data/test/sass/results/import_charset_1_8.css +0 -1
- data/test/sass/results/import_charset_ibm866.css +0 -1
- data/test/sass/results/scss_import.css +2 -2
- data/test/sass/results/units.css +1 -1
- data/test/sass/script_conversion_test.rb +0 -2
- data/test/sass/script_test.rb +4 -28
- data/test/sass/scss/css_test.rb +1 -79
- data/test/sass/scss/scss_test.rb +16 -96
- data/test/sass/templates/import_charset.sass +0 -2
- data/test/sass/templates/import_charset_1_8.sass +0 -2
- data/test/sass/templates/import_charset_ibm866.sass +0 -2
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util_test.rb +0 -28
- data/test/test_helper.rb +0 -2
- data/vendor/{listen → fssm}/LICENSE +1 -1
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +14 -0
- metadata +246 -281
- data/VERSION_DATE +0 -1
- data/lib/sass/logger.rb +0 -15
- data/lib/sass/logger/base.rb +0 -32
- data/lib/sass/logger/log_level.rb +0 -49
- data/lib/sass/tree/visitors/deep_copy.rb +0 -87
- data/lib/sass/tree/visitors/extend.rb +0 -42
- data/lib/sass/tree/visitors/set_options.rb +0 -97
- data/lib/sass/util/multibyte_string_scanner.rb +0 -134
- data/test/Gemfile +0 -4
- data/test/Gemfile.lock +0 -19
- data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
- data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
- data/test/sass/logger_test.rb +0 -58
- data/test/sass/templates/_double_import_loop2.sass +0 -1
- data/test/sass/templates/bork5.sass +0 -3
- data/test/sass/templates/double_import_loop1.sass +0 -1
- data/test/sass/templates/nested_bork5.sass +0 -2
- data/test/sass/templates/single_import_loop.sass +0 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +0 -147
- data/vendor/listen/CHANGELOG.md +0 -147
- data/vendor/listen/Gemfile +0 -23
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/README.md +0 -312
- data/vendor/listen/Rakefile +0 -47
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen.rb +0 -38
- data/vendor/listen/lib/listen/adapter.rb +0 -167
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -84
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -110
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -66
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -81
- data/vendor/listen/lib/listen/directory_record.rb +0 -318
- data/vendor/listen/lib/listen/listener.rb +0 -203
- data/vendor/listen/lib/listen/multi_listener.rb +0 -121
- data/vendor/listen/lib/listen/turnstile.rb +0 -28
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/listen.gemspec +0 -26
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -142
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -31
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -41
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -24
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1138
- data/vendor/listen/spec/listen/listener_spec.rb +0 -155
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -156
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -73
- data/vendor/listen/spec/spec_helper.rb +0 -18
- data/vendor/listen/spec/support/adapter_helper.rb +0 -716
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -144
- data/vendor/listen/spec/support/platform_helper.rb +0 -11
data/README.md
CHANGED
@@ -175,15 +175,16 @@ See `sass-convert --help` for further information and options.
|
|
175
175
|
|
176
176
|
Sass was envisioned by [Hampton Catlin](http://hamptoncatlin.com) (hcatlin).
|
177
177
|
However, Hampton doesn't even know his way around the code anymore and now
|
178
|
-
occasionally consults on the language issues. Hampton lives in
|
179
|
-
is the
|
178
|
+
occasionally consults on the language issues. Hampton lives in Jacksonville,
|
179
|
+
Florida and is the lead mobile developer for Wikimedia.
|
180
180
|
|
181
181
|
[Nathan Weizenbaum](http://nex-3.com) is the primary developer and architect of
|
182
182
|
Sass. His hard work has kept the project alive by endlessly answering forum
|
183
183
|
posts, fixing bugs, refactoring, finding speed improvements, writing
|
184
184
|
documentation, implementing new features, and getting Hampton coffee (a fitting
|
185
|
-
task for a boy-genius). Nathan lives in Seattle, Washington and
|
186
|
-
|
185
|
+
task for a boy-genius). Nathan lives in Seattle, Washington and while not being
|
186
|
+
a student at the University of Washington or working at an internship, he
|
187
|
+
consults for Unspace Interactive.
|
187
188
|
|
188
189
|
[Chris Eppstein](http://acts-as-architect.blogspot.com) is a core contributor to
|
189
190
|
Sass and the creator of Compass, the first Sass-based framework. Chris focuses
|
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
d30f40911d3707add3c20a224719b9a6bd20ee8e
|
data/Rakefile
CHANGED
@@ -24,7 +24,7 @@ end
|
|
24
24
|
# Don't use Rake::GemPackageTast because we want prerequisites to run
|
25
25
|
# before we load the gemspec.
|
26
26
|
desc "Build all the packages."
|
27
|
-
task :package => [:revision_file, :
|
27
|
+
task :package => [:revision_file, :submodules, :permissions] do
|
28
28
|
version = get_version
|
29
29
|
File.open(scope('VERSION'), 'w') {|f| f.puts(version)}
|
30
30
|
load scope('sass.gemspec')
|
@@ -51,7 +51,7 @@ task :permissions do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
task :revision_file do
|
54
|
-
require
|
54
|
+
require 'lib/sass'
|
55
55
|
|
56
56
|
release = Rake.application.top_level_tasks.include?('release') || File.exist?(scope('EDGE_GEM_VERSION'))
|
57
57
|
if Sass.version[:rev] && !release
|
@@ -63,17 +63,8 @@ task :revision_file do
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
task :date_file do
|
67
|
-
File.open(scope('VERSION_DATE'), 'w') do |f|
|
68
|
-
f.puts Time.now.utc.strftime('%d %B %Y %T %Z')
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
66
|
# We also need to get rid of this file after packaging.
|
73
|
-
at_exit
|
74
|
-
File.delete(scope('REVISION')) rescue nil
|
75
|
-
File.delete(scope('VERSION_DATE')) rescue nil
|
76
|
-
end
|
67
|
+
at_exit { File.delete(scope('REVISION')) rescue nil }
|
77
68
|
|
78
69
|
desc "Install Sass as a gem. Use SUDO=1 to install with sudo."
|
79
70
|
task :install => [:package] do
|
@@ -124,9 +115,9 @@ task :submodules do
|
|
124
115
|
if File.exist?(File.dirname(__FILE__) + "/.git")
|
125
116
|
sh %{git submodule sync}
|
126
117
|
sh %{git submodule update --init}
|
127
|
-
elsif !File.exist?(File.dirname(__FILE__) + "/vendor/
|
118
|
+
elsif !File.exist?(File.dirname(__FILE__) + "/vendor/fssm/lib")
|
128
119
|
warn <<WARN
|
129
|
-
WARNING: vendor/
|
120
|
+
WARNING: vendor/fssm doesn't exist, and this isn't a git repository so
|
130
121
|
I can't get it automatically!
|
131
122
|
WARN
|
132
123
|
end
|
@@ -156,7 +147,7 @@ def get_version
|
|
156
147
|
version.map! {|n| n =~ /^[0-9]+$/ ? n.to_i : n}
|
157
148
|
return written_version unless version.size == 5 && version[3] == "alpha" # prerelease
|
158
149
|
|
159
|
-
return written_version if (commit_count = `git log --pretty=oneline
|
150
|
+
return written_version if (commit_count = `git log --pretty=oneline --first-parent stable.. | wc -l`).empty?
|
160
151
|
version[4] = commit_count.strip
|
161
152
|
version.join('.')
|
162
153
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.0.alpha.3
|
data/VERSION_NAME
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Bleeding Edge
|
data/lib/sass.rb
CHANGED
@@ -49,8 +49,6 @@ module Sass
|
|
49
49
|
# @param obj [Object] The object to cache.
|
50
50
|
def store(key, sha, root)
|
51
51
|
_store(key, Sass::VERSION, sha, Marshal.dump(root))
|
52
|
-
rescue TypeError, LoadError => e
|
53
|
-
Sass::Util.sass_warn "Warning. Error encountered while saving cache #{path_to(key)}: #{e}"
|
54
52
|
end
|
55
53
|
|
56
54
|
# Retrieve a {Sass::Tree::RootNode}.
|
@@ -61,7 +59,7 @@ module Sass
|
|
61
59
|
def retrieve(key, sha)
|
62
60
|
contents = _retrieve(key, Sass::VERSION, sha)
|
63
61
|
Marshal.load(contents) if contents
|
64
|
-
rescue EOFError, TypeError, ArgumentError
|
62
|
+
rescue EOFError, TypeError, ArgumentError => e
|
65
63
|
Sass::Util.sass_warn "Warning. Error encountered while reading cache #{path_to(key)}: #{e}"
|
66
64
|
end
|
67
65
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
1
|
module Sass
|
4
2
|
module CacheStores
|
5
3
|
# A backend for the Sass cache using the filesystem.
|
@@ -53,7 +51,6 @@ module Sass
|
|
53
51
|
# @param key [String]
|
54
52
|
# @return [String] The path to the cache file.
|
55
53
|
def path_to(key)
|
56
|
-
key = key.gsub(/[<>:\\|?*%]/) {|c| "%%%03d" % Sass::Util.ord(c)}
|
57
54
|
File.join(cache_location, key)
|
58
55
|
end
|
59
56
|
end
|
data/lib/sass/css.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../sass'
|
2
2
|
require 'sass/tree/node'
|
3
3
|
require 'sass/scss/css_parser'
|
4
|
+
require 'strscan'
|
4
5
|
|
5
6
|
module Sass
|
6
7
|
# This class converts CSS documents into Sass or SCSS templates.
|
@@ -74,30 +75,15 @@ module Sass
|
|
74
75
|
#
|
75
76
|
# @return [Tree::Node] The root node of the parsed tree
|
76
77
|
def build_tree
|
77
|
-
root = Sass::SCSS::CssParser.new(@template
|
78
|
-
parse_selectors root
|
78
|
+
root = Sass::SCSS::CssParser.new(@template).parse
|
79
79
|
expand_commas root
|
80
|
-
nest_seqs root
|
81
80
|
parent_ref_rules root
|
81
|
+
remove_parent_refs root
|
82
82
|
flatten_rules root
|
83
83
|
fold_commas root
|
84
|
-
dump_selectors root
|
85
84
|
root
|
86
85
|
end
|
87
86
|
|
88
|
-
# Parse all the selectors in the document and assign them to
|
89
|
-
# {Sass::Tree::RuleNode#parsed_rules}.
|
90
|
-
#
|
91
|
-
# @param root [Tree::Node] The parent node
|
92
|
-
def parse_selectors(root)
|
93
|
-
root.children.each do |child|
|
94
|
-
next parse_selectors(child) if child.is_a?(Tree::DirectiveNode)
|
95
|
-
next unless child.is_a?(Tree::RuleNode)
|
96
|
-
parser = Sass::SCSS::CssParser.new(child.rule.first, child.filename, child.line)
|
97
|
-
child.parsed_rules = parser.parse_selector
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
87
|
# Transform
|
102
88
|
#
|
103
89
|
# foo, bar, baz
|
@@ -115,14 +101,12 @@ module Sass
|
|
115
101
|
# @param root [Tree::Node] The parent node
|
116
102
|
def expand_commas(root)
|
117
103
|
root.children.map! do |child|
|
118
|
-
|
119
|
-
unless child.is_a?(Tree::RuleNode) && child.parsed_rules.members.size > 1
|
104
|
+
unless child.is_a?(Tree::RuleNode) && child.rule.first.include?(',')
|
120
105
|
expand_commas(child) if child.is_a?(Tree::DirectiveNode)
|
121
106
|
next child
|
122
107
|
end
|
123
|
-
child.
|
124
|
-
node = Tree::RuleNode.new([])
|
125
|
-
node.parsed_rules = make_cseq(seq)
|
108
|
+
child.rule.first.split(',').map do |rule|
|
109
|
+
node = Tree::RuleNode.new([rule.strip])
|
126
110
|
node.children = child.children
|
127
111
|
node
|
128
112
|
end
|
@@ -130,7 +114,22 @@ module Sass
|
|
130
114
|
root.children.flatten!
|
131
115
|
end
|
132
116
|
|
133
|
-
# Make rules use
|
117
|
+
# Make rules use parent refs so that
|
118
|
+
#
|
119
|
+
# foo
|
120
|
+
# color: green
|
121
|
+
# foo.bar
|
122
|
+
# color: blue
|
123
|
+
#
|
124
|
+
# becomes
|
125
|
+
#
|
126
|
+
# foo
|
127
|
+
# color: green
|
128
|
+
# &.bar
|
129
|
+
# color: blue
|
130
|
+
#
|
131
|
+
# This has the side effect of nesting rules,
|
132
|
+
# so that
|
134
133
|
#
|
135
134
|
# foo
|
136
135
|
# color: green
|
@@ -143,31 +142,28 @@ module Sass
|
|
143
142
|
#
|
144
143
|
# foo
|
145
144
|
# color: green
|
146
|
-
# bar
|
145
|
+
# & bar
|
147
146
|
# color: red
|
148
|
-
# baz
|
147
|
+
# & baz
|
149
148
|
# color: blue
|
150
149
|
#
|
151
150
|
# @param root [Tree::Node] The parent node
|
152
|
-
def
|
151
|
+
def parent_ref_rules(root)
|
153
152
|
current_rule = nil
|
154
153
|
root.children.map! do |child|
|
155
154
|
unless child.is_a?(Tree::RuleNode)
|
156
|
-
|
155
|
+
parent_ref_rules(child) if child.is_a?(Tree::DirectiveNode)
|
157
156
|
next child
|
158
157
|
end
|
159
158
|
|
160
|
-
|
161
|
-
seq.members.reject! {|sseq| sseq == "\n"}
|
162
|
-
first, rest = seq.members.first, seq.members[1..-1]
|
159
|
+
first, rest = child.rule.first.scan(/\A(&?(?: .|[^ ])[^.#: \[]*)([.#: \[].*)?\Z/m).first
|
163
160
|
|
164
|
-
if current_rule.nil? ||
|
165
|
-
current_rule = Tree::RuleNode.new([])
|
166
|
-
current_rule.parsed_rules = make_seq(first)
|
161
|
+
if current_rule.nil? || current_rule.rule.first != first
|
162
|
+
current_rule = Tree::RuleNode.new([first])
|
167
163
|
end
|
168
164
|
|
169
|
-
|
170
|
-
child.
|
165
|
+
if rest
|
166
|
+
child.rule = ["&" + rest]
|
171
167
|
current_rule << child
|
172
168
|
else
|
173
169
|
current_rule.children += child.children
|
@@ -178,57 +174,32 @@ module Sass
|
|
178
174
|
root.children.compact!
|
179
175
|
root.children.uniq!
|
180
176
|
|
181
|
-
root.children.each {|v|
|
177
|
+
root.children.each { |v| parent_ref_rules(v) }
|
182
178
|
end
|
183
179
|
|
184
|
-
#
|
180
|
+
# Remove useless parent refs so that
|
185
181
|
#
|
186
182
|
# foo
|
187
|
-
#
|
188
|
-
#
|
189
|
-
# color: blue
|
183
|
+
# & bar
|
184
|
+
# color: blue
|
190
185
|
#
|
191
186
|
# becomes
|
192
187
|
#
|
193
188
|
# foo
|
194
|
-
#
|
195
|
-
# &.bar
|
189
|
+
# bar
|
196
190
|
# color: blue
|
197
191
|
#
|
198
192
|
# @param root [Tree::Node] The parent node
|
199
|
-
def
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
sseq = first_sseq(child)
|
208
|
-
next child unless sseq.is_a?(Sass::Selector::SimpleSequence)
|
209
|
-
|
210
|
-
firsts, rest = [sseq.members.first], sseq.members[1..-1]
|
211
|
-
firsts.push rest.shift if firsts.first.is_a?(Sass::Selector::Parent)
|
212
|
-
|
213
|
-
if current_rule.nil? || first_sseq(current_rule).members != firsts
|
214
|
-
current_rule = Tree::RuleNode.new([])
|
215
|
-
current_rule.parsed_rules = make_sseq(*firsts)
|
216
|
-
end
|
217
|
-
|
218
|
-
unless rest.empty?
|
219
|
-
rest.unshift Sass::Selector::Parent.new
|
220
|
-
child.parsed_rules = make_sseq(*rest)
|
221
|
-
current_rule << child
|
222
|
-
else
|
223
|
-
current_rule.children += child.children
|
193
|
+
def remove_parent_refs(root)
|
194
|
+
root.children.each do |child|
|
195
|
+
case child
|
196
|
+
when Tree::RuleNode
|
197
|
+
child.rule.first.gsub! /^& +/, ''
|
198
|
+
remove_parent_refs child
|
199
|
+
when Tree::DirectiveNode
|
200
|
+
remove_parent_refs child
|
224
201
|
end
|
225
|
-
|
226
|
-
current_rule
|
227
202
|
end
|
228
|
-
root.children.compact!
|
229
|
-
root.children.uniq!
|
230
|
-
|
231
|
-
root.children.each {|v| parent_ref_rules(v)}
|
232
203
|
end
|
233
204
|
|
234
205
|
# Flatten rules so that
|
@@ -265,7 +236,7 @@ module Sass
|
|
265
236
|
end
|
266
237
|
end
|
267
238
|
|
268
|
-
# Flattens a single rule
|
239
|
+
# Flattens a single rule
|
269
240
|
#
|
270
241
|
# @param rule [Tree::RuleNode] The candidate for flattening
|
271
242
|
# @see #flatten_rules
|
@@ -273,10 +244,10 @@ module Sass
|
|
273
244
|
while rule.children.size == 1 && rule.children.first.is_a?(Tree::RuleNode)
|
274
245
|
child = rule.children.first
|
275
246
|
|
276
|
-
if
|
277
|
-
rule.
|
247
|
+
if child.rule.first[0] == ?&
|
248
|
+
rule.rule = [child.rule.first.gsub(/^&/, rule.rule.first)]
|
278
249
|
else
|
279
|
-
rule.
|
250
|
+
rule.rule = ["#{rule.rule.first} #{child.rule.first}"]
|
280
251
|
end
|
281
252
|
|
282
253
|
rule.children = child.children
|
@@ -309,7 +280,7 @@ module Sass
|
|
309
280
|
end
|
310
281
|
|
311
282
|
if prev_rule && prev_rule.children == child.children
|
312
|
-
prev_rule.
|
283
|
+
prev_rule.rule.first << ", #{child.rule.first}"
|
313
284
|
next nil
|
314
285
|
end
|
315
286
|
|
@@ -319,72 +290,5 @@ module Sass
|
|
319
290
|
end
|
320
291
|
root.children.compact!
|
321
292
|
end
|
322
|
-
|
323
|
-
# Dump all the parsed {Sass::Tree::RuleNode} selectors to strings.
|
324
|
-
#
|
325
|
-
# @param root [Tree::Node] The parent node
|
326
|
-
def dump_selectors(root)
|
327
|
-
root.children.each do |child|
|
328
|
-
next dump_selectors(child) if child.is_a?(Tree::DirectiveNode)
|
329
|
-
next unless child.is_a?(Tree::RuleNode)
|
330
|
-
child.rule = [child.parsed_rules.to_s]
|
331
|
-
dump_selectors(child)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
# Create a {Sass::Selector::CommaSequence}.
|
336
|
-
#
|
337
|
-
# @param seqs [Array<Sass::Selector::Sequence>]
|
338
|
-
# @return [Sass::Selector::CommaSequence]
|
339
|
-
def make_cseq(*seqs)
|
340
|
-
Sass::Selector::CommaSequence.new(seqs)
|
341
|
-
end
|
342
|
-
|
343
|
-
# Create a {Sass::Selector::CommaSequence} containing only a single
|
344
|
-
# {Sass::Selector::Sequence}.
|
345
|
-
#
|
346
|
-
# @param sseqs [Array<Sass::Selector::Sequence, String>]
|
347
|
-
# @return [Sass::Selector::CommaSequence]
|
348
|
-
def make_seq(*sseqs)
|
349
|
-
make_cseq(Sass::Selector::Sequence.new(sseqs))
|
350
|
-
end
|
351
|
-
|
352
|
-
# Create a {Sass::Selector::CommaSequence} containing only a single
|
353
|
-
# {Sass::Selector::Sequence} which in turn contains only a single
|
354
|
-
# {Sass::Selector::SimpleSequence}.
|
355
|
-
#
|
356
|
-
# @param sseqs [Array<Sass::Selector::Sequence, String>]
|
357
|
-
# @return [Sass::Selector::CommaSequence]
|
358
|
-
def make_sseq(*sseqs)
|
359
|
-
make_seq(Sass::Selector::SimpleSequence.new(sseqs))
|
360
|
-
end
|
361
|
-
|
362
|
-
# Return the first {Sass::Selector::Sequence} in a {Sass::Tree::RuleNode}.
|
363
|
-
#
|
364
|
-
# @param rule [Sass::Tree::RuleNode]
|
365
|
-
# @return [Sass::Selector::Sequence]
|
366
|
-
def first_seq(rule)
|
367
|
-
rule.parsed_rules.members.first
|
368
|
-
end
|
369
|
-
|
370
|
-
# Return the first {Sass::Selector::SimpleSequence} in a
|
371
|
-
# {Sass::Tree::RuleNode}.
|
372
|
-
#
|
373
|
-
# @param rule [Sass::Tree::RuleNode]
|
374
|
-
# @return [Sass::Selector::SimpleSequence, String]
|
375
|
-
def first_sseq(rule)
|
376
|
-
first_seq(rule).members.first
|
377
|
-
end
|
378
|
-
|
379
|
-
# Return the first {Sass::Selector::Simple} in a {Sass::Tree::RuleNode},
|
380
|
-
# unless the rule begins with a combinator.
|
381
|
-
#
|
382
|
-
# @param rule [Sass::Tree::RuleNode]
|
383
|
-
# @return [Sass::Selector::Simple?]
|
384
|
-
def first_simple_sel(rule)
|
385
|
-
sseq = first_sseq(rule)
|
386
|
-
return unless sseq.is_a?(Sass::Selector::SimpleSequence)
|
387
|
-
sseq.members.first
|
388
|
-
end
|
389
293
|
end
|
390
294
|
end
|
data/lib/sass/engine.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'strscan'
|
1
2
|
require 'set'
|
2
3
|
require 'digest/sha1'
|
3
4
|
require 'sass/cache_stores'
|
@@ -25,11 +26,8 @@ require 'sass/tree/charset_node'
|
|
25
26
|
require 'sass/tree/visitors/base'
|
26
27
|
require 'sass/tree/visitors/perform'
|
27
28
|
require 'sass/tree/visitors/cssize'
|
28
|
-
require 'sass/tree/visitors/extend'
|
29
29
|
require 'sass/tree/visitors/convert'
|
30
30
|
require 'sass/tree/visitors/to_css'
|
31
|
-
require 'sass/tree/visitors/deep_copy'
|
32
|
-
require 'sass/tree/visitors/set_options'
|
33
31
|
require 'sass/tree/visitors/check_nesting'
|
34
32
|
require 'sass/selector'
|
35
33
|
require 'sass/environment'
|
@@ -90,10 +88,7 @@ module Sass
|
|
90
88
|
#
|
91
89
|
# `children`: `Array<Line>`
|
92
90
|
# : The lines nested below this one.
|
93
|
-
|
94
|
-
# `comment_tab_str`: `String?`
|
95
|
-
# : The prefix indentation for this comment, if it is a comment.
|
96
|
-
class Line < Struct.new(:text, :tabs, :index, :offset, :filename, :children, :comment_tab_str)
|
91
|
+
class Line < Struct.new(:text, :tabs, :index, :offset, :filename, :children)
|
97
92
|
def comment?
|
98
93
|
text[0] == COMMENT_CHAR && (text[1] == SASS_COMMENT_CHAR || text[1] == CSS_COMMENT_CHAR)
|
99
94
|
end
|
@@ -110,10 +105,6 @@ module Sass
|
|
110
105
|
# which is not output as a CSS comment.
|
111
106
|
SASS_COMMENT_CHAR = ?/
|
112
107
|
|
113
|
-
# The character that indicates that a comment allows interpolation
|
114
|
-
# and should be preserved even in `:compressed` mode.
|
115
|
-
SASS_LOUD_COMMENT_CHAR = ?!
|
116
|
-
|
117
108
|
# The character that follows the general COMMENT_CHAR and designates a CSS comment,
|
118
109
|
# which is embedded in the CSS document.
|
119
110
|
CSS_COMMENT_CHAR = ?*
|
@@ -219,7 +210,7 @@ module Sass
|
|
219
210
|
# If you're compiling a single Sass file from the filesystem,
|
220
211
|
# use \{Sass::Engine.for\_file}.
|
221
212
|
# If you're compiling multiple files from the filesystem,
|
222
|
-
# use {Sass::Plugin
|
213
|
+
# use {Sass::Plugin.
|
223
214
|
#
|
224
215
|
# @param template [String] The Sass template.
|
225
216
|
# This template can be encoded using any encoding
|
@@ -316,6 +307,7 @@ module Sass
|
|
316
307
|
sha = Digest::SHA1.hexdigest(@template)
|
317
308
|
|
318
309
|
if root = @options[:cache_store].retrieve(key, sha)
|
310
|
+
@options = root.options.merge(@options)
|
319
311
|
root.options = @options
|
320
312
|
return root
|
321
313
|
end
|
@@ -324,7 +316,7 @@ module Sass
|
|
324
316
|
check_encoding!
|
325
317
|
|
326
318
|
if @options[:syntax] == :scss
|
327
|
-
root = Sass::SCSS::Parser.new(@template
|
319
|
+
root = Sass::SCSS::Parser.new(@template).parse
|
328
320
|
else
|
329
321
|
root = Tree::RootNode.new(@template)
|
330
322
|
append_children(root, tree(tabulate(@template)).first, true)
|
@@ -334,7 +326,7 @@ module Sass
|
|
334
326
|
if @options[:cache] && key && sha
|
335
327
|
begin
|
336
328
|
old_options = root.options
|
337
|
-
root.options = {}
|
329
|
+
root.options = {:importer => root.options[:importer]}
|
338
330
|
@options[:cache_store].store(key, sha, root)
|
339
331
|
ensure
|
340
332
|
root.options = old_options
|
@@ -427,8 +419,7 @@ but this line was indented by #{Sass::Shared.human_indentation line[/^\s*/]}.
|
|
427
419
|
MSG
|
428
420
|
end
|
429
421
|
|
430
|
-
last.
|
431
|
-
last.text << "\n" << line
|
422
|
+
last.text << "\n" << $1
|
432
423
|
true
|
433
424
|
end
|
434
425
|
|
@@ -494,8 +485,8 @@ MSG
|
|
494
485
|
if child.is_a?(Tree::CommentNode) && child.silent
|
495
486
|
if continued_comment &&
|
496
487
|
child.line == continued_comment.line +
|
497
|
-
continued_comment.
|
498
|
-
continued_comment.value
|
488
|
+
continued_comment.value.count("\n") + 1
|
489
|
+
continued_comment.value << "\n" << child.value
|
499
490
|
next
|
500
491
|
end
|
501
492
|
|
@@ -546,7 +537,7 @@ WARNING
|
|
546
537
|
when ?$
|
547
538
|
parse_variable(line)
|
548
539
|
when COMMENT_CHAR
|
549
|
-
parse_comment(line)
|
540
|
+
parse_comment(line.text)
|
550
541
|
when DIRECTIVE_CHAR
|
551
542
|
parse_directive(parent, line, root)
|
552
543
|
when ESCAPE_CHAR
|
@@ -565,9 +556,9 @@ WARNING
|
|
565
556
|
end
|
566
557
|
|
567
558
|
def parse_property_or_rule(line)
|
568
|
-
scanner =
|
559
|
+
scanner = StringScanner.new(line.text)
|
569
560
|
hack_char = scanner.scan(/[:\*\.]|\#(?!\{)/)
|
570
|
-
parser = Sass::SCSS::SassParser.new(scanner, @
|
561
|
+
parser = Sass::SCSS::SassParser.new(scanner, @line)
|
571
562
|
|
572
563
|
unless res = parser.parse_interp_ident
|
573
564
|
return Tree::RuleNode.new(parse_interp(line.text))
|
@@ -608,21 +599,13 @@ WARNING
|
|
608
599
|
end
|
609
600
|
|
610
601
|
def parse_comment(line)
|
611
|
-
if line
|
612
|
-
silent = line
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
else
|
617
|
-
value = [line.text]
|
618
|
-
end
|
619
|
-
value = with_extracted_values(value) do |str|
|
620
|
-
str = str.gsub(/^#{line.comment_tab_str}/m, '')[2..-1] # get rid of // or /*
|
621
|
-
format_comment_text(str, silent)
|
622
|
-
end
|
623
|
-
Tree::CommentNode.new(value, silent, loud)
|
602
|
+
if line[1] == CSS_COMMENT_CHAR || line[1] == SASS_COMMENT_CHAR
|
603
|
+
silent = line[1] == SASS_COMMENT_CHAR
|
604
|
+
Tree::CommentNode.new(
|
605
|
+
format_comment_text(line[2..-1], silent),
|
606
|
+
silent)
|
624
607
|
else
|
625
|
-
Tree::RuleNode.new(parse_interp(line
|
608
|
+
Tree::RuleNode.new(parse_interp(line))
|
626
609
|
end
|
627
610
|
end
|
628
611
|
|
@@ -683,7 +666,7 @@ WARNING
|
|
683
666
|
:line => @line + 1) unless line.children.empty?
|
684
667
|
Tree::CharsetNode.new(name)
|
685
668
|
elsif directive == "media"
|
686
|
-
Tree::MediaNode.new(value
|
669
|
+
Tree::MediaNode.new(value)
|
687
670
|
else
|
688
671
|
Tree::DirectiveNode.new(line.text)
|
689
672
|
end
|
@@ -749,7 +732,7 @@ WARNING
|
|
749
732
|
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
|
750
733
|
:line => @line + 1) unless line.children.empty?
|
751
734
|
|
752
|
-
scanner =
|
735
|
+
scanner = StringScanner.new(value)
|
753
736
|
values = []
|
754
737
|
|
755
738
|
loop do
|
@@ -761,11 +744,6 @@ WARNING
|
|
761
744
|
break unless scanner.scan(/,\s*/)
|
762
745
|
end
|
763
746
|
|
764
|
-
if scanner.scan(/;/)
|
765
|
-
raise SyntaxError.new("Invalid @import: expected end of line, was \";\".",
|
766
|
-
:line => @line)
|
767
|
-
end
|
768
|
-
|
769
747
|
return values
|
770
748
|
end
|
771
749
|
|
@@ -773,19 +751,17 @@ WARNING
|
|
773
751
|
return if scanner.eos?
|
774
752
|
unless (str = scanner.scan(Sass::SCSS::RX::STRING)) ||
|
775
753
|
(uri = scanner.scan(Sass::SCSS::RX::URI))
|
776
|
-
return Tree::ImportNode.new(scanner.scan(/[
|
754
|
+
return Tree::ImportNode.new(scanner.scan(/[^,]+/))
|
777
755
|
end
|
778
756
|
|
779
757
|
val = scanner[1] || scanner[2]
|
780
758
|
scanner.scan(/\s*/)
|
781
|
-
if media = scanner.scan(/[
|
759
|
+
if media = scanner.scan(/[^,].*/)
|
782
760
|
Tree::DirectiveNode.new("@import #{str || uri} #{media}")
|
783
|
-
elsif !scanner.match?(/[,;]|$/)
|
784
|
-
raise SyntaxError.new("Invalid @import: \"#{str || uri} #{scanner.rest}\"")
|
785
761
|
elsif uri
|
786
762
|
Tree::DirectiveNode.new("@import #{uri}")
|
787
763
|
elsif val =~ /^http:\/\//
|
788
|
-
Tree::DirectiveNode.new("@import #{
|
764
|
+
Tree::DirectiveNode.new("@import url(#{val})")
|
789
765
|
else
|
790
766
|
Tree::ImportNode.new(val)
|
791
767
|
end
|