middleman-sprockets 4.0.0.beta.1 → 4.0.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -3
  3. data/Gemfile +15 -16
  4. data/README.md +0 -58
  5. data/Rakefile +1 -16
  6. data/features/asset_hash.feature +5 -6
  7. data/features/bower.feature +6 -6
  8. data/features/sprockets.feature +13 -65
  9. data/features/sprockets_gems.feature +7 -26
  10. data/features/step_definitions/server_steps.rb +0 -4
  11. data/fixtures/asset-paths-app/config.rb +1 -4
  12. data/fixtures/bower-app/config.rb +0 -2
  13. data/fixtures/bower-app/source/javascripts/application.js +1 -1
  14. data/fixtures/bower-app/source/javascripts/import.js +1 -0
  15. data/fixtures/bower-individual-outputdir-app/config.rb +0 -4
  16. data/fixtures/bower-individual-outputdir-app/source/javascripts/application.js +3 -0
  17. data/fixtures/bower-multiple-assets-app/config.rb +1 -7
  18. data/fixtures/{sprockets-app-debug-assets/source/stylesheets/dependency1.css → bower-multiple-assets-app/source/index.html} +0 -0
  19. data/fixtures/bower-multiple-assets-app/source/javascripts/core.js +2 -0
  20. data/fixtures/jquery-mobile-app/source/javascripts/app.js +1 -0
  21. data/fixtures/sprockets-app/config.rb +0 -5
  22. data/fixtures/sprockets-app/source/library/css/bootstrap_include.css.scss +1 -1
  23. data/fixtures/sprockets-app/source/library/css/plain.css +2 -0
  24. data/fixtures/sprockets-app/source/library/css/sprockets_base2.css.scss +1 -1
  25. data/fixtures/sprockets-app/source/library/js/jquery_include.js +1 -1
  26. data/fixtures/sprockets-app/source/library/js/plain.js +3 -0
  27. data/fixtures/sprockets-app2/source/stylesheets/sprockets_base2.css.scss +1 -1
  28. data/fixtures/sprockets-imported-asset-path-conflicts-app/config.rb +1 -1
  29. data/fixtures/sprockets-imported-assets-match-multiple-paths-app/config.rb +1 -1
  30. data/fixtures/sprockets-multiple-extensions-app/config.rb +0 -3
  31. data/fixtures/sprockets-multiple-extensions-app/source/stylesheets/app.css.scss +3 -0
  32. data/fixtures/sprockets-svg-font-app/config.rb +0 -4
  33. data/fixtures/sprockets-svg-font-app/source/stylesheets/app.css.scss +4 -0
  34. data/lib/middleman-sprockets.rb +1 -6
  35. data/lib/middleman-sprockets/extension.rb +197 -113
  36. data/lib/middleman-sprockets/version.rb +1 -1
  37. data/middleman-sprockets.gemspec +2 -4
  38. metadata +29 -74
  39. data/Gemfile-Sprockets3 +0 -36
  40. data/Gemfile-v3 +0 -36
  41. data/features/asset_hash-3.0.feature +0 -105
  42. data/fixtures/sprockets-app-debug-assets/config.rb +0 -1
  43. data/fixtures/sprockets-app-debug-assets/source/index.html.erb +0 -8
  44. data/fixtures/sprockets-app-debug-assets/source/javascripts/dependency1.js +0 -3
  45. data/fixtures/sprockets-app-debug-assets/source/javascripts/dependency2.js +0 -1
  46. data/fixtures/sprockets-app-debug-assets/source/javascripts/main.js +0 -4
  47. data/fixtures/sprockets-app-debug-assets/source/stylesheets/app.css.scss +0 -4
  48. data/fixtures/sprockets-app-debug-assets/source/stylesheets/dependency2.css.scss +0 -0
  49. data/lib/middleman-sprockets/asset.rb +0 -142
  50. data/lib/middleman-sprockets/asset_tag_helpers.rb +0 -54
  51. data/lib/middleman-sprockets/config_only_environment.rb +0 -50
  52. data/lib/middleman-sprockets/environment.rb +0 -293
  53. data/lib/middleman-sprockets/imported_asset.rb +0 -30
  54. data/lib/middleman-sprockets/sass_function_hack.rb +0 -9
  55. data/lib/middleman-sprockets/sass_utils.rb +0 -14
  56. data/spec/asset_spec.rb +0 -118
  57. data/spec/imported_asset_spec.rb +0 -42
@@ -1 +1,4 @@
1
+ //= link "underscore/underscore.js"
2
+ //= link "lightbox2/img/close.png"
3
+ //= link "lightbox2/js/lightbox.js"
1
4
  //= require underscore/underscore
@@ -1,7 +1 @@
1
- set :css_dir, 'stylesheets'
2
- set :js_dir, 'javascripts'
3
- set :images_dir, 'images'
4
-
5
- sprockets.append_path File.join(root, 'vendor/assets/components')
6
- sprockets.import_asset 'lightbox2/img/close.png'
7
- sprockets.import_asset 'lightbox2/js/lightbox.js'
1
+ sprockets.append_path File.join(root, 'vendor/assets/components')
@@ -0,0 +1,2 @@
1
+ //= link "lightbox2/img/close.png"
2
+ //= link "lightbox2/js/lightbox.js"
@@ -0,0 +1 @@
1
+ //= link "jquery.mobile"
@@ -1,7 +1,2 @@
1
1
  set :js_dir, "library/js"
2
2
  set :css_dir, "library/css"
3
-
4
- after_configuration do
5
- sprockets.import_asset "vendored.css"
6
- sprockets.import_asset "coffee.js"
7
- end
@@ -1 +1 @@
1
- //= require "bootstrap.scss"
1
+ //= require "bootstrap.scss"
@@ -1,3 +1,5 @@
1
+ /*= link "vendored.css" */
2
+
1
3
  #helloWorld {
2
4
  color: red;
3
5
  }
@@ -1 +1 @@
1
- @import "sprockets_sub";
1
+ @import "sprockets_sub.css";
@@ -1 +1 @@
1
- //= require "jquery"
1
+ //= require "jquery"
@@ -1,3 +1,6 @@
1
+ //= link "vendored_js"
2
+ //= link "coffee"
3
+
1
4
  function hellowWorld() {
2
5
 
3
6
  }
@@ -1 +1 @@
1
- @import "sprockets_sub";
1
+ @import "sprockets_sub.css";
@@ -1,4 +1,4 @@
1
1
  set :css_dir, "assets/css"
2
2
 
3
3
  sprockets.append_path File.join(root, 'resources/assets')
4
- sprockets.import_asset "stylesheets/test"
4
+ # sprockets.import_asset "stylesheets/test"
@@ -1,4 +1,4 @@
1
1
  set :css_dir, "assets/css"
2
2
 
3
3
  sprockets.append_path File.join(root, 'vendor/assets')
4
- sprockets.import_asset "css/test"
4
+ # sprockets.import_asset "css/test"
@@ -1,4 +1 @@
1
1
  sprockets.append_path File.join(root, 'vendor/assets/components')
2
- sprockets.import_asset('font-awesome/fonts/fontawesome-webfont-bower.svg.gz')
3
- sprockets.import_asset('jquery/jquery.min.js')
4
- sprockets.import_asset('jquery/jquery.asdf.asdf.js.min.asdf')
@@ -0,0 +1,3 @@
1
+ //= link "font-awesome/fonts/fontawesome-webfont-bower.svg.gz"
2
+ //= link "jquery/jquery.min.js"
3
+ //= link "jquery/jquery.asdf.asdf.js.min.asdf"
@@ -1,5 +1 @@
1
1
  sprockets.append_path File.join(root, 'vendor/assets/components')
2
- sprockets.import_asset('blub/images/drawing-bower.svg')
3
- sprockets.import_asset('font-awesome/fonts/fontawesome-webfont-bower.svg')
4
- sprockets.import_asset('font-awesome/fonts/fontawesome-webfont-bower.svg.gz')
5
- sprockets.import_asset('font-awesome/fonts/fontawesome-webfont-bower.ttf.gz')
@@ -0,0 +1,4 @@
1
+ //= link "blub/images/drawing-bower.svg"
2
+ //= link "font-awesome/fonts/fontawesome-webfont-bower.svg"
3
+ //= link "font-awesome/fonts/fontawesome-webfont-bower.svg.gz"
4
+ //= link "font-awesome/fonts/fontawesome-webfont-bower.ttf.gz"
@@ -1,11 +1,6 @@
1
1
  require "middleman-core"
2
2
 
3
- params = [:sprockets]
4
-
5
- # If we're in v4
6
- params << { auto_activate: :before_configuration } if Middleman::Extensions.method(:register).arity != -1
7
-
8
- Middleman::Extensions.register(*params) do
3
+ Middleman::Extensions.register(:sprockets, auto_activate: :before_configuration) do
9
4
  require "middleman-sprockets/extension"
10
5
  Middleman::SprocketsExtension
11
6
  end
@@ -1,148 +1,206 @@
1
1
  require "sprockets"
2
- require "sprockets-sass"
3
- require "middleman-sprockets/asset"
4
- require "middleman-sprockets/imported_asset"
5
- require "middleman-sprockets/config_only_environment"
6
- require "middleman-sprockets/environment"
7
- require "middleman-sprockets/asset_tag_helpers"
8
-
9
- class Sprockets::Sass::SassTemplate
10
- # Get the default, global Sass options. Start with Compass's
11
- # options, if it's available.
12
- def default_sass_options
13
- if defined?(Compass) && defined?(Compass.configuration)
14
- merge_sass_options Compass.configuration.to_sass_engine_options.dup, Sprockets::Sass.options
15
- else
16
- Sprockets::Sass.options.dup
17
- end
18
- end
19
- end
20
-
21
- IS_V4 = ::Middleman::Extension.respond_to? :expose_to_config
2
+ require "middleman-core/sitemap/resource"
22
3
 
23
- # Sprockets extension
24
4
  module Middleman
25
5
  class SprocketsExtension < Extension
26
- option :debug_assets, false, 'Split up each required asset into its own script/style tag instead of combining them (development only)'
27
-
28
6
  attr_reader :environment
29
7
 
30
- if IS_V4
31
- expose_to_config sprockets: :environment
32
- expose_to_template sprockets: :environment
33
- end
34
-
35
- # This module gets mixed into both the Middleman instance and the Middleman class,
36
- # so that it's available in config.rb
37
- module SprocketsAccessor
38
- # The sprockets environment
39
- # @return [Middleman::MiddlemanSprocketsEnvironment]
40
- def sprockets
41
- extensions[:sprockets].environment
42
- end
43
- end
8
+ expose_to_config sprockets: :environment
44
9
 
45
10
  def initialize(app, options_hash={}, &block)
46
- require "middleman-sprockets/sass_function_hack"
47
- require "middleman-sprockets/sass_utils"
48
-
49
11
  super
50
12
 
51
- # Start out with a stub environment that can only be configured (paths and such)
52
- @environment = ::Middleman::Sprockets::ConfigOnlyEnvironment.new
13
+ @inline_asset_references = Set.new
53
14
 
54
- # v3
55
- app.send :include, SprocketsAccessor if !IS_V4
56
- end
15
+ @environment = ::Sprockets::Environment.new
57
16
 
58
- helpers do
59
- include SprocketsAccessor if !IS_V4
60
- include ::Middleman::Sprockets::AssetTagHelpers
17
+ app.config.define_setting :sprockets_imported_asset_path, "assets", "Where under source should imported assets be placed."
61
18
  end
62
19
 
63
20
  def after_configuration
64
- begin
65
- require 'ejs'
66
- ::Tilt.register ::Sprockets::EjsTemplate, 'ejs'
67
- rescue LoadError
68
- end
21
+ @environment.append_path((app.source_dir + app.config[:js_dir]).to_s)
22
+ @environment.append_path((app.source_dir + app.config[:css_dir]).to_s)
69
23
 
70
- begin
71
- require 'eco'
72
- ::Tilt.register ::Sprockets::EcoTemplate, 'eco'
73
- rescue LoadError
74
- end
75
-
76
- ::Tilt.register ::Sprockets::JstProcessor, 'jst'
77
-
78
- if app.respond_to?(:template_extensions)
79
- app.template_extensions :jst => :js, :eco => :js, :ejs => :js
80
- end
24
+ append_paths_from_gems
81
25
 
82
- if app.config.defines_setting?(:debug_assets) && !options.setting(:debug_assets).value_set?
83
- options[:debug_assets] = app.config[:debug_assets]
26
+ the_app = app
27
+ the_env = environment
28
+
29
+ @environment.context_class.send(:define_method, :app) { the_app }
30
+ @environment.context_class.send(:define_method, :data) { the_app.data }
31
+ @environment.context_class.send(:define_method, :env) { the_env }
32
+
33
+ @environment.context_class.class_eval do
34
+ def asset_path(path, options = {})
35
+ # Handle people calling with the Middleman/Padrino asset path signature
36
+ if path.is_a?(::Symbol) && !options.is_a?(::Hash)
37
+ kind = path
38
+ path = options
39
+ else
40
+
41
+ kind = case options[:type]
42
+ when :image then :images
43
+ when :font then :fonts
44
+ when :javascript then :js
45
+ when :stylesheet then :css
46
+ else options[:type]
47
+ end
48
+ end
49
+
50
+ if app.extensions[:sprockets].check_asset(path)
51
+ "/#{app.config[:sprockets_imported_asset_path]}/#{path}"
52
+ else
53
+ app.asset_path(kind, path)
54
+ end
55
+ end
84
56
  end
57
+ end
85
58
 
86
- config_environment = @environment
87
- debug_assets = !app.build? && options[:debug_assets]
88
- @environment = ::Middleman::Sprockets::Environment.new(app, :debug_assets => debug_assets)
89
- config_environment.apply_to_environment(@environment)
90
-
91
- append_paths_from_gems
92
- import_images_and_fonts_from_gems
59
+ def base_resource?(r)
60
+ r.class.ancestors.first == ::Middleman::Sitemap::Resource
61
+ end
93
62
 
94
- # Setup Sprockets Sass options
95
- if app.config.defines_setting?(:sass)
96
- app.config[:sass].each { |k, v| ::Sprockets::Sass.options[k] = v }
63
+ def js?(r)
64
+ begin
65
+ r.source_file.start_with?((app.source_dir + app.config[:js_dir]).to_s)
66
+ rescue
67
+ require 'pry'
68
+ binding.pry
97
69
  end
70
+ end
98
71
 
99
- # Intercept requests to /javascripts and /stylesheets and pass to sprockets
100
- our_sprockets = self.environment
72
+ def css?(r)
73
+ r.source_file.start_with?((app.source_dir + app.config[:css_dir]).to_s)
74
+ end
101
75
 
102
- [app.config[:js_dir], app.config[:css_dir], app.config[:images_dir], app.config[:fonts_dir]].each do |dir|
103
- app.map("/#{dir}") { run our_sprockets }
76
+ def check_asset(path)
77
+ if asset = environment[path]
78
+ @inline_asset_references << path
79
+ true
80
+ else
81
+ false
104
82
  end
105
83
  end
106
84
 
107
- # Add sitemap resource for every image in the sprockets load path
108
85
  def manipulate_resource_list(resources)
109
- resources_list = []
110
-
111
- environment.prune_imported_assets!
112
- environment.imported_assets.each do |imported_asset|
113
- asset = Middleman::Sprockets::Asset.new @app, imported_asset.logical_path, environment
86
+ sprockets, non_sprockets = resources.partition do |r|
87
+ base_resource?(r) && (js?(r) || css?(r))
88
+ end
114
89
 
115
- if imported_asset.output_path
116
- destination = imported_asset.output_path
90
+ non_sprockets + sprockets.reduce([]) do |sum, r|
91
+ sprockets_path = if js?(r)
92
+ r.path.sub(%r{^#{app.config[:js_dir]}\/}, '')
117
93
  else
118
- destination = @app.sitemap.extensionless_path( asset.destination_path.to_s )
94
+ r.path.sub(%r{^#{app.config[:css_dir]}\/}, '')
119
95
  end
120
96
 
121
- # next if @app.sitemap.find_resource_by_destination_path destination.to_s
97
+ sprockets_resource = generate_resource(r.path, r.source_file, sprockets_path)
98
+ sum << sprockets_resource
122
99
 
123
- resource = ::Middleman::Sitemap::Resource.new( @app.sitemap, destination.to_s, asset.source_path.to_s )
124
- resource.add_metadata options: { sprockets: { logical_path: imported_asset.logical_path }}
100
+ if sprockets_resource.respond_to?(:sprockets_asset)
101
+ sprockets_resource.sprockets_asset.links.each do |a|
102
+ asset = environment[a]
103
+ path = "#{app.config[:sprockets_imported_asset_path]}/#{asset.logical_path}"
104
+ sum << generate_resource(path, asset.filename, asset.logical_path)
105
+ end
106
+ end
125
107
 
126
- resources_list << resource
108
+ sum
109
+ end + @inline_asset_references.map do |path|
110
+ asset = environment[path]
111
+ path = "#{app.config[:sprockets_imported_asset_path]}/#{asset.logical_path}"
112
+ generate_resource(path, asset.filename, asset.logical_path)
127
113
  end
128
-
129
- resources + resources_list
130
114
  end
131
115
 
132
116
  private
133
117
 
134
- # Add any directories from gems with Rails-like paths to sprockets load path
135
- def append_paths_from_gems
136
- root_paths = rubygems_latest_specs.map(&:full_gem_path) << app.root
137
- base_paths = %w[assets app app/assets vendor vendor/assets lib lib/assets]
138
- asset_dirs = %w[javascripts js stylesheets css images img fonts]
118
+ def generate_resource(path, source_file, sprockets_path)
119
+ begin
120
+ SprocketsResource.new(app.sitemap, path, source_file, sprockets_path, environment)
121
+ rescue Exception => e
122
+ raise e if app.build?
123
+
124
+ ext = File.extname(path)
125
+ error_message = if ext == '.css'
126
+ css_exception_response(e)
127
+ elsif ext == '.js'
128
+ javascript_exception_response(e)
129
+ else
130
+ e.to_s
131
+ end
139
132
 
140
- root_paths.product(base_paths.product(asset_dirs)).each do |root, (base, asset)|
141
- path = File.join(root, base, asset)
142
- environment.append_path(path) if File.directory?(path)
133
+ ::Middleman::Sitemap::StringResource.new(app.sitemap, path, error_message)
143
134
  end
144
135
  end
145
136
 
137
+ # Returns a JavaScript response that re-throws a Ruby exception
138
+ # in the browser
139
+ def javascript_exception_response(exception)
140
+ err = "#{exception.class.name}: #{exception.message}\n (in #{exception.backtrace[0]})"
141
+ "throw Error(#{err.inspect})"
142
+ end
143
+
144
+ # Returns a CSS response that hides all elements on the page and
145
+ # displays the exception
146
+ def css_exception_response(exception)
147
+ message = "\n#{exception.class.name}: #{exception.message}"
148
+ backtrace = "\n #{exception.backtrace.first}"
149
+
150
+ <<-CSS
151
+ html {
152
+ padding: 18px 36px;
153
+ }
154
+
155
+ head {
156
+ display: block;
157
+ }
158
+
159
+ body {
160
+ margin: 0;
161
+ padding: 0;
162
+ }
163
+
164
+ body > * {
165
+ display: none !important;
166
+ }
167
+
168
+ head:after, body:before, body:after {
169
+ display: block !important;
170
+ }
171
+
172
+ head:after {
173
+ font-family: sans-serif;
174
+ font-size: large;
175
+ font-weight: bold;
176
+ content: "Error compiling CSS asset";
177
+ }
178
+
179
+ body:before, body:after {
180
+ font-family: monospace;
181
+ white-space: pre-wrap;
182
+ }
183
+
184
+ body:before {
185
+ font-weight: bold;
186
+ content: "#{escape_css_content(message)}";
187
+ }
188
+
189
+ body:after {
190
+ content: "#{escape_css_content(backtrace)}";
191
+ }
192
+ CSS
193
+ end
194
+
195
+ # Escape special characters for use inside a CSS content("...") string
196
+ def escape_css_content(content)
197
+ content.
198
+ gsub('\\', '\\\\005c ').
199
+ gsub("\n", '\\\\000a ').
200
+ gsub('"', '\\\\0022 ').
201
+ gsub('/', '\\\\002f ')
202
+ end
203
+
146
204
  # Backwards compatible means of finding all the latest gemspecs
147
205
  # available on the system
148
206
  #
@@ -157,17 +215,43 @@ module Middleman
157
215
  end
158
216
  end
159
217
 
160
- def import_images_and_fonts_from_gems
161
- valid_paths = environment.paths
162
- .reject { |p| p.start_with?(app.source_dir.to_s) }
163
- .select { |p| p.end_with?('images') || p.end_with?('fonts') }
218
+ # Add any directories from gems with Rails-like paths to sprockets load path
219
+ def append_paths_from_gems
220
+ root_paths = rubygems_latest_specs.map(&:full_gem_path) << app.root
221
+ base_paths = %w[assets app app/assets vendor vendor/assets lib lib/assets]
222
+ asset_dirs = %w[javascripts js stylesheets css images img fonts]
223
+
224
+ root_paths.product(base_paths.product(asset_dirs)).each do |root, (base, asset)|
225
+ path = File.join(root, base, asset)
226
+ environment.append_path(path) if File.directory?(path)
227
+ end
228
+ end
229
+
230
+ class SprocketsResource < ::Middleman::Sitemap::Resource
231
+ def initialize(store, path, source_file, sprockets_path, environment)
232
+ @path = path
233
+ @sprockets_path = sprockets_path
234
+ @environment = environment
235
+ @source = sprockets_asset.source
164
236
 
165
- environment.files_in_paths(valid_paths).each do |(path, load_path)|
166
- if path.file? && !path.basename.to_s.start_with?('_')
167
- logical_path = path.sub /^#{load_path}/, ''
168
- environment.imported_assets << Middleman::Sprockets::ImportedAsset.new(logical_path)
169
- end
237
+ super(store, path, source_file)
238
+ end
239
+
240
+ def template?
241
+ true
242
+ end
243
+
244
+ def render(*)
245
+ @source
246
+ end
247
+
248
+ def sprockets_asset
249
+ @environment[@sprockets_path]
250
+ end
251
+
252
+ def binary?
253
+ false
170
254
  end
171
255
  end
172
256
  end
173
- end
257
+ end