middleman-core 3.3.11 → 3.3.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4bdee941102d480e0efde57121a8f4158b053579
4
- data.tar.gz: 4d51251656f7a673ebe12fa3c3a43ab97a885f1b
3
+ metadata.gz: 6bfeb7129e9a3c6e06a50e32856e7ec973c597a5
4
+ data.tar.gz: dbff503bac895a4e4ffa2f734e52144d0ebe3a6b
5
5
  SHA512:
6
- metadata.gz: 3645d04948555d0cc894ab7ce41b05c854a1b2e2b9c140fc087aca9d159004743a25ed4e684281cc5b99026eab36c6cf643bea374216e1b79c4392dbd657bb51
7
- data.tar.gz: 7568e90823fbfa99c5baf7aaf0ee51beb6191c0e0921ac998e5d1ff021a577fd2594e40daccd18ed8e6722cb1856358cff1046e337329bddda4cd3bdc6096bd6
6
+ metadata.gz: d983aca0f6732cad2fc53273562e67570d36f5cd20d100f756901849f256e55b8ee20583b620e227b5ee4b671b74074ab982d58aa904a3146752c4fe40d798a5
7
+ data.tar.gz: 1aed9d493d38c379270fff5b2e5da9373c88c1af73e3ea468e824e0333fb0351a0428b07be8347a790d5e328efde579f35782792ae73b40ad98b540e63f6f639
@@ -76,6 +76,13 @@ Feature: Assets get a file hash appended to their and references to them are upd
76
76
  And I should see 'images/100px-5fd6fb90.jpg'
77
77
  And I should see 'images/100px-1242c368.png'
78
78
 
79
+ Scenario: Hashed assets work with Slim
80
+ Given the Server is running at "asset-hash-app"
81
+ When I go to "/slim.html"
82
+ And I should see 'src="images/300px-59adce76.jpg"'
83
+ And I should see 'src="images/100px-5fd6fb90.jpg"'
84
+ And I should see 'srcset="images/100px-5fd6fb90.jpg 1x, images/200px-c11eb203.jpg 2x, images/300px-59adce76.jpg 3x"'
85
+
79
86
  Scenario: Enabling an asset host still produces hashed files and references
80
87
  Given the Server is running at "asset-hash-host-app"
81
88
  When I go to "/"
@@ -12,6 +12,8 @@ Feature: Setting the right content type for files
12
12
  Then the content type should be "text/css"
13
13
  When I go to "/README"
14
14
  Then the content type should be "text/plain"
15
+ When I go to "/index.php"
16
+ Then the content type should be "text/php"
15
17
 
16
18
  Scenario: Content type can be set explicitly via page or proxy or frontmatter
17
19
  Given a fixture app "content-type-app"
@@ -31,6 +33,7 @@ Feature: Setting the right content type for files
31
33
  When I go to "/override.html"
32
34
  Then the content type should be "text/neato"
33
35
 
36
+ @preserve_mime_types
34
37
  Scenario: Content types can be overridden with mime_type
35
38
  Given a fixture app "content-type-app"
36
39
  And a file named "config.rb" with:
@@ -26,6 +26,18 @@ Feature: Minify CSS
26
26
  When I go to "/stylesheets/report.css"
27
27
  Then I should see "p{border:1px solid #ff6600}"
28
28
 
29
+ Scenario: Rendering external css in a proxied resource
30
+ Given a fixture app "minify-css-app"
31
+ And a file named "config.rb" with:
32
+ """
33
+ activate :minify_css
34
+ proxy '/css-proxy', '/stylesheets/site.css', ignore: true
35
+ """
36
+ And the Server is running at "minify-css-app"
37
+ When I go to "/css-proxy"
38
+ Then I should see "1" lines
39
+ And I should see "only screen and (device-width"
40
+
29
41
  Scenario: Rendering external css with passthrough compressor
30
42
  Given a fixture app "passthrough-app"
31
43
  And a file named "config.rb" with:
@@ -124,4 +136,54 @@ Feature: Minify CSS
124
136
  <style>
125
137
  body{test:style;good:deal}
126
138
  </style>
127
- """
139
+ """
140
+
141
+ Scenario: Rendering inline css in a PHP document
142
+ Given a fixture app "minify-css-app"
143
+ And a file named "config.rb" with:
144
+ """
145
+ activate :minify_css, :inline => true
146
+ """
147
+ And the Server is running at "minify-css-app"
148
+ When I go to "/inline-css.php"
149
+ Then I should see:
150
+ """
151
+ <?='Hello'?>
152
+
153
+ <style>
154
+ body{test:style;good:deal}
155
+ </style>
156
+ """
157
+
158
+ Scenario: Rendering inline css in a proxied resource
159
+ Given a fixture app "minify-css-app"
160
+ And a file named "config.rb" with:
161
+ """
162
+ activate :minify_css, :inline => true
163
+ proxy '/inline-css-proxy', '/inline-css.html', ignore: true
164
+ """
165
+ And the Server is running at "minify-css-app"
166
+ When I go to "/inline-css-proxy"
167
+ Then I should see:
168
+ """
169
+ <style>
170
+ body{test:style;good:deal}
171
+ </style>
172
+ """
173
+
174
+ @preserve_mime_types
175
+ Scenario: Configuring content types of resources to be minified
176
+ Given a fixture app "minify-css-app"
177
+ And a file named "config.rb" with:
178
+ """
179
+ mime_type('.xcss', 'text/x-css')
180
+ activate :minify_css, content_types: ['text/x-css'],
181
+ inline: true,
182
+ inline_content_types: ['text/html']
183
+ """
184
+ And the Server is running at "minify-css-app"
185
+ When I go to "/stylesheets/site.xcss"
186
+ Then I should see "1" lines
187
+ And I should see "only screen and (device-width"
188
+ When I go to "/inline-css.php"
189
+ Then I should see "8" lines
@@ -88,7 +88,7 @@ Feature: Minify Javascript
88
88
  </script>
89
89
  """
90
90
 
91
- Scenario: Rendering inline css with a passthrough minifier using activate-style compressor
91
+ Scenario: Rendering inline JS with a passthrough minifier using activate-style compressor
92
92
  Given a fixture app "passthrough-app"
93
93
  And a file named "config.rb" with:
94
94
  """
@@ -148,6 +148,42 @@ Feature: Minify Javascript
148
148
  </script>
149
149
  """
150
150
 
151
+ Scenario: Rendering inline js in a PHP document
152
+ Given a fixture app "minify-js-app"
153
+ And a file named "config.rb" with:
154
+ """
155
+ activate :minify_javascript, :inline => true
156
+ """
157
+ And the Server is running at "minify-js-app"
158
+ When I go to "/inline-js.php"
159
+ Then I should see:
160
+ """
161
+ <?='Hello'?>
162
+
163
+ <script>
164
+ !function(){should(),all.be(),on={one:line}}();
165
+ </script>
166
+ <script type='text/javascript'>
167
+ //<!--
168
+ !function(){one,line(),here()}();
169
+ //-->
170
+ </script>
171
+ <script type='text/html'>
172
+ I'm a jQuery {{template}}.
173
+ </script>
174
+ """
175
+
176
+ Scenario: Rendering inline js in a proxied resource
177
+ Given a fixture app "minify-js-app"
178
+ And a file named "config.rb" with:
179
+ """
180
+ activate :minify_javascript, :inline => true
181
+ proxy '/inline-js-proxy', '/inline-js.html', ignore: true
182
+ """
183
+ And the Server is running at "minify-js-app"
184
+ When I go to "/inline-js-proxy"
185
+ Then I should see "14" lines
186
+
151
187
  Scenario: Rendering external js with the feature enabled
152
188
  Given a fixture app "minify-js-app"
153
189
  And a file named "config.rb" with:
@@ -160,6 +196,17 @@ Feature: Minify Javascript
160
196
  When I go to "/more-js/other.js"
161
197
  Then I should see "1" lines
162
198
 
199
+ Scenario: Rendering external js in a proxied resource
200
+ Given a fixture app "minify-js-app"
201
+ And a file named "config.rb" with:
202
+ """
203
+ activate :minify_javascript
204
+ proxy '/js-proxy', '/javascripts/js_test.js', ignore: true
205
+ """
206
+ And the Server is running at "minify-js-app"
207
+ When I go to "/js-proxy"
208
+ Then I should see "1" lines
209
+
163
210
  Scenario: Rendering external js with a passthrough minifier
164
211
  And the Server is running at "passthrough-app"
165
212
  When I go to "/javascripts/js_test.js"
@@ -0,0 +1,7 @@
1
+ Around('@preserve_mime_types') do |_scenario, block|
2
+ mime_types = ::Rack::Mime::MIME_TYPES.clone
3
+
4
+ block.call
5
+
6
+ ::Rack::Mime::MIME_TYPES.replace mime_types
7
+ end
@@ -0,0 +1,8 @@
1
+ ---
2
+ directory_index: false
3
+ layout: false
4
+ ---
5
+
6
+ = image_tag '100px.jpg', srcset: "100px.jpg 1x, 200px.jpg 2x, 300px.jpg 3x"
7
+
8
+ = image_tag "300px.jpg"
@@ -0,0 +1 @@
1
+ <?="I'm a PHP file!"?>
@@ -0,0 +1,8 @@
1
+ <?='Hello'?>
2
+
3
+ <style>
4
+ body {
5
+ test: style;
6
+ good: deal;
7
+ }
8
+ </style>
@@ -0,0 +1,5 @@
1
+ @import "compass/reset"
2
+
3
+ @media handheld, only screen and (device-width: 768px)
4
+ body
5
+ display: block
@@ -0,0 +1,22 @@
1
+ <?='Hello'?>
2
+
3
+ <script>
4
+ ;(function() {
5
+ this;
6
+ should();
7
+ all.be();
8
+ on = { one: line };
9
+ })();
10
+ </script>
11
+ <script type='text/javascript'>
12
+ //<!--
13
+ ;(function() {
14
+ one;
15
+ line();
16
+ here();
17
+ })();
18
+ //-->
19
+ </script>
20
+ <script type='text/html'>
21
+ I'm a jQuery {{template}}.
22
+ </script>
@@ -0,0 +1,8 @@
1
+ var race;
2
+ var __slice = Array.prototype.slice;
3
+
4
+ race = function() {
5
+ var runners, winner;
6
+ winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
7
+ return print(winner, runners);
8
+ };
@@ -67,14 +67,22 @@ module Middleman
67
67
  end
68
68
  delegate :root_path, to: :"self.class"
69
69
 
70
- # Which host preview should start on.
71
- # @return [Fixnum]
72
- config.define_setting :host, '0.0.0.0', 'The preview server host'
73
-
74
70
  # Which port preview should start on.
75
71
  # @return [Fixnum]
76
72
  config.define_setting :port, 4567, 'The preview server port'
77
73
 
74
+ # Whether to serve the preview server over HTTPS.
75
+ # @return [Boolean]
76
+ config.define_setting :https, false, 'Serve the preview server over SSL/TLS'
77
+
78
+ # The (optional) path to the SSL cert to use for the preview server.
79
+ # @return [String]
80
+ config.define_setting :ssl_certificate, nil, 'Path to an X.509 certificate to use for the preview server'
81
+
82
+ # The (optional) private key for the certificate in :ssl_certificate.
83
+ # @return [String]
84
+ config.define_setting :ssl_private_key, nil, "Path to an RSA private key for the preview server's certificate"
85
+
78
86
  # Name of the source directory
79
87
  # @return [String]
80
88
  config.define_setting :source, 'source', 'Name of the source directory'
@@ -11,13 +11,16 @@ module Middleman::Cli
11
11
  aliases: '-e',
12
12
  default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development',
13
13
  desc: 'The environment Middleman will run under'
14
- method_option :host,
15
- type: :string,
16
- aliases: '-h',
17
- desc: 'Bind to HOST address'
18
14
  method_option :port,
19
15
  aliases: '-p',
20
16
  desc: 'The port Middleman will listen on'
17
+ method_option :https,
18
+ type: :boolean,
19
+ desc: 'Serve the preview server over SSL/TLS'
20
+ method_option :ssl_certificate,
21
+ desc: 'Path to an X.509 certificate to use for the preview server'
22
+ method_option :ssl_private_key,
23
+ desc: "Path to an RSA private key for the preview server's certificate"
21
24
  method_option :verbose,
22
25
  type: :boolean,
23
26
  default: false,
@@ -62,7 +65,9 @@ module Middleman::Cli
62
65
 
63
66
  params = {
64
67
  port: options['port'],
65
- host: options['host'],
68
+ https: options['https'],
69
+ ssl_certificate: options['ssl_certificate'],
70
+ ssl_private_key: options['ssl_private_key'],
66
71
  environment: options['environment'],
67
72
  debug: options['verbose'],
68
73
  instrumenting: options['instrument'],
@@ -25,6 +25,9 @@ module Middleman
25
25
  # Sourcemap format
26
26
  ::Rack::Mime::MIME_TYPES['.map'] = 'application/json; charset=utf-8'
27
27
 
28
+ # Create a MIME type for PHP files (for detection by extensions)
29
+ ::Rack::Mime::MIME_TYPES['.php'] = 'text/php'
30
+
28
31
  app.extend ClassMethods
29
32
  app.extend ServerMethods
30
33
 
@@ -1,4 +1,7 @@
1
1
  require 'webrick'
2
+ require 'webrick/https'
3
+ require 'openssl'
4
+ require 'socket'
2
5
  require 'middleman-core/meta_pages'
3
6
  require 'middleman-core/logger'
4
7
 
@@ -6,17 +9,21 @@ require 'middleman-core/logger'
6
9
  module Middleman
7
10
  module PreviewServer
8
11
  class << self
9
- attr_reader :app, :host, :port
12
+ attr_reader :app, :host, :port, :ssl_certificate, :ssl_private_key
10
13
  delegate :logger, to: :app
11
14
 
15
+ def https?
16
+ @https
17
+ end
18
+
12
19
  # Start an instance of Middleman::Application
13
20
  # @return [void]
14
21
  def start(opts={})
15
22
  @options = opts
16
23
 
17
24
  mount_instance(new_app)
18
- logger.info "== The Middleman is standing watch at http://#{host}:#{port}"
19
- logger.info "== Inspect your site configuration at http://#{host}:#{port}/__middleman/"
25
+ logger.info "== The Middleman is standing watch at #{uri} (#{uri(public_ip)})"
26
+ logger.info "== Inspect your site configuration at #{uri + '__middleman'}"
20
27
 
21
28
  @initialized ||= false
22
29
  return if @initialized
@@ -104,12 +111,17 @@ module Middleman
104
111
  )
105
112
 
106
113
  config[:environment] = opts[:environment].to_sym if opts[:environment]
107
- config[:host] = opts[:host] if opts[:host]
108
114
  config[:port] = opts[:port] if opts[:port]
115
+ config[:https] = opts[:https] unless opts[:https].nil?
116
+ config[:ssl_certificate] = opts[:ssl_certificate] if opts[:ssl_certificate]
117
+ config[:ssl_private_key] = opts[:ssl_private_key] if opts[:ssl_private_key]
109
118
  end
110
119
 
111
- @host = @app.config[:host]
112
120
  @port = @app.config[:port]
121
+ @https = @app.config[:https]
122
+
123
+ @ssl_certificate = @app.config[:ssl_certificate]
124
+ @ssl_private_key = @app.config[:ssl_private_key]
113
125
 
114
126
  @app
115
127
  end
@@ -167,12 +179,27 @@ module Middleman
167
179
  # @return [void]
168
180
  def setup_webrick(is_logging)
169
181
  http_opts = {
170
- BindAddress: host,
171
182
  Port: port,
172
183
  AccessLog: [],
173
184
  DoNotReverseLookup: true
174
185
  }
175
186
 
187
+ if https?
188
+ http_opts[:SSLEnable] = true
189
+
190
+ if ssl_certificate || ssl_private_key
191
+ raise "You must provide both :ssl_certificate and :ssl_private_key" unless ssl_private_key && ssl_certificate
192
+ http_opts[:SSLCertificate] = OpenSSL::X509::Certificate.new File.read ssl_certificate
193
+ http_opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new File.read ssl_private_key
194
+ else
195
+ # use a generated self-signed cert
196
+ http_opts[:SSLCertName] = [
197
+ %w(CN localhost),
198
+ %w(CN #{Socket.gethostname})
199
+ ].uniq
200
+ end
201
+ end
202
+
176
203
  if is_logging
177
204
  http_opts[:Logger] = FilteredWebrickLog.new
178
205
  else
@@ -234,6 +261,21 @@ module Middleman
234
261
  end
235
262
  end
236
263
  end
264
+
265
+ # Returns the URI the preview server will run on
266
+ # @return [URI]
267
+ def uri(host = Socket.gethostname)
268
+ scheme = https? ? 'https' : 'http'
269
+ URI("#{scheme}://#{host}:#{@port}/")
270
+ end
271
+
272
+ # An IPv4 address on this machine which should be externally addressable.
273
+ # @return [String]
274
+ def public_ip
275
+ ip = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }
276
+ ip ? ip.ip_address : '127.0.0.1'
277
+ end
278
+
237
279
  end
238
280
 
239
281
  class FilteredWebrickLog < ::WEBrick::Log
@@ -2,18 +2,18 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta charset="utf-8">
5
-
5
+
6
6
  <!-- Always force latest IE rendering engine or request Chrome Frame -->
7
7
  <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
8
-
8
+
9
9
  <!-- Use title if it's in the page YAML frontmatter -->
10
10
  <title><%= current_page.data.title || "The Middleman" %></title>
11
-
11
+
12
12
  <%= stylesheet_link_tag "normalize", "all" %>
13
13
  <%= javascript_include_tag "all" %>
14
14
  </head>
15
-
15
+
16
16
  <body class="<%= page_classes %>">
17
17
  <%= yield %>
18
18
  </body>
19
- </html>
19
+ </html>
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  # Current Version
3
3
  # @return [String]
4
- VERSION = '3.3.11' unless const_defined?(:VERSION)
4
+ VERSION = '3.3.12' unless const_defined?(:VERSION)
5
5
  end
@@ -262,8 +262,16 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
262
262
  params.symbolize_keys!
263
263
 
264
264
  if params.key?(:srcset)
265
- images = params[:srcset].split(',').map {|size| (size.include?('//') ? size : asset_url("images/#{size.strip}")) }
266
- params[:srcset] = images.join(', ')
265
+ images_sources = params[:srcset].split(',').map do |src_def|
266
+ if src_def.include?('//')
267
+ src_def
268
+ else
269
+ image_def, size_def = src_def.strip.split(/\s+/)
270
+ asset_path(:images, image_def) + ' ' + size_def
271
+ end
272
+ end
273
+
274
+ params[:srcset] = images_sources.join(', ')
267
275
  end
268
276
 
269
277
  super(path, params)
@@ -3,6 +3,8 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
3
3
  option :compressor, nil, 'Set the CSS compressor to use.'
4
4
  option :inline, false, 'Whether to minify CSS inline within HTML files'
5
5
  option :ignore, [], 'Patterns to avoid minifying'
6
+ option :content_types, %w(text/css), 'Content types of resources that contain CSS'
7
+ option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline CSS'
6
8
 
7
9
  def initialize(app, options_hash={}, &block)
8
10
  super
@@ -16,7 +18,9 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
16
18
  # Setup Rack middleware to minify CSS
17
19
  app.use Rack, compressor: chosen_compressor,
18
20
  ignore: Array(options[:ignore]) + [/\.min\./],
19
- inline: options[:inline]
21
+ inline: options[:inline],
22
+ content_types: options[:content_types],
23
+ inline_content_types: options[:inline_content_types]
20
24
  end
21
25
 
22
26
  class SassCompressor
@@ -39,6 +43,8 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
39
43
  @compressor = options[:compressor]
40
44
  @ignore = options[:ignore]
41
45
  @inline = options[:inline]
46
+ @content_types = options[:content_types]
47
+ @inline_content_types = options[:inline_content_types]
42
48
  end
43
49
 
44
50
  # Rack interface
@@ -47,19 +53,18 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
47
53
  def call(env)
48
54
  status, headers, response = @app.call(env)
49
55
 
50
- if inline_html_content?(env['PATH_INFO'])
51
- minified = ::Middleman::Util.extract_response_text(response)
52
- minified.gsub!(INLINE_CSS_REGEX) do
53
- $1 << @compressor.compress($2) << $3
54
- end
56
+ content_type = headers['Content-Type'].try(:slice, /^[^;]*/)
57
+ path = env['PATH_INFO']
55
58
 
59
+ minified = if @inline && minifiable_inline?(content_type)
60
+ minify_inline(::Middleman::Util.extract_response_text(response))
61
+ elsif minifiable?(content_type) && !ignore?(path)
62
+ minify(::Middleman::Util.extract_response_text(response))
63
+ end
64
+
65
+ if minified
56
66
  headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
57
67
  response = [minified]
58
- elsif standalone_css_content?(env['PATH_INFO'])
59
- minified_css = @compressor.compress(::Middleman::Util.extract_response_text(response))
60
-
61
- headers['Content-Length'] = ::Rack::Utils.bytesize(minified_css).to_s
62
- response = [minified_css]
63
68
  end
64
69
 
65
70
  [status, headers, response]
@@ -67,12 +72,41 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
67
72
 
68
73
  private
69
74
 
70
- def inline_html_content?(path)
71
- (path.end_with?('.html') || path.end_with?('.php')) && @inline
75
+ # Whether the path should be ignored
76
+ # @param [String] path
77
+ # @return [Boolean]
78
+ def ignore?(path)
79
+ @ignore.any? { |ignore| Middleman::Util.path_match(ignore, path) }
80
+ end
81
+
82
+ # Whether this type of content can be minified
83
+ # @param [String, nil] content_type
84
+ # @return [Boolean]
85
+ def minifiable?(content_type)
86
+ @content_types.include?(content_type)
72
87
  end
73
88
 
74
- def standalone_css_content?(path)
75
- path.end_with?('.css') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) }
89
+ # Whether this type of content contains inline content that can be minified
90
+ # @param [String, nil] content_type
91
+ # @return [Boolean]
92
+ def minifiable_inline?(content_type)
93
+ @inline_content_types.include?(content_type)
94
+ end
95
+
96
+ # Minify the content
97
+ # @param [String] content
98
+ # @return [String]
99
+ def minify(content)
100
+ @compressor.compress(content)
101
+ end
102
+
103
+ # Detect and minify inline content
104
+ # @param [String] content
105
+ # @return [String]
106
+ def minify_inline(content)
107
+ content.gsub(INLINE_CSS_REGEX) do
108
+ $1 + minify($2) + $3
109
+ end
76
110
  end
77
111
  end
78
112
  end
@@ -3,6 +3,8 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
3
3
  option :compressor, nil, 'Set the JS compressor to use.'
4
4
  option :inline, false, 'Whether to minify JS inline within HTML files'
5
5
  option :ignore, [], 'Patterns to avoid minifying'
6
+ option :content_types, %w(application/javascript), 'Content types of resources that contain JS'
7
+ option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline JS'
6
8
 
7
9
  def initialize(app, options_hash={}, &block)
8
10
  super
@@ -16,14 +18,18 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
16
18
  ::Uglifier.new
17
19
  end
18
20
 
19
- # Setup Rack middleware to minify CSS
21
+ # Setup Rack middleware to minify JS
20
22
  app.use Rack, compressor: chosen_compressor,
21
23
  ignore: Array(options[:ignore]) + [/\.min\./],
22
- inline: options[:inline]
24
+ inline: options[:inline],
25
+ content_types: options[:content_types],
26
+ inline_content_types: options[:inline_content_types]
23
27
  end
24
28
 
25
29
  # Rack middleware to look for JS and compress it
26
30
  class Rack
31
+ INLINE_JS_REGEX = /(<script[^>]*>\s*(?:\/\/(?:(?:<!--)|(?:<!\[CDATA\[))\n)?)(.*?)((?:(?:\n\s*)?\/\/(?:(?:-->)|(?:\]\]>)))?\s*<\/script>)/m
32
+
27
33
  # Init
28
34
  # @param [Class] app
29
35
  # @param [Hash] options
@@ -32,6 +38,8 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
32
38
  @compressor = options[:compressor]
33
39
  @ignore = options[:ignore]
34
40
  @inline = options[:inline]
41
+ @content_types = options[:content_types]
42
+ @inline_content_types = options[:inline_content_types]
35
43
  end
36
44
 
37
45
  # Rack interface
@@ -40,25 +48,18 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
40
48
  def call(env)
41
49
  status, headers, response = @app.call(env)
42
50
 
51
+ type = headers['Content-Type'].try(:slice, /^[^;]*/)
43
52
  path = env['PATH_INFO']
44
53
 
45
- begin
46
- if @inline && (path.end_with?('.html') || path.end_with?('.php'))
47
- uncompressed_source = ::Middleman::Util.extract_response_text(response)
48
-
49
- minified = minify_inline_content(uncompressed_source)
50
-
51
- headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
52
- response = [minified]
53
- elsif path.end_with?('.js') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) }
54
- uncompressed_source = ::Middleman::Util.extract_response_text(response)
55
- minified = @compressor.compress(uncompressed_source)
54
+ minified = if @inline && minifiable_inline?(type)
55
+ minify_inline(::Middleman::Util.extract_response_text(response))
56
+ elsif minifiable?(type) && !ignore?(path)
57
+ minify(::Middleman::Util.extract_response_text(response))
58
+ end
56
59
 
57
- headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
58
- response = [minified]
59
- end
60
- rescue ExecJS::ProgramError => e
61
- warn "WARNING: Couldn't compress JavaScript in #{path}: #{e.message}"
60
+ if minified
61
+ headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
62
+ response = [minified]
62
63
  end
63
64
 
64
65
  [status, headers, response]
@@ -66,19 +67,48 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
66
67
 
67
68
  private
68
69
 
69
- def minify_inline_content(uncompressed_source)
70
- uncompressed_source.gsub(/(<script[^>]*>\s*(?:\/\/(?:(?:<!--)|(?:<!\[CDATA\[))\n)?)(.*?)((?:(?:\n\s*)?\/\/(?:(?:-->)|(?:\]\]>)))?\s*<\/script>)/m) do |match|
71
- first = $1
72
- javascript = $2
73
- last = $3
70
+ # Whether the path should be ignored
71
+ # @param [String] path
72
+ # @return [Boolean]
73
+ def ignore?(path)
74
+ @ignore.any? { |ignore| Middleman::Util.path_match(ignore, path) }
75
+ end
74
76
 
75
- # Only compress script tags that contain JavaScript (as opposed
76
- # to something like jQuery templates, identified with a "text/html"
77
- # type.
78
- if first =~ /<script>/ || first.include?('text/javascript')
79
- minified_js = @compressor.compress(javascript)
77
+ # Whether this type of content can be minified
78
+ # @param [String, nil] content_type
79
+ # @return [Boolean]
80
+ def minifiable?(content_type)
81
+ @content_types.include?(content_type)
82
+ end
83
+
84
+ # Whether this type of content contains inline content that can be minified
85
+ # @param [String, nil] content_type
86
+ # @return [Boolean]
87
+ def minifiable_inline?(content_type)
88
+ @inline_content_types.include?(content_type)
89
+ end
90
+
91
+ # Minify the content
92
+ # @param [String] content
93
+ # @return [String]
94
+ def minify(content)
95
+ @compressor.compress(content)
96
+ rescue ExecJS::ProgramError => e
97
+ warn "WARNING: Couldn't compress JavaScript in #{path}: #{e.message}"
98
+ content
99
+ end
80
100
 
81
- first << minified_js << last
101
+ # Detect and minify inline content
102
+ # @param [String] content
103
+ # @return [String]
104
+ def minify_inline(content)
105
+ content.gsub(INLINE_JS_REGEX) do |match|
106
+ first, inline_content, last = $1, $2, $3
107
+
108
+ # Only compress script tags that contain JavaScript (as opposed to
109
+ # something like jQuery templates, identified with a "text/html" type).
110
+ if first.include?('<script>') || first.include?('text/javascript')
111
+ first + minify(inline_content) + last
82
112
  else
83
113
  match
84
114
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.11
4
+ version: 3.3.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Reynolds
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-04-24 00:00:00.000000000 Z
13
+ date: 2015-05-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -300,6 +300,7 @@ files:
300
300
  - features/strip_url.feature
301
301
  - features/stylus.feature
302
302
  - features/support/env.rb
303
+ - features/support/preserve_mime_types.rb
303
304
  - features/tilde_directories.feature
304
305
  - features/twitter-bootstrap-compile.feature
305
306
  - features/unicode_filecontents.feature
@@ -336,6 +337,7 @@ files:
336
337
  - fixtures/asset-hash-app/source/layout.erb
337
338
  - fixtures/asset-hash-app/source/other.html.erb
338
339
  - fixtures/asset-hash-app/source/partials.html.erb
340
+ - fixtures/asset-hash-app/source/slim.html.slim
339
341
  - fixtures/asset-hash-app/source/stylesheets/_partial.sass
340
342
  - fixtures/asset-hash-app/source/stylesheets/site.css.scss
341
343
  - fixtures/asset-hash-app/source/stylesheets/uses_partials.css.sass
@@ -447,6 +449,7 @@ files:
447
449
  - fixtures/content-type-app/source/README
448
450
  - fixtures/content-type-app/source/images/blank.gif
449
451
  - fixtures/content-type-app/source/index.html
452
+ - fixtures/content-type-app/source/index.php
450
453
  - fixtures/content-type-app/source/javascripts/app.js
451
454
  - fixtures/content-type-app/source/override.html
452
455
  - fixtures/content-type-app/source/stylesheets/site.css
@@ -725,14 +728,18 @@ files:
725
728
  - fixtures/markdown-in-haml-app/source/images/blank.gif
726
729
  - fixtures/markdown-in-haml-app/source/link_target.html.markdown
727
730
  - fixtures/minify-css-app/source/inline-css.html.haml
731
+ - fixtures/minify-css-app/source/inline-css.php
728
732
  - fixtures/minify-css-app/source/more-css/site.css
729
733
  - fixtures/minify-css-app/source/stylesheets/report.css
730
734
  - fixtures/minify-css-app/source/stylesheets/site.css.sass
735
+ - fixtures/minify-css-app/source/stylesheets/site.xcss.sass
731
736
  - fixtures/minify-js-app/config.rb
732
737
  - fixtures/minify-js-app/source/inline-coffeescript.html.haml
733
738
  - fixtures/minify-js-app/source/inline-js.html.haml
739
+ - fixtures/minify-js-app/source/inline-js.php
734
740
  - fixtures/minify-js-app/source/javascripts/coffee_test.js.coffee
735
741
  - fixtures/minify-js-app/source/javascripts/js_test.js
742
+ - fixtures/minify-js-app/source/javascripts/js_test.xjs
736
743
  - fixtures/minify-js-app/source/more-js/other.js
737
744
  - fixtures/missing-tilt-library-app/config.rb
738
745
  - fixtures/missing-tilt-library-app/source/danger-zone/more-wiki.html.wiki
@@ -1376,6 +1383,7 @@ test_files:
1376
1383
  - features/strip_url.feature
1377
1384
  - features/stylus.feature
1378
1385
  - features/support/env.rb
1386
+ - features/support/preserve_mime_types.rb
1379
1387
  - features/tilde_directories.feature
1380
1388
  - features/twitter-bootstrap-compile.feature
1381
1389
  - features/unicode_filecontents.feature
@@ -1412,6 +1420,7 @@ test_files:
1412
1420
  - fixtures/asset-hash-app/source/layout.erb
1413
1421
  - fixtures/asset-hash-app/source/other.html.erb
1414
1422
  - fixtures/asset-hash-app/source/partials.html.erb
1423
+ - fixtures/asset-hash-app/source/slim.html.slim
1415
1424
  - fixtures/asset-hash-app/source/stylesheets/_partial.sass
1416
1425
  - fixtures/asset-hash-app/source/stylesheets/site.css.scss
1417
1426
  - fixtures/asset-hash-app/source/stylesheets/uses_partials.css.sass
@@ -1523,6 +1532,7 @@ test_files:
1523
1532
  - fixtures/content-type-app/source/README
1524
1533
  - fixtures/content-type-app/source/images/blank.gif
1525
1534
  - fixtures/content-type-app/source/index.html
1535
+ - fixtures/content-type-app/source/index.php
1526
1536
  - fixtures/content-type-app/source/javascripts/app.js
1527
1537
  - fixtures/content-type-app/source/override.html
1528
1538
  - fixtures/content-type-app/source/stylesheets/site.css
@@ -1801,14 +1811,18 @@ test_files:
1801
1811
  - fixtures/markdown-in-haml-app/source/images/blank.gif
1802
1812
  - fixtures/markdown-in-haml-app/source/link_target.html.markdown
1803
1813
  - fixtures/minify-css-app/source/inline-css.html.haml
1814
+ - fixtures/minify-css-app/source/inline-css.php
1804
1815
  - fixtures/minify-css-app/source/more-css/site.css
1805
1816
  - fixtures/minify-css-app/source/stylesheets/report.css
1806
1817
  - fixtures/minify-css-app/source/stylesheets/site.css.sass
1818
+ - fixtures/minify-css-app/source/stylesheets/site.xcss.sass
1807
1819
  - fixtures/minify-js-app/config.rb
1808
1820
  - fixtures/minify-js-app/source/inline-coffeescript.html.haml
1809
1821
  - fixtures/minify-js-app/source/inline-js.html.haml
1822
+ - fixtures/minify-js-app/source/inline-js.php
1810
1823
  - fixtures/minify-js-app/source/javascripts/coffee_test.js.coffee
1811
1824
  - fixtures/minify-js-app/source/javascripts/js_test.js
1825
+ - fixtures/minify-js-app/source/javascripts/js_test.xjs
1812
1826
  - fixtures/minify-js-app/source/more-js/other.js
1813
1827
  - fixtures/missing-tilt-library-app/config.rb
1814
1828
  - fixtures/missing-tilt-library-app/source/danger-zone/more-wiki.html.wiki