html-tag 1.3.3 → 3.0.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.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/lib/html-tag/globals.rb +49 -0
- data/lib/html-tag/html_tag.rb +40 -0
- data/lib/html-tag/inbound.rb +193 -0
- data/lib/html-tag/outbound.rb +127 -0
- data/lib/html-tag.rb +4 -5
- metadata +8 -20
- data/lib/html-tag/adapter.rb +0 -30
- data/lib/html-tag/base.rb +0 -119
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62429fba4dc4f58b599307927a448ac66ff140053a52f3641188cd9b1c261033
|
4
|
+
data.tar.gz: e692ee406a52cdd0d7c4750dd0553768ede5614ea17ca55f9c9c9066d0832c4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44aba32e3255ac8c7f843ac14919dde2994f42168d5c8594c96d46233964d0f09567f72c34c6301a4b8d6655694a6e36506fe153fbc2c01b9aee2ada2d62d677
|
7
|
+
data.tar.gz: f028fe5ee782953b8b6ad78774c2af0307774f069c050e1633c50e6d95886c31feb4d4272bac9cc7f514e12c44da1b913175c12f8824831c1c8575e025211c6b
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.1
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Hash
|
2
|
+
unless {}.respond_to?(:tag)
|
3
|
+
class Hash
|
4
|
+
def tag node_name, inner_html=nil
|
5
|
+
HtmlTag().send node_name, self, inner_html
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# String
|
11
|
+
unless ''.respond_to?(:tag)
|
12
|
+
class String
|
13
|
+
def tag node_name, opts = nil
|
14
|
+
HtmlTag().send node_name, self, opts
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# HtmlTag do ...
|
20
|
+
module HtmlTag
|
21
|
+
class Proxy
|
22
|
+
def initialize
|
23
|
+
@pointer = HtmlTag::Inbound.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing name, *args, &block
|
27
|
+
@pointer
|
28
|
+
.send(name, *args, &block)
|
29
|
+
.join('')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def HtmlTag *args, &block
|
35
|
+
args[0] ||= :div
|
36
|
+
|
37
|
+
if args[0].class == Hash
|
38
|
+
args[1] = args[0]
|
39
|
+
args[0] = :div
|
40
|
+
end
|
41
|
+
|
42
|
+
if block
|
43
|
+
out = HtmlTag::Inbound.new self
|
44
|
+
out.send(*args, &block)
|
45
|
+
out.render
|
46
|
+
else
|
47
|
+
HtmlTag::Proxy.new
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# inclue HtmlTag to import tag method
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module HtmlTag
|
6
|
+
extend self
|
7
|
+
|
8
|
+
###
|
9
|
+
|
10
|
+
OPTS = {
|
11
|
+
format: false
|
12
|
+
}
|
13
|
+
|
14
|
+
TAGS ||= Set.new %i(
|
15
|
+
a b button code colgroup dd div dl dt em fieldset form h1 h2 h3 h4 h5 h6
|
16
|
+
header i iframe label legend li main map nav noscript object ol optgroup option p pre q
|
17
|
+
script section select small span strong summary table tbody td textarea tfoot th thead title tr u ul video
|
18
|
+
)
|
19
|
+
|
20
|
+
EMPTY_TAGS ||= Set.new %w(area base br col embed hr img input keygen link meta param source track wbr)
|
21
|
+
|
22
|
+
def tag *args, &block
|
23
|
+
if block
|
24
|
+
HtmlTag *args, &block
|
25
|
+
else
|
26
|
+
# HtmlTag()
|
27
|
+
::HtmlTag::Outbound
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# forward to class only if
|
32
|
+
def method_missing tag_name, *args, &block
|
33
|
+
if self === HtmlTag
|
34
|
+
# Proxy.new.tag(tag_name, args[0], args[1], &block)
|
35
|
+
Outbound.tag(tag_name, args[0], args[1], &block)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# improved builder that is not pasing node pointers
|
2
|
+
|
3
|
+
# HtmlTag do
|
4
|
+
# form do
|
5
|
+
# input name: q
|
6
|
+
# end
|
7
|
+
# end
|
8
|
+
|
9
|
+
module HtmlTag
|
10
|
+
class Inbound
|
11
|
+
IVARS ||= Struct.new :HtmlTagInboundIvars, :context, :data, :depth, :inbound
|
12
|
+
|
13
|
+
# allows to add cusom tags if needed
|
14
|
+
# HtmlTag::Inbound.define :foo
|
15
|
+
def self.define tag, empty: false
|
16
|
+
if empty
|
17
|
+
EMPTY_TAGS.add tag
|
18
|
+
end
|
19
|
+
|
20
|
+
define_method tag do |*args, &block|
|
21
|
+
tag tag, *args, &block
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# create static methods for all common tags (method missing is slow)
|
26
|
+
(TAGS + EMPTY_TAGS).each {|tag| define tag }
|
27
|
+
|
28
|
+
###
|
29
|
+
|
30
|
+
def initialize context = nil
|
31
|
+
# copy all instance varialbes from context
|
32
|
+
for el in context.instance_variables
|
33
|
+
unless el.to_s.include?('@_')
|
34
|
+
val = context.instance_variable_get el
|
35
|
+
instance_variable_set el, val
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# lets keep all instance vars in one object
|
40
|
+
@_iv = IVARS.new
|
41
|
+
@_iv.context = context
|
42
|
+
@_iv.data = []
|
43
|
+
@_iv.depth = 0
|
44
|
+
@_iv.inbound = true
|
45
|
+
end
|
46
|
+
|
47
|
+
# access parent context via parent / context / this
|
48
|
+
# h1 class: this.class_name
|
49
|
+
def parent &block
|
50
|
+
if block
|
51
|
+
@_iv.context.instance_exec(&block)
|
52
|
+
else
|
53
|
+
@_iv.context
|
54
|
+
end
|
55
|
+
end
|
56
|
+
alias :context :parent
|
57
|
+
alias :this :parent
|
58
|
+
|
59
|
+
# export renderd data
|
60
|
+
def render
|
61
|
+
@_iv.data
|
62
|
+
.join('')
|
63
|
+
.gsub(/\n+/, $/)
|
64
|
+
.gsub(/([\w>])[[:blank:]]+</, '\1<')
|
65
|
+
end
|
66
|
+
|
67
|
+
# render single node
|
68
|
+
def tag name, *args, &block
|
69
|
+
name, opt_hash, opt_data = _prepare_tag_params name, args
|
70
|
+
|
71
|
+
tag_data = "%s%s<%s" % [_depth_new_line, _depth_spaces, name]
|
72
|
+
|
73
|
+
# if tag params given, add them
|
74
|
+
if opt_hash
|
75
|
+
tag_data += ' '
|
76
|
+
tag_data += opt_hash.inject([]) do |t, el|
|
77
|
+
key, value = el
|
78
|
+
|
79
|
+
if value.class == Hash
|
80
|
+
for el in value
|
81
|
+
t.push "%s-%s='%s'" % [key, el[0], _escape_param(el[1])]
|
82
|
+
end
|
83
|
+
else
|
84
|
+
if value.class == Array
|
85
|
+
value = value.join(' ')
|
86
|
+
end
|
87
|
+
|
88
|
+
key = key.to_s.sub(/^data_/, 'data-')
|
89
|
+
|
90
|
+
t.push "%s='%s'" % [key, _escape_param(value)]
|
91
|
+
end
|
92
|
+
t
|
93
|
+
end.join(' ')
|
94
|
+
end
|
95
|
+
|
96
|
+
unless EMPTY_TAGS.include?(name)
|
97
|
+
tag_data += '>'
|
98
|
+
end
|
99
|
+
|
100
|
+
@_iv.data << tag_data
|
101
|
+
|
102
|
+
# nested blocks
|
103
|
+
if block
|
104
|
+
@_iv.depth += 1
|
105
|
+
|
106
|
+
if @_iv.context
|
107
|
+
# HtmlTag scope
|
108
|
+
instance_exec(&block)
|
109
|
+
else
|
110
|
+
# outbound scope
|
111
|
+
block.call(self)
|
112
|
+
end
|
113
|
+
|
114
|
+
@_iv.depth -= 1
|
115
|
+
end
|
116
|
+
|
117
|
+
if EMPTY_TAGS.include?(name)
|
118
|
+
@_iv.data << ' />'
|
119
|
+
else
|
120
|
+
unless opt_data
|
121
|
+
@_iv.data << _depth_spaces
|
122
|
+
end
|
123
|
+
|
124
|
+
@_iv.data << '%s</%s>%s' % [opt_data, name, _depth_new_line]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def push data
|
129
|
+
@_iv.data << data
|
130
|
+
end
|
131
|
+
|
132
|
+
def method_missing name, *args, &block
|
133
|
+
klass = name.to_s
|
134
|
+
|
135
|
+
if klass.start_with?('_')
|
136
|
+
tag klass, *args, &block
|
137
|
+
else
|
138
|
+
message = [
|
139
|
+
%{HTML tag "#{name}" not found.},
|
140
|
+
"Use this.#{name}() to call method in parent context",
|
141
|
+
"or use tag(:#{name}, params, data) to add custom html node."
|
142
|
+
]
|
143
|
+
raise NoMethodError.new(message.join(' '))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def _prepare_tag_params name, args
|
150
|
+
opt_hash, opt_data = args
|
151
|
+
|
152
|
+
# allow any arragement of vars
|
153
|
+
# div class: :foo, 123
|
154
|
+
# div 123, class: :foo
|
155
|
+
if opt_hash && opt_hash.class != Hash
|
156
|
+
opt_hash, opt_data = opt_data, opt_hash
|
157
|
+
end
|
158
|
+
|
159
|
+
# _foo__bar-baz class: 'dux' -> <div class="foo bar-baz dux"></div>
|
160
|
+
klass = name.to_s
|
161
|
+
if klass.start_with?('_')
|
162
|
+
classes = klass
|
163
|
+
.sub('_', '')
|
164
|
+
.split('__')
|
165
|
+
.map{|it| it.gsub('_', '-') }
|
166
|
+
.join(' ')
|
167
|
+
|
168
|
+
klass = :div
|
169
|
+
|
170
|
+
opt_hash ||= {}
|
171
|
+
opt_hash[:class] = "#{classes} #{opt_hash[:class]}".sub(/\s+$/, '')
|
172
|
+
end
|
173
|
+
|
174
|
+
[klass, opt_hash, opt_data]
|
175
|
+
end
|
176
|
+
|
177
|
+
def _depth_spaces
|
178
|
+
if OPTS[:format]
|
179
|
+
' ' * 2 * @_iv.depth
|
180
|
+
else
|
181
|
+
''
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def _depth_new_line
|
186
|
+
OPTS[:format] ? $/ : ''
|
187
|
+
end
|
188
|
+
|
189
|
+
def _escape_param el
|
190
|
+
el.to_s.gsub(/'/, ''')
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module HtmlTag
|
2
|
+
class Outbound
|
3
|
+
class << self
|
4
|
+
# tag.div -> tag.tag :div
|
5
|
+
def method_missing name, *args, &block
|
6
|
+
tag name, args[0], args[1], &block
|
7
|
+
end
|
8
|
+
|
9
|
+
# tag :div, { 'class'=>'iform' } do
|
10
|
+
def tag name, *args
|
11
|
+
data, opts =
|
12
|
+
if args[1]
|
13
|
+
args[0].class == Hash ? args.reverse : args
|
14
|
+
elsif args[0]
|
15
|
+
if args[0].class == Symbol
|
16
|
+
# tag.div(:a) { 1 } -> <div class="a">1</div>
|
17
|
+
[nil, { class: args[0].to_s.gsub('__', ' ').gsub('_', '-') }]
|
18
|
+
elsif args[0].class == Hash
|
19
|
+
[nil, args[0]]
|
20
|
+
else
|
21
|
+
[args[0], {}]
|
22
|
+
end
|
23
|
+
else
|
24
|
+
[nil, {}]
|
25
|
+
end
|
26
|
+
|
27
|
+
opts ||= {}
|
28
|
+
|
29
|
+
unless opts.class == Hash
|
30
|
+
raise ArgumentError.new('HtmlTag: bad agrument, attributes are no a hash')
|
31
|
+
end
|
32
|
+
|
33
|
+
if data.class == Hash
|
34
|
+
raise ArgumentError.new('HtmlTag: bad agrument, data sent as hash')
|
35
|
+
end
|
36
|
+
|
37
|
+
# covert n._row_foo to n(class: 'row-foo')
|
38
|
+
name = name.to_s
|
39
|
+
if name.to_s[0, 1] == '_'
|
40
|
+
classes = name
|
41
|
+
.sub('_', '')
|
42
|
+
.split('__')
|
43
|
+
.map{|it| it.gsub('_', '-') }
|
44
|
+
.join(' ')
|
45
|
+
|
46
|
+
opts ||= {}
|
47
|
+
opts[:class] = "#{classes} #{opts[:class]}".sub(/\s+$/, '')
|
48
|
+
name = :div
|
49
|
+
end
|
50
|
+
|
51
|
+
if block_given?
|
52
|
+
if data
|
53
|
+
raise ArgumentError.new('HtmlTag: data is allreay defined and block is given')
|
54
|
+
end
|
55
|
+
|
56
|
+
stack = new
|
57
|
+
data = yield(stack, opts)
|
58
|
+
|
59
|
+
# if data is pushed to passed node, use that data
|
60
|
+
data = stack.data if stack.data.first
|
61
|
+
end
|
62
|
+
|
63
|
+
data = data.join('') if data.is_a?(Array)
|
64
|
+
|
65
|
+
build name, opts, data
|
66
|
+
end
|
67
|
+
|
68
|
+
# build html node
|
69
|
+
def build node, attrs={}, text=nil
|
70
|
+
node = node.to_s
|
71
|
+
|
72
|
+
opts = []
|
73
|
+
attrs.each do |attr_key, attr_value|
|
74
|
+
if attr_value.is_a?(Hash)
|
75
|
+
for data_key, data_value in attr_value
|
76
|
+
__add_opts opts, "#{attr_key}-#{data_key}", data_value
|
77
|
+
end
|
78
|
+
else
|
79
|
+
__add_opts opts, attr_key, attr_value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
opts = opts.first ? ' '+opts.join(' ') : ''
|
84
|
+
|
85
|
+
if node
|
86
|
+
text ||= '' unless EMPTY_TAGS.include?(node)
|
87
|
+
text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
|
88
|
+
else
|
89
|
+
opts
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# tag.div(class: 'klasa') do -> tag.('klasa') do
|
94
|
+
def call class_name, &block
|
95
|
+
tag(:div, class_name, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
def __add_opts opts, key, value
|
99
|
+
unless value.to_s == ''
|
100
|
+
value = value.join(' ') if value.is_a?(Array)
|
101
|
+
key = key.to_s.gsub(/data_/,'data-')
|
102
|
+
opts.push key+'="'+value.to_s.gsub(/"/,'"')+'"'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
###
|
108
|
+
|
109
|
+
attr_reader :data
|
110
|
+
|
111
|
+
def initialize
|
112
|
+
@data = []
|
113
|
+
end
|
114
|
+
|
115
|
+
# push data to stack
|
116
|
+
def push data=nil
|
117
|
+
@data.push block_given? ? yield : data
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# forward to class
|
123
|
+
def method_missing tag_name, *args, &block
|
124
|
+
@data.push self.class.tag(tag_name, args[0], args[1], &block)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/html-tag.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative './html-tag/html_tag'
|
2
|
+
require_relative './html-tag/outbound'
|
3
|
+
require_relative './html-tag/inbound'
|
4
|
+
require_relative './html-tag/globals'
|
4
5
|
|
5
|
-
require_relative './html-tag/base'
|
6
|
-
require_relative './html-tag/adapter'
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html-tag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dino Reic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: fast_blank
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1'
|
11
|
+
date: 2022-07-29 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
27
13
|
description: Fast and powerful tag builder, upgrade to Rails tag helper, framework
|
28
14
|
agnostic.
|
29
15
|
email: reic.dino@gmail.com
|
@@ -33,8 +19,10 @@ extra_rdoc_files: []
|
|
33
19
|
files:
|
34
20
|
- "./.version"
|
35
21
|
- "./lib/html-tag.rb"
|
36
|
-
- "./lib/html-tag/
|
37
|
-
- "./lib/html-tag/
|
22
|
+
- "./lib/html-tag/globals.rb"
|
23
|
+
- "./lib/html-tag/html_tag.rb"
|
24
|
+
- "./lib/html-tag/inbound.rb"
|
25
|
+
- "./lib/html-tag/outbound.rb"
|
38
26
|
homepage: https://github.com/dux/html-tag
|
39
27
|
licenses:
|
40
28
|
- MIT
|
@@ -54,7 +42,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
42
|
- !ruby/object:Gem::Version
|
55
43
|
version: '0'
|
56
44
|
requirements: []
|
57
|
-
rubygems_version: 3.
|
45
|
+
rubygems_version: 3.2.3
|
58
46
|
signing_key:
|
59
47
|
specification_version: 4
|
60
48
|
summary: HTML tag builder
|
data/lib/html-tag/adapter.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# Hash
|
2
|
-
unless {}.respond_to?(:tag)
|
3
|
-
class Hash
|
4
|
-
def tag node_name, inner_html=nil
|
5
|
-
HtmlTagBuilder.build self, node_name, inner_html
|
6
|
-
end
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
# String
|
11
|
-
unless ''.respond_to?(:tag)
|
12
|
-
class String
|
13
|
-
def tag node_name, opts={}
|
14
|
-
HtmlTagBuilder.build opts, node_name, self
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# All other objects
|
20
|
-
class Object
|
21
|
-
def tag
|
22
|
-
HtmlTagBuilder
|
23
|
-
end
|
24
|
-
|
25
|
-
# Rails has tag methd defeined in views, in ActionView::Helpers::TagHelper
|
26
|
-
# Access HtmlTagBuilder via xtag then
|
27
|
-
def xtag
|
28
|
-
HtmlTagBuilder
|
29
|
-
end
|
30
|
-
end
|
data/lib/html-tag/base.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
class HtmlTagBuilder
|
2
|
-
class << self
|
3
|
-
# tag.div -> tag.tag :div
|
4
|
-
def method_missing tag_name, *args, &block
|
5
|
-
tag tag_name, args[0], args[1], &block
|
6
|
-
end
|
7
|
-
|
8
|
-
# tag :div, { 'class'=>'iform' } do
|
9
|
-
def tag name=nil, opts={}, data=nil
|
10
|
-
if Array === opts
|
11
|
-
# join data given as an array
|
12
|
-
data = opts
|
13
|
-
opts = {}
|
14
|
-
elsif Hash === data
|
15
|
-
# tag.button('btn', href: '/') { 'Foo' }
|
16
|
-
opts = data.merge class: opts
|
17
|
-
data = nil
|
18
|
-
end
|
19
|
-
|
20
|
-
# tag.div(:a) { 1 } -> <div class="a">1</div>
|
21
|
-
opts = opts.to_s if opts.class == Symbol
|
22
|
-
|
23
|
-
# covert n._row_foo to n(class: 'row-foo')
|
24
|
-
name = name.to_s
|
25
|
-
if name.to_s[0, 1] == '_'
|
26
|
-
opts ||= {}
|
27
|
-
opts[:class] = name.to_s.sub('_', '').gsub('_', '-')
|
28
|
-
name = :div
|
29
|
-
end
|
30
|
-
|
31
|
-
# covert tag.a '.foo.bar' to class names
|
32
|
-
# covert tag.a '#id' to id names
|
33
|
-
if (data || block_given?) && opts.is_a?(String)
|
34
|
-
given = opts.dup
|
35
|
-
opts = {}
|
36
|
-
|
37
|
-
given.sub(/#([\w\-]+)/) { opts[:id] = $1 }
|
38
|
-
klass = given.sub(/^\./, '').gsub('.', ' ')
|
39
|
-
opts[:class] = klass unless klass.blank?
|
40
|
-
end
|
41
|
-
|
42
|
-
# fix data and opts unless opts is Hash
|
43
|
-
data, opts = opts, {} unless opts.class == Hash
|
44
|
-
|
45
|
-
if block_given?
|
46
|
-
stack = new
|
47
|
-
data = yield(stack, opts)
|
48
|
-
|
49
|
-
# if data is pushed to passed node, use that data
|
50
|
-
data = stack.data if stack.data.first
|
51
|
-
end
|
52
|
-
|
53
|
-
data = data.join('') if data.is_a?(Array)
|
54
|
-
|
55
|
-
build opts, name, data
|
56
|
-
end
|
57
|
-
|
58
|
-
# build html node
|
59
|
-
def build attrs, node=nil, text=nil
|
60
|
-
opts = []
|
61
|
-
attrs.each do |attr_key, attr_value|
|
62
|
-
if attr_value.is_a?(Hash)
|
63
|
-
for data_key, data_value in attr_value
|
64
|
-
__add_opts opts, "#{attr_key}-#{data_key}", data_value
|
65
|
-
end
|
66
|
-
else
|
67
|
-
__add_opts opts, attr_key, attr_value
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
opts = opts.first ? ' '+opts.join(' ') : ''
|
72
|
-
|
73
|
-
return opts unless node
|
74
|
-
|
75
|
-
empty_tags = ['input', 'img', 'meta', 'link', 'hr', 'br', 'col', 'frame', 'area']
|
76
|
-
text ||= '' unless empty_tags.include?(node.to_s)
|
77
|
-
out = text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
|
78
|
-
out.respond_to?(:html_safe) ? out.html_safe : out
|
79
|
-
end
|
80
|
-
|
81
|
-
# tag.div(class: 'klasa') do -> tag.('klasa') do
|
82
|
-
def call class_name, &block
|
83
|
-
tag(:div, class_name, &block)
|
84
|
-
end
|
85
|
-
|
86
|
-
def __add_opts opts, key, value
|
87
|
-
unless value.to_s.blank?
|
88
|
-
value = value.join(' ') if value.is_a?(Array)
|
89
|
-
key = key.to_s.gsub(/data_/,'data-')
|
90
|
-
opts.push key+'="'+value.to_s.gsub(/"/,'"')+'"'
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
###
|
96
|
-
|
97
|
-
attr_reader :data
|
98
|
-
|
99
|
-
def initialize
|
100
|
-
@data = []
|
101
|
-
end
|
102
|
-
|
103
|
-
# push data to stack
|
104
|
-
def push data=nil
|
105
|
-
@data.push block_given? ? yield : data
|
106
|
-
end
|
107
|
-
|
108
|
-
# n.('foo') do -> n.div(class: 'foo') do
|
109
|
-
def call class_name, &block
|
110
|
-
@data.push self.class.tag(:div, { class: class_name }, &block)
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
|
115
|
-
# forward to class
|
116
|
-
def method_missing tag_name, *args, &block
|
117
|
-
@data.push self.class.tag(tag_name, args[0], args[1], &block)
|
118
|
-
end
|
119
|
-
end
|