PageRenderTime 59ms CodeModel.GetById 41ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/scalate-jruby/src/main/resources/haml-3.0.25/lib/sass/tree/root_node.rb

http://github.com/scalate/scalate
Ruby | 163 lines | 103 code | 15 blank | 45 comment | 23 complexity | df1e45a7f4e3a39fb822484ced71a021 MD5 | raw file
  1module Sass
  2  module Tree
  3    # A static node that is the root node of the Sass document.
  4    class RootNode < Node
  5      # The Sass template from which this node was created
  6      #
  7      # @param template [String]
  8      attr_reader :template
  9
 10      # @param template [String] The Sass template from which this node was created
 11      def initialize(template)
 12        super()
 13        @template = template
 14      end
 15
 16      # @see Node#to_s
 17      def to_s(*args)
 18        super
 19      rescue Sass::SyntaxError => e
 20        e.sass_template ||= @template
 21        raise e
 22      end
 23
 24      # Runs the dynamic Sass code *and* computes the CSS for the tree.
 25      #
 26      # @see #perform
 27      # @see #to_s
 28      def render
 29        result, extends = perform(Environment.new).cssize
 30        result = result.do_extend(extends) unless extends.empty?
 31        result.to_s
 32      end
 33
 34      # @see Node#perform
 35      def perform(environment)
 36        environment.options = @options if environment.options.nil? || environment.options.empty?
 37        super
 38      rescue Sass::SyntaxError => e
 39        e.sass_template ||= @template
 40        raise e
 41      end
 42
 43      # Like {Node#cssize}, except that this method
 44      # will create its own `extends` map if necessary,
 45      # and it returns that map along with the cssized tree.
 46      #
 47      # @return [(Tree::Node, Haml::Util::SubsetMap)] The resulting tree of static nodes
 48      #   *and* the extensions defined for this tree
 49      def cssize(extends = Haml::Util::SubsetMap.new, parent = nil)
 50        return super(extends, parent), extends
 51      rescue Sass::SyntaxError => e
 52        e.sass_template ||= @template
 53        raise e
 54      end
 55
 56      # @see \{Node#perform!}
 57      def perform!(environment)
 58        environment.options = @options if environment.options.nil? || environment.options.empty?
 59        super
 60      end
 61
 62      # Converts a node to Sass code that will generate it.
 63      #
 64      # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
 65      # @return [String] The Sass code corresponding to the node
 66      def to_sass(opts = {})
 67        to_src(opts, :sass)
 68      end
 69
 70      # Converts a node to SCSS code that will generate it.
 71      #
 72      # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
 73      # @return [String] The SCSS code corresponding to the node
 74      def to_scss(opts = {})
 75        to_src(opts, :scss)
 76      end
 77
 78      protected
 79
 80      # @see Node#to_src
 81      def to_src(opts, fmt)
 82        Haml::Util.enum_cons(children + [nil], 2).map do |child, nxt|
 83          child.send("to_#{fmt}", 0, opts) +
 84            if nxt &&
 85                (child.is_a?(CommentNode) && child.line + child.value.count("\n") + 1 == nxt.line) ||
 86                (child.is_a?(ImportNode) && nxt.is_a?(ImportNode) && child.line + 1 == nxt.line) ||
 87                (child.is_a?(VariableNode) && nxt.is_a?(VariableNode) && child.line + 1 == nxt.line)
 88              ""
 89            else
 90              "\n"
 91            end
 92        end.join.rstrip + "\n"
 93      end
 94
 95      # Computes the CSS corresponding to this Sass tree.
 96      #
 97      # @param args [Array] ignored
 98      # @return [String] The resulting CSS
 99      # @see Sass::Tree
100      def _to_s(*args)
101        result = String.new
102        children.each do |child|
103          next if child.invisible?
104          child_str = child.to_s(1)
105          result << child_str + (style == :compressed ? '' : "\n")
106        end
107        result.rstrip!
108        return "" if result.empty?
109        result << "\n"
110        unless Haml::Util.ruby1_8? || result.ascii_only?
111          if children.first.is_a?(CharsetNode)
112            begin
113              encoding = children.first.name
114              # Default to big-endian encoding, because we have to decide somehow
115              encoding << 'BE' if encoding =~ /\Autf-(16|32)\Z/i
116              result = result.encode(Encoding.find(encoding))
117            rescue EncodingError
118            end
119          end
120
121          result = "@charset \"#{result.encoding.name}\";#{
122            style == :compressed ? '' : "\n"
123          }".encode(result.encoding) + result
124        end
125        result
126      end
127
128      # In Ruby 1.8, ensures that there's only one @charset directive
129      # and that it's at the top of the document.
130      #
131      # @see Node#cssize
132      def cssize!(extends, parent)
133        super
134
135        # In Ruby 1.9 we can make all @charset nodes invisible
136        # and infer the final @charset from the encoding of the final string.
137        if Haml::Util.ruby1_8? && parent.nil?
138          charset = self.children.find {|c| c.is_a?(CharsetNode)}
139          self.children.reject! {|c| c.is_a?(CharsetNode)}
140          self.children.unshift charset if charset
141        end
142      end
143
144      # Returns an error message if the given child node is invalid,
145      # and false otherwise.
146      #
147      # Only property nodes are invalid at root level.
148      #
149      # @see Node#invalid_child?
150      def invalid_child?(child)
151        case child
152        when Tree::ExtendNode
153          "Extend directives may only be used within rules."
154        when Tree::PropNode
155          "Properties aren't allowed at the root of a document." +
156            child.pseudo_class_selector_message
157        else
158          return
159        end
160      end
161    end
162  end
163end