2013-04-20 23:27:25 +02:00
# Minify CSS Extension
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'
2012-08-14 00:39:06 +02:00
2013-04-20 23:27:25 +02:00
def initialize ( app , options_hash = { } , & block )
super
2012-08-14 00:39:06 +02:00
2013-04-20 23:27:25 +02:00
app . config . define_setting :css_compressor , nil , 'Set the CSS compressor to use. Deprecated in favor of the :compressor option when activating :minify_css'
end
2012-04-08 05:00:24 +02:00
2013-04-20 23:27:25 +02:00
def after_configuration
chosen_compressor = app . config [ :css_compressor ] || options [ :compressor ] || SassCompressor
2012-08-14 00:39:06 +02:00
2013-04-20 23:27:25 +02:00
# Setup Rack middleware to minify CSS
app . use Rack , :compressor = > chosen_compressor ,
2013-04-28 23:08:09 +02:00
:ignore = > Array ( options [ :ignore ] ) + [ / \ .min \ . / ] ,
2013-04-20 23:27:25 +02:00
:inline = > options [ :inline ]
end
2013-03-20 00:21:49 +01:00
2013-04-20 23:27:25 +02:00
class SassCompressor
def self . compress ( style , options = { } )
root_node = :: Sass :: SCSS :: CssParser . new ( style , 'middleman-css-input' , 1 ) . parse
root_node . options = { :style = > :compressed }
root_node . render . strip
end
end
2012-04-08 05:00:24 +02:00
2013-04-20 23:27:25 +02:00
# Rack middleware to look for CSS and compress it
class Rack
2013-05-25 02:11:46 +02:00
INLINE_CSS_REGEX = / (<style[^>]*> \ s*(?: \/ \ *<! \ [CDATA \ [ \ * \/ \ n)?)(.*?)((?:(?: \ n \ s*)? \/ \ * \ ] \ ]> \ * \/ )? \ s*< \/ style>) /m
2013-04-20 23:27:25 +02:00
# Init
# @param [Class] app
# @param [Hash] options
def initialize ( app , options = { } )
@app = app
@compressor = options [ :compressor ]
@ignore = options [ :ignore ]
@inline = options [ :inline ]
end
2012-04-08 05:00:24 +02:00
2013-04-20 23:27:25 +02:00
# Rack interface
# @param [Rack::Environmemt] env
# @return [Array]
def call ( env )
status , headers , response = @app . call ( env )
2012-04-08 05:00:24 +02:00
2013-12-28 01:26:31 +01:00
if inline_html_content? ( env [ 'PATH_INFO' ] )
2013-05-25 02:11:46 +02:00
minified = :: Middleman :: Util . extract_response_text ( response )
minified . gsub! ( INLINE_CSS_REGEX ) do | match |
$1 << @compressor . compress ( $2 ) << $3
2013-04-20 23:27:25 +02:00
end
2012-04-08 05:00:24 +02:00
2013-12-28 01:26:31 +01:00
headers [ 'Content-Length' ] = :: Rack :: Utils . bytesize ( minified ) . to_s
2013-04-20 23:27:25 +02:00
response = [ minified ]
2013-12-28 01:26:31 +01:00
elsif standalone_css_content? ( env [ 'PATH_INFO' ] )
2013-05-25 02:11:46 +02:00
minified_css = @compressor . compress ( :: Middleman :: Util . extract_response_text ( response ) )
2012-04-08 05:00:24 +02:00
2013-12-28 01:26:31 +01:00
headers [ 'Content-Length' ] = :: Rack :: Utils . bytesize ( minified_css ) . to_s
2013-04-20 23:27:25 +02:00
response = [ minified_css ]
2012-04-08 05:00:24 +02:00
end
2013-04-20 23:27:25 +02:00
[ status , headers , response ]
2012-04-08 05:00:24 +02:00
end
2013-05-25 02:11:46 +02:00
private
def inline_html_content? ( path )
( path . end_with? ( '.html' ) || path . end_with? ( '.php' ) ) && @inline
end
def standalone_css_content? ( path )
path . end_with? ( '.css' ) && @ignore . none? { | ignore | Middleman :: Util . path_match ( ignore , path ) }
end
2012-04-08 05:00:24 +02:00
end
2012-04-27 06:55:07 +02:00
end