class Inkcite::Minifier
Constants
- HTML_COMMENT_REGEX
Regex to match HTML comments when removal is necessary. The ? makes the regex ungreedy. The /m at the end ensures the regex matches multiple lines.
- INLINE_STYLE_REGEX
Used to match inline styles that will be compressed when minifying the entire email.
- MAXIMUM_LINE_LENGTH
Maximum line length for CSS and HTML - lines exceeding this length cause problems in certain email clients.
- NEW_LINE
Public Class Methods
css(code, ctx)
click to toggle source
# File lib/inkcite/minifier.rb, line 10 def self.css code, ctx # Do nothing to the code unless minification is enabled. if minify?(ctx) # After YUI's CSS compressor started introducing problems into CSS3 # animations, I've switched to a homegrown, extremely simple compression # algorithm for CSS. Instead of messing with parameters, we're simply # eliminating whitespace. # Replace all line breaks with spaces code.gsub!(/[\n\r\f]/, ' ') # Remove whitespace at the beginning or ending of the code code.gsub!(/^\s+/, '') code.gsub!(/\s+$/, '') # Compress multiple whitespace characters into a single space. code.gsub!(/\s{2,}/, ' ') # Remove whitespace preceding or following open and close curly brackets. code.gsub!(/\s*([{};:])\s*/, "\\1") # Remove semicolons preceding close brackets. code.gsub!(';}', '}') # Certain versions of outlook have a problem with excessively long lines # so if this minified code now exceeds the maximum line limit, re-introduce # wrapping in spots where it won't break anything to do so - e.g. following # a semicolon or close bracket. if ctx.email? && code.length > MAXIMUM_LINE_LENGTH # Last position at which a line break was be inserted at. last_break_at = 0 # Work through the code injecting line breaks until either no further # breakable characters are found or we've reached the end of the code. while last_break_at < code.length break_at = code.rindex(/[ ,;{}]/, last_break_at + MAXIMUM_LINE_LENGTH) # No further characters match (unlikely) or an unbroken string since # the last time a break was injected. Either way, let's get out. break if break_at.nil? || break_at <= last_break_at # If we've found a space we can break at, do a direct replacement of the # space with a new line. Otherwise, inject a new line one spot after # the matching character. if code[break_at] == ' ' code[break_at] = NEW_LINE else break_at += 1 code.insert(break_at, NEW_LINE) break_at += 1 end last_break_at = break_at end end end code end
html(lines, ctx)
click to toggle source
# File lib/inkcite/minifier.rb, line 76 def self.html lines, ctx if minify?(ctx) # Will hold the assembled, minified HTML as it is prepared. html = '' # Will hold the line being assembled until it reaches the maximum # allowed line length. packed_line = '' lines.each do |line| next if line.blank? line.strip! ## Compress all in-line styles. #Parser.each line, INLINE_STYLE_REGEX do |style| # style.gsub!(/: +/, ':') # style.gsub!(/; +/, ';') # style.gsub!(/;+/, ';') # style.gsub!(/;+$/, '') # "style=\"#{style}\"" #end # If the length of the packed line with the addition of this line of content would # exceed the maximum allowed line length, then push the collected lines onto the # html and start a new line. if !packed_line.blank? && packed_line.length + line.length > MAXIMUM_LINE_LENGTH html << packed_line html << NEW_LINE packed_line = '' end packed_line << ' ' unless packed_line.blank? packed_line << line end # Make sure to get any last lines assembled on the packed line. html << packed_line unless packed_line.blank? html else lines.join(NEW_LINE) end end
js(code, ctx)
click to toggle source
# File lib/inkcite/minifier.rb, line 126 def self.js code, ctx minify?(ctx) ? js_compressor(ctx).compress(code) : code end
remove_comments(html, ctx)
click to toggle source
# File lib/inkcite/minifier.rb, line 130 def self.remove_comments html, ctx remove_comments?(ctx) ? html.gsub(HTML_COMMENT_REGEX, '') : html end
Private Class Methods
js_compressor(ctx)
click to toggle source
# File lib/inkcite/minifier.rb, line 157 def self.js_compressor ctx ctx.js_compressor ||= YUI::JavaScriptCompressor.new(:munge => true) end
minify?(ctx)
click to toggle source
# File lib/inkcite/minifier.rb, line 147 def self.minify? ctx ctx.is_enabled?(:minify) end
remove_comments?(ctx)
click to toggle source
Config attribute that allows for comment striping to be disabled. e.g. strip-comments: false
# File lib/inkcite/minifier.rb, line 153 def self.remove_comments? ctx minify?(ctx) && !ctx.is_disabled?(:'strip-comments') end