html5small 0.0.1 → 0.1.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/README.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # HTML5small
2
2
 
3
3
  HTML5small is a general-purpose minifier for HTML5 documents.
4
+ <br>
5
+ It is faster than [html_compressor](https://github.com/completelynovel/html_compressor)
6
+ and at the same time compresses much better,
7
+ while still generating valid HTML5.
8
+
9
+ ## Usage
10
+ ```sh
11
+ $ gem install html5small
12
+ ```
13
+
14
+ ```ruby
15
+ require 'html5small'
16
+ ::HTML5.minify '<html>...</html>'
17
+ ```
4
18
 
5
19
  ## Origin
6
20
  HTML5small is based on [h5-min](https://github.com/runpaint/h5-min),
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.0
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p><a href=foo&amp;bar>a</a>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p><a href=foo&amp;bar>a</a>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p><a href=a&quot;b>a</a>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p><a href=a&quot;b>a</a>
data/fixtures/dl.html.min CHANGED
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><dl><dt>Term<dd>Desc<dt>Term<dt>Term<dd>Desc</dl>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><dl><dt>Term<dd>Desc<dt>Term<dt>Term<dd>Desc</dl>
@@ -0,0 +1,5 @@
1
+ <!DOCTYPE html>
2
+ <meta charset=utf-8>
3
+ <title>Untitled</title>
4
+ <div itemscope hidden="">
5
+ </div>
@@ -0,0 +1 @@
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><div hidden itemscope></div>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>⋔ Ь
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>⋔ Ь
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>1 &amp; 2 &gt; ?
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>1 &amp; 2 &gt; ?
data/fixtures/ie.html.min CHANGED
@@ -1,3 +1,3 @@
1
1
  <!doctype html><meta charset=utf-8><title>Untitled</title><!--[if lt IE 9]>
2
2
  <script src=//html5shiv.googlecode.com/svn/trunk/html5.js></script>
3
- <![endif]--><h1>I.E!?!</h1>
3
+ <![endif]--><body><h1>I.E!?!</h1>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><ul><li><i>one</i><li><i>two</i></ul>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><ul><li><i>one</i><li><i>two</i></ul>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>Two lines
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>Two lines
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p><dfn title="a b">d</dfn>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p><dfn title="a b">d</dfn>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>p<p>p
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>p<p>p
@@ -1,4 +1,4 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><pre>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><pre>
2
2
  &lt; - &gt;
3
3
  &amp;
4
4
  </pre>
@@ -1,4 +1,4 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><pre>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><pre>
2
2
  This
3
3
  <b>is</b>
4
4
  pre-formatted .
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>"q'<pre>&amp;"'</pre>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>"q'<pre>&amp;"'</pre>
@@ -0,0 +1,8 @@
1
+ <!DOCTYPE html>
2
+ <meta charset=utf-8>
3
+ <title>Untitled</title>
4
+ <script>
5
+ console.log(1 < 2);
6
+ console.log(1 > 2);
7
+ console.log(1 && 2);
8
+ </script>
@@ -0,0 +1,5 @@
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><script>
2
+ console.log(1 < 2);
3
+ console.log(1 > 2);
4
+ console.log(1 && 2);
5
+ </script>
@@ -1 +1 @@
1
- <!doctype html><title>Untitled</title><meta charset=utf-8><link href=//creativecommons.org/licenses/by-sa/3.0/ rel=license><h1>Title</h1><p>Test
1
+ <!doctype html><title>Untitled</title><meta charset=utf-8><link href=//creativecommons.org/licenses/by-sa/3.0/ rel=license><body><h1>Title</h1><p>Test
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p><a class=c href=/ hreflang=az-Latn-x-latn style=s title=t>a</a>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p><a class=c href=/ hreflang=az-Latn-x-latn style=s title=t>a</a>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><table class=c><thead class=h><tr><th>H<th>H<tbody class=b><tr><td>D<td>D<tr><td>D<td>D</table>
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><table class=c><thead class=h><tr><th>H<th>H<tbody class=b><tr><td>D<td>D<tr><td>D<td>D</table>
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>Tab tab
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>Tab tab
@@ -1 +1 @@
1
- <!doctype html><meta charset=utf-8><title>Untitled</title><p>This is a<code>string</code>.
1
+ <!doctype html><meta charset=utf-8><title>Untitled</title><body><p>This is a<code>string</code>.
@@ -0,0 +1,103 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "html5small"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Run Paint Run Run", "Ruben Verborgh"]
12
+ s.date = "2012-11-04"
13
+ s.description = "Minifier for HTML5 documents"
14
+ s.email = "ruben.verborgh@gmail.com"
15
+ s.executables = ["html5small", "html5small"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bin/html5small",
27
+ "fixtures/attribute-value-ampersand.html",
28
+ "fixtures/attribute-value-ampersand.html.min",
29
+ "fixtures/attribute-value-quot.html",
30
+ "fixtures/attribute-value-quot.html.min",
31
+ "fixtures/dl.html",
32
+ "fixtures/dl.html.min",
33
+ "fixtures/empty-attributes.html",
34
+ "fixtures/empty-attributes.html.min",
35
+ "fixtures/entities-expand.html",
36
+ "fixtures/entities-expand.html.min",
37
+ "fixtures/entities-no-expand.html",
38
+ "fixtures/entities-no-expand.html.min",
39
+ "fixtures/ie.html",
40
+ "fixtures/ie.html.min",
41
+ "fixtures/lists.html",
42
+ "fixtures/lists.html.min",
43
+ "fixtures/newlines.html",
44
+ "fixtures/newlines.html.min",
45
+ "fixtures/normalise-attribute-name.html",
46
+ "fixtures/normalise-attribute-name.html.min",
47
+ "fixtures/normalise-tag-name.html",
48
+ "fixtures/normalise-tag-name.html.min",
49
+ "fixtures/pre-entities.html",
50
+ "fixtures/pre-entities.html.min",
51
+ "fixtures/pre.html",
52
+ "fixtures/pre.html.min",
53
+ "fixtures/quot-entity.html",
54
+ "fixtures/quot-entity.html.min",
55
+ "fixtures/scripts.html",
56
+ "fixtures/scripts.html.min",
57
+ "fixtures/skeleton.html",
58
+ "fixtures/skeleton.html.min",
59
+ "fixtures/sort-attributes.html",
60
+ "fixtures/sort-attributes.html.min",
61
+ "fixtures/table.html",
62
+ "fixtures/table.html.min",
63
+ "fixtures/tabs.html",
64
+ "fixtures/tabs.html.min",
65
+ "fixtures/whitespace-complex.html",
66
+ "fixtures/whitespace-complex.html.min",
67
+ "fixtures/whitespace-p.html",
68
+ "fixtures/whitespace-p.html.min",
69
+ "html5small.gemspec",
70
+ "lib/html5small.rb",
71
+ "lib/html5small/Minifier.rb",
72
+ "lib/html5small/OptionalTags.rb",
73
+ "spec/htmlsmall_spec.rb",
74
+ "spec/spec.opts",
75
+ "spec/spec_helper.rb"
76
+ ]
77
+ s.homepage = "http://github.com/RubenVerborgh/HTML5small"
78
+ s.require_paths = ["lib"]
79
+ s.rubygems_version = "1.8.23"
80
+ s.summary = "HTML5small"
81
+
82
+ if s.respond_to? :specification_version then
83
+ s.specification_version = 3
84
+
85
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
86
+ s.add_runtime_dependency(%q<htmlentities>, [">= 4.1.0"])
87
+ s.add_runtime_dependency(%q<nokogiri>, [">= 1.5.0"])
88
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
89
+ s.add_development_dependency(%q<yard>, [">= 0"])
90
+ else
91
+ s.add_dependency(%q<htmlentities>, [">= 4.1.0"])
92
+ s.add_dependency(%q<nokogiri>, [">= 1.5.0"])
93
+ s.add_dependency(%q<rspec>, [">= 2.0.0"])
94
+ s.add_dependency(%q<yard>, [">= 0"])
95
+ end
96
+ else
97
+ s.add_dependency(%q<htmlentities>, [">= 4.1.0"])
98
+ s.add_dependency(%q<nokogiri>, [">= 1.5.0"])
99
+ s.add_dependency(%q<rspec>, [">= 2.0.0"])
100
+ s.add_dependency(%q<yard>, [">= 0"])
101
+ end
102
+ end
103
+
@@ -16,31 +16,6 @@ module HTML5
16
16
  strong style sub sup svg table textarea time ul var video wbr
17
17
  }.map(&:to_sym)
18
18
 
19
- BOOL_ATTR = {
20
- _: [:itemscope, :hidden],
21
- audio: [:loop, :autoplay, :controls],
22
- button: [:formnovalidate, :disabled, :autofocus],
23
- command: [:disabled, :checked],
24
- details: [:open],
25
- fieldset: [:disabled],
26
- form: [:novalidate],
27
- iframe: [:seamless],
28
- img: [:ismap],
29
- input: [:autocomplete, :autofocus, :defaultchecked,
30
- :checked, :disabled, :formnovalidate, :indeterminate,
31
- :multiple, :readonly, :required],
32
- keygen: [:disabled, :autofocus],
33
- optgroup: [:disabled],
34
- option: [:disabled, :defaultselected, :selected],
35
- ol: [:reversed],
36
- select: [:autofocus, :disabled, :multiple],
37
- script: [:async, :defer],
38
- style: [:scoped],
39
- textarea: [:autofocus, :disabled, :readonly, :required],
40
- time: [:pubdate],
41
- video: [:loop, :autoplay, :controls],
42
- }
43
-
44
19
  attr_accessor :buf, :text_node, :entities
45
20
 
46
21
  def initialize
@@ -101,11 +76,8 @@ module HTML5
101
76
  end.sort_by do |name, value|
102
77
  name
103
78
  end.map do |name, value|
104
- if boolean_attribute?(element, name)
105
- name.to_s
106
- else
107
- "#{name}=#{value}"
108
- end
79
+ # Empty values can use the empty attribute syntax
80
+ value.empty? ? name.to_s : "#{name}=#{value}"
109
81
  end.join(' ').insert(0, ' ')
110
82
  end
111
83
 
@@ -114,13 +86,7 @@ module HTML5
114
86
  # ?
115
87
  def value_needs_quoting? value
116
88
  # must not contain any " ", """, "'", ">", or "=", characters
117
- value =~ /[[:space:]"'><=`]/ or value.empty?
118
- end
119
-
120
- def boolean_attribute? element, attribute
121
- e, a = [element, attribute].map(&:to_sym)
122
- BOOL_ATTR[:_].include?(a) or
123
- (BOOL_ATTR.key?(e) and BOOL_ATTR[e].include?(a))
89
+ value =~ /[[:space:]"'><=`]/
124
90
  end
125
91
 
126
92
  def format_entities html, except={}
@@ -130,13 +96,19 @@ module HTML5
130
96
  end
131
97
 
132
98
  def format_text_node
99
+ # Don't escape script contents
100
+ return text_node if in_script_element?
101
+ # Escape entities inside the text node
133
102
  text = format_entities text_node, {quot: ?", apos: ?'}
103
+ # Don't remove white space in elements with non-HTML content
134
104
  return text if in_pre_element?
135
- text.gsub!(/[\n\t]/,' ')
105
+ # Treat all whitespace as spaces
106
+ text.gsub!(/[\n\t]/, ' ')
136
107
  # Don't strip inter-element white space for flow elements
137
108
  unless buf =~ %r{</\w+>\s*\Z} and in_flow_element?
138
109
  text.lstrip!
139
110
  end
111
+ # Normalize spaces
140
112
  text.squeeze(' ')
141
113
  end
142
114
 
@@ -148,6 +120,10 @@ module HTML5
148
120
  not (PRE_TAGS & @stack).empty?
149
121
  end
150
122
 
123
+ def in_script_element?
124
+ @stack.include? :script
125
+ end
126
+
151
127
  def dump_text_node
152
128
  buf << format_text_node
153
129
  text_node.clear
@@ -20,7 +20,8 @@ module HTML5
20
20
  # if the first thing inside the body element is not a space character or
21
21
  # a comment, except if the first thing inside the body element is a
22
22
  # script or style element.
23
- %r{<body>\s?(?!<(script|style))},
23
+ # Unfortunately, this can confuse older IE browsers.
24
+ # %r{<body>\s?(?!<(script|style))},
24
25
  # A body element's end tag may be omitted if the body element is not
25
26
  # immediately followed by a comment.
26
27
  %r{</body>},
data/lib/html5small.rb CHANGED
@@ -1,5 +1,5 @@
1
- require_relative 'html5small/minifier'
2
- require_relative 'html5small/optional'
1
+ require_relative 'html5small/Minifier'
2
+ require_relative 'html5small/OptionalTags'
3
3
 
4
4
  module HTML5
5
5
  def self.minify html
@@ -25,6 +25,8 @@ end
25
25
  quot_entity: "expands &quot; entity in text nodes",
26
26
  newlines: "should treat newlines in text as a space",
27
27
  tabs: "should treat tabs in text as a space",
28
+ empty_attributes: "should use the empty attribute syntax when appropriate",
29
+ scripts: "should not escape entities inside scripts",
28
30
  }
29
31
 
30
32
  describe HTML5, '.minify' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html5small
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -97,6 +97,8 @@ files:
97
97
  - fixtures/attribute-value-quot.html.min
98
98
  - fixtures/dl.html
99
99
  - fixtures/dl.html.min
100
+ - fixtures/empty-attributes.html
101
+ - fixtures/empty-attributes.html.min
100
102
  - fixtures/entities-expand.html
101
103
  - fixtures/entities-expand.html.min
102
104
  - fixtures/entities-no-expand.html
@@ -117,6 +119,8 @@ files:
117
119
  - fixtures/pre.html.min
118
120
  - fixtures/quot-entity.html
119
121
  - fixtures/quot-entity.html.min
122
+ - fixtures/scripts.html
123
+ - fixtures/scripts.html.min
120
124
  - fixtures/skeleton.html
121
125
  - fixtures/skeleton.html.min
122
126
  - fixtures/sort-attributes.html
@@ -129,10 +133,11 @@ files:
129
133
  - fixtures/whitespace-complex.html.min
130
134
  - fixtures/whitespace-p.html
131
135
  - fixtures/whitespace-p.html.min
136
+ - html5small.gemspec
132
137
  - lib/html5small.rb
133
138
  - lib/html5small/Minifier.rb
134
- - lib/html5small/optional.rb
135
- - spec/h5-min_spec.rb
139
+ - lib/html5small/OptionalTags.rb
140
+ - spec/htmlsmall_spec.rb
136
141
  - spec/spec.opts
137
142
  - spec/spec_helper.rb
138
143
  homepage: http://github.com/RubenVerborgh/HTML5small