diff --git a/middleman-core/features/content_type.feature b/middleman-core/features/content_type.feature
index 175361d8..95aeadab 100644
--- a/middleman-core/features/content_type.feature
+++ b/middleman-core/features/content_type.feature
@@ -12,6 +12,8 @@ Feature: Setting the right content type for files
Then the content type should be "text/css"
When I go to "/README"
Then the content type should be "text/plain"
+ When I go to "/index.php"
+ Then the content type should be "text/php"
Scenario: Content type can be set explicitly via page or proxy or frontmatter
Given a fixture app "content-type-app"
@@ -31,6 +33,7 @@ Feature: Setting the right content type for files
When I go to "/override.html"
Then the content type should be "text/neato"
+ @preserve_mime_types
Scenario: Content types can be overridden with mime_type
Given a fixture app "content-type-app"
And a file named "config.rb" with:
diff --git a/middleman-core/features/minify_css.feature b/middleman-core/features/minify_css.feature
index 0c707861..29c3e8c6 100644
--- a/middleman-core/features/minify_css.feature
+++ b/middleman-core/features/minify_css.feature
@@ -26,6 +26,18 @@ Feature: Minify CSS
When I go to "/stylesheets/report.css"
Then I should see "p{border:1px solid #ff6600}"
+ Scenario: Rendering external css in a proxied resource
+ Given a fixture app "minify-css-app"
+ And a file named "config.rb" with:
+ """
+ activate :minify_css
+ proxy '/css-proxy', '/stylesheets/site.css', ignore: true
+ """
+ And the Server is running at "minify-css-app"
+ When I go to "/css-proxy"
+ Then I should see "1" lines
+ And I should see "only screen and (device-width"
+
Scenario: Rendering external css with passthrough compressor
Given a fixture app "passthrough-app"
And a file named "config.rb" with:
@@ -124,4 +136,54 @@ Feature: Minify CSS
- """
\ No newline at end of file
+ """
+
+ Scenario: Rendering inline css in a PHP document
+ Given a fixture app "minify-css-app"
+ And a file named "config.rb" with:
+ """
+ activate :minify_css, :inline => true
+ """
+ And the Server is running at "minify-css-app"
+ When I go to "/inline-css.php"
+ Then I should see:
+ """
+ ='Hello'?>
+
+
+ """
+
+ Scenario: Rendering inline css in a proxied resource
+ Given a fixture app "minify-css-app"
+ And a file named "config.rb" with:
+ """
+ activate :minify_css, :inline => true
+ proxy '/inline-css-proxy', '/inline-css.html', ignore: true
+ """
+ And the Server is running at "minify-css-app"
+ When I go to "/inline-css-proxy"
+ Then I should see:
+ """
+
+ """
+
+ @preserve_mime_types
+ Scenario: Configuring content types of resources to be minified
+ Given a fixture app "minify-css-app"
+ And a file named "config.rb" with:
+ """
+ mime_type('.xcss', 'text/x-css')
+ activate :minify_css, content_types: ['text/x-css'],
+ inline: true,
+ inline_content_types: ['text/html']
+ """
+ And the Server is running at "minify-css-app"
+ When I go to "/stylesheets/site.xcss"
+ Then I should see "1" lines
+ And I should see "only screen and (device-width"
+ When I go to "/inline-css.php"
+ Then I should see "8" lines
diff --git a/middleman-core/features/minify_javascript.feature b/middleman-core/features/minify_javascript.feature
index 1fb0e699..a8235368 100644
--- a/middleman-core/features/minify_javascript.feature
+++ b/middleman-core/features/minify_javascript.feature
@@ -88,7 +88,7 @@ Feature: Minify Javascript
"""
- Scenario: Rendering inline css with a passthrough minifier using activate-style compressor
+ Scenario: Rendering inline JS with a passthrough minifier using activate-style compressor
Given a fixture app "passthrough-app"
And a file named "config.rb" with:
"""
@@ -148,6 +148,42 @@ Feature: Minify Javascript
"""
+ Scenario: Rendering inline js in a PHP document
+ Given a fixture app "minify-js-app"
+ And a file named "config.rb" with:
+ """
+ activate :minify_javascript, :inline => true
+ """
+ And the Server is running at "minify-js-app"
+ When I go to "/inline-js.php"
+ Then I should see:
+ """
+ ='Hello'?>
+
+
+
+
+ """
+
+ Scenario: Rendering inline js in a proxied resource
+ Given a fixture app "minify-js-app"
+ And a file named "config.rb" with:
+ """
+ activate :minify_javascript, :inline => true
+ proxy '/inline-js-proxy', '/inline-js.html', ignore: true
+ """
+ And the Server is running at "minify-js-app"
+ When I go to "/inline-js-proxy"
+ Then I should see "14" lines
+
Scenario: Rendering external js with the feature enabled
Given a fixture app "minify-js-app"
And a file named "config.rb" with:
@@ -160,6 +196,17 @@ Feature: Minify Javascript
When I go to "/more-js/other.js"
Then I should see "1" lines
+ Scenario: Rendering external js in a proxied resource
+ Given a fixture app "minify-js-app"
+ And a file named "config.rb" with:
+ """
+ activate :minify_javascript
+ proxy '/js-proxy', '/javascripts/js_test.js', ignore: true
+ """
+ And the Server is running at "minify-js-app"
+ When I go to "/js-proxy"
+ Then I should see "1" lines
+
Scenario: Rendering external js with a passthrough minifier
And the Server is running at "passthrough-app"
When I go to "/javascripts/js_test.js"
diff --git a/middleman-core/features/support/preserve_mime_types.rb b/middleman-core/features/support/preserve_mime_types.rb
new file mode 100644
index 00000000..a791e49c
--- /dev/null
+++ b/middleman-core/features/support/preserve_mime_types.rb
@@ -0,0 +1,7 @@
+Around('@preserve_mime_types') do |_scenario, block|
+ mime_types = ::Rack::Mime::MIME_TYPES.clone
+
+ block.call
+
+ ::Rack::Mime::MIME_TYPES.replace mime_types
+end
diff --git a/middleman-core/fixtures/content-type-app/source/index.php b/middleman-core/fixtures/content-type-app/source/index.php
new file mode 100644
index 00000000..eb55fa96
--- /dev/null
+++ b/middleman-core/fixtures/content-type-app/source/index.php
@@ -0,0 +1 @@
+="I'm a PHP file!"?>
diff --git a/middleman-core/fixtures/minify-css-app/source/inline-css.php b/middleman-core/fixtures/minify-css-app/source/inline-css.php
new file mode 100644
index 00000000..d978aafd
--- /dev/null
+++ b/middleman-core/fixtures/minify-css-app/source/inline-css.php
@@ -0,0 +1,8 @@
+='Hello'?>
+
+
diff --git a/middleman-core/fixtures/minify-css-app/source/stylesheets/site.xcss.sass b/middleman-core/fixtures/minify-css-app/source/stylesheets/site.xcss.sass
new file mode 100755
index 00000000..0cf9e7da
--- /dev/null
+++ b/middleman-core/fixtures/minify-css-app/source/stylesheets/site.xcss.sass
@@ -0,0 +1,5 @@
+@import "compass/reset"
+
+@media handheld, only screen and (device-width: 768px)
+ body
+ display: block
\ No newline at end of file
diff --git a/middleman-core/fixtures/minify-js-app/source/inline-js.php b/middleman-core/fixtures/minify-js-app/source/inline-js.php
new file mode 100755
index 00000000..4a7fd303
--- /dev/null
+++ b/middleman-core/fixtures/minify-js-app/source/inline-js.php
@@ -0,0 +1,22 @@
+='Hello'?>
+
+
+
+
diff --git a/middleman-core/fixtures/minify-js-app/source/javascripts/js_test.xjs b/middleman-core/fixtures/minify-js-app/source/javascripts/js_test.xjs
new file mode 100644
index 00000000..f6a9406c
--- /dev/null
+++ b/middleman-core/fixtures/minify-js-app/source/javascripts/js_test.xjs
@@ -0,0 +1,8 @@
+var race;
+var __slice = Array.prototype.slice;
+
+race = function() {
+ var runners, winner;
+ winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+ return print(winner, runners);
+};
diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb
index 612001e1..cbef8d83 100644
--- a/middleman-core/lib/middleman-core/core_extensions/request.rb
+++ b/middleman-core/lib/middleman-core/core_extensions/request.rb
@@ -24,6 +24,9 @@ module Middleman
# Sourcemap format
::Rack::Mime::MIME_TYPES['.map'] = 'application/json; charset=utf-8'
+ # Create a MIME type for PHP files (for detection by extensions)
+ ::Rack::Mime::MIME_TYPES['.php'] = 'text/php'
+
app.extend ClassMethods
app.extend ServerMethods
diff --git a/middleman-core/lib/middleman-more/extensions/minify_css.rb b/middleman-core/lib/middleman-more/extensions/minify_css.rb
index 91cbf29a..61954a66 100644
--- a/middleman-core/lib/middleman-more/extensions/minify_css.rb
+++ b/middleman-core/lib/middleman-more/extensions/minify_css.rb
@@ -3,6 +3,8 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
option :compressor, nil, 'Set the CSS compressor to use.'
option :inline, false, 'Whether to minify CSS inline within HTML files'
option :ignore, [], 'Patterns to avoid minifying'
+ option :content_types, %w(text/css), 'Content types of resources that contain CSS'
+ option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline CSS'
def initialize(app, options_hash={}, &block)
super
@@ -16,7 +18,9 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
# Setup Rack middleware to minify CSS
app.use Rack, compressor: chosen_compressor,
ignore: Array(options[:ignore]) + [/\.min\./],
- inline: options[:inline]
+ inline: options[:inline],
+ content_types: options[:content_types],
+ inline_content_types: options[:inline_content_types]
end
class SassCompressor
@@ -39,6 +43,8 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
@compressor = options[:compressor]
@ignore = options[:ignore]
@inline = options[:inline]
+ @content_types = options[:content_types]
+ @inline_content_types = options[:inline_content_types]
end
# Rack interface
@@ -47,19 +53,18 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
def call(env)
status, headers, response = @app.call(env)
- if inline_html_content?(env['PATH_INFO'])
- minified = ::Middleman::Util.extract_response_text(response)
- minified.gsub!(INLINE_CSS_REGEX) do
- $1 << @compressor.compress($2) << $3
- end
+ content_type = headers['Content-Type'].try(:slice, /^[^;]*/)
+ path = env['PATH_INFO']
+ minified = if @inline && minifiable_inline?(content_type)
+ minify_inline(::Middleman::Util.extract_response_text(response))
+ elsif minifiable?(content_type) && !ignore?(path)
+ minify(::Middleman::Util.extract_response_text(response))
+ end
+
+ if minified
headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
response = [minified]
- elsif standalone_css_content?(env['PATH_INFO'])
- minified_css = @compressor.compress(::Middleman::Util.extract_response_text(response))
-
- headers['Content-Length'] = ::Rack::Utils.bytesize(minified_css).to_s
- response = [minified_css]
end
[status, headers, response]
@@ -67,12 +72,41 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
private
- def inline_html_content?(path)
- (path.end_with?('.html') || path.end_with?('.php')) && @inline
+ # Whether the path should be ignored
+ # @param [String] path
+ # @return [Boolean]
+ def ignore?(path)
+ @ignore.any? { |ignore| Middleman::Util.path_match(ignore, path) }
end
- def standalone_css_content?(path)
- path.end_with?('.css') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) }
+ # Whether this type of content can be minified
+ # @param [String, nil] content_type
+ # @return [Boolean]
+ def minifiable?(content_type)
+ @content_types.include?(content_type)
+ end
+
+ # Whether this type of content contains inline content that can be minified
+ # @param [String, nil] content_type
+ # @return [Boolean]
+ def minifiable_inline?(content_type)
+ @inline_content_types.include?(content_type)
+ end
+
+ # Minify the content
+ # @param [String] content
+ # @return [String]
+ def minify(content)
+ @compressor.compress(content)
+ end
+
+ # Detect and minify inline content
+ # @param [String] content
+ # @return [String]
+ def minify_inline(content)
+ content.gsub(INLINE_CSS_REGEX) do
+ $1 + minify($2) + $3
+ end
end
end
end
diff --git a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb
index d51d864f..df020765 100644
--- a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb
+++ b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb
@@ -3,6 +3,8 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
option :compressor, nil, 'Set the JS compressor to use.'
option :inline, false, 'Whether to minify JS inline within HTML files'
option :ignore, [], 'Patterns to avoid minifying'
+ option :content_types, %w(application/javascript), 'Content types of resources that contain JS'
+ option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline JS'
def initialize(app, options_hash={}, &block)
super
@@ -16,14 +18,18 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
::Uglifier.new
end
- # Setup Rack middleware to minify CSS
+ # Setup Rack middleware to minify JS
app.use Rack, compressor: chosen_compressor,
ignore: Array(options[:ignore]) + [/\.min\./],
- inline: options[:inline]
+ inline: options[:inline],
+ content_types: options[:content_types],
+ inline_content_types: options[:inline_content_types]
end
# Rack middleware to look for JS and compress it
class Rack
+ INLINE_JS_REGEX = /(