class SassC::ImportHandler::Importer
def canonicalize(url, from_import:)
def canonicalize(url, from_import:) return url if url.start_with?(Protocol::IMPORT, Protocol::LOADED) if url.start_with?(Protocol::LOAD) url = url.delete_prefix(Protocol::LOAD) return url if @importer_results.key?(url) path = URL.parse(url).route_from(@parent_urls.last).to_s resolved = resolve_path(path, URL.file_url_to_path(@parent_urls.last), from_import) return URL.path_to_file_url(resolved) unless resolved.nil? return end return unless url.start_with?(Protocol::FILE) path = URL.parse(url).route_from(@parent_urls.last).to_s parent_path = URL.file_url_to_path(@parent_urls.last) imports = @importer.imports(path, parent_path) imports = [SassC::Importer::Import.new(path)] if imports.nil? imports = [imports] unless imports.is_a?(Array) imports.each do |import| import.path = File.absolute_path(import.path, File.dirname(parent_path)) end import_url = URL.path_to_file_url(File.absolute_path(path, File.dirname(parent_path))) canonical_url = "#{Protocol::IMPORT}#{import_url}" @importer_results[canonical_url] = imports_to_native(imports) canonical_url end
def imports_to_native(imports)
def imports_to_native(imports) { contents: imports.flat_map do |import| file_url = URL.path_to_file_url(import.path) if import.source @importer_results[file_url] = if import.source.is_a?(Hash) { contents: import.source[:contents], syntax: import.source[:syntax], source_map_url: file_url } else { contents: import.source, syntax: syntax(import.path), source_map_url: file_url } end end [ "@import #{"#{Protocol::LOAD}#{file_url}".inspect};", "@import #{"#{Protocol::LOADED}#{file_url}".inspect};" ] end.join("\n"), syntax: :scss } end
def initialize(importer)
def initialize(importer) @importer = importer @importer_results = {} @parent_urls = [URL.path_to_file_url(File.absolute_path(@importer.options[:filename] || 'stdin'))] end
def load(canonical_url)
def load(canonical_url) if canonical_url.start_with?(Protocol::IMPORT) @importer_results.delete(canonical_url) elsif canonical_url.start_with?(Protocol::FILE) @parent_urls.push(canonical_url) if @importer_results.key?(canonical_url) @importer_results.delete(canonical_url) else path = URL.file_url_to_path(canonical_url) { contents: File.read(path), syntax: syntax(path), source_map_url: canonical_url } end elsif canonical_url.start_with?(Protocol::LOADED) @parent_urls.pop { contents: '', syntax: :scss } end end
def load_paths
def load_paths @load_paths ||= (@importer.options[:load_paths] || []) + SassC.load_paths end
def resolve_path(path, parent_path, from_import)
def resolve_path(path, parent_path, from_import) [File.dirname(parent_path)].concat(load_paths).each do |load_path| resolved = FileImporter.resolve_path(File.absolute_path(path, load_path), from_import) return resolved unless resolved.nil? end nil end
def syntax(path)
def syntax(path) case File.extname(path) when '.sass' :indented when '.css' :css else :scss end end