Created
July 28, 2011 15:54
-
-
Save jeremyroman/1111803 to your computer and use it in GitHub Desktop.
An HTTP importer for Sass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Additional caching and such might be helpful for performance. | |
# Sass's regeneration only on changed files should work as long as the server provides the Last-Modified header | |
require 'net/http' | |
require 'time' | |
require 'sass' | |
module Sass | |
module Importers | |
# Importer which issues HTTP requests | |
class HTTP < Base | |
def initialize(root) | |
@root = URI.parse(root) | |
unless @root.absolute? && @root.scheme == 'http' | |
raise ArgumentError, "Absolute HTTP URIs only" | |
end | |
end | |
def find_relative(uri, base, options) | |
_find(@root + base + uri, options) | |
end | |
def find(uri, options) | |
_find(@root + uri, options) | |
end | |
def mtime(uri, options) | |
uri = URI.parse(uri) | |
return unless uri.absolute? && uri.scheme == 'http' | |
Net::HTTP.start(uri.host, uri.port) do |http| | |
response = http.head(uri.request_uri) | |
if response.is_a?(Net::HTTPOK) && response['Last-Modified'] | |
Time.parse(response['Last-Modified']) | |
elsif response.is_a? Net::HTTPOK | |
# we must assume that it just changed | |
Time.now | |
else | |
nil | |
end | |
end | |
end | |
def key(uri, options) | |
[self.class.name, uri] | |
end | |
def to_s | |
@root.to_s | |
end | |
protected | |
def extensions | |
{'.sass' => :sass, '.scss' => :scss} | |
end | |
private | |
def exists?(uri) | |
Net::HTTP.start(uri.host, uri.port) do |http| | |
http.head(uri.request_uri).is_a? Net::HTTPOK | |
end | |
end | |
def _find(uri, options) | |
return unless uri.absolute? && uri.scheme == 'http' | |
# determine the syntax being used | |
ext = File.extname(uri.path) | |
syntax = extensions[ext] | |
# this must not be the full path: try another | |
if syntax.nil? | |
ext, syntax = extensions.find do |possible_ext, possible_syntax| | |
new_uri = uri.dup | |
new_uri.path += possible_ext | |
exists? new_uri | |
end | |
return if syntax.nil? | |
uri.path += ext | |
end | |
# fetch the content | |
Net::HTTP.start(uri.host, uri.port) do |http| | |
response = http.get(uri.request_uri) | |
response.value | |
options[:importer] = self | |
options[:filename] = uri.to_s | |
options[:syntax] = syntax | |
Sass::Engine.new(response.body, options) | |
end | |
rescue | |
nil | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Jeremy,
I had a great use for this the other day, and spent a day or so just packaging it up into a gem here: https://github.com/joeellis/remote-sass , complete with tests, README, some minor changes, etc. If it suits you, I'd like to add you in as an author as i didn't really make too many changes to your original code, so I believe you should have credit for that. Anyways, just let me know.