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 +4 -4
- data/features/asset_hash.feature +7 -0
- data/features/content_type.feature +3 -0
- data/features/minify_css.feature +63 -1
- data/features/minify_javascript.feature +48 -1
- data/features/support/preserve_mime_types.rb +7 -0
- data/fixtures/asset-hash-app/source/slim.html.slim +8 -0
- data/fixtures/content-type-app/source/index.php +1 -0
- data/fixtures/minify-css-app/source/inline-css.php +8 -0
- data/fixtures/minify-css-app/source/stylesheets/site.xcss.sass +5 -0
- data/fixtures/minify-js-app/source/inline-js.php +22 -0
- data/fixtures/minify-js-app/source/javascripts/js_test.xjs +8 -0
- data/lib/middleman-core/application.rb +12 -4
- data/lib/middleman-core/cli/server.rb +10 -5
- data/lib/middleman-core/core_extensions/request.rb +3 -0
- data/lib/middleman-core/preview_server.rb +48 -6
- data/lib/middleman-core/templates/default/source/layouts/layout.erb +5 -5
- data/lib/middleman-core/version.rb +1 -1
- data/lib/middleman-more/core_extensions/default_helpers.rb +10 -2
- data/lib/middleman-more/extensions/minify_css.rb +49 -15
- data/lib/middleman-more/extensions/minify_javascript.rb +59 -29
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bfeb7129e9a3c6e06a50e32856e7ec973c597a5
|
4
|
+
data.tar.gz: dbff503bac895a4e4ffa2f734e52144d0ebe3a6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d983aca0f6732cad2fc53273562e67570d36f5cd20d100f756901849f256e55b8ee20583b620e227b5ee4b671b74074ab982d58aa904a3146752c4fe40d798a5
|
7
|
+
data.tar.gz: 1aed9d493d38c379270fff5b2e5da9373c88c1af73e3ea468e824e0333fb0351a0428b07be8347a790d5e328efde579f35782792ae73b40ad98b540e63f6f639
|
data/features/asset_hash.feature
CHANGED
@@ -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:
|
data/features/minify_css.feature
CHANGED
@@ -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
|
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 @@
|
|
1
|
+
<?="I'm a PHP file!"?>
|
@@ -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>
|
@@ -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
|
-
|
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
|
19
|
-
logger.info "== Inspect your site configuration at
|
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>
|
@@ -262,8 +262,16 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
|
262
262
|
params.symbolize_keys!
|
263
263
|
|
264
264
|
if params.key?(:srcset)
|
265
|
-
|
266
|
-
|
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
|
-
|
51
|
-
|
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
|
-
|
71
|
-
|
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
|
-
|
75
|
-
|
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
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
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.
|
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
|
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
|