middleman-core 3.3.11 → 3.3.12

Sign up to get free protection for your applications and to get access to all the features.
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