ps-smurf 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +20 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +68 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/closure-compiler/COPYING +202 -0
- data/lib/closure-compiler/README +289 -0
- data/lib/closure-compiler/compiler.jar +0 -0
- data/lib/closure-compiler/version +1 -0
- data/lib/jsmin.rb +262 -0
- data/lib/smurf.rb +17 -0
- data/lib/smurf/javascript.rb +74 -0
- data/lib/smurf/noop.rb +8 -0
- data/lib/smurf/rainpress.rb +168 -0
- data/lib/smurf/stylesheet.rb +17 -0
- data/test/integration_test.rb +13 -0
- data/test/javascript_test.rb +31 -0
- data/test/rails/app/controllers/application.rb +2 -0
- data/test/rails/config/application.rb +17 -0
- data/test/rails/config/boot.rb +9 -0
- data/test/rails/config/environment.rb +5 -0
- data/test/rails/config/environments/test.rb +7 -0
- data/test/rails/config/routes.rb +5 -0
- data/test/rails/public/javascripts/cache/expected.js +2 -0
- data/test/rails/public/javascripts/projwcss/jscss.css +3 -0
- data/test/rails/public/javascripts/testing.js +3 -0
- data/test/rails/public/stylesheets/bar.css +44 -0
- data/test/rails/public/stylesheets/cache/expected-basic.css +1 -0
- data/test/rails/public/stylesheets/foo.css +48 -0
- data/test/stylesheet_test.rb +41 -0
- data/test/test_helper.rb +48 -0
- metadata +187 -0
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
20100917
|
data/lib/jsmin.rb
ADDED
@@ -0,0 +1,262 @@
|
|
1
|
+
#--
|
2
|
+
# jsmin.rb - Ruby implementation of Douglas Crockford's JSMin.
|
3
|
+
#
|
4
|
+
# This is a port of jsmin.c, and is distributed under the same terms, which are
|
5
|
+
# as follows:
|
6
|
+
#
|
7
|
+
# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
8
|
+
#
|
9
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
10
|
+
# of this software and associated documentation files (the "Software"), to deal
|
11
|
+
# in the Software without restriction, including without limitation the rights
|
12
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13
|
+
# copies of the Software, and to permit persons to whom the Software is
|
14
|
+
# furnished to do so, subject to the following conditions:
|
15
|
+
#
|
16
|
+
# The above copyright notice and this permission notice shall be included in all
|
17
|
+
# copies or substantial portions of the Software.
|
18
|
+
#
|
19
|
+
# The Software shall be used for Good, not Evil.
|
20
|
+
#
|
21
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
22
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
23
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
24
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
25
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
26
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
27
|
+
# SOFTWARE.
|
28
|
+
#++
|
29
|
+
|
30
|
+
require 'strscan'
|
31
|
+
|
32
|
+
# = JSMin
|
33
|
+
#
|
34
|
+
# Ruby implementation of Douglas Crockford's JavaScript minifier, JSMin.
|
35
|
+
#
|
36
|
+
# *Author*:: Ryan Grove (mailto:ryan@wonko.com)
|
37
|
+
# *Version*:: 1.0.1 (2008-11-10)
|
38
|
+
# *Copyright*:: Copyright (c) 2008 Ryan Grove. All rights reserved.
|
39
|
+
# *Website*:: http://github.com/rgrove/jsmin
|
40
|
+
#
|
41
|
+
# == Example
|
42
|
+
#
|
43
|
+
# require 'rubygems'
|
44
|
+
# require 'jsmin'
|
45
|
+
#
|
46
|
+
# File.open('example.js', 'r') {|file| puts JSMin.minify(file) }
|
47
|
+
#
|
48
|
+
module JSMin
|
49
|
+
CHR_APOS = "'".freeze
|
50
|
+
CHR_ASTERISK = '*'.freeze
|
51
|
+
CHR_BACKSLASH = '\\'.freeze
|
52
|
+
CHR_CR = "\r".freeze
|
53
|
+
CHR_FRONTSLASH = '/'.freeze
|
54
|
+
CHR_LF = "\n".freeze
|
55
|
+
CHR_QUOTE = '"'.freeze
|
56
|
+
CHR_SPACE = ' '.freeze
|
57
|
+
|
58
|
+
ORD_LF = ?\n
|
59
|
+
ORD_SPACE = ?\
|
60
|
+
ORD_TILDE = ?~
|
61
|
+
|
62
|
+
class ParseError < RuntimeError
|
63
|
+
attr_accessor :source, :line
|
64
|
+
def initialize(err, source, line)
|
65
|
+
@source = source,
|
66
|
+
@line = line
|
67
|
+
super "JSMin Parse Error: #{err} at line #{line} of #{source}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
def raise(err)
|
73
|
+
super ParseError.new(err, @source, @line)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Reads JavaScript from _input_ (which can be a String or an IO object) and
|
77
|
+
# returns a String containing minified JS.
|
78
|
+
def minify(input)
|
79
|
+
@js = StringScanner.new(input.is_a?(IO) ? input.read : input.to_s)
|
80
|
+
@source = input.is_a?(IO) ? input.inspect : input.to_s[0..100]
|
81
|
+
@line = 1
|
82
|
+
|
83
|
+
@a = "\n"
|
84
|
+
@b = nil
|
85
|
+
@lookahead = nil
|
86
|
+
@output = ''
|
87
|
+
|
88
|
+
action_get
|
89
|
+
|
90
|
+
while !@a.nil? do
|
91
|
+
case @a
|
92
|
+
when CHR_SPACE
|
93
|
+
if alphanum?(@b)
|
94
|
+
action_output
|
95
|
+
else
|
96
|
+
action_copy
|
97
|
+
end
|
98
|
+
|
99
|
+
when CHR_LF
|
100
|
+
if @b == CHR_SPACE
|
101
|
+
action_get
|
102
|
+
elsif @b =~ /[{\[\(+-]/
|
103
|
+
action_output
|
104
|
+
else
|
105
|
+
if alphanum?(@b)
|
106
|
+
action_output
|
107
|
+
else
|
108
|
+
action_copy
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
else
|
113
|
+
if @b == CHR_SPACE
|
114
|
+
if alphanum?(@a)
|
115
|
+
action_output
|
116
|
+
else
|
117
|
+
action_get
|
118
|
+
end
|
119
|
+
elsif @b == CHR_LF
|
120
|
+
if @a =~ /[}\]\)\\"+-]/
|
121
|
+
action_output
|
122
|
+
else
|
123
|
+
if alphanum?(@a)
|
124
|
+
action_output
|
125
|
+
else
|
126
|
+
action_get
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
action_output
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
@output
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# Corresponds to action(1) in jsmin.c.
|
141
|
+
def action_output
|
142
|
+
@output << @a
|
143
|
+
action_copy
|
144
|
+
end
|
145
|
+
|
146
|
+
# Corresponds to action(2) in jsmin.c.
|
147
|
+
def action_copy
|
148
|
+
@a = @b
|
149
|
+
|
150
|
+
if @a == CHR_APOS || @a == CHR_QUOTE
|
151
|
+
loop do
|
152
|
+
@output << @a
|
153
|
+
@a = get
|
154
|
+
|
155
|
+
break if @a == @b
|
156
|
+
|
157
|
+
if @a[0] <= ORD_LF
|
158
|
+
raise "unterminated string literal: #{@a.inspect}"
|
159
|
+
end
|
160
|
+
|
161
|
+
if @a == CHR_BACKSLASH
|
162
|
+
@output << @a
|
163
|
+
@a = get
|
164
|
+
|
165
|
+
if @a[0] <= ORD_LF
|
166
|
+
raise "unterminated string literal: #{@a.inspect}"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
action_get
|
173
|
+
end
|
174
|
+
|
175
|
+
# Corresponds to action(3) in jsmin.c.
|
176
|
+
def action_get
|
177
|
+
@b = nextchar
|
178
|
+
|
179
|
+
if @b == CHR_FRONTSLASH && (@a == CHR_LF || @a =~ /[\(,=:\[!&|?{};]/)
|
180
|
+
@output << @a
|
181
|
+
@output << @b
|
182
|
+
|
183
|
+
loop do
|
184
|
+
@a = get
|
185
|
+
|
186
|
+
if @a == CHR_FRONTSLASH
|
187
|
+
break
|
188
|
+
elsif @a == CHR_BACKSLASH
|
189
|
+
@output << @a
|
190
|
+
@a = get
|
191
|
+
elsif @a[0] <= ORD_LF
|
192
|
+
raise "unterminated regular expression : #{@a.inspect}"
|
193
|
+
end
|
194
|
+
|
195
|
+
@output << @a
|
196
|
+
end
|
197
|
+
|
198
|
+
@b = nextchar
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Returns true if +c+ is a letter, digit, underscore, dollar sign,
|
203
|
+
# backslash, or non-ASCII character.
|
204
|
+
def alphanum?(c)
|
205
|
+
c.is_a?(String) && !c.empty? && (c[0] > ORD_TILDE || c =~ /[0-9a-z_$\\]/i)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Returns the next character from the input. If the character is a control
|
209
|
+
# character, it will be translated to a space or linefeed.
|
210
|
+
def get
|
211
|
+
if @lookahead
|
212
|
+
c = @lookahead
|
213
|
+
@lookahead = nil
|
214
|
+
else
|
215
|
+
c = @js.getch
|
216
|
+
if c == CHR_LF || c == CHR_CR
|
217
|
+
@line += 1
|
218
|
+
return CHR_LF
|
219
|
+
end
|
220
|
+
return ' ' unless c.nil? || c[0] >= ORD_SPACE
|
221
|
+
end
|
222
|
+
c
|
223
|
+
end
|
224
|
+
|
225
|
+
# Gets the next character, excluding comments.
|
226
|
+
def nextchar
|
227
|
+
c = get
|
228
|
+
return c unless c == CHR_FRONTSLASH
|
229
|
+
|
230
|
+
case peek
|
231
|
+
when CHR_FRONTSLASH
|
232
|
+
loop do
|
233
|
+
c = get
|
234
|
+
return c if c[0] <= ORD_LF
|
235
|
+
end
|
236
|
+
|
237
|
+
when CHR_ASTERISK
|
238
|
+
get
|
239
|
+
loop do
|
240
|
+
case get
|
241
|
+
when CHR_ASTERISK
|
242
|
+
if peek == CHR_FRONTSLASH
|
243
|
+
get
|
244
|
+
return ' '
|
245
|
+
end
|
246
|
+
|
247
|
+
when nil
|
248
|
+
raise 'unterminated comment'
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
else
|
253
|
+
return c
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Gets the next character without getting it.
|
258
|
+
def peek
|
259
|
+
@lookahead = get
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
data/lib/smurf.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'smurf/javascript'
|
2
|
+
require 'smurf/stylesheet'
|
3
|
+
require 'smurf/noop'
|
4
|
+
require 'smurf/rainpress'
|
5
|
+
|
6
|
+
module ActionView::Helpers::AssetTagHelper
|
7
|
+
private
|
8
|
+
def minifiers
|
9
|
+
@@minifiers ||= [Smurf::Javascript, Smurf::Stylesheet, Smurf::Noop]
|
10
|
+
end
|
11
|
+
|
12
|
+
def join_asset_file_contents_with_minification(paths)
|
13
|
+
content = join_asset_file_contents_without_minification(paths)
|
14
|
+
minifiers.detect { |minifier| minifier.minifies?(paths) }.new(content).minified
|
15
|
+
end
|
16
|
+
alias_method_chain :join_asset_file_contents, :minification
|
17
|
+
end # ActionView::Helpers::AssetTagHelper
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Author: Justin Knowlden
|
2
|
+
# Adaption of jsmin.rb published by Uladzislau Latynski
|
3
|
+
#
|
4
|
+
# -------------------
|
5
|
+
# jsmin.rb 2007-07-20
|
6
|
+
# Author: Uladzislau Latynski
|
7
|
+
# This work is a translation from C to Ruby of jsmin.c published by
|
8
|
+
# Douglas Crockford. Permission is hereby granted to use the Ruby
|
9
|
+
# version under the same conditions as the jsmin.c on which it is
|
10
|
+
# based.
|
11
|
+
#
|
12
|
+
# /* jsmin.c
|
13
|
+
# 2003-04-21
|
14
|
+
#
|
15
|
+
# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
16
|
+
#
|
17
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
18
|
+
# this software and associated documentation files (the "Software"), to deal in
|
19
|
+
# the Software without restriction, including without limitation the rights to
|
20
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
21
|
+
# of the Software, and to permit persons to whom the Software is furnished to do
|
22
|
+
# so, subject to the following conditions:
|
23
|
+
#
|
24
|
+
# The above copyright notice and this permission notice shall be included in all
|
25
|
+
# copies or substantial portions of the Software.
|
26
|
+
#
|
27
|
+
# The Software shall be used for Good, not Evil.
|
28
|
+
#
|
29
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
30
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
31
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
32
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
33
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
34
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
35
|
+
# SOFTWARE.
|
36
|
+
|
37
|
+
require 'stringio'
|
38
|
+
require 'jsmin'
|
39
|
+
|
40
|
+
module Smurf
|
41
|
+
class Javascript
|
42
|
+
def self.minifies?(paths) !paths.grep(%r[\.js(\?\d+)?$]).empty?; end
|
43
|
+
|
44
|
+
def initialize(content)
|
45
|
+
@content = nil
|
46
|
+
java_exists = %x[which java].present?
|
47
|
+
|
48
|
+
if java_exists
|
49
|
+
@content = minify_with_closure_compiler(content)
|
50
|
+
Rails.logger.info "Closure Compiler failed" if @content.blank?
|
51
|
+
end
|
52
|
+
|
53
|
+
if @content.blank?
|
54
|
+
Rails.logger.info "Closure Compiler not found" unless java_exists
|
55
|
+
@content = JSMin.minify(content)
|
56
|
+
end
|
57
|
+
|
58
|
+
@content
|
59
|
+
end
|
60
|
+
|
61
|
+
def minified; @content end
|
62
|
+
|
63
|
+
def minify_with_closure_compiler(content)
|
64
|
+
jar_file = File.join(File.dirname(__FILE__), '..', 'closure-compiler', 'compiler.jar')
|
65
|
+
IO.popen("java -jar #{jar_file}", "r+") do |p|
|
66
|
+
p.write content
|
67
|
+
p.close_write
|
68
|
+
content = p.read
|
69
|
+
end
|
70
|
+
content if $? == 0
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
data/lib/smurf/noop.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
module Smurf
|
2
|
+
# This is a no-op; essentially a NullObject pattern implementation. Saves from implementing logic elsewhere
|
3
|
+
class Noop
|
4
|
+
def self.minifies?(paths) true; end
|
5
|
+
def initialize(content) @content = content; end
|
6
|
+
def minified; @content; end
|
7
|
+
end # Noop
|
8
|
+
end # Smurf
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# == Information
|
2
|
+
#
|
3
|
+
# This is the main class of Rainpress, create an instance of it to compress
|
4
|
+
# your CSS-styles.
|
5
|
+
#
|
6
|
+
# Author:: Uwe L. Korn <uwelk@xhochy.org>
|
7
|
+
#
|
8
|
+
# <b>Options:</b>
|
9
|
+
#
|
10
|
+
# * <tt>:comments</tt> - if set to false, comments will not be removed
|
11
|
+
# * <tt>:newlines</tt> - if set to false, newlines will not be removed
|
12
|
+
# * <tt>:spaces</tt> - if set to false, spaces will not be removed
|
13
|
+
# * <tt>:colors</tt> - if set to false, colors will not be modified
|
14
|
+
# * <tt>:misc</tt> - if set to false, miscellaneous compression parts will be skipped
|
15
|
+
class Rainpress
|
16
|
+
# Quick-compress the styles.
|
17
|
+
# This eliminates the need to create an instance of the class
|
18
|
+
def self.compress(style, options = {})
|
19
|
+
self.new(style, options).compress!
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(style, opts = {})
|
23
|
+
@style = style
|
24
|
+
@opts = {
|
25
|
+
:comments => true,
|
26
|
+
:newlines => true,
|
27
|
+
:spaces => true,
|
28
|
+
:colors => true,
|
29
|
+
:misc => true
|
30
|
+
}
|
31
|
+
@opts.merge! opts
|
32
|
+
end
|
33
|
+
|
34
|
+
# Run the compressions and return the newly compressed text
|
35
|
+
def compress!
|
36
|
+
remove_comments! if @opts[:comments]
|
37
|
+
remove_newlines! if @opts[:newlines]
|
38
|
+
remove_spaces! if @opts[:spaces]
|
39
|
+
shorten_colors! if @opts[:colors]
|
40
|
+
do_misc! if @opts[:misc]
|
41
|
+
@style
|
42
|
+
end
|
43
|
+
|
44
|
+
# Remove all comments out of the CSS-Document
|
45
|
+
#
|
46
|
+
# Only /* text */ comments are supported.
|
47
|
+
# Attention: If you are doing css hacks for IE using the comment tricks,
|
48
|
+
# they will be removed using this function. Please consider for IE css style
|
49
|
+
# corrections the usage of conditionals comments in your (X)HTML document.
|
50
|
+
def remove_comments!
|
51
|
+
input = @style
|
52
|
+
@style = ''
|
53
|
+
|
54
|
+
while input.length > 0 do
|
55
|
+
pos = input.index("/*");
|
56
|
+
|
57
|
+
# No more comments
|
58
|
+
if pos == nil
|
59
|
+
@style += input
|
60
|
+
input = '';
|
61
|
+
else # Comment beginning at pos
|
62
|
+
@style += input[0..(pos-1)] if pos > 0 # only append text if there is some
|
63
|
+
input = input[(pos+2)..-1]
|
64
|
+
# Comment ending at pos
|
65
|
+
pos = input.index("*/")
|
66
|
+
input = input[(pos+2)..-1]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Remove all newline characters
|
72
|
+
#
|
73
|
+
# We take care of Windows(\r\n), Unix(\n) and Mac(\r) newlines.
|
74
|
+
def remove_newlines!
|
75
|
+
@style.gsub! /\n|\r/, ''
|
76
|
+
end
|
77
|
+
|
78
|
+
# Remove unneeded spaces
|
79
|
+
#
|
80
|
+
# 1. Turn mutiple spaces into a single
|
81
|
+
# 2. Remove spaces around ;:{},
|
82
|
+
# 3. Remove tabs
|
83
|
+
def remove_spaces!
|
84
|
+
@style.gsub! /\s*(\s|;|:|\}|\{|,)\s*/, '\1'
|
85
|
+
@style.gsub! "\t", ''
|
86
|
+
end
|
87
|
+
|
88
|
+
# Replace color values with their shorter equivalent
|
89
|
+
#
|
90
|
+
# 1. Turn rgb(,,)-colors into #-values
|
91
|
+
# 2. Shorten #AABBCC down to #ABC
|
92
|
+
# 3. Replace names with their shorter hex-equivalent
|
93
|
+
# * white -> #fff
|
94
|
+
# * black -> #000
|
95
|
+
# 4. Replace #-values with their shorter name
|
96
|
+
# * #f00 -> red
|
97
|
+
def shorten_colors!
|
98
|
+
# rgb(50,101,152) to #326598
|
99
|
+
@style.gsub! /rgb\s*\(\s*([0-9,\s]+)\s*\)/ do |match|
|
100
|
+
out = '#'
|
101
|
+
$1.split(',').each do |num|
|
102
|
+
out += '0' if num.to_i < 16
|
103
|
+
out += num.to_i.to_s(16) # convert to hex
|
104
|
+
end
|
105
|
+
out
|
106
|
+
end
|
107
|
+
# Convert #AABBCC to #ABC, keep if preceed by a '='
|
108
|
+
@style.gsub! /([^\"'=\s])(\s*)#([\da-f])\3([\da-f])\4([\da-f])\5/i, '\1#\3\4\5'
|
109
|
+
|
110
|
+
# At the moment we assume that colours only appear before ';' or '}' and
|
111
|
+
# after a ':', if there could be an occurence of a color before or after
|
112
|
+
# an other character, submit either a bug report or, better, a patch that
|
113
|
+
# enables Rainpress to take care of this.
|
114
|
+
|
115
|
+
# shorten several names to numbers
|
116
|
+
## shorten white -> #fff
|
117
|
+
@style.gsub! /:\s*white\s*(;|\})/, ':#fff\1'
|
118
|
+
|
119
|
+
## shorten black -> #000
|
120
|
+
@style.gsub! /:\s*black\s*(;|\})/, ':#000\1'
|
121
|
+
|
122
|
+
# shotern several numbers to names
|
123
|
+
## shorten #f00 or #ff0000 -> red
|
124
|
+
@style.gsub! /:\s*#f{1,2}0{2,4}(;|\})/i, ':red\1'
|
125
|
+
end
|
126
|
+
|
127
|
+
# Do miscellaneous compression methods on the style.
|
128
|
+
def do_misc!
|
129
|
+
# Replace 0(pt,px,em,%) with 0 but only when preceded by : or a white-space
|
130
|
+
@style.gsub! /([\s:]+)(0)(px|em|%|in|cm|mm|pc|pt|ex)/i, '\1\2'
|
131
|
+
|
132
|
+
# Replace :0 0 0 0(;|}) with :0(;|})
|
133
|
+
@style.gsub! /:0 0 0 0(;|\})/, ':0\1'
|
134
|
+
|
135
|
+
# Replace :0 0 0(;|}) with :0(;|})
|
136
|
+
@style.gsub! /:0 0 0(;|\})/, ':0\1'
|
137
|
+
|
138
|
+
# Replace :0 0(;|}) with :0(;|})
|
139
|
+
@style.gsub! /:0 0(;|\})/, ':0\1'
|
140
|
+
|
141
|
+
# Replace background-position:0; with background-position:0 0;
|
142
|
+
@style.gsub! 'background-position:0;', 'background-position:0 0;'
|
143
|
+
|
144
|
+
# Replace 0.6 to .6, but only when preceded by : or a white-space
|
145
|
+
@style.gsub! /[:\s]0+\.(\d+)/ do |match|
|
146
|
+
match.sub '0', '' # only first '0' !!
|
147
|
+
end
|
148
|
+
|
149
|
+
# Replace multiple ';' with a single ';'
|
150
|
+
@style.gsub! /[;]+/, ';'
|
151
|
+
|
152
|
+
# Replace ;} with }
|
153
|
+
@style.gsub! ';}', '}'
|
154
|
+
|
155
|
+
# Replace font-weight:normal; with 400
|
156
|
+
@style.gsub! /font-weight[\s]*:[\s]*normal[\s]*(;|\})/i,'font-weight:400\1'
|
157
|
+
@style.gsub! /font[\s]*:[\s]*normal[\s;\}]*/ do |match|
|
158
|
+
match.sub 'normal', '400'
|
159
|
+
end
|
160
|
+
|
161
|
+
# Replace font-weight:bold; with 700
|
162
|
+
@style.gsub! /font-weight[\s]*:[\s]*bold[\s]*(;|\})/,'font-weight:700\1'
|
163
|
+
@style.gsub! /font[\s]*:[\s]*bold[\s;\}]*/ do |match|
|
164
|
+
match.sub 'bold', '700'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|