discourse/lib/sass/discourse_sass_compiler.rb
Guo Xiang Tan 256d7a00e9 Update sprockets. (#4167)
* Update sass-rails.

* FIX: Tilt dependency has been removed from Ember::Handlebars::Template.

* Update `DiscourseIIFE` to new Sprockets API.

* `Rails.application.assets` returns `nil` in production.

* Move sprockets-rails out of the assets group.

* Pin ember-rails to 0.18.5 which works with Sprockets 3.x.

* Update sprockets to 3.6.0.

* Make `DiscourseSassCompiler` work with Sprockets 3.

* Use `Sass::Rails::SassImporterGlobbing` instead of haxxing our own.

* Moneky patch so that we don't add dependencies for our custom css.

* FIX: Missing class.

* Upgrade ember-handlebars-template.

* FIX: require path needs to share the same root as the folder's path.

* Bump discourse-qunit-rails.

* Update ember-template-compiler.js to 1.12.2.

* `prepend` is private in Ruby 2.0.0.
2016-04-18 10:47:52 +08:00

85 lines
2.1 KiB
Ruby

require_dependency 'sass/discourse_sass_importer'
require 'pathname'
module Sass::Script::Functions
def _error(message)
raise Sass::SyntaxError, mesage
end
end
class DiscourseSassCompiler
def self.compile(scss, target, opts={})
self.new(scss, target).compile(opts)
end
# Takes a Sass::SyntaxError and generates css that will show the
# error at the bottom of the page.
def self.error_as_css(sass_error, label)
error = sass_error.sass_backtrace_str(label)
error.gsub!("\n", '\A ')
error.gsub!("'", '\27 ')
"footer { white-space: pre; }
footer:after { content: '#{error}' }"
end
def initialize(scss, target)
@scss = scss
@target = target
unless Sass::Script::Functions < Sprockets::SassFunctions
Sass::Script::Functions.send :include, Sprockets::SassFunctions
end
end
# Compiles the given scss and output the css as a string.
#
# Options:
# safe: (boolean) if true, theme and plugin stylesheets will not be included. Default is false.
def compile(opts={})
app = Rails.application
env = app.assets || Sprockets::Railtie.build_environment(app)
pathname = Pathname.new("app/assets/stylesheets/#{@target}.scss")
context = env.context_class.new(
environment: env,
filename: "#{@target}.scss",
pathname: pathname,
metadata: {}
)
debug_opts = Rails.env.production? ? {} : {
line_numbers: true,
# debug_info: true, # great with Firebug + FireSass, but not helpful elsewhere
style: :expanded
}
importer_class = opts[:safe] ? DiscourseSafeSassImporter : DiscourseSassImporter
css = ::Sass::Engine.new(@scss, {
syntax: :scss,
cache: false,
read_cache: false,
style: :compressed,
filesystem_importer: importer_class,
load_paths: context.environment.paths.map { |path| importer_class.new(path.to_s) },
sprockets: {
context: context,
environment: context.environment
}
}.merge(debug_opts)).render
css_output = css
if opts[:rtl]
begin
require 'r2'
css_output = R2.r2(css) if defined?(R2)
rescue; end
end
css_output
end
end