module Sass module Importers # The abstract base class for Sass importers. # All importers should inherit from this. # # At the most basic level, an importer is given a string # and must return a {Sass::Engine} containing some Sass code. # This string can be interpreted however the importer wants; # however, subclasses are encouraged to use the URI format # for pathnames. # # Importers that have some notion of "relative imports" # should take a single load path in their constructor, # and interpret paths as relative to that. # They should also implement the \{#find\_relative} method. # # Importers should be serializable via `Marshal.dump`. # # @abstract class Base # Find a Sass file relative to another file. # Importers without a notion of "relative paths" # should just return nil here. # # If the importer does have a notion of "relative paths", # it should ignore its load path during this method. # # See \{#find} for important information on how this method should behave. # # The `:filename` option passed to the returned {Sass::Engine} # should be of a format that could be passed to \{#find}. # # @param uri [String] The URI to import. This is not necessarily relative, # but this method should only return true if it is. # @param base [String] The base filename. If `uri` is relative, # it should be interpreted as relative to `base`. # `base` is guaranteed to be in a format importable by this importer. # @param options [{Symbol => Object}] Options for the Sass file # containing the `@import` that's currently being resolved. # @return [Sass::Engine, nil] An Engine containing the imported file, # or nil if it couldn't be found or was in the wrong format. def find_relative(uri, base, options) Sass::Util.abstract(self) end # Find a Sass file, if it exists. # # This is the primary entry point of the Importer. # It corresponds directly to an `@import` statement in Sass. # It should do three basic things: # # * Determine if the URI is in this importer's format. # If not, return nil. # * Determine if the file indicated by the URI actually exists and is readable. # If not, return nil. # * Read the file and place the contents in a {Sass::Engine}. # Return that engine. # # If this importer's format allows for file extensions, # it should treat them the same way as the default {Filesystem} importer. # If the URI explicitly has a `.sass` or `.scss` filename, # the importer should look for that exact file # and import it as the syntax indicated. # If it doesn't exist, the importer should return nil. # # If the URI doesn't have either of these extensions, # the importer should look for files with the extensions. # If no such files exist, it should return nil. # # The {Sass::Engine} to be returned should be passed `options`, # with a few modifications. `:syntax` should be set appropriately, # `:filename` should be set to `uri`, # and `:importer` should be set to this importer. # # @param uri [String] The URI to import. # @param options [{Symbol => Object}] Options for the Sass file # containing the `@import` that's currently being resolved. # This is safe for subclasses to modify destructively. # Callers should only pass in a value they don't mind being destructively modified. # @return [Sass::Engine, nil] An Engine containing the imported file, # or nil if it couldn't be found or was in the wrong format. def find(uri, options) Sass::Util.abstract(self) end # Returns the time the given Sass file was last modified. # # If the given file has been deleted or the time can't be accessed # for some other reason, this should return nil. # # @param uri [String] The URI of the file to check. # Comes from a `:filename` option set on an engine returned by this importer. # @param options [{Symbol => Object}] Options for the Sass file # containing the `@import` currently being checked. # @return [Time, nil] def mtime(uri, options) Sass::Util.abstract(self) end # Get the cache key pair for the given Sass URI. # The URI need not be checked for validity. # # The only strict requirement is that the returned pair of strings # uniquely identify the file at the given URI. # However, the first component generally corresponds roughly to the directory, # and the second to the basename, of the URI. # # Note that keys must be unique *across importers*. # Thus it's probably a good idea to include the importer name # at the beginning of the first component. # # @param uri [String] A URI known to be valid for this importer. # @param options [{Symbol => Object}] Options for the Sass file # containing the `@import` currently being checked. # @return [(String, String)] The key pair which uniquely identifies # the file at the given URI. def key(uri, options) Sass::Util.abstract(self) end # Get the publicly-visible URL for an imported file. This URL is used by # source maps to link to the source stylesheet. This may return `nil` to # indicate that no public URL is available; however, this will cause # sourcemap generation to fail if any CSS is generated from files imported # from this importer. # # If an absolute "file:" URI can be produced for an imported file, that # should be preferred to returning `nil`. However, a URL relative to # `sourcemap_directory` should be preferred over an absolute "file:" URI. # # @param uri [String] A URI known to be valid for this importer. # @param sourcemap_directory [String, NilClass] The absolute path to a # directory on disk where the sourcemap will be saved. If uri refers to # a file on disk that's accessible relative to sourcemap_directory, this # may return a relative URL. This may be `nil` if the sourcemap's # eventual location is unknown. # @return [String?] The publicly-visible URL for this file, or `nil` # indicating that no publicly-visible URL exists. This should be # appropriately URL-escaped. def public_url(uri, sourcemap_directory) return if @public_url_warning_issued @public_url_warning_issued = true Sass::Util.sass_warn <] List of absolute paths of directories to watch def directories_to_watch [] end # If this importer is based on files on the local filesystem This method # should return true if the file, when changed, should trigger a # recompile. # # It is acceptable for non-sass files to be watched and trigger a recompile. # # @param filename [String] The absolute filename for a file that has changed. # @return [Boolean] When the file changed should cause a recompile. def watched_file?(filename) false end end end end