Skip to content

Commit 6c4a250

Browse files
committed
replace hardcoded Strings with StringsInjector
* move hardcoded Strings in constants into StringsInjector builder have its own strings collection * adds ability to override strings collection per builder class
1 parent 5be0308 commit 6c4a250

11 files changed

+301
-265
lines changed

.rvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
rvm use 1.9.2@hammer-builder --create
1+
rvm use 1.9.3@hammer-builder --create

lib/hammer_builder/abstract.rb

+33-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require 'active_support/core_ext/string/inflections'
44

55
require 'hammer_builder/dynamic_classes'
6-
require 'hammer_builder/strings'
6+
require 'hammer_builder/strings_injector'
77
require 'hammer_builder/data'
88
require 'hammer_builder/data/html5'
99
require "hammer_builder/pool"
@@ -19,6 +19,26 @@ class Abstract
1919
require "hammer_builder/abstract/abstract_single_tag"
2020
require "hammer_builder/abstract/abstract_double_tag"
2121

22+
def self.strings_injector
23+
@strings_injector ||= StringsInjector.new do
24+
add :lt, '<'
25+
add :gt, '>'
26+
add :slash_lt, '</'
27+
add :slash_gt, ' />'
28+
add :underscore, '_'
29+
add :space, ' '
30+
add :spaces, Array.new(300) { |i| (' ' * i).freeze }
31+
add :newline, "\n"
32+
add :quote, '"'
33+
add :eql, '='
34+
add :eql_quote, self[:eql] + self[:quote]
35+
add :comment_start, '<!--'
36+
add :comment_end, '-->'
37+
add :cdata_start, '<![CDATA['
38+
add :cdata_end, ']]>'
39+
end
40+
end
41+
2242
# << faster then +
2343
# yield faster then block.call
2444
# accessing ivar and constant is faster then accesing hash or cvar
@@ -58,6 +78,9 @@ def initialize()
5878
@_output = ""
5979
@_stack = []
6080
@_current = nil
81+
82+
self.class.strings_injector.inject_to self
83+
6184
# tag classes initialization
6285
tags.each do |klass|
6386
instance_variable_set(:"@_#{klass}", self.class.dynamic_classes[klass.camelize.to_sym].new(self))
@@ -79,13 +102,13 @@ def raw(text)
79102
# inserts +comment+
80103
def comment(comment)
81104
flush
82-
@_output << Strings::COMMENT_START << comment.to_s << Strings::COMMENT_END
105+
@_output << @_str_comment_start << comment.to_s << @_str_comment_end
83106
end
84107

85108
# insersts CDATA with +content+
86109
def cdata(content)
87110
flush
88-
@_output << Strings::CDATA_START << content.to_s << Strings::CDATA_END
111+
@_output << @_str_cdata_start << content.to_s << @_str_cdata_end
89112
end
90113

91114
# renders html5 doc type
@@ -186,13 +209,13 @@ def js(js, options = { })
186209
def join(collection, glue = nil, &it)
187210
# TODO as helper? two block method call #join(collection, &item).with(&glue)
188211
glue_block = case glue
189-
when String
190-
lambda { text glue }
191-
when Proc
192-
glue
193-
else
194-
lambda { }
195-
end
212+
when String
213+
lambda { text glue }
214+
when Proc
215+
glue
216+
else
217+
lambda { }
218+
end
196219

197220
collection.each_with_index do |obj, i|
198221
glue_block.call() if i > 0

lib/hammer_builder/abstract/abstract_double_tag.rb

+64-71
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,50 @@ class Abstract
55
def_class :AbstractDoubleTag, :AbstractTag do ###import
66
nil
77

8-
# defined by class_eval because there is a error cased by super
9-
# super from singleton method that is defined to multiple classes is not supported;
10-
# this will be fixed in 1.9.3 or later (NotImplementedError)
11-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
12-
# @api private
13-
def initialize(builder)
14-
super
15-
@content = nil
16-
end
8+
# @api private
9+
def initialize(builder)
10+
super
11+
@content = nil
12+
end
1713

18-
# allows data-* attributes and id, classes by method_missing
19-
def method_missing(method, *args, &block)
20-
method = method.to_s
21-
if method =~ METHOD_MISSING_REGEXP
22-
if $1
23-
self.rclass.add_attributes Data::Attribute.new(method.to_sym, :string)
24-
self.send method, *args, &block
25-
else
26-
self.content(args[0]) if args[0]
27-
self.__send__($3 == '!' ? :id : :class, $2, &block)
28-
end
14+
# allows data-* attributes and id, classes by method_missing
15+
def method_missing(method, *args, &block)
16+
method = method.to_s
17+
if method =~ METHOD_MISSING_REGEXP
18+
if $1
19+
self.rclass.add_attributes Data::Attribute.new(method.to_sym, :string)
20+
self.send method, *args, &block
2921
else
30-
super(method, *args, &block)
22+
self.content(args[0]) if args[0]
23+
self.__send__($3 == '!' ? :id : :class, $2, &block)
3124
end
25+
else
26+
super(method, *args, &block)
3227
end
28+
end
3329

34-
# @api private
35-
def open(*args, &block)
36-
attributes = if args.last.is_a?(Hash)
37-
args.pop
38-
end
39-
content args[0]
40-
super attributes
41-
@stack << @tag_name
42-
if block
43-
with &block
44-
else
45-
self
46-
end
30+
# @api private
31+
def open(*args, &block)
32+
attributes = if args.last.is_a?(Hash)
33+
args.pop
34+
end
35+
content args[0]
36+
super attributes
37+
@stack << @tag_name
38+
if block
39+
with &block
40+
else
41+
self
4742
end
48-
RUBY
43+
end
4944

5045
# @api private
5146
# closes the tag
5247
def flush
5348
flush_classes
54-
@output << Strings::GT
49+
@output << @_str_gt
5550
@output << CGI.escapeHTML(@content) if @content
56-
@output << Strings::SLASH_LT << @stack.pop << Strings::GT
51+
@output << @_str_slash_lt << @stack.pop << @_str_gt
5752
@content = nil
5853
end
5954

@@ -76,45 +71,43 @@ def content(content)
7671
# end # => <div id="id">content</div>
7772
def with
7873
flush_classes
79-
@output << Strings::GT
74+
@output << @_str_gt
8075
@content = nil
8176
@builder.current = nil
8277
yield
8378
#if (content = yield).is_a?(String)
8479
# @output << EscapeUtils.escape_html(content)
8580
#end
8681
@builder.flush
87-
@output << Strings::SLASH_LT << @stack.pop << Strings::GT
82+
@output << @_str_slash_lt << @stack.pop << @_str_gt
8883
nil
8984
end
9085

9186
alias_method :w, :with
9287

93-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
94-
def mimic(obj, &block)
95-
super(obj, &nil)
96-
return with(&block) if block
97-
self
98-
end
88+
def mimic(obj, &block)
89+
super(obj, &nil)
90+
return with(&block) if block
91+
self
92+
end
9993

100-
def data(hash, &block)
101-
super(hash, &nil)
102-
return with(&block) if block
103-
self
104-
end
94+
def data(hash, &block)
95+
super(hash, &nil)
96+
return with(&block) if block
97+
self
98+
end
10599

106-
def attribute(name, value, &block)
107-
super(name, value, &nil)
108-
return with(&block) if block
109-
self
110-
end
100+
def attribute(name, value, &block)
101+
super(name, value, &nil)
102+
return with(&block) if block
103+
self
104+
end
111105

112-
def attributes(attrs, &block)
113-
super(attrs, &nil)
114-
return with(&block) if block
115-
self
116-
end
117-
RUBY
106+
def attributes(attrs, &block)
107+
super(attrs, &nil)
108+
return with(&block) if block
109+
self
110+
end
118111

119112
protected
120113

@@ -125,20 +118,20 @@ def self.define_attribute_method(attribute)
125118

126119
if instance_methods.include?(attribute.name)
127120
class_eval <<-RUBY, __FILE__, __LINE__ + 1
128-
def #{name}(*args, &block)
129-
super(*args, &nil)
130-
return with(&block) if block
131-
self
132-
end
121+
def #{name}(*args, &block)
122+
super(*args, &nil)
123+
return with(&block) if block
124+
self
125+
end
133126
RUBY
134127
else
135128
content_rendering = attribute_content_rendering(attribute)
136129
class_eval <<-RUBY, __FILE__, __LINE__ + 1
137-
def #{name}(content#{' = true' if attribute.type == :boolean}, &block)
138-
#{content_rendering}
139-
return with(&block) if block
140-
self
141-
end
130+
def #{name}(content#{' = true' if attribute.type == :boolean}, &block)
131+
#{content_rendering}
132+
return with(&block) if block
133+
self
134+
end
142135
RUBY
143136
end
144137
end

lib/hammer_builder/abstract/abstract_single_tag.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Abstract
88
# closes the tag
99
def flush
1010
flush_classes
11-
@output << Strings::SLASH_GT
11+
@output << @_str_slash_gt
1212
nil
1313
end
1414
end ###import

0 commit comments

Comments
 (0)