Class: Sass::Plugin::Compiler
- Inherits:
-
Object
- Object
- Sass::Plugin::Compiler
- Extended by:
- Callbacks
- Includes:
- Configuration
- Defined in:
- lib/sass/plugin/compiler.rb
Overview
The Compiler class handles compilation of multiple files and/or directories, including checking which CSS files are out-of-date and need to be updated and calling Sass to perform the compilation on those files.
Sass::Plugin uses this class to update stylesheets for a single application. Unlike Sass::Plugin, though, the Compiler class has no global state, and so multiple instances may be created and used independently.
If you need to compile a Sass string into CSS, please see the Engine class.
Unlike Sass::Plugin, this class doesn't keep track of
whether or how many times a stylesheet should be updated.
Therefore, the following Sass::Plugin
options are ignored by the Compiler:
:never_update
:always_check
Instance Method Summary collapse
-
#engine_options(additional_options = {}) ⇒ {Symbol => Object}
Non-destructively modifies Sass::Plugin::Configuration#options so that default values are properly set, and returns the result.
-
#initialize(opts = {}) ⇒ Compiler
constructor
Creates a new compiler.
-
#stylesheet_needs_update?(css_file, template_file) ⇒ Boolean
Compass expects this to exist.
-
#update_stylesheets(individual_files = [])
Updates out-of-date stylesheets.
-
#watch(individual_files = [])
Watches the template directory (or directories) and updates the CSS files whenever the related Sass/SCSS files change.
Methods included from Callbacks
Methods included from Configuration
#add_template_location, #default_options, #options, #remove_template_location, #reset!, #template_location_array
Constructor Details
#initialize(opts = {}) ⇒ Compiler
Creates a new compiler.
35 36 37 |
# File 'lib/sass/plugin/compiler.rb', line 35
def initialize(opts = {})
options.merge!(opts)
end
|
Instance Method Details
#engine_options(additional_options = {}) ⇒ {Symbol => Object}
Non-destructively modifies Sass::Plugin::Configuration#options so that default values are properly set, and returns the result.
265 266 267 268 269 |
# File 'lib/sass/plugin/compiler.rb', line 265
def engine_options(additional_options = {})
opts = options.merge(additional_options)
opts[:load_paths] = load_paths(opts)
opts
end
|
#stylesheet_needs_update?(css_file, template_file) ⇒ Boolean
Compass expects this to exist
272 273 274 |
# File 'lib/sass/plugin/compiler.rb', line 272
def stylesheet_needs_update?(css_file, template_file)
StalenessChecker.stylesheet_needs_update?(css_file, template_file)
end
|
#update_stylesheets(individual_files = [])
Updates out-of-date stylesheets.
Checks each Sass/SCSS file in
:template_location
to see if it's been modified more recently than the corresponding CSS file
in :css_location
.
If it has, it updates the CSS file.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/sass/plugin/compiler.rb', line 171
def update_stylesheets(individual_files = [])
individual_files = individual_files.dup
Sass::Plugin.checked_for_updates = true
staleness_checker = StalenessChecker.new(engine_options)
template_location_array.each do |template_location, css_location|
Sass::Util.glob(File.join(template_location, "**", "[^_]*.s[ca]ss")).sort.each do |file|
# Get the relative path to the file
name = file.sub(template_location.to_s.sub(/\/*$/, '/'), "")
css = css_filename(name, css_location)
sourcemap = Sass::Util.sourcemap_name(css) if engine_options[:sourcemap]
individual_files << [file, css, sourcemap]
end
end
individual_files.each do |file, css, sourcemap|
# TODO: Does staleness_checker need to check the sourcemap file as well?
if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
update_stylesheet(file, css, sourcemap)
else
run_not_updating_stylesheet(file, css, sourcemap)
end
end
end
|
#watch(individual_files = [])
Watches the template directory (or directories)
and updates the CSS files whenever the related Sass/SCSS files change.
watch
never returns.
Whenever a change is detected to a Sass/SCSS file in
:template_location
,
the corresponding CSS file in :css_location
will be recompiled.
The CSS files of any Sass/SCSS files that import the changed file will also be recompiled.
Before the watching starts in earnest, watch
calls #update_stylesheets.
Note that watch
uses the Listen library
to monitor the filesystem for changes.
Listen isn't loaded until watch
is run.
The version of Listen distributed with Sass is loaded by default,
but if another version has already been loaded that will be used instead.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/sass/plugin/compiler.rb', line 220
def watch(individual_files = [])
update_stylesheets(individual_files)
directories = watched_paths
individual_files.each do |(source, _, _)|
directories << File.dirname(File.expand_path(source))
end
directories = remove_redundant_directories(directories)
# A Listen version prior to 2.0 will write a test file to a directory to
# see if a watcher supports watching that directory. That breaks horribly
# on read-only directories, so we filter those out.
directories.reject {|d| File.writable?(d)} unless Sass::Util.listen_geq_2?
# TODO: Keep better track of what depends on what
# so we don't have to run a global update every time anything changes.
listener_args = directories + [{:relative_paths => false}]
# The native windows listener is much slower than the polling option, according to
# https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e
poll = @options[:poll] || Sass::Util.windows?
if poll && Sass::Util.listen_geq_2?
# In Listen 2.0.0 and on, :force_polling is an option. In earlier
# versions, it's a method on the listener (called below).
listener_args.last[:force_polling] = true
end
listener = create_listener(*listener_args) do |modified, added, removed|
on_file_changed(individual_files, modified, added, removed)
end
if poll && !Sass::Util.listen_geq_2?
# In Listen 2.0.0 and on, :force_polling is an option (set above). In
# earlier versions, it's a method on the listener.
listener.force_polling(true)
end
listen_to(listener)
end
|