hom 1.3.0 → 1.3.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 80265a394bf1cecc27755bfcc583dbc81cb3ea51ffcb110fae6a61ecc3d0f0cd
4
+ data.tar.gz: 9ab3f813474864c3db170c4add2780309a2470f8bc4acca7c6daa2355bd27087
5
+ SHA512:
6
+ metadata.gz: 1d7d556b5749cd886a0731f39734e32cd34dde6ee8ffc0c07294034d0554c0f9bc2f6c35c51bf1f206b50bd9f03a6c01fae28bab158590f1792782f1bee341d6
7
+ data.tar.gz: 6e27e6d36d7648c968c8bec6c45a99c263e056945eacab2b4de3538220a40f5ad881e5cf30974e5561c0645044eb3ea9968cda6c2ea0e4ab148e1f1d207206c7
@@ -0,0 +1,57 @@
1
+ # 1.3.1
2
+
3
+ * Added metadata to gemspec
4
+
5
+ # 1.3.0
6
+
7
+ * HOM::NodeList#join now returns a new node list
8
+
9
+ * Added plus method to HOM::Element
10
+
11
+ * Added plus method to HOM::Entity
12
+
13
+ # 1.2.0
14
+
15
+ * Added html_safe? methods to HOM::Element and HOM::NodeList for compatibility with [erubis-auto](https://github.com/timcraft/erubis-auto)
16
+
17
+ # 1.1.0
18
+
19
+ * Added HOM::NodeList class
20
+
21
+ # 1.0.0
22
+
23
+ * Ruby 1.8.7 compatibility
24
+
25
+ * Removed support for rendering arbitrary objects by calling #html
26
+
27
+ # 0.4.0
28
+
29
+ * Deprecated support for rendering arbitrary objects by calling #html
30
+
31
+ * Added notion of undefined content, changing how elements with nil content are rendered:
32
+
33
+ With an element like this: `HOM::Element.new(:h1, {}, nil)`
34
+
35
+ Pre v0.4.0 rendering: `<h1>`
36
+
37
+ Post v0.4.0 rendering: `<h1></h1>`
38
+
39
+ # 0.3.0
40
+
41
+ * Added notion of undefined attribute values, nil is now rendered as an empty value:
42
+
43
+ With an element like this: `HOM::Element.new(:input, {:value => nil})`
44
+
45
+ Pre v0.3.0 rendering: `<input value>`
46
+
47
+ Post v0.3.0 rendering: `<input value="">`
48
+
49
+ * Removed Element#lookup method
50
+
51
+ # 0.2.0
52
+
53
+ * Replaced method missing attribute access with Element#lookup method
54
+
55
+ # 0.1.0
56
+
57
+ * First version!
@@ -0,0 +1,4 @@
1
+ Copyright (c) 2011-2020 TIMCRAFT
2
+
3
+ This is an Open Source project licensed under the terms of the LGPLv3 license.
4
+ Please see <http://www.gnu.org/licenses/lgpl-3.0.html> for license text.
data/README.md CHANGED
@@ -1,26 +1,24 @@
1
- hom
2
- ===
1
+ # hom
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/hom.svg)](https://badge.fury.io/rb/hom) [![Build Status](https://api.travis-ci.org/timcraft/hom.svg?branch=master)](https://travis-ci.org/timcraft/hom)
3
4
 
4
5
 
5
6
  A straightforward API for generating HTML.
6
7
 
7
8
 
8
- Motivation
9
- ----------
9
+ ## Motivation
10
10
 
11
11
  HOM helps you implement HTML presentation logic in your code. Things like
12
12
  navigation links, select boxes, sets of checkboxes; anything with behaviour
13
13
  that is too complex for your templates.
14
14
 
15
15
 
16
- Installation
17
- ------------
16
+ ## Installation
18
17
 
19
18
  $ gem install hom
20
19
 
21
20
 
22
- Quick start
23
- -----------
21
+ ## Quick start
24
22
 
25
23
  ```ruby
26
24
  require 'hom'
@@ -29,8 +27,7 @@ puts HOM::Element.new(:h1, nil, 'hello world')
29
27
  ```
30
28
 
31
29
 
32
- Using HOM::Element
33
- ------------------
30
+ ## Using HOM::Element
34
31
 
35
32
  Create instances of HOM::Element to represent DOM elements. The first
36
33
  constructor argument is a symbol representing the tag name. For example,
@@ -73,8 +70,7 @@ generated HTML markup. HOM::Element objects are safe to use directly in Rails
73
70
  templates, all escaping is handled automatically.
74
71
 
75
72
 
76
- Using HOM::Entity
77
- -----------------
73
+ ## Using HOM::Entity
78
74
 
79
75
  Create instances of HOM::Entity to represent HTML entities. Use an integer
80
76
  argument for numeric entities and a symbol/string argument for named entities,
@@ -87,8 +83,7 @@ HOM::Entity.new(:nbsp)
87
83
  ```
88
84
 
89
85
 
90
- Using HOM::NodeList
91
- -------------------
86
+ ## Using HOM::NodeList
92
87
 
93
88
  Use HOM::NodeList to group nodes together without having to wrap them in an
94
89
  outer element. For example:
@@ -100,3 +95,37 @@ HOM::NodeList.new(['This is a ', HOM::Element.new(:strong, nil, 'Contrived'), '
100
95
  Calling #to_s on a HOM::NodeList object will return a string containing the
101
96
  generated HTML markup. Calling #join will insert separator nodes, a bit like
102
97
  Array#join, but returning HTML safe output.
98
+
99
+
100
+ ## XSS 101
101
+
102
+ Do you have helper methods that look like this:
103
+
104
+ ```ruby
105
+ def user_name(user)
106
+ "<strong>#{user.name}</strong>".html_safe
107
+ end
108
+ ```
109
+
110
+ Bzzzt, that's a security vulnerability right there. If you're using Rails
111
+ you should have code that looks like this:
112
+
113
+ ```ruby
114
+ def user_name(user)
115
+ content_tag(:strong, user.name)
116
+ end
117
+ ```
118
+
119
+ The content_tag helper will automatically escape content not explicitly
120
+ marked as safe. HOM will do very much the same thing, the equivalent helper
121
+ method would look like this:
122
+
123
+ ```ruby
124
+ def user_name(user)
125
+ HOM::Element.new(:strong, nil, user.name)
126
+ end
127
+ ```
128
+
129
+ Moral of the story: building up fragments of HTML using string interpolation
130
+ and concatenation is highly error prone. Solution: use content_tag or HOM to
131
+ safely build your content, and audit your usage of html_safe.
@@ -1,18 +1,20 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'hom'
3
- s.version = '1.3.0'
3
+ s.version = '1.3.1'
4
+ s.license = 'LGPL-3.0'
4
5
  s.platform = Gem::Platform::RUBY
5
6
  s.authors = ['Tim Craft']
6
7
  s.email = ['mail@timcraft.com']
7
- s.homepage = 'http://github.com/timcraft/hom'
8
+ s.homepage = 'https://github.com/timcraft/hom'
8
9
  s.description = 'A straightforward API for generating HTML'
9
10
  s.summary = 'See description'
10
- s.files = Dir.glob('{lib,spec}/**/*') + %w(Rakefile README.md hom.gemspec)
11
- s.add_development_dependency('rake', '~> 10.0.3')
12
- s.add_development_dependency('activesupport', ['>= 3.0.3'])
11
+ s.files = Dir.glob('lib/**/*.rb') + %w(LICENSE.txt README.md CHANGES.md hom.gemspec)
12
+ s.required_ruby_version = '>= 1.9.3'
13
13
  s.require_path = 'lib'
14
-
15
- if RUBY_VERSION == '1.8.7'
16
- s.add_development_dependency('minitest', '>= 4.2.0')
17
- end
14
+ s.metadata = {
15
+ 'homepage' => 'https://github.com/timcraft/hom',
16
+ 'source_code_uri' => 'https://github.com/timcraft/hom',
17
+ 'bug_tracker_uri' => 'https://github.com/timcraft/hom/issues',
18
+ 'changelog_uri' => 'https://github.com/timcraft/hom/blob/main/CHANGES.md'
19
+ }
18
20
  end
metadata CHANGED
@@ -1,48 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hom
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
5
- prerelease:
4
+ version: 1.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tim Craft
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-10 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rake
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: 10.0.3
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: 10.0.3
30
- - !ruby/object:Gem::Dependency
31
- name: activesupport
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: 3.0.3
38
- type: :development
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: 3.0.3
11
+ date: 2020-11-03 00:00:00.000000000 Z
12
+ dependencies: []
46
13
  description: A straightforward API for generating HTML
47
14
  email:
48
15
  - mail@timcraft.com
@@ -50,37 +17,36 @@ executables: []
50
17
  extensions: []
51
18
  extra_rdoc_files: []
52
19
  files:
53
- - lib/hom.rb
54
- - spec/element_spec.rb
55
- - spec/encoding_spec.rb
56
- - spec/entity_spec.rb
57
- - spec/node_list_spec.rb
58
- - Rakefile
20
+ - CHANGES.md
21
+ - LICENSE.txt
59
22
  - README.md
60
23
  - hom.gemspec
61
- homepage: http://github.com/timcraft/hom
62
- licenses: []
63
- post_install_message:
24
+ - lib/hom.rb
25
+ homepage: https://github.com/timcraft/hom
26
+ licenses:
27
+ - LGPL-3.0
28
+ metadata:
29
+ homepage: https://github.com/timcraft/hom
30
+ source_code_uri: https://github.com/timcraft/hom
31
+ bug_tracker_uri: https://github.com/timcraft/hom/issues
32
+ changelog_uri: https://github.com/timcraft/hom/blob/main/CHANGES.md
33
+ post_install_message:
64
34
  rdoc_options: []
65
35
  require_paths:
66
36
  - lib
67
37
  required_ruby_version: !ruby/object:Gem::Requirement
68
- none: false
69
38
  requirements:
70
- - - ! '>='
39
+ - - ">="
71
40
  - !ruby/object:Gem::Version
72
- version: '0'
41
+ version: 1.9.3
73
42
  required_rubygems_version: !ruby/object:Gem::Requirement
74
- none: false
75
43
  requirements:
76
- - - ! '>='
44
+ - - ">="
77
45
  - !ruby/object:Gem::Version
78
46
  version: '0'
79
47
  requirements: []
80
- rubyforge_project:
81
- rubygems_version: 1.8.25
82
- signing_key:
83
- specification_version: 3
48
+ rubygems_version: 3.1.4
49
+ signing_key:
50
+ specification_version: 4
84
51
  summary: See description
85
52
  test_files: []
86
- has_rdoc:
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require 'rake/testtask'
2
-
3
- task :default => :spec
4
-
5
- Rake::TestTask.new(:spec) do |t|
6
- t.test_files = FileList['spec/*_spec.rb']
7
- t.warning = true
8
- end
@@ -1,42 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'active_support/core_ext/string/output_safety'
3
-
4
- if defined? require_relative
5
- require_relative '../lib/hom'
6
- else
7
- require File.join(File.dirname(__FILE__), '../lib/hom')
8
- end
9
-
10
- describe 'HOM::Element' do
11
- describe 'content query method' do
12
- it 'returns false if the content is undefined' do
13
- HOM::Element.new(:br).content?.must_equal(false)
14
- end
15
-
16
- it 'returns true otherwise' do
17
- HOM::Element.new(:h1, nil, '').content?.must_equal(true)
18
- end
19
- end
20
-
21
- describe 'html_safe query method' do
22
- it 'returns true' do
23
- HOM::Element.new(:br).html_safe?.must_equal(true)
24
- end
25
- end
26
-
27
- describe 'to_s method' do
28
- it 'returns an html safe string containing the encoded element' do
29
- output = HOM::Element.new(:br).to_s
30
- output.html_safe?.must_equal(true)
31
- output.must_equal('<br>')
32
- end
33
- end
34
-
35
- describe 'addition of an element with another object' do
36
- it 'returns a node list containing the two nodes' do
37
- nodes = HOM::Element.new(:br) + "\n"
38
- nodes.must_be_instance_of(HOM::NodeList)
39
- nodes.to_s.must_equal("<br>\n")
40
- end
41
- end
42
- end
@@ -1,102 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'active_support/core_ext/string/output_safety'
3
-
4
- if defined? require_relative
5
- require_relative '../lib/hom'
6
- else
7
- require File.join(File.dirname(__FILE__), '../lib/hom')
8
- end
9
-
10
- describe 'HOM::Encoding' do
11
- describe 'encode method' do
12
- it 'renders elements with a tag name' do
13
- element = HOM::Element.new(:br)
14
-
15
- HOM::Encoding.encode(element).must_equal('<br>')
16
- end
17
-
18
- it 'renders elements with a symbol attribute' do
19
- element = HOM::Element.new(:input, :disabled)
20
-
21
- HOM::Encoding.encode(element).must_equal('<input disabled>')
22
- end
23
-
24
- it 'renders elements with a hash of attributes' do
25
- element = HOM::Element.new(:input, {:type => :text, :size => 30, :value => nil})
26
-
27
- output = HOM::Encoding.encode(element)
28
- output.must_match(/<input .+>/)
29
- output.must_include(' type="text"')
30
- output.must_include(' size="30"')
31
- output.must_include(' value=""')
32
- end
33
-
34
- it 'renders elements with an array of mixed attributes' do
35
- element = HOM::Element.new(:input, [{:type => :text, :size => 30}, :disabled])
36
-
37
- output = HOM::Encoding.encode(element)
38
- output.must_match(/<input .+>/)
39
- output.must_include(' type="text"')
40
- output.must_include(' size="30"')
41
- output.must_include(' disabled')
42
- end
43
-
44
- it 'renders elements with empty content' do
45
- element = HOM::Element.new(:h1, nil, '')
46
-
47
- HOM::Encoding.encode(element).must_equal('<h1></h1>')
48
- end
49
-
50
- it 'renders elements with string content' do
51
- element = HOM::Element.new(:h2, nil, 'hello world')
52
-
53
- HOM::Encoding.encode(element).must_equal('<h2>hello world</h2>')
54
- end
55
-
56
- it 'renders elements with numeric content' do
57
- element = HOM::Element.new(:h4, nil, 1234567890)
58
-
59
- HOM::Encoding.encode(element).must_equal('<h4>1234567890</h4>')
60
- end
61
-
62
- it 'renders elements with a single child element' do
63
- element = HOM::Element.new(:h5, nil, HOM::Element.new(:b, nil, 'how bold'))
64
-
65
- HOM::Encoding.encode(element).must_equal('<h5><b>how bold</b></h5>')
66
- end
67
-
68
- it 'renders elements with nil content' do
69
- element = HOM::Element.new(:h6, nil, nil)
70
-
71
- HOM::Encoding.encode(element).must_equal('<h6></h6>')
72
- end
73
-
74
- it 'renders elements with multiple child elements' do
75
- element = HOM::Element.new(:ul, nil, (1..3).map { |n| HOM::Element.new(:li, nil, n) })
76
-
77
- HOM::Encoding.encode(element).must_equal('<ul><li>1</li><li>2</li><li>3</li></ul>')
78
- end
79
-
80
- it 'escapes string content' do
81
- element = HOM::Element.new(:h3, nil, 'a && b, x > y')
82
-
83
- HOM::Encoding.encode(element).must_equal('<h3>a &amp;&amp; b, x &gt; y</h3>')
84
- end
85
-
86
- it 'does not escape content that has been marked as html safe' do
87
- element = HOM::Element.new(:span, nil, '<br>'.html_safe)
88
-
89
- HOM::Encoding.encode(element).must_equal('<span><br></span>')
90
- end
91
- end
92
-
93
- describe 'safe_encode method' do
94
- it 'encodes the argument and marks it as html safe' do
95
- element = HOM::Element.new(:br)
96
-
97
- output = HOM::Encoding.safe_encode(element)
98
- output.must_equal('<br>')
99
- output.html_safe?.must_equal(true)
100
- end
101
- end
102
- end
@@ -1,67 +0,0 @@
1
- require 'minitest/autorun'
2
-
3
- if defined? require_relative
4
- require_relative '../lib/hom'
5
- else
6
- require File.join(File.dirname(__FILE__), '../lib/hom')
7
- end
8
-
9
- describe 'HOM::Entity' do
10
- before do
11
- @named_entity = HOM::Entity.new(:nbsp)
12
-
13
- @numeric_entity = HOM::Entity.new(160)
14
- end
15
-
16
- describe 'value method' do
17
- it 'returns the value passed to the constructor' do
18
- @named_entity.value.must_equal(:nbsp)
19
-
20
- @numeric_entity.value.must_equal(160)
21
- end
22
- end
23
-
24
- describe 'numeric query method' do
25
- it 'returns false for named entities' do
26
- @named_entity.numeric?.must_equal(false)
27
- end
28
-
29
- it 'returns true for numeric entities' do
30
- @numeric_entity.numeric?.must_equal(true)
31
- end
32
- end
33
-
34
- describe 'named query method' do
35
- it 'returns true for named entities' do
36
- @named_entity.named?.must_equal(true)
37
- end
38
-
39
- it 'returns false for numeric entities' do
40
- @numeric_entity.named?.must_equal(false)
41
- end
42
- end
43
-
44
- describe 'to_s method' do
45
- it 'returns the encoded html entity' do
46
- @named_entity.to_s.must_equal('&nbsp;')
47
-
48
- @numeric_entity.to_s.must_equal('&#160;')
49
- end
50
- end
51
-
52
- describe 'html_safe query method' do
53
- it 'returns true' do
54
- @named_entity.html_safe?.must_equal(true)
55
-
56
- @numeric_entity.html_safe?.must_equal(true)
57
- end
58
- end
59
-
60
- describe 'addition of an entity with another object' do
61
- it 'returns a node list containing the two nodes' do
62
- nodes = HOM::Entity.new(:pound) + '9.99'
63
- nodes.must_be_instance_of(HOM::NodeList)
64
- nodes.to_s.must_equal('&pound;9.99')
65
- end
66
- end
67
- end
@@ -1,59 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'active_support/core_ext/string/output_safety'
3
-
4
- if defined? require_relative
5
- require_relative '../lib/hom'
6
- else
7
- require File.join(File.dirname(__FILE__), '../lib/hom')
8
- end
9
-
10
- describe 'HOM::NodeList' do
11
- describe 'html_safe query method' do
12
- it 'returns true' do
13
- HOM::NodeList.new([]).html_safe?.must_equal(true)
14
- end
15
- end
16
-
17
- describe 'to_s method' do
18
- it 'returns an html safe string containing the encoded nodes' do
19
- nodes = HOM::NodeList.new(['Hello', HOM::Entity.new(:nbsp), HOM::Element.new(:b, nil, 'World')])
20
-
21
- output = nodes.to_s
22
- output.must_equal('Hello&nbsp;<b>World</b>')
23
- output.html_safe?.must_equal(true)
24
- end
25
- end
26
-
27
- describe 'to_a method' do
28
- it 'returns the array of nodes passed to the constructor' do
29
- nodes = HOM::NodeList.new(%w(a b c))
30
- nodes.to_a.must_equal(%w(a b c))
31
- end
32
- end
33
-
34
- describe 'addition of two node lists' do
35
- it 'returns a new node list containing the items in each list' do
36
- nodes = HOM::NodeList.new(['one']) + HOM::NodeList.new(['two'])
37
- nodes.must_be_instance_of(HOM::NodeList)
38
- nodes.to_a.must_equal(%w(one two))
39
- end
40
- end
41
-
42
- describe 'addition of a node list with an element object' do
43
- it 'returns a new node list containing the items in the list and the additional element' do
44
- element = HOM::Element.new(:b, nil, 'World')
45
-
46
- nodes = HOM::NodeList.new(['Hello', HOM::Entity.new(:nbsp)]) + element
47
- nodes.must_be_instance_of(HOM::NodeList)
48
- nodes.to_s.must_equal('Hello&nbsp;<b>World</b>')
49
- end
50
- end
51
-
52
- describe 'join method' do
53
- it 'returns a new node list containing the items in the list seperated by the given node' do
54
- nodes = HOM::NodeList.new(%w(a b c)).join(HOM::Entity.new(:nbsp))
55
- nodes.must_be_instance_of(HOM::NodeList)
56
- nodes.to_s.must_equal('a&nbsp;b&nbsp;c')
57
- end
58
- end
59
- end