lib/xass.rb in xass-0.1.7 vs lib/xass.rb in xass-0.1.8
- old
+ new
@@ -1,67 +1,107 @@
require_relative 'initialize'
-module Sass
- module Tree
- class RootNode
- alias :old_render :render
+module Sass::Tree
+ class Visitors::Perform
+ def visit_mixin(node)
+ include_loop = true
+ handle_include_loop!(node) if @stack.any? {|e| e[:name] == node.name}
+ include_loop = false
- def render
- old_render.split('/*').map { |x|
- next x unless x.match(/^ line [0-9]+, /)
- a, b = x.split("\n", 2)
- m = a.match(/\/app\/assets\/stylesheets\/([^. ]+)\./)
- next "#{a}\n#{b}" unless m
- selector = class_replaced_selector(b.split("\n")[0].strip[0...-1].strip, class_prefix(m[1]))
- "#{a}\n#{selector} {\n#{b.split("\n", 2)[1]}"
- }.join('/*')
+ @stack.push(:filename => node.filename, :line => node.line, :name => node.name)
+ raise Sass::SyntaxError.new("Undefined mixin '#{node.name}'.") unless mixin = @environment.mixin(node.name)
+
+ if node.children.any? && !mixin.has_content
+ raise Sass::SyntaxError.new(%Q{Mixin "#{node.name}" does not accept a content block.})
end
- private
+ args = node.args.map {|a| a.perform(@environment)}
+ keywords = Sass::Util.map_hash(node.keywords) {|k, v| [k, v.perform(@environment)]}
+ splat = node.splat.perform(@environment) if node.splat
- def class_replaced_selector(selector, class_prefix)
- doc = CSSPool.CSS("#{selector} {}")
- replace_class(doc, class_prefix)
- doc_to_selector(doc)
- end
+ self.class.perform_arguments(mixin, args, keywords, splat) do |env|
+ env.caller = Sass::Environment.new(@environment)
+ env.content = node.children if node.has_children
- def class_prefix(name)
- names = name.split('/')
- names = names[1..(names.index { |x| x.start_with?('!') } || -1)]
- names.join('__')
+ trace_node = Sass::Tree::TraceNode.from_node(node.name, node)
+ with_environment(env) {
+ trace_node.children = mixin.tree.map {|c|
+ d = c.dup
+ d.filename = node.filename
+ visit(d)
+ }.flatten
+ }
+ trace_node
end
+ rescue Sass::SyntaxError => e
+ unless include_loop
+ e.modify_backtrace(:mixin => node.name, :line => node.line)
+ e.add_backtrace(:line => node.line)
+ end
+ raise e
+ ensure
+ @stack.pop unless include_loop
+ end
+ end
- def replace_class(doc, class_prefix)
- doc.rule_sets[0].selectors.map do |selector|
- selector.simple_selectors.each do |simple_selector|
- simple_selector.additional_selectors.each do |additional_selector|
- case additional_selector
- when CSSPool::Selectors::Class
- additional_selector.name = extended_selector(class_prefix, additional_selector.name)
- when CSSPool::Selectors::PseudoClass
- next unless additional_selector.extra
- extra = class_replaced_selector(additional_selector.extra, class_prefix) rescue nil
- additional_selector.extra = extra if extra
- end
+ class RootNode
+ alias :old_render :render
+
+ def render
+ old_render.split('/*').map { |x|
+ next x unless x.match(/^ line [0-9]+, /)
+ a, b = x.split("\n", 2)
+ m = a.match(/\/app\/assets\/stylesheets\/([^. ]+)\./)
+ next "#{a}\n#{b}" unless m
+ selector = class_replaced_selector(b.split("\n")[0].strip[0...-1].strip, class_prefix(m[1]))
+ "#{a}\n#{selector} {\n#{b.split("\n", 2)[1]}"
+ }.join('/*')
+ end
+
+ private
+
+ def class_replaced_selector(selector, class_prefix)
+ doc = CSSPool.CSS("#{selector} {}")
+ replace_class(doc, class_prefix)
+ doc_to_selector(doc)
+ end
+
+ def class_prefix(name)
+ names = name.split('/')
+ names = names[1..(names.index { |x| x.start_with?('!') } || -1)]
+ names.join('__')
+ end
+
+ def replace_class(doc, class_prefix)
+ doc.rule_sets[0].selectors.map do |selector|
+ selector.simple_selectors.each do |simple_selector|
+ simple_selector.additional_selectors.each do |additional_selector|
+ case additional_selector
+ when CSSPool::Selectors::Class
+ additional_selector.name = extended_selector(class_prefix, additional_selector.name)
+ when CSSPool::Selectors::PseudoClass
+ next unless additional_selector.extra
+ extra = class_replaced_selector(additional_selector.extra, class_prefix) rescue nil
+ additional_selector.extra = extra if extra
end
end
end
end
+ end
- def doc_to_selector(doc)
- doc.to_css.split("\n")[0][0...-1].strip.gsub(/\\[0-9a-f]{6}/) do |c|
- [c[1..-1].tr('0', '').to_i(16)].pack('U')
- end
+ def doc_to_selector(doc)
+ doc.to_css.split("\n")[0][0...-1].strip.gsub(/\\[0-9a-f]{6}/) do |c|
+ [c[1..-1].tr('0', '').to_i(16)].pack('U')
end
+ end
- def extended_selector(class_prefix, klass)
- if klass == 'root'
- class_prefix
- elsif klass.start_with?('_')
- klass[1..-1]
- else
- "#{class_prefix}___#{klass}"
- end
+ def extended_selector(class_prefix, klass)
+ if klass == 'root'
+ class_prefix
+ elsif klass.start_with?('_')
+ klass[1..-1]
+ else
+ "#{class_prefix}___#{klass}"
end
end
end
end