element_factory 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in element_factory.gemspec
4
+ gemspec
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/element_factory/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Robert Ross
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Element Factory
2
+
3
+ Element Factory is a more object oriented approach to generating markup in Ruby. No DSL to learn, just objects.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'element_factory'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install element_factory
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'element_factory/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "element_factory"
8
+ gem.version = ElementFactory::VERSION
9
+ gem.authors = ["Robert Ross"]
10
+ gem.email = ["robert@creativequeries.com"]
11
+ gem.description = %q{Element Factory is a more object oriented approach to generating markup.}
12
+ gem.summary = %q{Element Factory isn't a fancy DSL, it's Ruby, it's friendly, it's neat.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency('rspec', '~> 2.11')
21
+ gem.add_development_dependency('simplecov')
22
+ gem.add_development_dependency('awesome_print')
23
+ gem.add_development_dependency('nokogiri')
24
+ gem.add_development_dependency('pry')
25
+ gem.add_development_dependency('guard-rspec')
26
+ gem.add_development_dependency('rake')
27
+ gem.add_development_dependency('rb-fsevent', '~> 0.9.1')
28
+
29
+ gem.add_dependency('activesupport', '~> 3.2.11')
30
+ end
@@ -0,0 +1,14 @@
1
+ require "element_factory/version"
2
+ require "active_support/core_ext/string"
3
+ require "active_support/core_ext/hash"
4
+
5
+ require "erb"
6
+
7
+ module ElementFactory
8
+ autoload :Element, "element_factory/element"
9
+ autoload :HtmlAttributes, "element_factory/html_attributes"
10
+
11
+ module Elements
12
+ autoload :TextElement, "element_factory/elements/text_element"
13
+ end
14
+ end
@@ -0,0 +1,62 @@
1
+ module ElementFactory
2
+ class Element
3
+ attr_accessor :name, :attributes
4
+
5
+ def initialize(name, attributes_or_string=nil)
6
+ @name = name.to_s
7
+ @attributes = coerce_attributes(attributes_or_string)
8
+
9
+ if attributes[:text].is_a?(String)
10
+ add_child Elements::TextElement.new(attributes[:text])
11
+ end
12
+ end
13
+
14
+ def to_html
15
+ tag_start + tag_middle + tag_end
16
+ end
17
+ alias to_s to_html
18
+
19
+ def html_attributes
20
+ HtmlAttributes.new(self.attributes.dup)
21
+ end
22
+
23
+ def add_child(child)
24
+ children << child
25
+ end
26
+ alias << add_child
27
+
28
+ def add_children(children)
29
+ children.each {|child| add_child(child) }
30
+ end
31
+
32
+ def children
33
+ @children ||= []
34
+ end
35
+
36
+ def tag_start
37
+ tag_attributes = attributes.any?? " #{html_attributes}" : ""
38
+ %|<%s%s>| % [name, tag_attributes]
39
+ end
40
+
41
+ def tag_end
42
+ %|</%s>| % name
43
+ end
44
+
45
+ def tag_middle
46
+ children.map(&:to_html).join
47
+ end
48
+
49
+ private
50
+
51
+ def coerce_attributes(attributes)
52
+ case attributes
53
+ when String
54
+ {text: attributes}
55
+ when Hash
56
+ attributes
57
+ else
58
+ {}
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,15 @@
1
+ module ElementFactory
2
+ module Elements
3
+ class TextElement
4
+ attr_accessor :string
5
+
6
+ def initialize(string)
7
+ @string = string
8
+ end
9
+
10
+ def to_html
11
+ ERB::Util.h(string)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ module ElementFactory
2
+ class HtmlAttributes
3
+ BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
4
+ autoplay controls loop selected hidden scoped async
5
+ defer reversed ismap seemless muted required
6
+ autofocus novalidate formnovalidate open pubdate)
7
+
8
+ attr_accessor :attributes
9
+
10
+ def initialize(attributes={})
11
+ @attributes = attributes
12
+ end
13
+
14
+ def data_attributes
15
+ (attributes[:data] || {}).each_with_object({}) do |(key,value), new_attributes|
16
+ new_attributes["data-#{key.to_s.dasherize}"] = value
17
+ end
18
+ end
19
+
20
+ def boolean_attributes
21
+ attributes.each_with_object({}) do |(key, value), new_attributes|
22
+ next unless BOOLEAN_ATTRIBUTES.include?(key.to_s)
23
+ new_attributes[key] = key.to_s
24
+ end
25
+ end
26
+
27
+ def to_s
28
+ attributes = self.attributes
29
+ .merge(data_attributes)
30
+ .merge(boolean_attributes)
31
+ .stringify_keys
32
+
33
+ attributes.delete("data")
34
+
35
+ attributes.keys.sort.map do |attribute|
36
+ value = ERB::Util.html_escape(attributes[attribute])
37
+ %(#{attribute}="#{value}")
38
+ end.join(" ").html_safe
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module ElementFactory
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,108 @@
1
+ require "spec_helper"
2
+
3
+ describe ElementFactory::Element do
4
+ subject { described_class.new(:table) }
5
+
6
+ context "initializes" do
7
+ subject { described_class }
8
+
9
+ specify "with a tag" do
10
+ tag = subject.new(:table)
11
+ expect(tag.name).to eq("table")
12
+ end
13
+
14
+ specify "with attributes" do
15
+ tag = subject.new(:table, {class: "something"})
16
+ expect(tag.attributes).to have_key :class
17
+ expect(tag.attributes[:class]).to eq("something")
18
+ end
19
+
20
+ specify "with a string" do
21
+ tag = subject.new(:span, "Some text")
22
+ expect(tag.attributes[:text]).to eq("Some text")
23
+ end
24
+
25
+ specify "with a string adds a child" do
26
+ tag = subject.new(:span, "Some text")
27
+ expect(tag).to have(1).children
28
+ end
29
+ end
30
+
31
+ context "tag pieces" do
32
+ subject { described_class.new(:table) }
33
+
34
+ context ".tag_start" do
35
+ it "returns correct markup" do
36
+ expect(subject.tag_start).to eq("<table>")
37
+ end
38
+
39
+ it "returns with attributes" do
40
+ subject.attributes[:class] = "something"
41
+ expect(subject.tag_start).to eq("<table class=\"something\">")
42
+ end
43
+ end
44
+ end
45
+
46
+ context ".html_attributes" do
47
+ let(:attributes) { Hash.new }
48
+ subject { described_class.new(:table) }
49
+ before do
50
+ ElementFactory::HtmlAttributes.
51
+ should_receive(:new).
52
+ and_return(attributes)
53
+ end
54
+
55
+ specify "are delegated" do
56
+ expect(subject.html_attributes).to be attributes
57
+ end
58
+ end
59
+
60
+ context ".to_html" do
61
+ subject { described_class.new(:table, class: "a-class") }
62
+
63
+ it "returns the tag" do
64
+ expect(subject.to_html).to match /<table(.*)>(.*)<\/table>/
65
+ end
66
+
67
+ it "returns the tag with attributes" do
68
+ element = to_element(subject.to_html, "table")
69
+ expect(element[:class]).to eq("a-class")
70
+ end
71
+
72
+ context "with children" do
73
+ let(:child) { described_class.new(:tr) }
74
+ before { subject << child }
75
+
76
+ it "recusively renders all children of the node" do
77
+ element = to_element(subject.to_html, "table")
78
+ expect(element.at_css("tr")).to be_present
79
+ end
80
+ end
81
+
82
+ context "with string children" do
83
+ subject { described_class.new(:span, "Text") }
84
+
85
+ it "includes a string node" do
86
+ element = to_element(subject.to_html, "span")
87
+ expect(element.text).to eq("Text")
88
+ end
89
+ end
90
+ end
91
+
92
+ context "children" do
93
+ let(:child) { described_class.new(:tr) }
94
+ let(:children) { [described_class.new(:td),described_class.new(:td)] }
95
+
96
+ context ".add_child" do
97
+ it "adds a child element to the list" do
98
+ expect { subject.add_child(child) }.to change(subject.children, :size).by(1)
99
+ end
100
+ end
101
+
102
+ context ".add_children" do
103
+ it "adds multiple chilren" do
104
+ expect { subject.add_children(children) }.to change(subject.children, :size).by(2)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe ElementFactory::Elements::TextElement do
4
+ subject { described_class.new("Some text") }
5
+
6
+ context ".to_html" do
7
+ it "returns the text" do
8
+ expect(subject.to_html).to eq("Some text")
9
+ end
10
+
11
+ it "escapes naughty things" do
12
+ subject.string = "Some & Thing"
13
+ expect(subject.to_html).to eq("Some &amp; Thing")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ require "spec_helper"
2
+
3
+ describe ElementFactory::HtmlAttributes do
4
+ let(:attributes) { Hash.new }
5
+ subject { described_class.new(attributes) }
6
+
7
+ it "assigns attributes" do
8
+ expect(subject.attributes).to eq(attributes)
9
+ end
10
+
11
+ context ".data_attributes" do
12
+ it "returns keys with data prefix" do
13
+ attributes[:data] = {key1: "value1"}
14
+ expect(subject.data_attributes).to have_key "data-key1"
15
+ end
16
+
17
+ it "dasherizes the keys" do
18
+ attributes[:data] = {key_1: "value"}
19
+ expect(subject.data_attributes).to have_key "data-key-1"
20
+ end
21
+ end
22
+
23
+ context ".boolean_attributes" do
24
+ it "returns itself if true" do
25
+ attributes[:disabled] = true
26
+ expect(subject.boolean_attributes[:disabled]).to eq("disabled")
27
+ end
28
+ end
29
+
30
+ context ".to_s" do
31
+ it "returns attributes in markup form" do
32
+ attributes[:class] = "a-class"
33
+ attributes[:data] = {key: "val"}
34
+ attributes[:disabled] = true
35
+
36
+ expect(subject.to_s).to eq(%(class="a-class" data-key="val" disabled="disabled"))
37
+ end
38
+
39
+ it "escapes attribute values" do
40
+ attributes[:class] = "<lawl> \""
41
+ expect(subject.to_s).to eq(%(class="&lt;lawl&gt; &quot;"))
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require "element_factory"
2
+ Dir['./spec/support/**/*.rb'].each {|f| require f }
3
+
4
+ require "awesome_print"
5
+ require "nokogiri"
6
+ require "pry"
7
+ require "active_support/core_ext/class"
8
+
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+ config.include ElementHelpers
20
+ end
@@ -0,0 +1,5 @@
1
+ module ElementHelpers
2
+ def to_element(string, type)
3
+ Nokogiri::HTML(string).at_xpath(".//#{type}")
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,213 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: element_factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Robert Ross
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.11'
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: '2.11'
30
+ - !ruby/object:Gem::Dependency
31
+ name: simplecov
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
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: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: awesome_print
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: nokogiri
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: pry
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-fsevent
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 0.9.1
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 0.9.1
142
+ - !ruby/object:Gem::Dependency
143
+ name: activesupport
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 3.2.11
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 3.2.11
158
+ description: Element Factory is a more object oriented approach to generating markup.
159
+ email:
160
+ - robert@creativequeries.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .gitignore
166
+ - .rspec
167
+ - Gemfile
168
+ - Guardfile
169
+ - LICENSE.txt
170
+ - README.md
171
+ - Rakefile
172
+ - element_factory.gemspec
173
+ - lib/element_factory.rb
174
+ - lib/element_factory/element.rb
175
+ - lib/element_factory/elements/text_element.rb
176
+ - lib/element_factory/html_attributes.rb
177
+ - lib/element_factory/version.rb
178
+ - spec/lib/element_spec.rb
179
+ - spec/lib/elements/text_element_spec.rb
180
+ - spec/lib/html_attributes_spec.rb
181
+ - spec/spec_helper.rb
182
+ - spec/support/element_helpers.rb
183
+ homepage: ''
184
+ licenses: []
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ none: false
191
+ requirements:
192
+ - - ! '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ none: false
197
+ requirements:
198
+ - - ! '>='
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ requirements: []
202
+ rubyforge_project:
203
+ rubygems_version: 1.8.23
204
+ signing_key:
205
+ specification_version: 3
206
+ summary: Element Factory isn't a fancy DSL, it's Ruby, it's friendly, it's neat.
207
+ test_files:
208
+ - spec/lib/element_spec.rb
209
+ - spec/lib/elements/text_element_spec.rb
210
+ - spec/lib/html_attributes_spec.rb
211
+ - spec/spec_helper.rb
212
+ - spec/support/element_helpers.rb
213
+ has_rdoc: