helpers 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/CHANGELOG +3 -0
- data/LICENSE +20 -0
- data/README.textile +9 -0
- data/helpers.gemspec +36 -0
- data/helpers.pre.gemspec +8 -0
- data/lib/helpers.rb +148 -0
- data/lib/helpers/adapters/rails.rb +5 -0
- data/lib/helpers/adapters/rango.rb +5 -0
- data/spec/helpers_spec.rb +41 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +7 -0
- metadata +66 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jakub Stastny aka Botanicus
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
data/helpers.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# Run ./helpers.gemspec or gem build helpers.gemspec
|
5
|
+
require "base64"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "helpers"
|
9
|
+
s.version = "0.0.1"
|
10
|
+
s.authors = ["Jakub Stastny aka Botanicus"]
|
11
|
+
s.homepage = "http://github.com/botanicus/helpers"
|
12
|
+
s.summary = "Framework-agnostic template helpers"
|
13
|
+
s.description = "" # TODO: long description
|
14
|
+
s.cert_chain = nil
|
15
|
+
s.email = Base64.decode64("c3Rhc3RueUAxMDFpZGVhcy5jeg==\n")
|
16
|
+
s.has_rdoc = true
|
17
|
+
|
18
|
+
# files
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
# Ruby version
|
24
|
+
s.required_ruby_version = ::Gem::Requirement.new(">= 1.9")
|
25
|
+
|
26
|
+
begin
|
27
|
+
require "changelog"
|
28
|
+
rescue LoadError
|
29
|
+
warn "You have to have changelog gem installed for post install message"
|
30
|
+
else
|
31
|
+
s.post_install_message = CHANGELOG.new.version_changes
|
32
|
+
end
|
33
|
+
|
34
|
+
# RubyForge
|
35
|
+
s.rubyforge_project = "helpers"
|
36
|
+
end
|
data/helpers.pre.gemspec
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# You might think this is a terrible mess and guess what, you're
|
5
|
+
# right mate! However say thanks to authors of RubyGems, not me.
|
6
|
+
eval(File.read("helpers.gemspec")).tap do |specification|
|
7
|
+
specification.version = "#{specification.version}.pre"
|
8
|
+
end
|
data/lib/helpers.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Helpers
|
4
|
+
module HtmlAttrsMixin
|
5
|
+
def to_html_attrs
|
6
|
+
self.inject(String.new) do |result, pair|
|
7
|
+
key, value = pair
|
8
|
+
result + " #{key}='#{value}'"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class SelfCloseTag
|
14
|
+
attr_accessor :name, :attrs
|
15
|
+
def initialize(name, attrs = Hash.new, &block)
|
16
|
+
attrs.extend(HtmlAttrsMixin)
|
17
|
+
@name, @attrs = name, attrs
|
18
|
+
block.call(self) unless block.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](attr)
|
22
|
+
self.attrs[attr]
|
23
|
+
end
|
24
|
+
|
25
|
+
def []=(attr, value)
|
26
|
+
self.attrs[attr] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
# Tag.new(:form) { |form| form.data[:confirm] = "Send it now?" }
|
30
|
+
def data
|
31
|
+
@attrs["data-"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
"<#{name}#{attrs.to_html_attrs} />"
|
36
|
+
end
|
37
|
+
|
38
|
+
# NOTE: we can't use aliasing because it just copy the method so inheritance doesn't work as expected
|
39
|
+
def inspect
|
40
|
+
self.to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Tag < SelfCloseTag
|
45
|
+
# content can be string, tag or an array of tags
|
46
|
+
attr_writer :content
|
47
|
+
def content
|
48
|
+
@content ||= Array.new
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_writer :indentation
|
52
|
+
def indentation
|
53
|
+
@indentation ||= 0
|
54
|
+
end
|
55
|
+
|
56
|
+
def each(&block)
|
57
|
+
self.to_s.split("\n").each do |item|
|
58
|
+
block.call("#{item}\n") # otherwise content-length will lie
|
59
|
+
end
|
60
|
+
# specially for rack
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize(name, content = nil, attrs = Hash.new, &block)
|
64
|
+
attrs, content = content, nil if content.is_a?(Hash) && attrs.empty?
|
65
|
+
self.content = ContentList.new(content, self.indentation + 1)
|
66
|
+
super(name, attrs, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def tag(*args, &block)
|
70
|
+
self.content.push(Tag.new(*args, &block))
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
"#{" " * self.indentation}<#{name}#{attrs.to_html_attrs}>\n#{" " * self.indentation}#{content}\n#{" " * self.indentation}</#{name}>"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class ContentList < Array
|
79
|
+
attr_accessor :indentation
|
80
|
+
def initialize(items, indentation)
|
81
|
+
self.indentation = indentation
|
82
|
+
self.push(*items)
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_s
|
86
|
+
self.map do |item|
|
87
|
+
if item.respond_to?(:indentation)
|
88
|
+
item.indentation = self.indentation
|
89
|
+
item
|
90
|
+
else
|
91
|
+
"#{" " * self.indentation}#{item}"
|
92
|
+
end
|
93
|
+
end.join("\n")
|
94
|
+
end
|
95
|
+
|
96
|
+
def find_tag(&block)
|
97
|
+
self.find do |item|
|
98
|
+
block.call(item) if item.respond_to?(:name)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def select_tags(&block)
|
103
|
+
self.select do |item|
|
104
|
+
block.call(item) if item.respond_to?(:name)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def inspect
|
109
|
+
self.to_s
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Form.new("/posts/create") do |form|
|
114
|
+
# form.text_field "post[title]"
|
115
|
+
# form.text_area "post[body]"
|
116
|
+
# form.submit "Create"
|
117
|
+
# end
|
118
|
+
class Form < Tag
|
119
|
+
def initialize
|
120
|
+
super(:form, Array.new, action)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Form.new(@post, "/posts/create") do |form|
|
125
|
+
# form.text_field :title
|
126
|
+
# form.text_area :body
|
127
|
+
# form.submit "Create"
|
128
|
+
# end
|
129
|
+
class FormFor < Form
|
130
|
+
def initialize(object, action)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# ButtonToDelete.new(post_path(@post), confirm: "Are you sure?")
|
135
|
+
class ButtonTo < Tag
|
136
|
+
def initialize(title, action, attrs = Hash.new, &block)
|
137
|
+
button = Tag.new(:button, title, attrs.merge(type: "submit"))
|
138
|
+
super(:form, button, action: action, &block)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class ButtonToDelete < ButtonTo
|
143
|
+
def initialize(title, action = nil, attrs = Hash.new)
|
144
|
+
action, title = title, "Destroy" if title && action.nil?
|
145
|
+
super(title, action + "?_method=DELETE", attrs.merge(name: name, value: value))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
4
|
+
require_relative "../lib/helpers"
|
5
|
+
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
describe "Helpers::HtmlAttrsMixin#to_html_attrs" do
|
9
|
+
before(:each) do
|
10
|
+
@attrs = {href: "http://google.com", id: "link", "data-type" => :external}
|
11
|
+
@attrs.extend(HtmlAttrsMixin)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should convert a hash into a string" do
|
15
|
+
@attrs.to_html_attrs.should eql(" href='http://google.com' id='link' data-type='external'")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Helpers::SelfCloseTag" do
|
20
|
+
it "should " do
|
21
|
+
SelfCloseTag.new(:br).to_s.should eql("<br />")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should " do
|
25
|
+
SelfCloseTag.new(:br, id: "clear").to_s.should eql("<br id='clear' />")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Helpers::Tag" do
|
30
|
+
it "should " do
|
31
|
+
Tag.new(:a).to_s.should eql("<a></a>")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should " do
|
35
|
+
Tag.new(:a, id: "link").to_s.should eql("<a id='link'></a>")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should " do
|
39
|
+
Tag.new(:a, "title", id: "link").to_s.should match(%r[<a id='link'>\s*title\s*</a>])
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: helpers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jakub Stastny aka Botanicus
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
date: 2010-02-02 00:00:00 +00:00
|
12
|
+
default_executable:
|
13
|
+
dependencies: []
|
14
|
+
|
15
|
+
description: ""
|
16
|
+
email: stastny@101ideas.cz
|
17
|
+
executables: []
|
18
|
+
|
19
|
+
extensions: []
|
20
|
+
|
21
|
+
extra_rdoc_files: []
|
22
|
+
|
23
|
+
files:
|
24
|
+
- .gitignore
|
25
|
+
- CHANGELOG
|
26
|
+
- LICENSE
|
27
|
+
- README.textile
|
28
|
+
- helpers.gemspec
|
29
|
+
- helpers.pre.gemspec
|
30
|
+
- lib/helpers.rb
|
31
|
+
- lib/helpers/adapters/rails.rb
|
32
|
+
- lib/helpers/adapters/rango.rb
|
33
|
+
- spec/helpers_spec.rb
|
34
|
+
- spec/spec.opts
|
35
|
+
- spec/spec_helper.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/botanicus/helpers
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message: "[\e[32mVersion 0.0.1\e[0m] Tag, SelfCloseTag builder classes\n\
|
41
|
+
[\e[32mVersion 0.0.1\e[0m] Form, FormFor, ButtonTo, ButtonToDelete classes\n"
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "1.9"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project: helpers
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Framework-agnostic template helpers
|
65
|
+
test_files: []
|
66
|
+
|