hom 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: