hom 1.0.0 → 1.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.
Files changed (5) hide show
  1. data/README.md +38 -16
  2. data/hom.gemspec +1 -1
  3. data/lib/hom.rb +34 -0
  4. data/spec/node_list_spec.rb +48 -0
  5. metadata +5 -3
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
- A straightforward API for generating HTML
2
- =========================================
1
+ hom
2
+ ===
3
+
4
+
5
+ A straightforward API for generating HTML.
3
6
 
4
7
 
5
8
  Motivation
@@ -26,12 +29,12 @@ puts HOM::Element.new(:h1, nil, 'hello world')
26
29
  ```
27
30
 
28
31
 
29
- Usage
30
- -----
32
+ Using HOM::Element
33
+ ------------------
31
34
 
32
- Build up an object tree using `HOM::Element` objects. The first constuctor
33
- argument is a symbol representing the tag name. For example, here's how you'd
34
- represent a line break element:
35
+ Create instances of HOM::Element to represent DOM elements. The first
36
+ constructor argument is a symbol representing the tag name. For example,
37
+ you can represent a line break element like this:
35
38
 
36
39
  ```ruby
37
40
  HOM::Element.new(:br)
@@ -50,8 +53,8 @@ HOM::Element.new(:input, [{type: :text, size: 30}, :disabled])
50
53
  ```
51
54
 
52
55
  The third constructor argument is the inner content, which can be a string,
53
- another element object, or an array of child items. For example, here's how
54
- you can represent elements with attributes:
56
+ another element object, or an array of child nodes. For example, here's how
57
+ you can represent various elements with inner content:
55
58
 
56
59
  ```ruby
57
60
  span = HOM::Element.new(:span, nil, '')
@@ -65,16 +68,35 @@ link = HOM::Element.new(:a, {target: :_blank, href: '/'}, image)
65
68
  list = HOM::Element.new(:ul, nil, (1..3).map { |n| HOM::Element.new(:li, nil, n) })
66
69
  ```
67
70
 
68
- There's also a `HOM::Entity` class which you can use to represent HTML entities;
69
- integer values for numeric entities and symbol/string values for named entities,
71
+ Calling #to_s on a HOM::Element object will return a string containing the
72
+ generated HTML markup. HOM::Element objects are safe to use directly in Rails
73
+ templates, all escaping is handled automatically.
74
+
75
+
76
+ Using HOM::Entity
77
+ -----------------
78
+
79
+ Create instances of HOM::Entity to represent HTML entities. Use an integer
80
+ argument for numeric entities and a symbol/string argument for named entities,
70
81
  for example:
71
82
 
72
83
  ```ruby
73
- HOM::Element.new(:span, nil, HOM::Entity.new(160))
84
+ HOM::Entity.new(160)
74
85
 
75
- HOM::Element.new(:span, nil, HOM::Entity.new(:nbsp))
86
+ HOM::Entity.new(:nbsp)
87
+ ```
88
+
89
+
90
+ Using HOM::NodeList
91
+ -------------------
92
+
93
+ Use HOM::NodeList to group nodes together without having to wrap them in an
94
+ outer element. For example:
95
+
96
+ ```ruby
97
+ HOM::NodeList.new(['This is a ', HOM::Element.new(:strong, nil, 'Contrived'), ' example'])
76
98
  ```
77
99
 
78
- Calling `#to_s` on a `HOM::Element` object will return a string containing
79
- the generated markup. `HOM::Element` objects are safe to use directly in
80
- Rails templates, all escaping is handled automatically.
100
+ Calling #to_s on a HOM::NodeList object will return a string containing the
101
+ generated HTML markup. Calling #join will insert separator nodes, a bit like
102
+ Array#join, but returning HTML safe output.
data/hom.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'hom'
3
- s.version = '1.0.0'
3
+ s.version = '1.1.0'
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = ['Tim Craft']
6
6
  s.email = ['mail@timcraft.com']
data/lib/hom.rb CHANGED
@@ -43,6 +43,38 @@ module HOM
43
43
  end
44
44
  end
45
45
 
46
+ class NodeList
47
+ def initialize(nodes)
48
+ @nodes = Array(nodes)
49
+ end
50
+
51
+ def to_s
52
+ Encoding.safe_encode(self)
53
+ end
54
+
55
+ def to_a
56
+ @nodes
57
+ end
58
+
59
+ def +(object)
60
+ self.class.new(@nodes + Array(object))
61
+ end
62
+
63
+ def join(separator)
64
+ Encoding.safe_encode(intersperse(separator, @nodes))
65
+ end
66
+
67
+ private
68
+
69
+ def intersperse(separator, array)
70
+ array.inject([]) do |tmp, item|
71
+ tmp << separator unless tmp.empty?
72
+ tmp << item
73
+ tmp
74
+ end
75
+ end
76
+ end
77
+
46
78
  class AttributeList
47
79
  def initialize
48
80
  @index = {}
@@ -80,6 +112,8 @@ module HOM
80
112
  def self.encode(object)
81
113
  if object.is_a?(Array)
82
114
  object.map { |item| encode(item) }.join
115
+ elsif object.is_a?(NodeList)
116
+ object.to_a.map { |item| encode(item) }.join
83
117
  elsif object.is_a?(Element)
84
118
  encode_element(object)
85
119
  elsif object.respond_to?(:html_safe?) && object.html_safe?
@@ -0,0 +1,48 @@
1
+ require 'minitest/autorun'
2
+ require 'active_support/core_ext/string/output_safety'
3
+ require 'hom'
4
+
5
+ describe 'HOM::NodeList' do
6
+ describe 'to_a method' do
7
+ it 'returns the array of nodes passed to the constructor' do
8
+ nodes = HOM::NodeList.new(%w(a b c))
9
+ nodes.to_a.must_equal(%w(a b c))
10
+ end
11
+ end
12
+
13
+ describe 'to_s method' do
14
+ it 'returns an html safe string containing the encoded nodes' do
15
+ nodes = HOM::NodeList.new(['Hello', HOM::Entity.new(:nbsp), HOM::Element.new(:b, nil, 'World')])
16
+
17
+ output = nodes.to_s
18
+ output.must_equal('Hello&nbsp;<b>World</b>')
19
+ output.html_safe?.must_equal(true)
20
+ end
21
+ end
22
+
23
+ describe 'addition of two node lists' do
24
+ it 'returns a new node list containing the items in each list' do
25
+ nodes = HOM::NodeList.new(['one']) + HOM::NodeList.new(['two'])
26
+ nodes.must_be_instance_of(HOM::NodeList)
27
+ nodes.to_a.must_equal(%w(one two))
28
+ end
29
+ end
30
+
31
+ describe 'addition of a node list with an element object' do
32
+ it 'returns a new node list containing the items in the list and the additional element' do
33
+ element = HOM::Element.new(:b, nil, 'World')
34
+
35
+ nodes = HOM::NodeList.new(['Hello', HOM::Entity.new(:nbsp)]) + element
36
+ nodes.must_be_instance_of(HOM::NodeList)
37
+ nodes.to_s.must_equal('Hello&nbsp;<b>World</b>')
38
+ end
39
+ end
40
+
41
+ describe 'join method' do
42
+ it 'returns an html safe string containing the encoded nodes seperated by the argument' do
43
+ output = HOM::NodeList.new(%w(a b c)).join(HOM::Entity.new(:nbsp))
44
+ output.html_safe?.must_equal(true)
45
+ output.must_equal('a&nbsp;b&nbsp;c')
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hom
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-16 00:00:00.000000000 Z
12
+ date: 2013-03-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -70,6 +70,7 @@ files:
70
70
  - spec/element_spec.rb
71
71
  - spec/encoding_spec.rb
72
72
  - spec/entity_spec.rb
73
+ - spec/node_list_spec.rb
73
74
  - Rakefile
74
75
  - README.md
75
76
  - hom.gemspec
@@ -93,8 +94,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
94
  version: '0'
94
95
  requirements: []
95
96
  rubyforge_project:
96
- rubygems_version: 1.8.24
97
+ rubygems_version: 1.8.25
97
98
  signing_key:
98
99
  specification_version: 3
99
100
  summary: See description
100
101
  test_files: []
102
+ has_rdoc: