diff --git a/Gemfile b/Gemfile index 37505ff9..04f5ee70 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,8 @@ platforms :ruby do gem 'therubyracer' gem 'redcarpet', '~> 3.1' gem 'pry', require: false, group: :development + # gem 'pry-debugger', require: false, group: :development + # gem 'pry-stack_explorer', require: false, group: :development end platforms :jruby do @@ -35,5 +37,6 @@ gem 'rubocop', require: false # Middleman itself gem 'middleman-core', path: 'middleman-core' gem 'middleman-cli', path: 'middleman-cli' +gem 'middleman-compass', path: 'middleman-compass', require: false gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', require: false gem 'middleman', path: 'middleman' diff --git a/Rakefile b/Rakefile index b48c1b51..16b61bd1 100644 --- a/Rakefile +++ b/Rakefile @@ -46,7 +46,6 @@ task :test do GEM_PATHS.each do |g| Dir.chdir("#{File.join(ROOT, g)}") { sh "#{Gem.ruby} -S rake test" } end - Rake::Task['rubocop'].invoke end desc 'Run specs for all middleman gems' @@ -56,10 +55,15 @@ task :spec do end end -require 'rubocop/rake_task' -desc 'Run RuboCop to check code consistency' -Rubocop::RakeTask.new(:rubocop) do |task| - task.fail_on_error = false +begin + require 'rubocop/rake_task' + if defined?(Rubocop) + desc 'Run RuboCop to check code consistency' + Rubocop::RakeTask.new(:rubocop) do |task| + task.fail_on_error = false + end + end +rescue LoadError end desc 'Run tests for all middleman gems' diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 621e7d26..7b105629 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -187,9 +187,9 @@ module Middleman::Cli resource.ext == '.css' end.each(&method(:build_resource)) - logger.debug '== Checking for Compass sprites' + logger.debug '== Checking for generated images' - # Double-check for compass sprites + # Double-check for generated images @app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) @app.sitemap.ensure_resource_list_updated! diff --git a/middleman-compass/.gitignore b/middleman-compass/.gitignore new file mode 100644 index 00000000..be83c767 --- /dev/null +++ b/middleman-compass/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +Gemfile.lock +Gemfile-v4.lock +tmp +.rbenv-* +.sass-cache +pkg +build +.ruby-version +.cache diff --git a/middleman-compass/.travis.yml b/middleman-compass/.travis.yml new file mode 100644 index 00000000..a032273c --- /dev/null +++ b/middleman-compass/.travis.yml @@ -0,0 +1,16 @@ +rvm: + - 1.9.3 + - 2.0.0 + - 2.1.1 + - jruby-19mode + +gemfile: + - Gemfile + - Gemfile-v4 + +script: "bundle exec rake test" + +env: TEST=true + +matrix: + fast_finish: true \ No newline at end of file diff --git a/middleman-compass/CONTRIBUTING.md b/middleman-compass/CONTRIBUTING.md new file mode 100644 index 00000000..97bdc981 --- /dev/null +++ b/middleman-compass/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing +In the spirit of [free software][free-sw], **everyone** is encouraged to help +improve this project. + +[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html + +Here are some ways *you* can contribute: + +* by using alpha, beta, and prerelease versions +* by reporting bugs +* by suggesting new features +* by writing or editing documentation +* by writing specifications +* by writing code ( **no patch is too small** : fix typos, add comments, clean up inconsistent whitespace ) +* by refactoring code +* by closing [issues][] +* by reviewing patches + +[issues]: https://github.com/middleman/middleman-compass/issues + +## Submitting an Issue +We use the [GitHub issue tracker][issues] to track bugs and features. Before +submitting a bug report or feature request, check to make sure it hasn't +already been submitted. When submitting a bug report, please include a [Gist][] +that includes a stack trace and any details that may be necessary to reproduce +the bug, including your gem version, Ruby version, and operating system. +Ideally, a bug report should include a pull request with failing specs. + +[gist]: https://gist.github.com/ + +## Submitting a Pull Request +1. [Fork the repository.][fork] +2. [Create a topic branch.][branch] +3. Add specs for your unimplemented feature or bug fix. +4. Run `bundle exec rake test`. If your specs pass, return to step 3. +5. Implement your feature or bug fix. +6. Run `bundle exec rake test`. If your specs fail, return to step 5. +7. Add, commit, and push your changes. +8. [Submit a pull request.][pr] + +[fork]: http://help.github.com/fork-a-repo/ +[branch]: http://learn.github.com/p/branching.html +[pr]: http://help.github.com/send-pull-requests/ diff --git a/middleman-compass/Gemfile b/middleman-compass/Gemfile new file mode 100644 index 00000000..e3a01e2e --- /dev/null +++ b/middleman-compass/Gemfile @@ -0,0 +1,17 @@ +source "https://rubygems.org" + +gem "middleman-cli", :github => "middleman/middleman", :branch => "master" +gem "middleman-core", :github => "middleman/middleman", :branch => "master" + +# Specify your gem's dependencies in middleman-sprockets.gemspec +gemspec + +gem "rake", "~> 10.0.3", :require => false +gem "yard", "~> 0.8.0", :require => false + +# Test tools +gem "cucumber" +gem "fivemat", "~> 1.2.1" +gem "aruba" +gem "rspec", "~> 2.14" +gem "builder", "~> 3.0" diff --git a/middleman-compass/LICENSE.md b/middleman-compass/LICENSE.md new file mode 100644 index 00000000..8ffe042d --- /dev/null +++ b/middleman-compass/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2012-2013 Thomas Reynolds + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-compass/README.md b/middleman-compass/README.md new file mode 100644 index 00000000..c4d23d97 --- /dev/null +++ b/middleman-compass/README.md @@ -0,0 +1,59 @@ +# Middleman-compass + +`middleman-compass` is an extension for the [Middleman] static site generator that allows support for [Compass](http://compass-style.org) in your assets. + +## Installation + +If you're just getting started, install the `middleman` gem and generate a new project: + +``` +gem install middleman +middleman init MY_PROJECT +``` + +If you already have a Middleman project: Add `gem "middleman-compass"` to your `Gemfile` and run `bundle install` + +## Configuration + +``` +activate :compass +``` + +## Build & Dependency Status + +[![Gem Version](https://badge.fury.io/rb/middleman-compass.png)][gem] +[![Build Status](https://travis-ci.org/middleman/middleman-compass.png)][travis] +[![Dependency Status](https://gemnasium.com/middleman/middleman-compass.png?travis)][gemnasium] +[![Code Quality](https://codeclimate.com/github/middleman/middleman-compass.png)][codeclimate] + +## Community + +The official community forum is available at: http://forum.middlemanapp.com + +## Bug Reports + +Github Issues are used for managing bug reports and feature requests. If you run into issues, please search the issues and submit new problems: https://github.com/middleman/middleman-compass/issues + +The best way to get quick responses to your issues and swift fixes to your bugs is to submit detailed bug reports, include test cases and respond to developer questions in a timely manner. Even better, if you know Ruby, you can submit [Pull Requests](https://help.github.com/articles/using-pull-requests) containing Cucumber Features which describe how your feature should work or exploit the bug you are submitting. + +## How to Run Cucumber Tests + +1. Checkout Repository: `git clone https://github.com/middleman/middleman-compass.git` +2. Install Bundler: `gem install bundler` +3. Run `bundle install` inside the project root to install the gem dependencies. +4. Run test cases: `bundle exec rake test` + +## Donate + +[Click here to lend your support to Middleman](https://spacebox.io/s/4dXbHBorC3) + +## License + +Copyright (c) 2012-2013 Thomas Reynolds. MIT Licensed, see [LICENSE] for details. + +[middleman]: http://middlemanapp.com +[gem]: https://rubygems.org/gems/middleman-compass +[travis]: http://travis-ci.org/middleman/middleman-compass +[gemnasium]: https://gemnasium.com/middleman/middleman-compass +[codeclimate]: https://codeclimate.com/github/middleman/middleman-compass +[LICENSE]: https://github.com/middleman/middleman-compass/blob/master/LICENSE.md \ No newline at end of file diff --git a/middleman-compass/Rakefile b/middleman-compass/Rakefile new file mode 100644 index 00000000..e23e477b --- /dev/null +++ b/middleman-compass/Rakefile @@ -0,0 +1,20 @@ +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'cucumber/rake/task' + +require 'middleman-core/version' + +Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t| + exempt_tags = ["--tags ~@wip"] + t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" +end + +require 'rake/clean' + +task :test => [:cucumber] + +desc "Build HTML documentation" +task :doc do + sh 'bundle exec yard' +end diff --git a/middleman-core/features/compass-sprites.feature b/middleman-compass/features/compass-sprites.feature similarity index 100% rename from middleman-core/features/compass-sprites.feature rename to middleman-compass/features/compass-sprites.feature diff --git a/middleman-core/features/fonts.feature b/middleman-compass/features/fonts.feature similarity index 100% rename from middleman-core/features/fonts.feature rename to middleman-compass/features/fonts.feature diff --git a/middleman-compass/features/support/env.rb b/middleman-compass/features/support/env.rb new file mode 100644 index 00000000..12233ac0 --- /dev/null +++ b/middleman-compass/features/support/env.rb @@ -0,0 +1,7 @@ +PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) +ENV['TEST'] = 'true' +require "middleman-core" +require "middleman-core/step_definitions" +require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-compass') +require "erubis" + diff --git a/middleman-compass/fixtures/compass-sprites-app/config.rb b/middleman-compass/fixtures/compass-sprites-app/config.rb new file mode 100644 index 00000000..6347d3ab --- /dev/null +++ b/middleman-compass/fixtures/compass-sprites-app/config.rb @@ -0,0 +1,2 @@ +require 'middleman-compass' +activate :compass \ No newline at end of file diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_down.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_down.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_left.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_left.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_right.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_right.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_up.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_up.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/stylesheets/site.css.scss b/middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/stylesheets/site.css.scss rename to middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss diff --git a/middleman-core/fixtures/compass-sprites-app/config.rb b/middleman-compass/fixtures/fonts-app/config.rb similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/config.rb rename to middleman-compass/fixtures/fonts-app/config.rb diff --git a/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf b/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf new file mode 100755 index 00000000..aa601879 Binary files /dev/null and b/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf differ diff --git a/.gitmodules b/middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf similarity index 100% rename from .gitmodules rename to middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf diff --git a/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.sass b/middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass similarity index 100% rename from middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.sass rename to middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass diff --git a/middleman-compass/lib/middleman-compass.rb b/middleman-compass/lib/middleman-compass.rb new file mode 100644 index 00000000..66f0db45 --- /dev/null +++ b/middleman-compass/lib/middleman-compass.rb @@ -0,0 +1,6 @@ +require "middleman-core" + +Middleman::Extensions.register :compass, auto_activate: :before_configuration do + require "middleman-compass/extension" + Middleman::CompassExtension +end diff --git a/middleman-compass/lib/middleman-compass/extension.rb b/middleman-compass/lib/middleman-compass/extension.rb new file mode 100644 index 00000000..c7e93a3f --- /dev/null +++ b/middleman-compass/lib/middleman-compass/extension.rb @@ -0,0 +1,64 @@ +module Middleman + class CompassExtension < Extension + def initialize(app, options_hash={}, &block) + require 'middleman-core/renderers/sass' + require 'compass' + + super + + # Hooks to manually update the compass config after we're + # done with it + app.define_hook :compass_config + end + + def after_configuration + ::Compass.configuration do |compass| + compass.project_path = app.source_dir + compass.environment = :development + compass.cache = false + compass.sass_dir = app.config[:css_dir] + compass.css_dir = app.config[:css_dir] + compass.javascripts_dir = app.config[:js_dir] + compass.fonts_dir = app.config[:fonts_dir] + compass.images_dir = app.config[:images_dir] + compass.http_path = app.config[:http_prefix] + + # Disable this initially, the cache_buster extension will + # re-enable it if requested. + compass.asset_cache_buster { |_| nil } + + # Disable this initially, the relative_assets extension will + + compass.relative_assets = false + + # Default output style + compass.output_style = :nested + end + + # Call hook + app.run_hook_for :compass_config, app, ::Compass.configuration + + # Tell Tilt to use it as well (for inline sass blocks) + ::Tilt.register 'sass', CompassSassTemplate + ::Tilt.prefer(CompassSassTemplate) + + # Tell Tilt to use it as well (for inline scss blocks) + ::Tilt.register 'scss', CompassScssTemplate + ::Tilt.prefer(CompassScssTemplate) + end + + # A Compass Sass template for Tilt, adding our options in + class CompassSassTemplate < ::Middleman::Renderers::Sass::SassPlusCSSFilenameTemplate + def sass_options + super.merge(::Compass.configuration.to_sass_engine_options) + end + end + + # A Compass Scss template for Tilt, adding our options in + class CompassScssTemplate < ::Middleman::Renderers::Sass::ScssPlusCSSFilenameTemplate + def sass_options + super.merge(::Compass.configuration.to_sass_engine_options) + end + end + end +end \ No newline at end of file diff --git a/middleman-compass/lib/middleman-compass/version.rb b/middleman-compass/lib/middleman-compass/version.rb new file mode 100644 index 00000000..fcc5622e --- /dev/null +++ b/middleman-compass/lib/middleman-compass/version.rb @@ -0,0 +1,5 @@ +module Middleman + module Compass + VERSION = "4.0.0" + end +end diff --git a/middleman-compass/middleman-compass.gemspec b/middleman-compass/middleman-compass.gemspec new file mode 100644 index 00000000..ad108349 --- /dev/null +++ b/middleman-compass/middleman-compass.gemspec @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "middleman-compass/version" + +Gem::Specification.new do |s| + s.name = "middleman-compass" + s.version = Middleman::Compass::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ['Thomas Reynolds', 'Ben Hollis', 'Karl Freeman'] + s.email = ['me@tdreyno.com', 'ben@benhollis.net', 'karlfreeman@gmail.com'] + s.homepage = "https://github.com/middleman/middleman-compass" + s.summary = %q{Compass support for Middleman} + s.description = %q{Compass support for Middleman} + s.license = "MIT" + s.files = `git ls-files -z`.split("\0") + s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0") + s.require_paths = ["lib"] + s.add_dependency("middleman-core")#, [">= 4.0.0"]) + s.add_dependency('compass', ['>= 1.0.0.alpha.19']) +end diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index 27362377..3c39f833 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -10,7 +10,7 @@ Feature: Assets get a file hash appended to their and references to them are upd | images/100px-5fd6fb90.jpg | | images/100px-5fd6fb90.gif | | javascripts/application-1d8d5276.js | - | stylesheets/site-50eaa978.css | + | stylesheets/site-7474cadd.css | | index.html | | subdir/index.html | | other/index.html | @@ -22,15 +22,18 @@ Feature: Assets get a file hash appended to their and references to them are upd | stylesheets/site.css | And the file "javascripts/application-1d8d5276.js" should contain "img.src = '/images/100px-5fd6fb90.jpg'" - And the file "stylesheets/site-50eaa978.css" should contain "background-image: url('../images/100px-5fd6fb90.jpg')" + And the file "stylesheets/site-7474cadd.css" should contain: + """ + background-image: url("../images/100px-5fd6fb90.jpg") + """ And the file "index.html" should contain 'href="apple-touch-icon.png"' - And the file "index.html" should contain 'href="stylesheets/site-50eaa978.css"' + And the file "index.html" should contain 'href="stylesheets/site-7474cadd.css"' And the file "index.html" should contain 'src="javascripts/application-1d8d5276.js"' And the file "index.html" should contain 'src="images/100px-5fd6fb90.jpg"' - And the file "subdir/index.html" should contain 'href="../stylesheets/site-50eaa978.css"' + And the file "subdir/index.html" should contain 'href="../stylesheets/site-7474cadd.css"' And the file "subdir/index.html" should contain 'src="../javascripts/application-1d8d5276.js"' And the file "subdir/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"' - And the file "other/index.html" should contain 'href="../stylesheets/site-50eaa978.css"' + And the file "other/index.html" should contain 'href="../stylesheets/site-7474cadd.css"' And the file "other/index.html" should contain 'src="../javascripts/application-1d8d5276.js"' And the file "other/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"' @@ -38,32 +41,35 @@ Feature: Assets get a file hash appended to their and references to them are upd Given the Server is running at "asset-hash-app" When I go to "/" Then I should see 'href="apple-touch-icon.png"' - And I should see 'href="stylesheets/site-50eaa978.css"' + And I should see 'href="stylesheets/site-7474cadd.css"' And I should see 'src="javascripts/application-1d8d5276.js"' And I should see 'src="images/100px-5fd6fb90.jpg"' When I go to "/subdir/" - Then I should see 'href="../stylesheets/site-50eaa978.css"' + Then I should see 'href="../stylesheets/site-7474cadd.css"' And I should see 'src="../javascripts/application-1d8d5276.js"' And I should see 'src="../images/100px-5fd6fb90.jpg"' When I go to "/other/" - Then I should see 'href="../stylesheets/site-50eaa978.css"' + Then I should see 'href="../stylesheets/site-7474cadd.css"' And I should see 'src="../javascripts/application-1d8d5276.js"' And I should see 'src="../images/100px-5fd6fb90.jpg"' When I go to "/javascripts/application-1d8d5276.js" Then I should see "img.src = '/images/100px-5fd6fb90.jpg'" - When I go to "/stylesheets/site-50eaa978.css" - Then I should see "background-image: url('../images/100px-5fd6fb90.jpg')" + When I go to "/stylesheets/site-7474cadd.css" + Then I should see: + """ + background-image: url("../images/100px-5fd6fb90.jpg") + """ Scenario: Enabling an asset host still produces hashed files and references Given the Server is running at "asset-hash-host-app" When I go to "/" - Then I should see 'href="http://middlemanapp.com/stylesheets/site-54baaf3a.css"' + Then I should see 'href="http://middlemanapp.com/stylesheets/site-1fdf4fb5.css"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' When I go to "/subdir/" - Then I should see 'href="http://middlemanapp.com/stylesheets/site-54baaf3a.css"' + Then I should see 'href="http://middlemanapp.com/stylesheets/site-1fdf4fb5.css"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' When I go to "/other/" - Then I should see 'href="http://middlemanapp.com/stylesheets/site-54baaf3a.css"' + Then I should see 'href="http://middlemanapp.com/stylesheets/site-1fdf4fb5.css"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' # Asset helpers don't appear to work from Compass right now # When I go to "/stylesheets/site-e5a31a3e.css" @@ -98,11 +104,11 @@ Feature: Assets get a file hash appended to their and references to them are upd """ Given the Server is running at "asset-hash-app" When I go to "/" - Then I should see 'href="stylesheets/site-5770af52.css' - When I go to "stylesheets/site-5770af52.css" + Then I should see 'href="stylesheets/site-ac2166fd.css' + When I go to "stylesheets/site-ac2166fd.css" Then I should see 'background-image' Then I should see 'Added by Rack filter' - When I go to "stylesheets/site-50eaa978.css" + When I go to "stylesheets/site-7474cadd.css" Then I should see 'Not Found' Scenario: Hashed-asset files are not produced for ignored paths @@ -137,7 +143,7 @@ Feature: Assets get a file hash appended to their and references to them are upd | images/100px-5fd6fb90.jpg | | images/100px-5fd6fb90.gif | | javascripts/application-1d8d5276.js | - | stylesheets/site-50eaa978.css | + | stylesheets/site-7474cadd.css | # @wip Currently broken, we should move all asset-host functionality out of Compass and into something more similar to asset_hash with Rack-based rewrites # Scenario: Enabling an asset host and referencing assets in CSS with URL fragments are rewritten correctly diff --git a/middleman-core/features/asset_host.feature b/middleman-core/features/asset_host.feature index eb82f43b..19c6b14d 100644 --- a/middleman-core/features/asset_host.feature +++ b/middleman-core/features/asset_host.feature @@ -2,34 +2,6 @@ Feature: Alternate between multiple asset hosts In order to speed up page loading Scenario: Set single host globally - Given a fixture app "asset-host-app" - And a file named "config.rb" with: - """ - activate :asset_host - set :asset_host, "http://assets1.example.com" - """ - And the Server is running - When I go to "/asset_host.html" - Then I should see "http://assets1" - When I go to "/stylesheets/asset_host.css" - Then I should see "http://assets1" - - Scenario: Set proc host globally - Given a fixture app "asset-host-app" - And a file named "config.rb" with: - """ - activate :asset_host - set :asset_host do |asset| - "http://assets%d.example.com" % (asset.hash % 4) - end - """ - And the Server is running - When I go to "/asset_host.html" - Then I should see "http://assets" - When I go to "/stylesheets/asset_host.css" - Then I should see "http://assets" - - Scenario: Set single host with inline-option Given a fixture app "asset-host-app" And a file named "config.rb" with: """ @@ -41,6 +13,20 @@ Feature: Alternate between multiple asset hosts When I go to "/stylesheets/asset_host.css" Then I should see "http://assets1" + Scenario: Set single host with inline-option + Given a fixture app "asset-host-app" + And a file named "config.rb" with: + """ + activate :asset_host, host: "http://assets1.example.com" + """ + And the Server is running + When I go to "/asset_host.html" + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} + When I go to "/stylesheets/asset_host.css" + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} + Scenario: Set proc host with inline-option Given a fixture app "asset-host-app" And a file named "config.rb" with: @@ -51,6 +37,8 @@ Feature: Alternate between multiple asset hosts """ And the Server is running When I go to "/asset_host.html" - Then I should see "http://assets" + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} When I go to "/stylesheets/asset_host.css" - Then I should see "http://assets" \ No newline at end of file + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} \ No newline at end of file diff --git a/middleman-core/features/cache_buster.feature b/middleman-core/features/cache_buster.feature index 11040ba5..d452234e 100644 --- a/middleman-core/features/cache_buster.feature +++ b/middleman-core/features/cache_buster.feature @@ -5,7 +5,7 @@ Feature: Generate mtime-based query string for busting browser caches Given "cache_buster" feature is "disabled" And the Server is running at "cache-buster-app" When I go to "/stylesheets/relative_assets.css" - Then I should see "blank.gif'" + Then I should see 'blank.gif"' Scenario: Rendering html with the feature disabled Given "cache_buster" feature is "disabled" diff --git a/middleman-core/features/minify_css.feature b/middleman-core/features/minify_css.feature index 87238eb4..066eb530 100644 --- a/middleman-core/features/minify_css.feature +++ b/middleman-core/features/minify_css.feature @@ -8,7 +8,7 @@ Feature: Minify CSS """ And the Server is running at "minify-css-app" When I go to "/stylesheets/site.css" - Then I should see "50" lines + Then I should see "7" lines And I should see "only screen and (device-width" Scenario: Rendering external css with the feature enabled @@ -40,7 +40,7 @@ Feature: Minify CSS """ And the Server is running at "passthrough-app" When I go to "/stylesheets/site.css" - Then I should see "46" lines + Then I should see "5" lines Scenario: Rendering inline css with the feature disabled Given a fixture app "minify-css-app" diff --git a/middleman-core/features/relative_assets.feature b/middleman-core/features/relative_assets.feature index 1ebafdfa..05c069ce 100644 --- a/middleman-core/features/relative_assets.feature +++ b/middleman-core/features/relative_assets.feature @@ -6,7 +6,7 @@ Feature: Relative Assets And the Server is running at "relative-assets-app" When I go to "/stylesheets/relative_assets.css" Then I should not see "url('../" - And I should see "/images/blank.gif')" + And I should see '/images/blank.gif")' Scenario: Building css with the feature disabled Given a fixture app "relative-assets-app" @@ -15,7 +15,7 @@ Feature: Relative Assets """ Given a successfully built app at "relative-assets-app" When I cd to "build" - Then the file "stylesheets/relative_assets.css" should contain "url('/images/blank.gif')" + Then the file "stylesheets/relative_assets.css" should contain 'url("/images/blank.gif")' Scenario: Rendering html with the feature disabled Given "relative_assets" feature is "disabled" @@ -27,7 +27,9 @@ Feature: Relative Assets Given "relative_assets" feature is "enabled" And the Server is running at "relative-assets-app" When I go to "/stylesheets/relative_assets.css" - Then I should see "url('../images/blank.gif" + Then I should see 'url("../images/blank.gif' + When I go to "/javascripts/application.js" + Then I should not see "../" Scenario: Building css with the feature enabled Given a fixture app "relative-assets-app" @@ -37,7 +39,8 @@ Feature: Relative Assets """ Given a successfully built app at "relative-assets-app" When I cd to "build" - Then the file "stylesheets/relative_assets.css" should contain "url('../images/blank.gif')" + Then the file "stylesheets/relative_assets.css" should contain 'url("../images/blank.gif")' + Then the file "javascripts/application.js" should not contain "../" Scenario: Relative css reference with directory indexes Given a fixture app "relative-assets-app" @@ -57,48 +60,18 @@ Feature: Relative Assets Then I should not see "/images/blank.gif" And I should see "images/blank.gif" - Scenario: Rendering css with a custom images_dir - Given "relative_assets" feature is "enabled" - And "images_dir" is set to "img" - And the Server is running at "relative-assets-app" - When I go to "/stylesheets/relative_assets.css" - Then I should see "url('../img/blank.gif')" - - Scenario: Building css with a custom images_dir - Given a fixture app "relative-assets-app" - And a file named "config.rb" with: - """ - set :images_dir, "img" - activate :relative_assets - """ - Given a successfully built app at "relative-assets-app" - When I cd to "build" - Then the file "stylesheets/relative_assets.css" should contain "url('../img/blank.gif')" - - Scenario: Rendering html with a custom images_dir - Given "relative_assets" feature is "enabled" - And "images_dir" is set to "img" - And the Server is running at "relative-assets-app" - When I go to "/relative_image.html" - Then I should not see "/images/blank.gif" - Then I should not see "/img/blank.gif" - And I should see "img/blank.gif" - Scenario: Rendering scss with the feature enabled Given "relative_assets" feature is "enabled" And the Server is running at "fonts-app" When I go to "/stylesheets/fonts.css" - Then I should see "url('../fonts/StMarie-Thin.otf" - And I should see "url('../fonts/blank/blank.otf" - - Scenario: Rendering scss with the feature enabled and a custom fonts_dir - Given "relative_assets" feature is "enabled" - And "fonts_dir" is set to "otf" - And the Server is running at "fonts-app" - When I go to "/stylesheets/fonts.css" - Then I should not see "url('../fonts/StMarie-Thin.otf" - And I should see "url('../otf/StMarie-Thin.otf" - And I should see "url('../otf/blank/blank.otf" + Then I should see: + """ + url("../fonts/StMarie-Thin.otf" + """ + And I should see: + """ + url("../fonts/blank/blank.otf" + """ Scenario: Building scss with the feature enabled Given a fixture app "fonts-app" @@ -108,21 +81,14 @@ Feature: Relative Assets """ Given a successfully built app at "fonts-app" When I cd to "build" - Then the file "stylesheets/fonts.css" should contain "url('../fonts/StMarie-Thin.otf')" - And the file "stylesheets/fonts.css" should contain "url('../fonts/blank/blank.otf')" - - Scenario: Building scss with the feature enabled and a custom fonts_dir - Given a fixture app "fonts-app" - And a file named "config.rb" with: + Then the file "stylesheets/fonts.css" should contain: """ - set :fonts_dir, "otf" - activate :relative_assets + url("../fonts/StMarie-Thin.otf") + """ + And the file "stylesheets/fonts.css" should contain: + """ + url("../fonts/blank/blank.otf") """ - Given a successfully built app at "fonts-app" - When I cd to "build" - Then the file "stylesheets/fonts.css" should not contain "url('../fonts/StMarie-Thin.otf')" - And the file "stylesheets/fonts.css" should contain "url('../otf/StMarie-Thin.otf')" - And the file "stylesheets/fonts.css" should contain "url('../otf/blank/blank.otf')" Scenario: Relative assets via image_tag Given a fixture app "relative-assets-app" diff --git a/middleman-core/features/slim.feature b/middleman-core/features/slim.feature index acf8b82c..02663f3a 100644 --- a/middleman-core/features/slim.feature +++ b/middleman-core/features/slim.feature @@ -24,6 +24,8 @@ Feature: Support slim templating language Given an empty app And a file named "config.rb" with: """ + require 'middleman-compass' + activate :compass """ And a file named "source/scss.html.slim" with: """ diff --git a/middleman-core/features/support/env.rb b/middleman-core/features/support/env.rb index ba524651..08e3442a 100644 --- a/middleman-core/features/support/env.rb +++ b/middleman-core/features/support/env.rb @@ -1,5 +1,5 @@ ENV["TEST"] = "true" -ENV["AUTOLOAD_SPROCKETS"] = "false" +ENV["AUTOLOAD_SPROCKETS"] ||= "false" require 'simplecov' SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/../..')) diff --git a/middleman-core/fixtures/asset-hash-host-app/config.rb b/middleman-core/fixtures/asset-hash-host-app/config.rb index f40e1c63..085caeb7 100644 --- a/middleman-core/fixtures/asset-hash-host-app/config.rb +++ b/middleman-core/fixtures/asset-hash-host-app/config.rb @@ -1,6 +1,4 @@ activate :asset_hash activate :directory_indexes -activate :asset_host - -set :asset_host, 'http://middlemanapp.com' +activate :asset_host, host: 'http://middlemanapp.com' diff --git a/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb b/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb index fb441334..dbef372a 100755 --- a/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb +++ b/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb @@ -1 +1,20 @@ -<%= image_tag "blank.gif" %> \ No newline at end of file +<%= image_tag "blank0.gif" %> +<%= image_tag "blank1.gif" %> +<%= image_tag "blank2.gif" %> +<%= image_tag "blank3.gif" %> +<%= image_tag "blank4.gif" %> +<%= image_tag "blank10.gif" %> +<%= image_tag "blank21.gif" %> +<%= image_tag "blank32.gif" %> +<%= image_tag "blank43.gif" %> +<%= image_tag "blank54.gif" %> +<%= image_tag "blank20.gif" %> +<%= image_tag "blank21.gif" %> +<%= image_tag "blank22.gif" %> +<%= image_tag "blank23.gif" %> +<%= image_tag "blank24.gif" %> +<%= image_tag "blank30.gif" %> +<%= image_tag "blank31.gif" %> +<%= image_tag "blank32.gif" %> +<%= image_tag "blank33.gif" %> +<%= image_tag "blank34.gif" %> \ No newline at end of file diff --git a/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass b/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass index 5a67f373..874297d9 100644 --- a/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass +++ b/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass @@ -1,3 +1,48 @@ -@import "compass" h1 - background: image-url("blank.gif") \ No newline at end of file + background: image-url("blank1.gif") +h2 + background: image-url("blank2.gif") +h3 + background: image-url("blank3.gif") +h4 + background: image-url("blank4.gif") +h5 + background: image-url("blank5.gif") +h6 + background: image-url("blank6.gif") +h7 + background: image-url("blank7.gif") +h8 + background: image-url("blank8.gif") +h11 + background: image-url("blank11.gif") +h12 + background: image-url("blank21.gif") +h13 + background: image-url("blank31.gif") +h14 + background: image-url("blank41.gif") +h15 + background: image-url("blank51.gif") +h16 + background: image-url("blank61.gif") +h17 + background: image-url("blank71.gif") +h18 + background: image-url("blank81.gif") +h21 + background: image-url("blank12.gif") +h22 + background: image-url("blank22.gif") +h23 + background: image-url("blank32.gif") +h24 + background: image-url("blank42.gif") +h25 + background: image-url("blank52.gif") +h26 + background: image-url("blank62.gif") +h27 + background: image-url("blank72.gif") +h28 + background: image-url("blank82.gif") \ No newline at end of file diff --git a/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass b/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass index 5a67f373..1ed5fcad 100755 --- a/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass +++ b/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass @@ -1,3 +1,2 @@ -@import "compass" h1 background: image-url("blank.gif") \ No newline at end of file diff --git a/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass b/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass index d143e05e..0ddfd8be 100755 --- a/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass +++ b/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass @@ -1 +1,3 @@ -@import "compass/reset" \ No newline at end of file +body { + background: white; +} \ No newline at end of file diff --git a/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss b/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss new file mode 100644 index 00000000..19075547 --- /dev/null +++ b/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss @@ -0,0 +1,6 @@ +@font-face { + font-family: "St Marie"; + src: url("/fonts/StMarie-Thin.otf") format('opentype'); } +@font-face { + font-family: "St Marie"; + src: url("/fonts/blank/blank.otf") format('opentype'); } diff --git a/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass b/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass index 0cf9e7da..afb9ffdb 100755 --- a/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass +++ b/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass @@ -1,4 +1,6 @@ -@import "compass/reset" +body + margin: 0px + padding: 0px @media handheld, only screen and (device-width: 768px) body diff --git a/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass b/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass index d143e05e..47a66dce 100755 --- a/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass +++ b/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass @@ -1 +1,5 @@ -@import "compass/reset" \ No newline at end of file +body + padding: 0px + margin: 0 + div + background: white \ No newline at end of file diff --git a/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass b/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass index 5a67f373..77fd4605 100755 --- a/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass +++ b/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass @@ -1,3 +1,2 @@ -@import "compass" h1 - background: image-url("blank.gif") \ No newline at end of file + background: url("images/blank.gif") \ No newline at end of file diff --git a/middleman-core/fixtures/relative-assets-app/source/javascripts/application.js b/middleman-core/fixtures/relative-assets-app/source/javascripts/application.js new file mode 100644 index 00000000..7402bc83 --- /dev/null +++ b/middleman-core/fixtures/relative-assets-app/source/javascripts/application.js @@ -0,0 +1,8 @@ +function foo() { + var img = document.createElement('img'); + img.src = '/images/100px.jpg'; + var body = document.getElementsByTagName('body')[0]; + body.insertBefore(img, body.firstChild); +} + +window.onload = foo; \ No newline at end of file diff --git a/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass b/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass index 3c10c7cf..8aec4c51 100755 --- a/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass +++ b/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass @@ -1,3 +1,2 @@ -@import "compass" h1 - background: image-url("blank.gif") + background: url("/images/blank.gif") diff --git a/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss b/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss index 0cc04182..a44b6e67 100755 --- a/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss +++ b/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss @@ -1 +1,3 @@ -@import "compass/reset"; \ No newline at end of file +html, body { + width: 100%; +} \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 729ebdc3..9fd5f985 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -32,14 +32,6 @@ Middleman::Extensions.register :default_helpers, auto_activate: :before_configur Middleman::CoreExtensions::DefaultHelpers end -# Compass framework -begin - require 'middleman-core/core_extensions/compass' - Middleman::Extensions.register :compass, Middleman::CoreExtensions::Compass, auto_activate: :before_configuration -rescue LoadError - # Compass is not available, don't complain about it -end - # Lorem provides a handful of helpful prototyping methods to generate # words, paragraphs, fake images, names and email addresses. Middleman::Extensions.register :lorem, auto_activate: :before_configuration do diff --git a/middleman-core/lib/middleman-core/core_extensions/compass.rb b/middleman-core/lib/middleman-core/core_extensions/compass.rb deleted file mode 100644 index 1d3c13c0..00000000 --- a/middleman-core/lib/middleman-core/core_extensions/compass.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'middleman-core/renderers/sass' -require 'compass' - -class Middleman::CoreExtensions::Compass < ::Middleman::Extension - def initialize(app, options_hash={}, &block) - super - - # Hooks to manually update the compass config after we're - # done with it - app.define_hook :compass_config - - # Location of SASS/SCSS files external to source directory. - # @return [Array] - # config[:sass_assets_paths] = ["#{root}/assets/sass/", "/path/2/external/sass/repository/"] - app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' - end - - def after_configuration - ::Compass.configuration do |compass_config| - compass_config.project_path = app.source_dir - compass_config.environment = :development - compass_config.cache = false - compass_config.sass_dir = app.config[:css_dir] - compass_config.css_dir = app.config[:css_dir] - compass_config.javascripts_dir = app.config[:js_dir] - compass_config.fonts_dir = app.config[:fonts_dir] - compass_config.images_dir = app.config[:images_dir] - compass_config.http_path = app.config[:http_prefix] - - app.config[:sass_assets_paths].each do |path| - compass_config.add_import_path path - end - - # Disable this initially, the cache_buster extension will - # re-enable it if requested. - compass_config.asset_cache_buster { |_| nil } - - # Disable this initially, the relative_assets extension will - - compass_config.relative_assets = false - - # Default output style - compass_config.output_style = :nested - - # No line-comments in test mode (changing paths mess with sha1) - compass_config.line_comments = false if ENV['TEST'] - end - - # Call hook - app.run_hook_for :compass_config, app, ::Compass.configuration - - # Tell Tilt to use it as well (for inline sass blocks) - ::Tilt.register 'sass', CompassSassTemplate - ::Tilt.prefer(CompassSassTemplate) - - # Tell Tilt to use it as well (for inline scss blocks) - ::Tilt.register 'scss', CompassScssTemplate - ::Tilt.prefer(CompassScssTemplate) - end - - # A Compass Sass template for Tilt, adding our options in - class CompassSassTemplate < ::Middleman::Renderers::Sass::SassPlusCSSFilenameTemplate - def sass_options - super.merge(::Compass.configuration.to_sass_engine_options) - end - end - - # A Compass Scss template for Tilt, adding our options in - class CompassScssTemplate < ::Middleman::Renderers::Sass::ScssPlusCSSFilenameTemplate - def sass_options - super.merge(::Compass.configuration.to_sass_engine_options) - end - end -end diff --git a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb index aeaaf500..0388f7f7 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -162,27 +162,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @param [Hash] options Data to pass through. # @return [String] def asset_path(kind, source, options={}) - return source if source.to_s.include?('//') || source.to_s.start_with?('data:') - - asset_folder = case kind - when :css - config[:css_dir] - when :js - config[:js_dir] - when :images - config[:images_dir] - when :fonts - config[:fonts_dir] - else - kind.to_s - end - - source = source.to_s.tr(' ', '') - ignore_extension = (kind == :images || kind == :fonts) # don't append extension - source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") - asset_folder = '' if source.start_with?('/') # absolute path - - asset_url(source, asset_folder, options) + ::Middleman::Util.asset_path(app, kind, source, options) end # Get the URL of an asset given a type/prefix @@ -190,22 +170,8 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @param [String] path The path (such as "photo.jpg") # @param [String] prefix The type prefix (such as "images") # @return [String] The fully qualified asset url - def asset_url(path, prefix='', _) - # Don't touch assets which already have a full path - if path.include?('//') || path.start_with?('data:') - path - else # rewrite paths to use their destination path - if resource = sitemap.find_resource_by_destination_path(url_for(path)) - resource.url - else - path = File.join(prefix, path) - if resource = sitemap.find_resource_by_path(path) - resource.url - else - File.join(config[:http_prefix], path) - end - end - end + def asset_url(path, prefix='', options={}) + ::Middleman::Util.asset_url(app, prefix, options) end # Given a source path (referenced either absolutely or relatively) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index b6efa1d7..475024a1 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -14,6 +14,9 @@ module Middleman app.define_hook :build_config app.define_hook :development_config + app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' + app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] + app.extend ClassMethods app.delegate :configure, to: :"self.class" end @@ -90,7 +93,7 @@ module Middleman activate ext_name end - if ENV['AUTOLOAD_SPROCKETS'] != 'false' + if config[:autoload_sprockets] begin require 'middleman-sprockets' activate :sprockets diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index c0f531d9..ab8f4fac 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -26,7 +26,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension :proc => method(:rewrite_url) end - def rewrite_url(asset_path, dirpath) + def rewrite_url(asset_path, dirpath, request_path) relative_path = Pathname.new(asset_path).relative? full_asset_path = if relative_path diff --git a/middleman-core/lib/middleman-core/extensions/asset_host.rb b/middleman-core/lib/middleman-core/extensions/asset_host.rb index 2234bdcf..9a872b5d 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_host.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_host.rb @@ -1,51 +1,36 @@ +require 'middleman-core/middleware/inline_url_rewriter' -# Asset Host module class Middleman::Extensions::AssetHost < ::Middleman::Extension - option :host, nil, 'The asset host to use, or false for no asset host, or a Proc to determine asset host' + option :host, nil, 'The asset host to use or a Proc to determine asset host' + option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif), 'List of extensions that get cache busters strings appended to them.' + option :sources, %w(.htm .html .php .css .js), 'List of extensions that are searched for bustable assets.' + option :ignore, [], 'Regexes of filenames to skip adding query strings to' - def initialize(app, options_hash={}, &block) - super - - # Backwards compatible API - app.config.define_setting :asset_host, nil, 'The asset host to use, or false for no asset host, or a Proc to determine asset host' - - app.compass_config do |config| - if asset_host = extensions[:asset_host].host - if asset_host.is_a?(Proc) - config.asset_host(&asset_host) - else - config.asset_host do |_| - asset_host - end - end - end - end if app.respond_to?(:compass_config) + def after_configuration + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :asset_host, + :url_extensions => options.exts, + :source_extensions => options.sources, + :ignore => options.ignore, + :middleman_app => app, + :proc => method(:rewrite_url) end - def host - app.config[:asset_host] || options[:host] - end + def rewrite_url(asset_path, dirpath, request_path) + relative_path = Pathname.new(asset_path).relative? - helpers do - # Override default asset url helper to include asset hosts - # - # @param [String] path - # @param [String] prefix - # @param [Hash] options Data to pass through. - # @return [String] - def asset_url(path, prefix='', options={}) - controller = extensions[:asset_host] - - original_output = super - return original_output unless controller.host - - asset_prefix = if controller.host.is_a?(Proc) - controller.host.call(original_output) - elsif controller.host.is_a?(String) - controller.host - end - - File.join(asset_prefix, original_output) + full_asset_path = if relative_path + dirpath.join(asset_path).to_s + else + asset_path end + + asset_prefix = if options[:host].is_a?(Proc) + options[:host].call(full_asset_path) + elsif options[:host].is_a?(String) + options[:host] + end + + File.join(asset_prefix, full_asset_path) end end diff --git a/middleman-core/lib/middleman-core/extensions/cache_buster.rb b/middleman-core/lib/middleman-core/extensions/cache_buster.rb index 7036d5fc..b6ffd1d9 100644 --- a/middleman-core/lib/middleman-core/extensions/cache_buster.rb +++ b/middleman-core/lib/middleman-core/extensions/cache_buster.rb @@ -1,56 +1,26 @@ # The Cache Buster extension class Middleman::Extensions::CacheBuster < ::Middleman::Extension + option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif), 'List of extensions that get cache busters strings appended to them.' + option :sources, %w(.htm .html .php .css .js), 'List of extensions that are searched for bustable assets.' + option :ignore, [], 'Regexes of filenames to skip adding query strings to' + def initialize(app, options_hash={}, &block) super - # After compass is setup, make it use the registered cache buster - app.compass_config do |config| - config.asset_cache_buster do |path, real_path| - real_path = real_path.path if real_path.is_a? File - real_path = real_path.gsub(File.join(app.root, app.config[:build_dir]), app.config[:source]) - if File.readable?(real_path) - File.mtime(real_path).strftime('%s') - else - logger.warn "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}" - end - end - end if app.respond_to?(:compass_config) + require 'middleman-core/middleware/inline_url_rewriter' end - helpers do - # asset_url override if we're using cache busting - # @param [String] path - # @param [String] prefix - # @param [Hash] options Data to pass through. - def asset_url(path, prefix='', options={}) - http_path = super + def after_configuration + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :cache_buster, + :url_extensions => options.exts, + :source_extensions => options.sources, + :ignore => options.ignore, + :middleman_app => app, + :proc => method(:rewrite_url) + end - if http_path.include?('://') || !%w(.css .png .jpg .jpeg .svg .svgz .js .gif).include?(File.extname(http_path)) - http_path - else - if respond_to?(:http_images_path) && prefix == http_images_path - prefix = images_dir - end - - real_path_static = File.join(prefix, path) - - if build? - real_path_dynamic = File.join(config[:build_dir], prefix, path) - real_path_dynamic = File.expand_path(real_path_dynamic, root) - http_path << '?' + File.mtime(real_path_dynamic).strftime('%s') if File.readable?(real_path_dynamic) - elsif resource = sitemap.find_resource_by_path(real_path_static) - if !resource.template? - http_path << '?' + File.mtime(resource.source_file).strftime('%s') - else - # It's a template, possible with partials. We can't really - # know when it's updated, so generate fresh cache buster every - # time during developement - http_path << '?' + Time.now.strftime('%s') - end - end - - http_path - end - end + def rewrite_url(asset_path, dirpath, request_path) + asset_path + '?' + Time.now.strftime('%s') end end diff --git a/middleman-core/lib/middleman-core/extensions/relative_assets.rb b/middleman-core/lib/middleman-core/extensions/relative_assets.rb index ec7d3cf0..474f914a 100644 --- a/middleman-core/lib/middleman-core/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-core/extensions/relative_assets.rb @@ -1,31 +1,37 @@ # Relative Assets extension class Middleman::Extensions::RelativeAssets < ::Middleman::Extension + option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif .ttf .otf .woff), 'List of extensions that get cache busters strings appended to them.' + option :sources, %w(.htm .html .css), 'List of extensions that are searched for relative assets.' + option :ignore, [], 'Regexes of filenames to skip adding query strings to' + def initialize(app, options_hash={}, &block) super - # After compass is setup, make it use the registered cache buster - app.compass_config do |config| - config.relative_assets = true - end if app.respond_to?(:compass_config) + require 'middleman-core/middleware/inline_url_rewriter' end - helpers do - # asset_url override for relative assets - # @param [String] path - # @param [String] prefix - # @param [Hash] options Data to pass through. - # @return [String] - def asset_url(path, prefix='', options={}) - path = super + def after_configuration + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :asset_hash, + :url_extensions => options.exts, + :source_extensions => options.sources, + :ignore => options.ignore, + :middleman_app => app, + :proc => method(:rewrite_url) + end - requested_resource = options[:current_resource] || current_resource + def rewrite_url(asset_path, dirpath, request_path) + relative_path = Pathname.new(asset_path).relative? - if path.include?('//') || path.start_with?('data:') || !requested_resource - path - else - current_dir = Pathname('/' + requested_resource.destination_path) - Pathname(path).relative_path_from(current_dir.dirname).to_s - end + full_asset_path = if relative_path + dirpath.join(asset_path).to_s + else + asset_path + end + + if !full_asset_path.include?('//') && !asset_path.start_with?('data:') + current_dir = Pathname('/' + request_path).dirname + Pathname(full_asset_path).relative_path_from(current_dir).to_s end end end diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb index 4617b07d..d0fbc115 100644 --- a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -49,7 +49,7 @@ module Middleman asset_path end - @ignore.none? { |r| should_ignore?(r, full_asset_path) } && @proc.call(asset_path, dirpath) + @ignore.none? { |r| should_ignore?(r, full_asset_path) } && @proc.call(asset_path, dirpath, path) end status, headers, response = ::Rack::Response.new( diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 9c7a237a..3baf2872 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -38,8 +38,13 @@ module Middleman class << self # Once registered def registered(app) + opts = { output_style: :nested } + opts[:line_comments] = false if ENV['TEST'] + # Default sass options - app.config.define_setting :sass, {}, 'Sass engine options' + app.config.define_setting :sass, opts, 'Sass engine options' + + app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' # Tell Tilt to use it as well (for inline sass blocks) ::Tilt.register 'sass', SassPlusCSSFilenameTemplate @@ -50,6 +55,8 @@ module Middleman ::Tilt.prefer(ScssPlusCSSFilenameTemplate) ::Compass::ImportOnce.activate! + + require 'middleman-core/renderers/sass_functions' end alias_method :included, :registered @@ -88,14 +95,22 @@ module Middleman # Change Sass path, for url functions, to the build folder if we're building # @return [Hash] def sass_options - more_opts = { filename: eval_file, line: line, syntax: syntax } + ctx = ::Middleman::Renderers::Haml.last_haml_scope || @context - if @context.is_a?(::Middleman::TemplateContext) && file - location_of_sass_file = @context.source_dir + more_opts = { + load_paths: ctx.config[:sass_assets_paths], + filename: eval_file, + line: line, + syntax: syntax, + custom: { middleman_context: ctx.app } + } + + if ctx.is_a?(::Middleman::TemplateContext) && file + location_of_sass_file = ctx.source_dir parts = basename.split('.') parts.pop - more_opts[:css_filename] = File.join(location_of_sass_file, @context.config[:css_dir], parts.join('.')) + more_opts[:css_filename] = File.join(location_of_sass_file, ctx.config[:css_dir], parts.join('.')) end options.merge(more_opts) diff --git a/middleman-core/lib/middleman-core/renderers/sass_functions.rb b/middleman-core/lib/middleman-core/renderers/sass_functions.rb new file mode 100644 index 00000000..e7d955ac --- /dev/null +++ b/middleman-core/lib/middleman-core/renderers/sass_functions.rb @@ -0,0 +1,117 @@ +module Sprockets + module Sass + module Functions + + # Using Middleman::Util#asset_path, return the full path + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # background: url(image-path("image.jpg")); // background: url("/assets/image.jpg"); + # background: url(image-path("image.jpg", $digest: true)); // background: url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg"); + # + def image_path(source, options = {}) + p = ::Middleman::Util.asset_path(middleman_context, :images, source.value, map_options(options)) + ::Sass::Script::String.new p.to_s, :string + end + + # Using Middleman::Util#asset_path, return the url CSS + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # background: image-url("image.jpg"); // background: url("/assets/image.jpg"); + # background: image-url("image.jpg", $digest: true); // background: url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg"); + # + def image_url(source, options = {}, cache_buster = nil) + # Work with the Compass #image_url API + if options.respond_to? :value + case options.value + when true + return image_path source + else + options = {} + end + end + ::Sass::Script::String.new "url(#{image_path(source, options)})" + end + + # Using Middleman::Util#asset_path, return the full path + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # src: url(font-path("font.ttf")); // src: url("/assets/font.ttf"); + # src: url(font-path("font.ttf", $digest: true)); // src: url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf"); + # + def font_path(source, options = {}) + p = ::Middleman::Util.asset_path(middleman_context, :fonts, source.value, map_options(options)) + ::Sass::Script::String.new p.to_s, :string + end + + # Using Middleman::Util#asset_path, return the url CSS + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # src: font-url("font.ttf"); // src: url("/assets/font.ttf"); + # src: font-url("image.jpg", $digest: true); // src: url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf"); + # + def font_url(source, options = {}) + # Work with the Compass #font_url API + if options.respond_to? :value + case options.value + when true + return font_path source + else + options = {} + end + end + ::Sass::Script::String.new "url(#{font_path(source, options)})" + end + + protected + + # Returns a reference to Middleman's context through + # the importer. + def middleman_context # :nodoc: + options[:custom][:middleman_context] + end + + # Returns an options hash where the keys are symbolized + # and the values are unwrapped Sass literals. + def map_options(options = {}) # :nodoc: + ::Sass::Util.map_hash(options) do |key, value| + [key.to_sym, value.respond_to?(:value) ? value.value : value] + end + end + end + end +end + +module Sass::Script::Functions + include Sprockets::Sass::Functions + + # Hack to ensure previous API declarations (by Compass or whatever) + # don't take precedence. + [:asset_path, :asset_url, :image_path, :image_url, :font_path, :font_url, :asset_data_uri].each do |method| + defined?(@signatures) && @signatures.delete(method) + end + + declare :asset_path, [:source], :var_kwargs => true + declare :asset_path, [:source, :kind] + declare :asset_url, [:source], :var_kwargs => true + declare :asset_url, [:source, :kind] + declare :image_path, [:source], :var_kwargs => true + declare :image_url, [:source], :var_kwargs => true + declare :image_url, [:source, :only_path] + declare :image_url, [:source, :only_path, :cache_buster] + declare :font_path, [:source], :var_kwargs => true + declare :font_url, [:source], :var_kwargs => true + declare :font_url, [:source, :only_path] + declare :asset_data_uri, [:source] +end diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index 16bf2f25..46ecaa08 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -33,7 +33,7 @@ module Middleman app.after_configuration do context_hack = { - context: self + context: self.template_context_class.new(self) } ::Slim::Embedded::SassEngine.disable_option_validator! diff --git a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb index 52394f89..0009e67a 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -97,6 +97,14 @@ Then /^I should not see "([^\"]*)"$/ do |expected| @last_response.body.should_not include(expected) end +Then /^I should see content matching %r{(.*)}$/ do |expected| + @last_response.body.should match(expected) +end + +Then /^I should not see content matching %r{(.*)}$/ do |expected| + @last_response.body.should_not match(expected) +end + Then /^I should see "([^\"]*)" lines$/ do |lines| @last_response.body.chomp.split($/).length.should == lines.to_i end diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index a9f7c22c..1b47db05 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -37,6 +37,7 @@ module Middleman # Sandboxed class for template eval context = @app.template_context_class.new(@app, locs, opts) + # TODO: Only for HAML files context.init_haml_helpers if context.respond_to?(:init_haml_helpers) # Keep rendering template until we've used up all extensions. This diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 03c06e05..80800ac2 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -135,6 +135,55 @@ module Middleman end end + # Get the path of a file of a given type + # + # @param [Symbol] kind The type of file + # @param [String] source The path to the file + # @param [Hash] options Data to pass through. + # @return [String] + def asset_path(app, kind, source, options={}) + return source if source.to_s.include?('//') || source.to_s.start_with?('data:') + + asset_folder = case kind + when :css then app.config[:css_dir] + when :js then app.config[:js_dir] + when :images then app.config[:images_dir] + when :fonts then app.config[:fonts_dir] + else kind.to_s + end + + source = source.to_s.tr(' ', '') + ignore_extension = (kind == :images || kind == :fonts) # don't append extension + source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") + asset_folder = '' if source.start_with?('/') # absolute path + + asset_url(app, source, asset_folder, options) + end + + # Get the URL of an asset given a type/prefix + # + # @param [String] path The path (such as "photo.jpg") + # @param [String] prefix The type prefix (such as "images") + # @param [Hash] options Data to pass through. + # @return [String] The fully qualified asset url + def asset_url(app, path, prefix='', options={}) + # Don't touch assets which already have a full path + if path.include?('//') or path.start_with?('data:') + path + else # rewrite paths to use their destination path + if resource = app.sitemap.find_resource_by_destination_path(url_for(app, path)) + resource.url + else + path = File.join(prefix, path) + if resource = app.sitemap.find_resource_by_path(path) + resource.url + else + File.join(app.config[:http_prefix], path) + end + end + end + end + # Given a source path (referenced either absolutely or relatively) # or a Resource, this will produce the nice URL configured for that # path, respecting :relative_links, directory indexes, etc. diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index 070339ab..9da9f039 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -37,4 +37,14 @@ Gem::Specification.new do |s| # Automatic Image Sizes s.add_dependency('fastimage', ['~> 1.6.2']) + + # Minify CSS + s.add_dependency('sass', ['>= 3.3.4']) + + # Work around Sass performance + s.add_dependency('compass-import-once', ['~> 1.0.4']) + + # Minify JS + s.add_dependency('uglifier', ['~> 2.5']) + s.add_dependency('execjs', ['~> 2.0']) end diff --git a/middleman/middleman.gemspec b/middleman/middleman.gemspec index e0268027..045919b9 100644 --- a/middleman/middleman.gemspec +++ b/middleman/middleman.gemspec @@ -21,12 +21,8 @@ Gem::Specification.new do |s| s.add_dependency('middleman-core', Middleman::VERSION) s.add_dependency('middleman-cli', Middleman::VERSION) s.add_dependency('middleman-sprockets', '>= 3.1.2') + s.add_dependency('middleman-compass', '~> 4.0.0') s.add_dependency('haml', ['>= 4.0.5']) - s.add_dependency('sass', ['>= 3.3.4']) - s.add_dependency("compass-import-once", ["1.0.4"]) - s.add_dependency('compass', ['>= 1.0.0.alpha.19']) - s.add_dependency('uglifier', ['~> 2.5']) s.add_dependency('coffee-script', ['~> 2.2.0']) - s.add_dependency('execjs', ['~> 2.0']) s.add_dependency('kramdown', ['~> 1.2']) end