Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asset collections #2099

Open
wants to merge 9 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/test/fixtures/stylesheets/busted_font_urls/css/screen.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.showgrid { font-family: url('http://assets3.example.com/fonts/grid-BUSTED.ttf'); }
.showgrid { font-family: url('http://assets2.example.com/fonts/grid-BUSTED.ttf'); }

.no-buster { font-family: url('http://assets3.example.com/fonts/grid.ttf'); }

.buster-by-default { font-family: url('http://assets3.example.com/fonts/grid-BUSTED.ttf'); }
.buster-by-default { font-family: url('http://assets2.example.com/fonts/grid-BUSTED.ttf'); }

.feed { font-family: url('http://assets3.example.com/fonts/feed.ttf?query_string'); }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.showgrid { background-image: url('http://assets0.example.com/images/grid-BUSTED.png'); }
.showgrid { background-image: url('http://assets3.example.com/images/grid-BUSTED.png'); }

.inlinegrid { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAUEAYAAACv1qP4AAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAZ0lEQVRYw+3QwQ2AIBAFUTEUwI3+uzN7gDscsIgxEuO8An52J11X73OudfxMraXkzHfO3Y98nQEhA0IGhAwIGRAyIGRAyICQASEDQgaEDAgZEDIgZEDIgJABoZzSGK3tPuN9ERFP7Nw4fg+c5g8V1wAAAABJRU5ErkJggg=='); }

Expand Down
2 changes: 1 addition & 1 deletion cli/test/fixtures/stylesheets/compass/css/images.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
background-image: url('/images/4x6.png?busted=true'); }

.absolute {
background-image: url(http://example.com/images/4x6.png); }
background-image: url('http://example.com/images/4x6.png'); }
Empty file.
Empty file.
7 changes: 7 additions & 0 deletions cli/test/fixtures/stylesheets/image_urls/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@
asset_host do |path|
"http://assets%d.example.com" % (path.size % 4)
end

add_asset_collection(
:root_dir => "other/asset_collection",
:http_dir => "ext-assets",
:images_dir => "img",
:sass_dir => "scss"
)
2 changes: 2 additions & 0 deletions cli/test/fixtures/stylesheets/image_urls/css/screen.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.imported-from-asset-collection { color: red; }

.showgrid { background-image: url('http://assets0.example.com/images/grid.png?busted=true'); }

.inlinegrid { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAUEAYAAACv1qP4AAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAZ0lEQVRYw+3QwQ2AIBAFUTEUwI3+uzN7gDscsIgxEuO8An52J11X73OudfxMraXkzHfO3Y98nQEhA0IGhAwIGRAyIGRAyICQASEDQgaEDAgZEDIgZEDIgJABoZzSGK3tPuN9ERFP7Nw4fg+c5g8V1wAAAABJRU5ErkJggg=='); }
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.imported-from-asset-collection { color: red; }
2 changes: 2 additions & 0 deletions cli/test/fixtures/stylesheets/image_urls/sass/screen.sass
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import "ac-stylesheet"

.showgrid
background-image: image-url(unquote("grid.png"))

Expand Down
36 changes: 21 additions & 15 deletions cli/test/units/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,24 +206,30 @@ def test_serialization_warns_with_asset_cache_buster_set
end

def test_cache_buster_file_not_passed_when_the_file_does_not_exist
config = Compass::Configuration::Data.new("test_cache_buster_file_not_passed_when_the_file_does_not_exist")
the_file = nil
was_called = nil
config.asset_cache_buster do |path, file|
was_called = true
the_file = file
"busted=true"
end
FileUtils.mkdir_p("images")
begin
config = Compass::Configuration::Data.new("test_cache_buster_file_not_passed_when_the_file_does_not_exist")
open("images/asdf.gif", "w") {|f| }
the_file = nil
was_called = nil
config.asset_cache_buster do |path, file|
was_called = true
the_file = file
"busted=true"
end

Compass.add_configuration(config)
Compass.add_configuration(config)


sass = Sass::Engine.new(<<-SCSS, Compass.configuration.to_sass_engine_options.merge(:syntax => :scss))
.foo { background: image-url("asdf.gif") }
SCSS
sass.render
assert was_called
assert_nil the_file
sass = Sass::Engine.new(<<-SCSS, Compass.configuration.to_sass_engine_options.merge(:syntax => :scss))
.foo { background: image-url("asdf.gif") }
SCSS
sass.render
assert was_called
assert the_file.closed?
ensure
FileUtils.rm_r("images")
end
end

def test_cache_buster_file_is_closed
Expand Down
16 changes: 8 additions & 8 deletions cli/test/units/sass_extensions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,18 @@ def test_css2_fallback

def test_font_files
assert_equal '', evaluate('font_files()')
assert_equal "url(/font/name.woff) format('woff'), url(/font/name.woff2) format('woff2'), url(/fonts/name.ttf) format('truetype'), url(/fonts/name.svg#fontpath) format('svg')", evaluate("font-files('/font/name.woff', woff, '/font/name.woff2', woff2, '/fonts/name.ttf', truetype, '/fonts/name.svg#fontpath', svg)")
assert_equal "url('/font/name.woff') format('woff'), url('/font/name.woff2') format('woff2'), url('/fonts/name.ttf') format('truetype'), url('/fonts/name.svg#fontpath') format('svg')", evaluate("font-files('/font/name.woff', woff, '/font/name.woff2', woff2, '/fonts/name.ttf', truetype, '/fonts/name.svg#fontpath', svg)")

assert_equal "url(/font/with/right_ext.woff) format('woff')", evaluate("font_files('/font/with/right_ext.woff')")
assert_equal "url(/font/with/wrong_ext.woff) format('svg')", evaluate("font_files('/font/with/wrong_ext.woff', 'svg')")
assert_equal "url(/font/with/no_ext) format('opentype')", evaluate("font_files('/font/with/no_ext', 'otf')")
assert_equal "url(/font/with/weird.ext) format('truetype')", evaluate("font_files('/font/with/weird.ext', 'ttf')")
assert_equal "url('/font/with/right_ext.woff') format('woff')", evaluate("font_files('/font/with/right_ext.woff')")
assert_equal "url('/font/with/wrong_ext.woff') format('svg')", evaluate("font_files('/font/with/wrong_ext.woff', 'svg')")
assert_equal "url('/font/with/no_ext') format('opentype')", evaluate("font_files('/font/with/no_ext', 'otf')")
assert_equal "url('/font/with/weird.ext') format('truetype')", evaluate("font_files('/font/with/weird.ext', 'ttf')")

# unquoted path strings used to break because of a regex test
assert_equal "url(/font/with/right_ext.woff) format('woff')", evaluate("font_files(unquote('/font/with/right_ext.woff'))")
assert_equal "url('/font/with/right_ext.woff') format('woff')", evaluate("font_files(unquote('/font/with/right_ext.woff'))")

assert_equal "url(/font/with/right_ext.woff) format('woff'), url(/font/with/right_ext_also.otf) format('opentype')", evaluate("font_files('/font/with/right_ext.woff', '/font/with/right_ext_also.otf')")
assert_equal "url(/font/with/wrong_ext.woff) format('truetype'), url(/font/with/right_ext.otf) format('opentype')", evaluate("font_files('/font/with/wrong_ext.woff', 'ttf', '/font/with/right_ext.otf')")
assert_equal "url('/font/with/right_ext.woff') format('woff'), url('/font/with/right_ext_also.otf') format('opentype')", evaluate("font_files('/font/with/right_ext.woff', '/font/with/right_ext_also.otf')")
assert_equal "url('/font/with/wrong_ext.woff') format('truetype'), url('/font/with/right_ext.otf') format('opentype')", evaluate("font_files('/font/with/wrong_ext.woff', 'ttf', '/font/with/right_ext.otf')")

assert_nothing_raised Sass::SyntaxError do
evaluate("font-files('/font/name.woff')")
Expand Down
18 changes: 18 additions & 0 deletions compass-style.org/content/CHANGELOG.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ The Documentation for the [latest preview release](http://beta.compass-style.org

Every release contains updated caniuse data unless otherwise noted.

1.1.0 (UNRELEASED)
------------------

* Asset Collections - Each asset collection is a bundle of sass stylesheets,
images, and fonts that potentially have their own URL location, cache
busting, and host requirements. Unlike compass extensions, asset
collections don't require the publisher to package their assets
in any particular way and the image and fonts don't need to be bundled
or delivered as part of your projects's assets. This makes asset
collections ideal for integrating with drupal extensions, bower, and
other front-end packagers.

To add an asset collection to your project, call `add_asset_collection`
and pass the asset collection configuration options to describe where
to find the assets and how the urls for them are constructed. [Asset
Collection Documentation](/help/documentation/configuration-reference/#asset-collections).


1.0.1 (08/19/2014)
------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,68 @@ To disable the asset cache buster:

---

<a name="asset-collections"></a>
**`add_asset_collection`** - Each asset collection is a bundle of sass stylesheets,
images, and fonts that potentially have their own URL location, cache
busting, and host requirements. Unlike compass extensions, asset
collections don't require the publisher to package their assets
in any particular way and the image and fonts don't need to be bundled
or delivered as part of your projects's assets. This makes asset
collections ideal for integrating with drupal extensions, bower, and
other front-end packagers.

To add an asset collection to your project, call `add_asset_collection`
and pass the asset collection configuration options to describe where
to find the assets and how the urls for them are constructed. The
following options are allowed:


* `:root_path` - The absolute path to the asset collection.
* `:root_dir` - A relative path to the asset collection from the project path.
* `:http_path` - Web root location of assets in this collection.
Starts with '/'.
* `:http_dir` - Web root location of assets in this collection.
Relative to the project's `http_path`.
* `:sass_dir` - Sass directory to be added to the Sass import paths.
Relative to the `:root_path` or `:root_dir.`
* `:fonts_dir` - Directory of fonts to be added to the font look up path.
Relative to the `:root_path` or `:root_dir.`
* `:http_fonts_dir` - Where to find fonts on the webserver relative to
the `http_path` or `http_dir.` Defaults to `<http_path>/<fonts_dir>`.
Can be overridden by setting `:http_fonts_path`.
* `:http_fonts_path` - Where to find fonts on the webserver.
* `:images_dir` - Directory of images to be added to the image look up path.
Relative to the `:root_path` or `:root_dir.`
* `:http_images_dir` - Where to find images on the webserver relative to
the `http_path` or `http_dir.` Defaults to `<http_path>/<images_dir>`.
Can be overridden by setting `:http_images_path`.
* `:http_images_path` - Where to find images on the webserver.
* `:asset_host` - A string starting with `'http://'` for a single host,
or a lambda or proc that will compute the asset host for assets in this collection.
If `:http_dir` is set instead of `http_path,` this defaults to the project's `asset_host`.
* `:asset_cache_buster` - A string, `:none`, or
or a lambda or proc that will compute the `cache_buster` for assets in this collection.
If `:http_dir` is set instead of `http_path,` this defaults to the project's `asset_cache_buster`.

It is required to pass either `:root_path` or `:root_dir` and
`:http_path` or `:http_dir`.

Example:

add_asset_collection(
:root_dir => "other/asset_collection",
:http_dir => "ext-assets",
:images_dir => "img",
:sass_dir => "scss"
:asset_cache_buster => proc {|url_path, file|
{:path => "/#{Digest::MD5.file(file)}#{File.extname(url_path)}"} },
:asset_host => proc {|url_path|
"http://assets#{url_path.hash % 4 + 1}.other-asset-server.com" }
)


---

**`watch`** -- React to changes to arbitrary files within your project. Can be invoked
more than once. Example:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ The options that can be set via Sass configuration are:
containing the keys query and/or path mapped to a string. The string
is a simple value to set as the query parameter on all urls, when
`null`, the cache busting feature is disabled.
* `asset-collections` - List of Maps. Each map is a set of keys
that describe an asset collection. The keys are basically the same
as for the [ruby configuration of asset
collections](/help/documentation/configuration-reference/#asset-collections)
with the following exceptions: 1. keys can be dashed instead of
underscored. 2. Procs should be function references as described here
for `asset-cache-buster` and `asset-host`. 3. The `sass-dir` option
doesn't work because it must be set up external to the sass file itself.
* `asset-host` - Function reference, or `null`. When `null` this feature
is disabled (default). A referenced function must accept a single
argument (the root relative url) and return a full url (starting with
Expand Down
6 changes: 4 additions & 2 deletions core/lib/compass/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,16 @@ def remove_configuration_property(name)
:sprite_load_path,
:required_libraries,
:loaded_frameworks,
:framework_path
:framework_path,
:asset_collections
]

ARRAY_ATTRIBUTE_OPTIONS = {
:sprite_load_path => { :clobbers => true }
}

RUNTIME_READONLY_ATTRIBUTES = [
:additional_import_paths,
:cache,
attributes_for_directory(:cache, nil),
:chunky_png_options,
Expand Down Expand Up @@ -170,6 +172,6 @@ def deprojectize(path, project_path = nil)
end
end

%w(defaults inheritance paths data watch adapters).each do |lib|
%w(defaults inheritance paths data watch adapters asset_collection).each do |lib|
require "compass/configuration/#{lib}"
end
5 changes: 4 additions & 1 deletion core/lib/compass/configuration/adapters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ def resolve_additional_import_paths
else
path
end
end
end +
(asset_collections || []).map do |asset_collection|
asset_collection.sass_path
end.compact
end

def absolute_path?(path)
Expand Down
Loading