html_press 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -6
- data/.travis.yml +8 -8
- data/Gemfile +6 -6
- data/Readme.md +73 -71
- data/html_press.gemspec +26 -26
- data/lib/html_press.rb +24 -23
- data/lib/html_press/html.rb +325 -325
- data/lib/html_press/html_entities.rb +36 -36
- data/lib/html_press/version.rb +3 -3
- data/profile/index.html +37689 -37689
- data/profile/profile.rb +28 -28
- data/spec/html_press_spec.rb +258 -256
- metadata +19 -37
data/profile/profile.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
require "bundler"
|
2
|
-
Bundler.setup
|
3
|
-
|
4
|
-
require 'ruby-prof'
|
5
|
-
require 'html_press'
|
6
|
-
|
7
|
-
file_path = File.expand_path("../index.html", __FILE__)
|
8
|
-
html = File.open(file_path, "r:UTF-8").read
|
9
|
-
|
10
|
-
# require 'open-uri'
|
11
|
-
# html = open('http://www.amazon.com/') {|f| f.read }
|
12
|
-
|
13
|
-
before = html.bytesize
|
14
|
-
html.force_encoding "UTF-8" if html.respond_to?(:force_encoding)
|
15
|
-
|
16
|
-
RubyProf.start
|
17
|
-
html = HtmlPress.press html
|
18
|
-
result = RubyProf.stop
|
19
|
-
|
20
|
-
after = html.bytesize
|
21
|
-
puts "Economy: " + ((before - after).to_f/1024).round(2).to_s + "kb (" +
|
22
|
-
(100*(before - after).to_f/before).round(2).to_s + "%)"
|
23
|
-
|
24
|
-
report_path = File.expand_path("../reports", __FILE__)
|
25
|
-
FileUtils.rm_rf(report_path)
|
26
|
-
Dir.mkdir(report_path) unless File.exist?(report_path)
|
27
|
-
printer = RubyProf::MultiPrinter.new(result)
|
28
|
-
printer.print(:path => report_path, :profile => "profile")
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'ruby-prof'
|
5
|
+
require 'html_press'
|
6
|
+
|
7
|
+
file_path = File.expand_path("../index.html", __FILE__)
|
8
|
+
html = File.open(file_path, "r:UTF-8").read
|
9
|
+
|
10
|
+
# require 'open-uri'
|
11
|
+
# html = open('http://www.amazon.com/') {|f| f.read }
|
12
|
+
|
13
|
+
before = html.bytesize
|
14
|
+
html.force_encoding "UTF-8" if html.respond_to?(:force_encoding)
|
15
|
+
|
16
|
+
RubyProf.start
|
17
|
+
html = HtmlPress.press html
|
18
|
+
result = RubyProf.stop
|
19
|
+
|
20
|
+
after = html.bytesize
|
21
|
+
puts "Economy: " + ((before - after).to_f/1024).round(2).to_s + "kb (" +
|
22
|
+
(100*(before - after).to_f/before).round(2).to_s + "%)"
|
23
|
+
|
24
|
+
report_path = File.expand_path("../reports", __FILE__)
|
25
|
+
FileUtils.rm_rf(report_path)
|
26
|
+
Dir.mkdir(report_path) unless File.exist?(report_path)
|
27
|
+
printer = RubyProf::MultiPrinter.new(result)
|
28
|
+
printer.print(:path => report_path, :profile => "profile")
|
data/spec/html_press_spec.rb
CHANGED
@@ -1,257 +1,259 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("../lib/html_press", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class LoggerStub
|
6
|
-
attr_accessor :errors
|
7
|
-
def initialize
|
8
|
-
@errors = []
|
9
|
-
end
|
10
|
-
def error text
|
11
|
-
@errors.push text
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe HtmlPress do
|
16
|
-
before :each do
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should leave only one whitespace between inline tags" do
|
20
|
-
HtmlPress.press("<p>lorem <b>ipsum</b> <i>dolor</i> </p>").should eql "<p>lorem <b>ipsum</b> <i>dolor</i></p>"
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should leave no whitespaces between block tags" do
|
24
|
-
HtmlPress.press("<div></div> \t\r\n <div></div>").should eql "<div></div><div></div>"
|
25
|
-
HtmlPress.press("<div> <div> \t\r\n </div> </div>").should eql "<div><div></div></div>"
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should leave only one whitespace in text" do
|
29
|
-
HtmlPress.press("<p>a a</p>").should eql "<p>a a</p>"
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should leave newlines in pre tags and remove trailing spaces" do
|
33
|
-
HtmlPress.press("<pre>a \t </pre>").should eql "<pre>a</pre>"
|
34
|
-
HtmlPress.press("<pre>qwe \r\nasd </pre>").should eql "<pre>qwe\nasd</pre>"
|
35
|
-
HtmlPress.press("<pre> qwe \n\r\n asd </pre>").should eql "<pre> qwe\n\n asd</pre>"
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should leave textareas as is" do
|
39
|
-
text = "<textarea> \t </textarea>"
|
40
|
-
HtmlPress.press(text).should eql text
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should compress js in script tags" do
|
44
|
-
script = " (function(undefined){ \t\n var long_name = ' '; }()) \n \r"
|
45
|
-
pressed_script = "<script>" + HtmlPress.js_compressor(script) + "</script>"
|
46
|
-
script = " <script>" + script + "</script> "
|
47
|
-
HtmlPress.press(script).should eql pressed_script
|
48
|
-
|
49
|
-
script = %q{<script>window.jQuery||document.write('<script src="/components/jquery/jquery.js"><\/script>')</script>}
|
50
|
-
HtmlPress.press(script).should eql script
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should compress css in style tags" do
|
54
|
-
style = " div { margin: 0px 0px; \n} "
|
55
|
-
pressed_style = "<style>" + MultiCss.min(style) + "</style>"
|
56
|
-
style = " <style>" + style + "</style> "
|
57
|
-
HtmlPress.press(style).should eql pressed_style
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should remove html comments" do
|
61
|
-
HtmlPress.press("<p></p><!-- comment --><p></p>").should eql "<p></p><p></p>"
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should leave IE conditional comments" do
|
65
|
-
text = "<!--[if IE]><html class=\"ie\"><![endif]--><div></div>"
|
66
|
-
HtmlPress.press(text).should eql text
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should work with special utf-8 symbols" do
|
70
|
-
HtmlPress.press("✪<p></p> <p></p>").should eql "✪<p></p><p></p>"
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should work with tags in upper case" do
|
74
|
-
HtmlPress.press("<P> </p>").should eql "<P></p>"
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should remove whitespaces between IE conditional comments" do
|
78
|
-
text = "<p></p> <!--[if IE]><html class=\"ie\"> <![endif]--> <!--[if IE]><html class=\"ie1\"><![endif]-->"
|
79
|
-
text2 = "<p></p> <!--[if IE]><html class=\"ie\"><![endif]--><!--[if IE]><html class=\"ie1\"><![endif]-->"
|
80
|
-
# TODO ↑ remove this whitespace
|
81
|
-
HtmlPress.press(text).should eql text2
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should remove whitespaces between script tags" do
|
85
|
-
text = "<p></p> <script>var a</script> \t <script>var b</script>"
|
86
|
-
text2 = "<p></p> <script>var a</script><script>var b</script>"
|
87
|
-
HtmlPress.press(text).should eql text2
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should concatenate adjacent script tags" do
|
91
|
-
pending "Not implemented yet" do
|
92
|
-
text = "<p></p> <script>var a</script> \t <script>function b(){}</script>"
|
93
|
-
text2 = "<p></p> <script>var a;function b(){}</script>"
|
94
|
-
HtmlPress.press(text).should eql text2
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should treat text inside IE conditional comments as it was without comments" do
|
99
|
-
text = "<div class=\"a\" id=\"b\"> </div> <p></p>"
|
100
|
-
text2 = HtmlPress.press(text)
|
101
|
-
text = "<!--[if IE]>" + text + "<![endif]-->"
|
102
|
-
text2 = "<!--[if IE]>" + text2 + "<![endif]-->"
|
103
|
-
HtmlPress.press(text).should eql text2
|
104
|
-
text = "<script> (function(undefined){ var a;}()) </script>"
|
105
|
-
text2 = HtmlPress.press(text)
|
106
|
-
text = "<!--[if IE]>" + text + "<![endif]-->"
|
107
|
-
text2 = "<!--[if IE]>" + text2 + "<![endif]-->"
|
108
|
-
HtmlPress.press(text).should eql text2
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should remove unnecessary whitespaces inside tag" do
|
112
|
-
HtmlPress.press("<p class=\"a\" id=\"b\"></p>").should eql "<p class=\"a\" id=\"b\"></p>"
|
113
|
-
HtmlPress.press("<p class=\"a\" ></p>").should eql "<p class=\"a\"></p>"
|
114
|
-
HtmlPress.press("<img src=\"\" />").should eql "<img src=\"\"/>"
|
115
|
-
HtmlPress.press("<br />").should eql "<br/>"
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should work with 'badly' formatted attributes" do
|
119
|
-
HtmlPress.press("<p class='a' id='b'></p>").should eql "<p class='a' id='b'></p>"
|
120
|
-
# HtmlPress.press("<p class = 'a'></p>").should eql "<p class='a'></p>"
|
121
|
-
# HtmlPress.press("<p class = a></p>").should eql "<p class=a></p>"
|
122
|
-
end
|
123
|
-
|
124
|
-
it "should work with different case attributes" do
|
125
|
-
text = '<embed allowFullScreen="true" allowScriptAccess="always"/>'
|
126
|
-
HtmlPress.press(text).should eql text
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should optimize attributes" do
|
130
|
-
HtmlPress.press("<p class=\"a b\"></p>").should eql "<p class=\"a b\"></p>"
|
131
|
-
# TODO http(s):// to //
|
132
|
-
end
|
133
|
-
|
134
|
-
it "should compress css in style attributes" do
|
135
|
-
HtmlPress.press("<p style=\"display: none;\"></p>").should eql "<p style=\"display:none\"></p>"
|
136
|
-
HtmlPress.press("<p style=\"\"></p>").should eql "<p style=\"\"></p>"
|
137
|
-
#FIX those tests can be broken if algorithm of css_press will be changed
|
138
|
-
HtmlPress.press("<p style=\"font-family:Arial ,'Helvetica Neue'\"></p>").should eql "<p style=\"font-family:Arial ,'Helvetica Neue'\"></p>"
|
139
|
-
HtmlPress.press("<p style='font-family:Arial ,\"Helvetica Neue\"'></p>").should eql "<p style='font-family:Arial ,\"Helvetica Neue\"'></p>"
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should work with namespaces" do
|
143
|
-
text = "<html xmlns:og=\"http://ogp.me/ns#\" class=\"a b\"><og:like>like</og:like></html>"
|
144
|
-
HtmlPress.press(text).should eql text
|
145
|
-
end
|
146
|
-
|
147
|
-
it "should compress namespaces" do
|
148
|
-
pending "Not implemented yet" do
|
149
|
-
text = "<html xmlns:og=\"http://ogp.me/ns#\" class=\"a b\"><og:like>like</og:like></html>"
|
150
|
-
text1 = "<html xmlns:a=\"http://ogp.me/ns#\" class=\"a b\"><a:like>like</a:like></html>"
|
151
|
-
HtmlPress.press(text).should eql text1
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
it "should not modify input value" do
|
156
|
-
text = "<div> </div>"
|
157
|
-
text1 = text.dup
|
158
|
-
HtmlPress.press(text).should_not eql text
|
159
|
-
text.should eql text1
|
160
|
-
end
|
161
|
-
|
162
|
-
it "should leave whitespaces inside other attributes" do
|
163
|
-
text = "<a onclick=\"alert(' ')\" unknown_attr=' a a'>a</a>"
|
164
|
-
HtmlPress.press(text).should eql text
|
165
|
-
end
|
166
|
-
|
167
|
-
it "should report javascript errors" do
|
168
|
-
["<script>function(){</script>", "<a onclick=\"return false\"></a>"].each do |script_with_error|
|
169
|
-
log = LoggerStub.new
|
170
|
-
HtmlPress.press(script_with_error, {:logger => log}).should eql script_with_error
|
171
|
-
log.errors.size.should eql 1
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
it "should report css errors" do
|
176
|
-
["<style>.clas{margin:</style>", "<a style=\"#asd\">link</a>"].each do |style_with_error|
|
177
|
-
log = LoggerStub.new
|
178
|
-
HtmlPress.press(style_with_error, {:logger => log}).should eql style_with_error
|
179
|
-
log.errors.size.should eql 1
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should remove values of boolean attributes" do
|
184
|
-
HtmlPress.press("<option selected=\"selected\">a</option>").should eql "<option selected>a</option>"
|
185
|
-
HtmlPress.press("<input type=\"checkbox\" checked=\"checked\"/>").should eql "<input type=\"checkbox\" checked/>"
|
186
|
-
HtmlPress.press("<input type=\"radio\" checked=\"checked\"/>").should eql "<input type=\"radio\" checked/>"
|
187
|
-
# disabled (input, textarea, button, select, option, optgroup)
|
188
|
-
HtmlPress.press("<input disabled=\"disabled\"/>").should eql "<input disabled/>"
|
189
|
-
# readonly (input type=text/password, textarea)
|
190
|
-
HtmlPress.press("<input readonly=\"readonly\"/>").should eql "<input readonly/>"
|
191
|
-
pending "Not implemented yet" do
|
192
|
-
HtmlPress.press("<script src=\"example.com\" async=\"async\"></script>").should eql "<script src=\"example.com\" async></script>"
|
193
|
-
HtmlPress.press("<script src=\"example.com\" defer=\"defer\"></script>").should eql "<script src=\"example.com\" defer></script>"
|
194
|
-
HtmlPress.press("<select multiple=\"multiple\"/>").should eql "<select multiple/>"
|
195
|
-
# ismap isMap (img, input type=image)
|
196
|
-
# declare (object; never used)
|
197
|
-
# noresize noResize (frame)
|
198
|
-
# nowrap noWrap (td, th; deprecated)
|
199
|
-
# noshade noShade (hr; deprecated)
|
200
|
-
# compact (ul, ol, dl, menu, dir; deprecated)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should remove attributes with default values" do
|
205
|
-
HtmlPress.press("<script type=\"text/javascript\" language=\"JavaScript\">var a</script>").should eql "<script>var a</script>"
|
206
|
-
HtmlPress.press("<
|
207
|
-
|
208
|
-
HtmlPress.press("<
|
209
|
-
HtmlPress.press("<
|
210
|
-
HtmlPress.press("<
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
HtmlPress.press(
|
227
|
-
text = "<p id=\"a
|
228
|
-
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
229
|
-
text = "<p id=\"a
|
230
|
-
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
231
|
-
text = "<p id=\"a
|
232
|
-
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
233
|
-
text = "<p id
|
234
|
-
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
235
|
-
text = "<p id
|
236
|
-
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require File.expand_path("../lib/html_press", File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class LoggerStub
|
6
|
+
attr_accessor :errors
|
7
|
+
def initialize
|
8
|
+
@errors = []
|
9
|
+
end
|
10
|
+
def error text
|
11
|
+
@errors.push text
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe HtmlPress do
|
16
|
+
before :each do
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should leave only one whitespace between inline tags" do
|
20
|
+
HtmlPress.press("<p>lorem <b>ipsum</b> <i>dolor</i> </p>").should eql "<p>lorem <b>ipsum</b> <i>dolor</i></p>"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should leave no whitespaces between block tags" do
|
24
|
+
HtmlPress.press("<div></div> \t\r\n <div></div>").should eql "<div></div><div></div>"
|
25
|
+
HtmlPress.press("<div> <div> \t\r\n </div> </div>").should eql "<div><div></div></div>"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should leave only one whitespace in text" do
|
29
|
+
HtmlPress.press("<p>a a</p>").should eql "<p>a a</p>"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should leave newlines in pre tags and remove trailing spaces" do
|
33
|
+
HtmlPress.press("<pre>a \t </pre>").should eql "<pre>a</pre>"
|
34
|
+
HtmlPress.press("<pre>qwe \r\nasd </pre>").should eql "<pre>qwe\nasd</pre>"
|
35
|
+
HtmlPress.press("<pre> qwe \n\r\n asd </pre>").should eql "<pre> qwe\n\n asd</pre>"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should leave textareas as is" do
|
39
|
+
text = "<textarea> \t </textarea>"
|
40
|
+
HtmlPress.press(text).should eql text
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should compress js in script tags" do
|
44
|
+
script = " (function(undefined){ \t\n var long_name = ' '; }()) \n \r"
|
45
|
+
pressed_script = "<script>" + HtmlPress.js_compressor(script) + "</script>"
|
46
|
+
script = " <script>" + script + "</script> "
|
47
|
+
HtmlPress.press(script).should eql pressed_script
|
48
|
+
|
49
|
+
script = %q{<script>window.jQuery||document.write('<script src="/components/jquery/jquery.js"><\/script>')</script>}
|
50
|
+
HtmlPress.press(script).should eql script
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should compress css in style tags" do
|
54
|
+
style = " div { margin: 0px 0px; \n} "
|
55
|
+
pressed_style = "<style>" + MultiCss.min(style) + "</style>"
|
56
|
+
style = " <style>" + style + "</style> "
|
57
|
+
HtmlPress.press(style).should eql pressed_style
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should remove html comments" do
|
61
|
+
HtmlPress.press("<p></p><!-- comment --><p></p>").should eql "<p></p><p></p>"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should leave IE conditional comments" do
|
65
|
+
text = "<!--[if IE]><html class=\"ie\"><![endif]--><div></div>"
|
66
|
+
HtmlPress.press(text).should eql text
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should work with special utf-8 symbols" do
|
70
|
+
HtmlPress.press("✪<p></p> <p></p>").should eql "✪<p></p><p></p>"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should work with tags in upper case" do
|
74
|
+
HtmlPress.press("<P> </p>").should eql "<P></p>"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should remove whitespaces between IE conditional comments" do
|
78
|
+
text = "<p></p> <!--[if IE]><html class=\"ie\"> <![endif]--> <!--[if IE]><html class=\"ie1\"><![endif]-->"
|
79
|
+
text2 = "<p></p> <!--[if IE]><html class=\"ie\"><![endif]--><!--[if IE]><html class=\"ie1\"><![endif]-->"
|
80
|
+
# TODO ↑ remove this whitespace
|
81
|
+
HtmlPress.press(text).should eql text2
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should remove whitespaces between script tags" do
|
85
|
+
text = "<p></p> <script>var a</script> \t <script>var b</script>"
|
86
|
+
text2 = "<p></p> <script>var a</script><script>var b</script>"
|
87
|
+
HtmlPress.press(text).should eql text2
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should concatenate adjacent script tags" do
|
91
|
+
pending "Not implemented yet" do
|
92
|
+
text = "<p></p> <script>var a</script> \t <script>function b(){}</script>"
|
93
|
+
text2 = "<p></p> <script>var a;function b(){}</script>"
|
94
|
+
HtmlPress.press(text).should eql text2
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should treat text inside IE conditional comments as it was without comments" do
|
99
|
+
text = "<div class=\"a\" id=\"b\"> </div> <p></p>"
|
100
|
+
text2 = HtmlPress.press(text)
|
101
|
+
text = "<!--[if IE]>" + text + "<![endif]-->"
|
102
|
+
text2 = "<!--[if IE]>" + text2 + "<![endif]-->"
|
103
|
+
HtmlPress.press(text).should eql text2
|
104
|
+
text = "<script> (function(undefined){ var a;}()) </script>"
|
105
|
+
text2 = HtmlPress.press(text)
|
106
|
+
text = "<!--[if IE]>" + text + "<![endif]-->"
|
107
|
+
text2 = "<!--[if IE]>" + text2 + "<![endif]-->"
|
108
|
+
HtmlPress.press(text).should eql text2
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should remove unnecessary whitespaces inside tag" do
|
112
|
+
HtmlPress.press("<p class=\"a\" id=\"b\"></p>").should eql "<p class=\"a\" id=\"b\"></p>"
|
113
|
+
HtmlPress.press("<p class=\"a\" ></p>").should eql "<p class=\"a\"></p>"
|
114
|
+
HtmlPress.press("<img src=\"\" />").should eql "<img src=\"\"/>"
|
115
|
+
HtmlPress.press("<br />").should eql "<br/>"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should work with 'badly' formatted attributes" do
|
119
|
+
HtmlPress.press("<p class='a' id='b'></p>").should eql "<p class='a' id='b'></p>"
|
120
|
+
# HtmlPress.press("<p class = 'a'></p>").should eql "<p class='a'></p>"
|
121
|
+
# HtmlPress.press("<p class = a></p>").should eql "<p class=a></p>"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should work with different case attributes" do
|
125
|
+
text = '<embed allowFullScreen="true" allowScriptAccess="always"/>'
|
126
|
+
HtmlPress.press(text).should eql text
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should optimize attributes" do
|
130
|
+
HtmlPress.press("<p class=\"a b\"></p>").should eql "<p class=\"a b\"></p>"
|
131
|
+
# TODO http(s):// to //
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should compress css in style attributes" do
|
135
|
+
HtmlPress.press("<p style=\"display: none;\"></p>").should eql "<p style=\"display:none\"></p>"
|
136
|
+
HtmlPress.press("<p style=\"\"></p>").should eql "<p style=\"\"></p>"
|
137
|
+
#FIX those tests can be broken if algorithm of css_press will be changed
|
138
|
+
HtmlPress.press("<p style=\"font-family:Arial ,'Helvetica Neue'\"></p>").should eql "<p style=\"font-family:Arial ,'Helvetica Neue'\"></p>"
|
139
|
+
HtmlPress.press("<p style='font-family:Arial ,\"Helvetica Neue\"'></p>").should eql "<p style='font-family:Arial ,\"Helvetica Neue\"'></p>"
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should work with namespaces" do
|
143
|
+
text = "<html xmlns:og=\"http://ogp.me/ns#\" class=\"a b\"><og:like>like</og:like></html>"
|
144
|
+
HtmlPress.press(text).should eql text
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should compress namespaces" do
|
148
|
+
pending "Not implemented yet" do
|
149
|
+
text = "<html xmlns:og=\"http://ogp.me/ns#\" class=\"a b\"><og:like>like</og:like></html>"
|
150
|
+
text1 = "<html xmlns:a=\"http://ogp.me/ns#\" class=\"a b\"><a:like>like</a:like></html>"
|
151
|
+
HtmlPress.press(text).should eql text1
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should not modify input value" do
|
156
|
+
text = "<div> </div>"
|
157
|
+
text1 = text.dup
|
158
|
+
HtmlPress.press(text).should_not eql text
|
159
|
+
text.should eql text1
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should leave whitespaces inside other attributes" do
|
163
|
+
text = "<a onclick=\"alert(' ')\" unknown_attr=' a a'>a</a>"
|
164
|
+
HtmlPress.press(text).should eql text
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should report javascript errors" do
|
168
|
+
["<script>function(){</script>", "<a onclick=\"return false\"></a>"].each do |script_with_error|
|
169
|
+
log = LoggerStub.new
|
170
|
+
HtmlPress.press(script_with_error, {:logger => log}).should eql script_with_error
|
171
|
+
log.errors.size.should eql 1
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should report css errors" do
|
176
|
+
["<style>.clas{margin:</style>", "<a style=\"#asd\">link</a>"].each do |style_with_error|
|
177
|
+
log = LoggerStub.new
|
178
|
+
HtmlPress.press(style_with_error, {:logger => log}).should eql style_with_error
|
179
|
+
log.errors.size.should eql 1
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should remove values of boolean attributes" do
|
184
|
+
HtmlPress.press("<option selected=\"selected\">a</option>").should eql "<option selected>a</option>"
|
185
|
+
HtmlPress.press("<input type=\"checkbox\" checked=\"checked\"/>").should eql "<input type=\"checkbox\" checked/>"
|
186
|
+
HtmlPress.press("<input type=\"radio\" checked=\"checked\"/>").should eql "<input type=\"radio\" checked/>"
|
187
|
+
# disabled (input, textarea, button, select, option, optgroup)
|
188
|
+
HtmlPress.press("<input disabled=\"disabled\"/>").should eql "<input disabled/>"
|
189
|
+
# readonly (input type=text/password, textarea)
|
190
|
+
HtmlPress.press("<input readonly=\"readonly\"/>").should eql "<input readonly/>"
|
191
|
+
pending "Not implemented yet" do
|
192
|
+
HtmlPress.press("<script src=\"example.com\" async=\"async\"></script>").should eql "<script src=\"example.com\" async></script>"
|
193
|
+
HtmlPress.press("<script src=\"example.com\" defer=\"defer\"></script>").should eql "<script src=\"example.com\" defer></script>"
|
194
|
+
HtmlPress.press("<select multiple=\"multiple\"/>").should eql "<select multiple/>"
|
195
|
+
# ismap isMap (img, input type=image)
|
196
|
+
# declare (object; never used)
|
197
|
+
# noresize noResize (frame)
|
198
|
+
# nowrap noWrap (td, th; deprecated)
|
199
|
+
# noshade noShade (hr; deprecated)
|
200
|
+
# compact (ul, ol, dl, menu, dir; deprecated)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should remove attributes with default values" do
|
205
|
+
HtmlPress.press("<script type=\"text/javascript\" language=\"JavaScript\">var a</script>").should eql "<script>var a</script>"
|
206
|
+
HtmlPress.press("<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\"> </script>").
|
207
|
+
should eql "<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\"></script>"
|
208
|
+
HtmlPress.press("<style type=\"text/stylesheet\"></style>").should eql "<style></style>"
|
209
|
+
HtmlPress.press("<link type=\"text/stylesheet\"/>").should eql "<link/>"
|
210
|
+
HtmlPress.press("<link rel=\"alternate\" type=\"application/rss+xml\"/>").should eql "<link rel=\"alternate\" type=\"application/rss+xml\"/>"
|
211
|
+
HtmlPress.press("<form method=\"get\"></form>").should eql "<form></form>"
|
212
|
+
HtmlPress.press("<input type=\"text\"/>").should eql "<input/>"
|
213
|
+
# input value "" ?
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should convert html entities to utf-8 symbols" do
|
217
|
+
HtmlPress.press("< < > > & &").should eql "< < > > & &"
|
218
|
+
HtmlPress.press("élan").should eql "élan"
|
219
|
+
%W{textarea pre}.each do |t|
|
220
|
+
HtmlPress.press("<#{t}>'</#{t}>").should eql "<#{t}>'</#{t}>"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should remove unnecessary quotes for attribute values" do
|
225
|
+
HtmlPress.press("<img src=\"\">", {:unquoted_attributes => true}).should eql "<img src=\"\">"
|
226
|
+
HtmlPress.press("<p id=\"a\"></p>", {:unquoted_attributes => true}).should eql "<p id=a></p>"
|
227
|
+
text = "<p id=\"a b\"></p>"
|
228
|
+
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
229
|
+
text = "<p id=\"a=\"></p>"
|
230
|
+
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
231
|
+
text = "<p id=\"a'\"></p>"
|
232
|
+
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
233
|
+
text = "<p id=\"a`\"></p>"
|
234
|
+
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
235
|
+
text = "<p id='a\"'></p>"
|
236
|
+
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
237
|
+
text = "<p id=\"a\t\"></p>"
|
238
|
+
HtmlPress.press(text, {:unquoted_attributes => true}).should eql text
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should remove empty attribute values" do
|
242
|
+
HtmlPress.press("<img src=\"\">", {:drop_empty_values => true}).should eql "<img src>"
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should compress javascript in event attributes" do
|
246
|
+
%w[onfocus onblur onselect onchange onclick
|
247
|
+
ondblclick onmousedown onmouseup onmouseover onmousemove
|
248
|
+
onmouseout onkeypress onkeydown onkeyup
|
249
|
+
].each do |evt|
|
250
|
+
HtmlPress.press("<a #{evt}=\"javacript: alert(' ');\"></a>").should eql "<a #{evt}=\"alert(' ')\"></a>"
|
251
|
+
HtmlPress.press("<a #{evt}=\"\"></a>").should eql "<a #{evt}=\"\"></a>"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should concatenate adjecent style tags" do
|
256
|
+
pending "Not implemented yet"
|
257
|
+
# all stylle tags can be collected, concatneated and placed in header
|
258
|
+
end
|
257
259
|
end
|