class Sass::Source::Map
Attributes
The mapping data ordered by the location in the target.
@return [Array<Mapping>]
Public Class Methods
# File lib/sass/source/map.rb, line 23 def initialize @data = [] end
Public Instance Methods
Adds a new mapping from one source range to another. Multiple invocations of this method should have each `output` range come after all previous ranges.
@param input [Sass::Source::Range]
The source range in the input document.
@param output [Sass::Source::Range]
The source range in the output document.
# File lib/sass/source/map.rb, line 34 def add(input, output) @data.push(Mapping.new(input, output)) end
Shifts all output source ranges forward one or more lines.
@param delta [Fixnum] The number of lines to shift the ranges forward.
# File lib/sass/source/map.rb, line 41 def shift_output_lines(delta) return if delta == 0 @data.each do |m| m.output.start_pos.line += delta m.output.end_pos.line += delta end end
Shifts any output source ranges that lie on the first line forward one or more characters on that line.
@param delta [Fixnum] The number of characters to shift the ranges
forward.
# File lib/sass/source/map.rb, line 54 def shift_output_offsets(delta) return if delta == 0 @data.each do |m| break if m.output.start_pos.line > 1 m.output.start_pos.offset += delta m.output.end_pos.offset += delta if m.output.end_pos.line > 1 end end
Returns the standard JSON representation of the source map.
If the `:css_uri` option isn't specified, the `:css_path` and `:sourcemap_path` options must both be specified. Any options may also be specified alongside the `:css_uri` option. If `:css_uri` isn't specified, it will be inferred from `:css_path` and `:sourcemap_path` using the assumption that the local file system has the same layout as the server.
Regardless of which options are passed to this method, source stylesheets that are imported using a non-default importer will only be linked to in the source map if their importers implement {Sass::Importers::Base#public_url}.
@option options :css_uri [String]
The publicly-visible URI of the CSS output file.
@option options :css_path [String]
The local path of the CSS output file.
@option options :sourcemap_path [String]
The (eventual) local path of the sourcemap file.
@option options :type [Symbol]
`:auto` (default), `:file`, or `:inline`.
@return [String] The JSON string. @raise [ArgumentError] If neither `:css_uri` nor `:css_path` and
`:sourcemap_path` are specified.
@comment
rubocop:disable MethodLength
# File lib/sass/source/map.rb, line 89 def to_json(options) css_uri, css_path, sourcemap_path = options[:css_uri], options[:css_path], options[:sourcemap_path] unless css_uri || (css_path && sourcemap_path) raise ArgumentError.new("Sass::Source::Map#to_json requires either " "the :css_uri option or both the :css_path and :soucemap_path options.") end css_path &&= Sass::Util.pathname(Sass::Util.absolute_path(css_path)) sourcemap_path &&= Sass::Util.pathname(Sass::Util.absolute_path(sourcemap_path)) css_uri ||= Sass::Util.file_uri_from_path( Sass::Util.relative_path_from(css_path, sourcemap_path.dirname)) result = "{\n" write_json_field(result, "version", 3, true) source_uri_to_id = {} id_to_source_uri = {} id_to_contents = {} if options[:type] == :inline next_source_id = 0 line_data = [] segment_data_for_line = [] # These track data necessary for the delta coding. previous_target_line = nil previous_target_offset = 1 previous_source_line = 1 previous_source_offset = 1 previous_source_id = 0 @data.each do |m| file, importer = m.input.file, m.input.importer if options[:type] == :inline source_uri = file else sourcemap_dir = sourcemap_path && sourcemap_path.dirname.to_s sourcemap_dir = nil if options[:type] == :file source_uri = importer && importer.public_url(file, sourcemap_dir) next unless source_uri end current_source_id = source_uri_to_id[source_uri] unless current_source_id current_source_id = next_source_id next_source_id += 1 source_uri_to_id[source_uri] = current_source_id id_to_source_uri[current_source_id] = source_uri if options[:type] == :inline id_to_contents[current_source_id] = importer.find(file, {}).instance_variable_get('@template') end end [ [m.input.start_pos, m.output.start_pos], [m.input.end_pos, m.output.end_pos] ].each do |source_pos, target_pos| if previous_target_line != target_pos.line line_data.push(segment_data_for_line.join(",")) unless segment_data_for_line.empty? (target_pos.line - 1 - (previous_target_line || 0)).times {line_data.push("")} previous_target_line = target_pos.line previous_target_offset = 1 segment_data_for_line = [] end # `segment` is a data chunk for a single position mapping. segment = "" # Field 1: zero-based starting offset. segment << Sass::Util.encode_vlq(target_pos.offset - previous_target_offset) previous_target_offset = target_pos.offset # Field 2: zero-based index into the "sources" list. segment << Sass::Util.encode_vlq(current_source_id - previous_source_id) previous_source_id = current_source_id # Field 3: zero-based starting line in the original source. segment << Sass::Util.encode_vlq(source_pos.line - previous_source_line) previous_source_line = source_pos.line # Field 4: zero-based starting offset in the original source. segment << Sass::Util.encode_vlq(source_pos.offset - previous_source_offset) previous_source_offset = source_pos.offset segment_data_for_line.push(segment) previous_target_line = target_pos.line end end line_data.push(segment_data_for_line.join(",")) write_json_field(result, "mappings", line_data.join(";")) source_names = [] (0...next_source_id).each {|id| source_names.push(id_to_source_uri[id].to_s)} write_json_field(result, "sources", source_names) if options[:type] == :inline write_json_field(result, "sourcesContent", (0...next_source_id).map {|id| id_to_contents[id]}) end write_json_field(result, "names", []) write_json_field(result, "file", css_uri) result << "\n}" result end
Private Instance Methods
@comment
rubocop:enable MethodLength
# File lib/sass/source/map.rb, line 203 def write_json_field(out, name, value, is_first = false) out << (is_first ? "" : ",\n") << "\"" << Sass::Util.json_escape_string(name) << "\": " << Sass::Util.json_value_of(value) end