html_press 0.0.2 → 0.0.3
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/Readme.md +44 -19
- data/lib/html_press/html.rb +49 -11
- data/lib/html_press/version.rb +1 -1
- data/spec/html_press_spec.rb +83 -16
- metadata +10 -10
data/Readme.md
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
#html_press
|
2
2
|
|
3
|
-
##
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
- https://github.com/completelynovel/html_compressor
|
8
|
-
- https://github.com/MadRabbit/frontcompiler
|
9
|
-
|
10
|
-
###Other
|
11
|
-
|
12
|
-
- http://code.google.com/p/htmlcompressor/
|
13
|
-
- smarty `strip` tag
|
14
|
-
- W3 total cache (WP plugin from smashingmagazine contains html minifier)
|
3
|
+
## how it works
|
4
|
+
|
5
|
+
Remove all whitespace junk. Leave only HTML
|
15
6
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
```
|
8
|
+
1. ┌――――――――――――――――――╖ 2. ┌――――――――――――――――――╖
|
9
|
+
●――――――――――――――├―╢ <html> ws junk ║ ●――――――――├―――――――――╢ <html> ║
|
10
|
+
└――――――――――――――――――╜ └――――――――――――――――――╜
|
11
|
+
```
|
21
12
|
|
22
13
|
## Usage
|
23
14
|
|
@@ -35,11 +26,23 @@ _plugins/strip_tag.rb
|
|
35
26
|
```ruby
|
36
27
|
module Jekyll
|
37
28
|
class StripTag < Liquid::Block
|
29
|
+
@total_economy = 0
|
30
|
+
class << self
|
31
|
+
attr_accessor :total_economy
|
32
|
+
end
|
33
|
+
|
38
34
|
begin
|
39
35
|
require 'html_press'
|
40
36
|
def render(context)
|
41
37
|
text = super
|
42
|
-
|
38
|
+
before = text.bytesize
|
39
|
+
text = HtmlPress.compress text
|
40
|
+
after = text.bytesize
|
41
|
+
|
42
|
+
self.class.total_economy += before - after
|
43
|
+
economy = (self.class.total_economy.to_f / 1024).round(2)
|
44
|
+
p 'totally saved: ' + economy.to_s + ' Kb'
|
45
|
+
text
|
43
46
|
end
|
44
47
|
rescue LoadError => e
|
45
48
|
p "Unable to load 'html_press'"
|
@@ -62,5 +65,27 @@ Run
|
|
62
65
|
|
63
66
|
```
|
64
67
|
bundle install
|
65
|
-
bundle exec
|
68
|
+
bundle exec jekyll
|
66
69
|
```
|
70
|
+
|
71
|
+
## Alternatives
|
72
|
+
|
73
|
+
###Ruby
|
74
|
+
|
75
|
+
- https://github.com/completelynovel/html_compressor
|
76
|
+
- https://github.com/MadRabbit/frontcompiler
|
77
|
+
|
78
|
+
###Other
|
79
|
+
|
80
|
+
- http://code.google.com/p/htmlcompressor/
|
81
|
+
- smarty `strip` tag
|
82
|
+
- W3 total cache (WP plugin from smashingmagazine contains html minifier)
|
83
|
+
|
84
|
+
## TODO
|
85
|
+
|
86
|
+
- options
|
87
|
+
- bin
|
88
|
+
- Support other minifiers (Closure, YUI compressor)
|
89
|
+
- htmlTydi
|
90
|
+
- add examples of usage with Sinatra and Rails
|
91
|
+
|
data/lib/html_press/html.rb
CHANGED
@@ -138,6 +138,11 @@ module HtmlPress
|
|
138
138
|
attr k, "'", tag
|
139
139
|
end
|
140
140
|
|
141
|
+
if attributes_compressed == " /"
|
142
|
+
attributes_compressed = "/"
|
143
|
+
elsif attributes_compressed == " "
|
144
|
+
attributes_compressed = ""
|
145
|
+
end
|
141
146
|
return m.gsub(attributes, attributes_compressed)
|
142
147
|
end
|
143
148
|
|
@@ -147,37 +152,70 @@ module HtmlPress
|
|
147
152
|
def attr(attribute, delimiter, tag)
|
148
153
|
re = "([a-z\\-_:]+)(=" + delimiter + "[^" + delimiter + "]*" + delimiter + ")?"
|
149
154
|
re = Regexp.new re
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
155
|
+
value_original = attribute.gsub(re, "\\2")
|
156
|
+
value = value_original.downcase
|
157
|
+
name_original = attribute.gsub(re, "\\1")
|
158
|
+
name = name_original.downcase
|
159
|
+
tag_name = tag.downcase
|
160
|
+
|
161
|
+
case tag_name
|
162
|
+
when "script"
|
154
163
|
if name == "type" || name == "language"
|
155
164
|
return ""
|
165
|
+
elsif name == "async" || name == "defer"
|
166
|
+
return name_original
|
167
|
+
end
|
168
|
+
when "form"
|
169
|
+
if name == "method" && (value == "=\"get\"" || value == "='get'")
|
170
|
+
return ""
|
171
|
+
end
|
172
|
+
when /link|style/
|
173
|
+
if name == "type"
|
174
|
+
return ""
|
175
|
+
end
|
176
|
+
when /input|textarea|button|select|option|optgroup/
|
177
|
+
if name == "disabled"
|
178
|
+
return name_original
|
179
|
+
end
|
180
|
+
if (tag_name == "input" || tag_name == "textarea") && name == "readonly"
|
181
|
+
return name_original
|
182
|
+
end
|
183
|
+
if tag_name == "option" && name == "selected"
|
184
|
+
return name_original
|
185
|
+
end
|
186
|
+
if tag_name == "input"
|
187
|
+
if name == "type" && (value == "=\"text\"" || value == "='text'")
|
188
|
+
return ""
|
189
|
+
end
|
190
|
+
if name == "checked"
|
191
|
+
return name_original
|
192
|
+
end
|
193
|
+
# if name == "value" && (value == "=\"\"" || value == "=''")
|
194
|
+
# return ''
|
195
|
+
# end
|
156
196
|
end
|
157
197
|
end
|
158
198
|
|
159
199
|
if value.size != 0
|
160
200
|
|
161
|
-
name = attribute.gsub(re, "\\1")
|
162
|
-
|
163
201
|
re = "^=" + delimiter + "|" + delimiter + "$"
|
164
202
|
re = Regexp.new re
|
165
|
-
|
203
|
+
value_original.gsub!(re, "")
|
166
204
|
|
167
205
|
if name == "style"
|
168
|
-
|
206
|
+
value_original = HtmlPress.css_compressor value_original
|
169
207
|
end
|
170
208
|
|
171
209
|
if name == "class"
|
172
|
-
|
173
|
-
|
210
|
+
value_original.gsub!(/\s+/, " ")
|
211
|
+
value_original.gsub!(/^\s+|\s+$/, "")
|
174
212
|
end
|
175
213
|
|
176
214
|
# if name == "onclick"
|
177
215
|
# value = HtmlPress.js_compressor value
|
178
216
|
# end
|
179
217
|
|
180
|
-
attribute =
|
218
|
+
attribute = name_original + "=" + delimiter + value_original + delimiter
|
181
219
|
end
|
182
220
|
|
183
221
|
attribute
|
data/lib/html_press/version.rb
CHANGED
data/spec/html_press_spec.rb
CHANGED
@@ -62,15 +62,6 @@ describe HtmlPress do
|
|
62
62
|
HtmlPress.compress(text).should eql text
|
63
63
|
end
|
64
64
|
|
65
|
-
it "should remove unnecessary whitespaces between attributes" do
|
66
|
-
HtmlPress.compress("<p class=\"a\" id=\"b\"></p>").should eql "<p class=\"a\" id=\"b\"></p>"
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should leave whitespaces everywhere else" do
|
70
|
-
text = "<a onclick=\"alert(' ')\" unknown_attr=' a a'>a</a>"
|
71
|
-
HtmlPress.compress(text).should eql text
|
72
|
-
end
|
73
|
-
|
74
65
|
it "should work with special utf-8 symbols" do
|
75
66
|
HtmlPress.compress("✪<p></p> <p></p>").should eql "✪<p></p><p></p>"
|
76
67
|
end
|
@@ -98,12 +89,25 @@ describe HtmlPress do
|
|
98
89
|
HtmlPress.compress(text).should eql text2
|
99
90
|
end
|
100
91
|
|
101
|
-
it "should remove unnecessary whitespaces
|
92
|
+
it "should remove unnecessary whitespaces inside tag" do
|
93
|
+
HtmlPress.compress("<p class=\"a\" id=\"b\"></p>").should eql "<p class=\"a\" id=\"b\"></p>"
|
94
|
+
HtmlPress.compress("<p class=\"a\" ></p>").should eql "<p class=\"a\"></p>"
|
95
|
+
HtmlPress.compress("<img src=\"\" />").should eql "<img src=\"\"/>"
|
96
|
+
HtmlPress.compress("<br />").should eql "<br/>"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should work with 'badly' formatted attributes" do
|
100
|
+
HtmlPress.compress("<p class='a' id='b'></p>").should eql "<p class='a' id='b'></p>"
|
101
|
+
# HtmlPress.compress("<p class = 'a'></p>").should eql "<p class='a'></p>"
|
102
|
+
# HtmlPress.compress("<p class = a></p>").should eql "<p class=a></p>"
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should optimize attributes" do
|
102
106
|
HtmlPress.compress("<p class=\"a b\"></p>").should eql "<p class=\"a b\"></p>"
|
103
|
-
|
107
|
+
# http(s):// to //
|
104
108
|
end
|
105
109
|
|
106
|
-
it "should
|
110
|
+
it "should compress css in style attributes" do
|
107
111
|
HtmlPress.compress("<p style=\"display: none;\"></p>").should eql "<p style=\"display:none;\"></p>"
|
108
112
|
end
|
109
113
|
|
@@ -118,16 +122,79 @@ describe HtmlPress do
|
|
118
122
|
HtmlPress.compress(text)
|
119
123
|
text.should eql text1
|
120
124
|
end
|
121
|
-
|
122
|
-
it "should
|
125
|
+
|
126
|
+
it "should leave whitespaces inside other attributes" do
|
127
|
+
text = "<a onclick=\"alert(' ')\" unknown_attr=' a a'>a</a>"
|
128
|
+
HtmlPress.compress(text).should eql text
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should report javascript errors" do
|
123
132
|
script_with_error = "<script>function(){</script>"
|
124
133
|
l = Lg.new
|
125
134
|
l.warns.size.should eql 0
|
126
135
|
HtmlPress.compress(script_with_error, {:logger => l}).should eql script_with_error
|
127
136
|
l.warns.size.should eql 1
|
128
137
|
end
|
129
|
-
|
130
|
-
|
138
|
+
|
139
|
+
# it "should report css errors" do
|
140
|
+
# script_with_error = "<style>.clas{margin:</style>"
|
141
|
+
# l = Lg.new
|
142
|
+
# l.warns.size.should eql 0
|
143
|
+
# HtmlPress.compress(script_with_error, {:logger => l}).should eql script_with_error
|
144
|
+
# l.warns.size.should eql 1
|
145
|
+
# end
|
146
|
+
|
147
|
+
it "should remove values of boolean attributes" do
|
148
|
+
HtmlPress.compress("<option selected=\"selected\">a</option>").should eql "<option selected>a</option>"
|
149
|
+
HtmlPress.compress("<input type=\"checkbox\" checked=\"checked\"/>").should eql "<input type=\"checkbox\" checked/>"
|
150
|
+
HtmlPress.compress("<input type=\"radio\" checked=\"checked\"/>").should eql "<input type=\"radio\" checked/>"
|
151
|
+
# disabled (input, textarea, button, select, option, optgroup)
|
152
|
+
HtmlPress.compress("<input disabled=\"disabled\"/>").should eql "<input disabled/>"
|
153
|
+
# readonly (input type=text/password, textarea)
|
154
|
+
HtmlPress.compress("<input readonly=\"readonly\"/>").should eql "<input readonly/>"
|
155
|
+
# HtmlPress.compress("<script src=\"example.com\" async=\"async\"></script>").should eql "<script src=\"example.com\" async></script>"
|
156
|
+
# HtmlPress.compress("<script src=\"example.com\" defer=\"defer\"></script>").should eql "<script src=\"example.com\" async></script>"
|
157
|
+
# HtmlPress.compress("<select multiple=\"multiple\"/>").should eql "<select multiple/>"
|
158
|
+
# ismap isMap (img, input type=image)
|
159
|
+
# declare (object; never used)
|
160
|
+
# noresize noResize (frame)
|
161
|
+
# nowrap noWrap (td, th; deprecated)
|
162
|
+
# noshade noShade (hr; deprecated)
|
163
|
+
# compact (ul, ol, dl, menu, dir; deprecated)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should remove attributes with default values" do
|
167
|
+
# HtmlPress.compress("<script type=\"text/javascript\" language=\"JavaScript\">var a;</script>").should eql "<script>var a;</script>"
|
168
|
+
# HtmlPress.compress("<style type=\"text/stylesheet\"></style>").should eql "<style></style>"
|
169
|
+
HtmlPress.compress("<link type=\"text/stylesheet\"/>").should eql "<link/>"
|
170
|
+
HtmlPress.compress("<form method=\"get\"></form>").should eql "<form></form>"
|
171
|
+
HtmlPress.compress("<input type=\"text\"/>").should eql "<input/>"
|
172
|
+
# input value "" ?
|
173
|
+
end
|
174
|
+
|
175
|
+
# it "should compress javascript in event attributes" do
|
176
|
+
# # javascript: - remove
|
177
|
+
# # onfocus
|
178
|
+
# # onblur
|
179
|
+
# # onselect
|
180
|
+
# # onchange
|
181
|
+
# # onclick
|
182
|
+
# # ondblclick
|
183
|
+
# # onmousedown
|
184
|
+
# # onmouseup
|
185
|
+
# # onmouseover
|
186
|
+
# # onmousemove
|
187
|
+
# # onmouseout
|
188
|
+
# # onkeypress
|
189
|
+
# # onkeydown
|
190
|
+
# # onkeyup
|
191
|
+
# end
|
192
|
+
#
|
193
|
+
# it "should remove unnecessary quotes for attributes values" do
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# it "should convert html entities to utf-8 symbols" do
|
197
|
+
# # except <>&
|
131
198
|
# end
|
132
199
|
|
133
200
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html_press
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-05 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &26078568 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *26078568
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &26078208 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *26078208
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rainpress
|
38
|
-
requirement: &
|
38
|
+
requirement: &26077776 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *26077776
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: uglifier
|
49
|
-
requirement: &
|
49
|
+
requirement: &26077452 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *26077452
|
58
58
|
description: Ruby gem for compressing html
|
59
59
|
email:
|
60
60
|
- stereobooster@gmail.com
|