wunderbar 0.14.4 → 0.14.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/wunderbar/html-methods.rb +306 -299
- data/lib/wunderbar/rails.rb +1 -1
- data/lib/wunderbar/server.rb +5 -2
- data/lib/wunderbar/version.rb +1 -1
- data/wunderbar.gemspec +3 -3
- metadata +13 -13
@@ -1,373 +1,380 @@
|
|
1
1
|
# Wrapper class that understands HTML
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def xhtml(*args, &block)
|
22
|
-
@xhtml = true
|
23
|
-
html(*args, &block)
|
24
|
-
end
|
25
|
-
|
26
|
-
def html(*args, &block)
|
27
|
-
# default namespace
|
28
|
-
args << {} if args.empty?
|
29
|
-
args.first[:xmlns] ||= 'http://www.w3.org/1999/xhtml' if Hash === args.first
|
30
|
-
@_width = args.first.delete(:_width) if Hash === args.first
|
31
|
-
|
32
|
-
@x.text! "\xEF\xBB\xBF"
|
33
|
-
@x.declare! :DOCTYPE, :html
|
34
|
-
@x.tag! :html, *args do
|
35
|
-
set_variables_from_params
|
36
|
-
instance_eval(&block)
|
2
|
+
module Wunderbar
|
3
|
+
class HtmlMarkup < BuilderBase
|
4
|
+
VOID = %w(
|
5
|
+
area base br col command embed hr img input keygen
|
6
|
+
link meta param source track wbr
|
7
|
+
)
|
8
|
+
|
9
|
+
HTML5_BLOCK = %w(
|
10
|
+
# https://developer.mozilla.org/en/HTML/Block-level_elements
|
11
|
+
address article aside audio blockquote br canvas dd div dl fieldset
|
12
|
+
figcaption figcaption figure footer form h1 h2 h3 h4 h5 h6 header hgroup
|
13
|
+
hr noscript ol output p pre section table tfoot ul video
|
14
|
+
)
|
15
|
+
|
16
|
+
def initialize(scope)
|
17
|
+
@_scope = scope
|
18
|
+
@x = XmlMarkup.new :scope => scope, :indent => 2, :target => []
|
19
|
+
@xthml = false
|
37
20
|
end
|
38
21
|
|
39
|
-
|
40
|
-
|
22
|
+
def xhtml(*args, &block)
|
23
|
+
@xhtml = true
|
24
|
+
html(*args, &block)
|
41
25
|
end
|
42
26
|
|
43
|
-
|
44
|
-
|
27
|
+
def html(*args, &block)
|
28
|
+
# default namespace
|
29
|
+
args << {} if args.empty?
|
30
|
+
if Hash === args.first
|
31
|
+
args.first[:xmlns] ||= 'http://www.w3.org/1999/xhtml'
|
32
|
+
end
|
33
|
+
@_width = args.first.delete(:_width) if Hash === args.first
|
45
34
|
|
46
|
-
|
47
|
-
|
48
|
-
|
35
|
+
@x.text! "\xEF\xBB\xBF"
|
36
|
+
@x.declare! :DOCTYPE, :html
|
37
|
+
@x.tag! :html, *args do
|
38
|
+
set_variables_from_params
|
39
|
+
instance_eval(&block)
|
40
|
+
end
|
49
41
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
42
|
+
if @_width
|
43
|
+
self.class.reflow(@x.target!, @_width)
|
44
|
+
end
|
54
45
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
46
|
+
@x.target!.join
|
47
|
+
end
|
58
48
|
|
59
|
-
|
60
|
-
|
61
|
-
name, flag = $1, $2
|
62
|
-
elsif @_scope and @_scope.respond_to? name
|
63
|
-
return @_scope.__send__ name, *args, &block
|
64
|
-
else
|
65
|
-
error = NameError.new "undefined local variable or method `#{name}'", name
|
66
|
-
error.set_backtrace caller
|
67
|
-
raise error
|
49
|
+
def _html(*args, &block)
|
50
|
+
html(*args, &block)
|
68
51
|
end
|
69
52
|
|
70
|
-
|
71
|
-
@
|
72
|
-
|
53
|
+
def _xhtml(*args, &block)
|
54
|
+
@xhtml = true
|
55
|
+
html(*args, &block)
|
73
56
|
end
|
74
57
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
58
|
+
def xhtml?
|
59
|
+
@xhtml
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(name, *args, &block)
|
63
|
+
if name.to_s =~ /^_(\w+)(!|\?|)$/
|
64
|
+
name, flag = $1, $2
|
65
|
+
elsif @_scope and @_scope.respond_to? name
|
66
|
+
return @_scope.__send__ name, *args, &block
|
67
|
+
else
|
68
|
+
err = NameError.new "undefined local variable or method `#{name}'", name
|
69
|
+
err.set_backtrace caller
|
70
|
+
raise err
|
71
|
+
end
|
72
|
+
|
73
|
+
if name.sub!(/_$/,'')
|
74
|
+
@x.margin!
|
75
|
+
return __send__ "_#{name}", *args, &block if respond_to? "_#{name}"
|
76
|
+
end
|
77
|
+
|
78
|
+
if flag != '!'
|
79
|
+
if %w(script style).include?(name)
|
80
|
+
if String === args.first and not block
|
81
|
+
text = args.shift
|
82
|
+
if !text.include? '&' and !text.include? '<'
|
83
|
+
block = Proc.new do
|
84
|
+
@x.indented_data!(text)
|
85
|
+
end
|
86
|
+
elsif name == 'style'
|
87
|
+
block = Proc.new do
|
88
|
+
@x.indented_data!(text, "/*<![CDATA[*/", "/*]]>*/")
|
89
|
+
end
|
90
|
+
else
|
91
|
+
block = Proc.new do
|
92
|
+
@x.indented_data!(text, "//<![CDATA[", "//]]>")
|
93
|
+
end
|
86
94
|
end
|
87
|
-
|
88
|
-
|
89
|
-
|
95
|
+
end
|
96
|
+
|
97
|
+
args << {} if args.length == 0
|
98
|
+
if Hash === args.last
|
99
|
+
args.last[:lang] ||= 'text/javascript' if name == 'script'
|
100
|
+
args.last[:type] ||= 'text/css' if name == 'style'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# ensure that non-void elements are explicitly closed
|
105
|
+
if not block and not VOID.include?(name)
|
106
|
+
symbol = (args.shift if args.length > 0 and Symbol === args.first)
|
107
|
+
if args.length == 0 or (args.length == 1 and Hash === args.first)
|
108
|
+
args.unshift ''
|
109
|
+
end
|
110
|
+
args.unshift(symbol) if symbol
|
111
|
+
end
|
112
|
+
|
113
|
+
if String === args.first and args.first.respond_to? :html_safe?
|
114
|
+
if args.first.html_safe? and not block
|
115
|
+
if args.first.include? '>' or args.first.include? '&'
|
116
|
+
markup = args.shift
|
117
|
+
block = Proc.new {_ markup}
|
90
118
|
end
|
91
119
|
end
|
92
120
|
end
|
93
121
|
|
94
|
-
args << {} if args.length == 0
|
95
122
|
if Hash === args.last
|
96
|
-
|
97
|
-
args.last
|
98
|
-
end
|
99
|
-
end
|
123
|
+
# remove attributes with nil, false values
|
124
|
+
args.last.delete_if {|key, value| !value}
|
100
125
|
|
101
|
-
|
102
|
-
|
103
|
-
symbol = (args.shift if args.length > 0 and Symbol === args.first)
|
104
|
-
if args.length == 0 or (args.length == 1 and Hash === args.first)
|
105
|
-
args.unshift ''
|
126
|
+
# replace boolean 'true' attributes with the name of the attribute
|
127
|
+
args.last.each {|key, value| args.last[key]=key if value == true}
|
106
128
|
end
|
107
|
-
args.unshift(symbol) if symbol
|
108
129
|
end
|
109
130
|
|
110
|
-
if
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
131
|
+
if flag == '!'
|
132
|
+
@x.disable_indentation! do
|
133
|
+
@x.tag! name, *args, &block
|
134
|
+
end
|
135
|
+
elsif flag == '?'
|
136
|
+
# capture exceptions, produce filtered tracebacks
|
137
|
+
@x.tag!(name, *args) do
|
138
|
+
begin
|
139
|
+
block.call
|
140
|
+
rescue ::Exception => exception
|
141
|
+
options = (Hash === args.last)? args.last : {}
|
142
|
+
options[:log_level] = 'warn'
|
143
|
+
_exception exception, options
|
115
144
|
end
|
116
145
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
146
|
+
else
|
147
|
+
target = @x.tag! name, *args, &block
|
148
|
+
if block and %w(script style).include?(name)
|
149
|
+
if %w{//]]> /*]]>*/}.include? target[-4]
|
150
|
+
target[-4], target[-3] = target[-3], target[-4]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
target
|
125
154
|
end
|
126
155
|
end
|
127
156
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
157
|
+
def _exception(*args)
|
158
|
+
exception = args.first
|
159
|
+
if exception.respond_to? :backtrace
|
160
|
+
options = (Hash === args.last)? args.last : {}
|
161
|
+
traceback_class = options.delete(:traceback_class)
|
162
|
+
traceback_style = options.delete(:traceback_style)
|
163
|
+
traceback_style ||= 'background-color:#ff0; margin: 1em 0; ' +
|
164
|
+
'padding: 1em; border: 4px solid red; border-radius: 1em'
|
165
|
+
|
166
|
+
text = exception.inspect
|
167
|
+
log_level = options.delete(:log_level) || :error
|
168
|
+
Wunderbar.send log_level, text
|
169
|
+
exception.backtrace.each do |frame|
|
170
|
+
next if Wunderbar::CALLERS_TO_IGNORE.any? {|re| frame =~ re}
|
171
|
+
Wunderbar.send log_level, " #{frame}"
|
172
|
+
text += "\n #{frame}"
|
141
173
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
target[-4], target[-3] = target[-3], target[-4]
|
174
|
+
|
175
|
+
if traceback_class
|
176
|
+
@x.tag! :pre, text, :class=>traceback_class
|
177
|
+
else
|
178
|
+
@x.tag! :pre, text, :style=>traceback_style
|
148
179
|
end
|
180
|
+
else
|
181
|
+
super
|
149
182
|
end
|
150
|
-
target
|
151
183
|
end
|
152
|
-
end
|
153
184
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
traceback_class = options.delete(:traceback_class)
|
159
|
-
traceback_style = options.delete(:traceback_style)
|
160
|
-
traceback_style ||= 'background-color:#ff0; margin: 1em 0; ' +
|
161
|
-
'padding: 1em; border: 4px solid red; border-radius: 1em'
|
162
|
-
|
163
|
-
text = exception.inspect
|
164
|
-
log_level = options.delete(:log_level) || :error
|
165
|
-
Wunderbar.send log_level, text
|
166
|
-
exception.backtrace.each do |frame|
|
167
|
-
next if Wunderbar::CALLERS_TO_IGNORE.any? {|re| frame =~ re}
|
168
|
-
Wunderbar.send log_level, " #{frame}"
|
169
|
-
text += "\n #{frame}"
|
170
|
-
end
|
171
|
-
|
172
|
-
if traceback_class
|
173
|
-
@x.tag! :pre, text, :class=>traceback_class
|
174
|
-
else
|
175
|
-
@x.tag! :pre, text, :style=>traceback_style
|
185
|
+
def _head(*args, &block)
|
186
|
+
@x.tag!('head', *args) do
|
187
|
+
@x.tag! :meta, :charset => 'utf-8'
|
188
|
+
block.call if block
|
176
189
|
end
|
177
|
-
else
|
178
|
-
super
|
179
190
|
end
|
180
|
-
end
|
181
191
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
192
|
+
def _svg(*args, &block)
|
193
|
+
args << {} if args.empty?
|
194
|
+
args.first['xmlns'] = 'http://www.w3.org/2000/svg' if Hash === args.first
|
195
|
+
@x.tag! :svg, *args, &block
|
186
196
|
end
|
187
|
-
end
|
188
197
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
198
|
+
def _math(*args, &block)
|
199
|
+
args << {} if args.empty?
|
200
|
+
if Hash === args.first
|
201
|
+
args.first['xmlns'] = 'http://www.w3.org/1998/Math/MathML'
|
202
|
+
end
|
203
|
+
@x.tag! :math, *args, &block
|
204
|
+
end
|
194
205
|
|
195
|
-
|
196
|
-
|
197
|
-
if Hash === args.first
|
198
|
-
args.first['xmlns'] = 'http://www.w3.org/1998/Math/MathML'
|
206
|
+
def _?(text)
|
207
|
+
@x.indented_text! text.to_s
|
199
208
|
end
|
200
|
-
@x.tag! :math, *args, &block
|
201
|
-
end
|
202
209
|
|
203
|
-
|
204
|
-
|
205
|
-
|
210
|
+
def _!(text)
|
211
|
+
@x.text! text.to_s
|
212
|
+
end
|
206
213
|
|
207
|
-
|
208
|
-
|
209
|
-
end
|
214
|
+
def _(children=nil)
|
215
|
+
return @x if children == nil
|
210
216
|
|
211
|
-
|
212
|
-
|
217
|
+
if String === children
|
218
|
+
safe = !children.tainted?
|
219
|
+
safe ||= children.html_safe? if children.respond_to? :html_safe?
|
213
220
|
|
214
|
-
|
215
|
-
|
216
|
-
|
221
|
+
if safe and (children.include? '<' or children.include? '&')
|
222
|
+
require 'nokogiri'
|
223
|
+
children = Nokogiri::HTML::fragment(children.to_s).children
|
224
|
+
else
|
225
|
+
return @x.indented_text! children
|
226
|
+
end
|
227
|
+
end
|
217
228
|
|
218
|
-
|
219
|
-
|
220
|
-
children
|
221
|
-
else
|
222
|
-
return @x.indented_text! children
|
229
|
+
# remove leading and trailing space
|
230
|
+
if children.first.text? and children.first.text.strip.empty?
|
231
|
+
children.shift
|
223
232
|
end
|
224
|
-
end
|
225
233
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
children.pop if children.last.text? and children.last.text.strip.empty?
|
230
|
-
end
|
234
|
+
if not children.empty?
|
235
|
+
children.pop if children.last.text? and children.last.text.strip.empty?
|
236
|
+
end
|
231
237
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
238
|
+
children.each do |child|
|
239
|
+
if child.text? or child.cdata?
|
240
|
+
text = child.text
|
241
|
+
if text.strip.empty?
|
242
|
+
@x.text! "\n" if text.count("\n")>1
|
243
|
+
elsif @x.indentation_state!.first == 0
|
244
|
+
@x.indented_text! text.gsub(/\s+/, ' ')
|
245
|
+
else
|
246
|
+
@x.indented_text! text.strip
|
247
|
+
end
|
248
|
+
elsif child.comment?
|
249
|
+
@x.comment! child.text.sub(/\A /,'').sub(/ \Z/, '')
|
250
|
+
elsif self.class.flatten? child.children
|
251
|
+
block_element = Proc.new do |node|
|
252
|
+
node.element? and HTML5_BLOCK.include?(node.name)
|
253
|
+
end
|
248
254
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
255
|
+
if child.children.any?(&block_element)
|
256
|
+
# indent children, but disable indentation on consecutive
|
257
|
+
# sequences of non-block-elements. Put another way: break
|
258
|
+
# out block elements to a new line.
|
259
|
+
@x.tag!(child.name, child.attributes) do
|
260
|
+
children = child.children.to_a
|
261
|
+
while not children.empty?
|
262
|
+
stop = children.index(&block_element)
|
263
|
+
if stop == 0
|
264
|
+
_ [children.shift]
|
265
|
+
else
|
266
|
+
@x.disable_indentation! do
|
267
|
+
_ children.shift(stop || children.length)
|
268
|
+
end
|
262
269
|
end
|
263
270
|
end
|
264
271
|
end
|
272
|
+
else
|
273
|
+
# disable indentation on the entire element
|
274
|
+
@x.disable_indentation! do
|
275
|
+
@x.tag!(child.name, child.attributes) {_ child.children}
|
276
|
+
end
|
265
277
|
end
|
278
|
+
elsif child.children.empty? and VOID.include? child.name
|
279
|
+
@x.tag!(child.name, child.attributes)
|
280
|
+
elsif child.children.all? {|gchild| gchild.text?}
|
281
|
+
@x.tag!(child.name, child.text.strip, child.attributes)
|
282
|
+
elsif child.children.any? {|gchild| gchild.cdata?} and
|
283
|
+
(child.text.include? '<' or child.text.include? '&')
|
284
|
+
@x << child
|
266
285
|
else
|
267
|
-
|
268
|
-
@x.disable_indentation! do
|
269
|
-
@x.tag!(child.name, child.attributes) {_ child.children}
|
270
|
-
end
|
286
|
+
@x.tag!(child.name, child.attributes) {_ child.children}
|
271
287
|
end
|
272
|
-
elsif child.children.empty? and VOID.include? child.name
|
273
|
-
@x.tag!(child.name, child.attributes)
|
274
|
-
elsif child.children.all? {|gchild| gchild.text?}
|
275
|
-
@x.tag!(child.name, child.text.strip, child.attributes)
|
276
|
-
elsif child.children.any? {|gchild| gchild.cdata?} and
|
277
|
-
(child.text.include? '<' or child.text.include? '&')
|
278
|
-
@x << child
|
279
|
-
else
|
280
|
-
@x.tag!(child.name, child.attributes) {_ child.children}
|
281
288
|
end
|
282
289
|
end
|
283
|
-
end
|
284
290
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
+
def _coffeescript(text)
|
292
|
+
require 'coffee-script'
|
293
|
+
_script CoffeeScript.compile(text)
|
294
|
+
rescue LoadError
|
295
|
+
_script text, :lang => 'text/coffeescript'
|
296
|
+
end
|
291
297
|
|
292
|
-
|
293
|
-
|
294
|
-
|
298
|
+
def clear!
|
299
|
+
@x.target!.clear
|
300
|
+
end
|
295
301
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
302
|
+
def self.flatten?(children)
|
303
|
+
# do any of the text nodes need special processing to preserve spacing?
|
304
|
+
flatten = false
|
305
|
+
space = true
|
306
|
+
if children.any? {|child| child.text? and !child.text.strip.empty?}
|
307
|
+
children.each do |child|
|
308
|
+
if child.text? or child.element?
|
309
|
+
unless child.text == ''
|
310
|
+
flatten = true if not space and not child.text =~ /\A\s/
|
311
|
+
space = (child.text =~ /\s\Z/)
|
312
|
+
end
|
313
|
+
space = true if child.element? and HTML5_BLOCK.include? child.name
|
306
314
|
end
|
307
|
-
space = true if child.element? and HTML5_BLOCK.include? child.name
|
308
315
|
end
|
309
316
|
end
|
317
|
+
flatten
|
310
318
|
end
|
311
|
-
flatten
|
312
|
-
end
|
313
319
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
320
|
+
# reflow long lines
|
321
|
+
def self.reflow(stream, width)
|
322
|
+
source = stream.slice!(0..-1)
|
323
|
+
indent = col = 0
|
324
|
+
breakable = true
|
325
|
+
pre = false
|
326
|
+
while not source.empty?
|
327
|
+
token = source.shift
|
328
|
+
indent = token[/^ */].length if col == 0
|
329
|
+
|
330
|
+
if token.start_with? '<'
|
331
|
+
breakable = false
|
332
|
+
pre = true if token == '<pre'
|
333
|
+
end
|
328
334
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
335
|
+
# flow text
|
336
|
+
while token.length + col > width and breakable and not pre
|
337
|
+
break if token[0...-1].include? "\n"
|
338
|
+
split = token.rindex(' ', [width-col,0].max) || token.index(' ')
|
339
|
+
break unless split
|
340
|
+
break if col+split < indent+width/2
|
341
|
+
stream << token[0...split] << "\n" << (' '*indent)
|
342
|
+
col = indent
|
343
|
+
token = token[split+1..-1]
|
344
|
+
end
|
339
345
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
346
|
+
# break around tags
|
347
|
+
if token.end_with? '>'
|
348
|
+
if col > indent + 4 and stream[-2..-1] == ['<br', '/']
|
349
|
+
stream << token << "\n"
|
350
|
+
col = 0
|
351
|
+
token = ' '*indent
|
352
|
+
source[0] = source.first.lstrip unless source.empty?
|
353
|
+
elsif col > width and not pre
|
354
|
+
# break on previous space within text
|
355
|
+
pcol = col
|
356
|
+
stream.reverse_each do |xtoken|
|
357
|
+
break if xtoken.include? "\n"
|
358
|
+
split = xtoken.rindex(' ')
|
359
|
+
breakable = false if xtoken.end_with? '>'
|
360
|
+
if breakable and split
|
361
|
+
col = col - pcol + xtoken.length - split + indent
|
362
|
+
xtoken[split] = "\n#{' '*indent}"
|
363
|
+
break
|
364
|
+
end
|
365
|
+
breakable = true if xtoken.start_with? '<'
|
366
|
+
pcol -= xtoken.length
|
367
|
+
break if pcol < (width + indent)/2
|
358
368
|
end
|
359
|
-
breakable = true if xtoken.start_with? '<'
|
360
|
-
pcol -= xtoken.length
|
361
|
-
break if pcol < (width + indent)/2
|
362
369
|
end
|
370
|
+
breakable = true
|
371
|
+
pre = false if token == '</pre>'
|
363
372
|
end
|
364
|
-
breakable = true
|
365
|
-
pre = false if token == '</pre>'
|
366
|
-
end
|
367
373
|
|
368
|
-
|
369
|
-
|
370
|
-
|
374
|
+
stream << token
|
375
|
+
col += token.length
|
376
|
+
col = 0 if token.end_with? "\n"
|
377
|
+
end
|
371
378
|
end
|
372
379
|
end
|
373
380
|
end
|
data/lib/wunderbar/rails.rb
CHANGED
@@ -9,7 +9,7 @@ module Wunderbar
|
|
9
9
|
def self.call(template)
|
10
10
|
%{
|
11
11
|
compiled = Proc.new {#{template.source}}
|
12
|
-
x = HtmlMarkup.new(self);
|
12
|
+
x = Wunderbar::HtmlMarkup.new(self);
|
13
13
|
instance_variables.each do |var|
|
14
14
|
x.instance_variable_set var, instance_variable_get(var)
|
15
15
|
end
|
data/lib/wunderbar/server.rb
CHANGED
@@ -54,8 +54,11 @@ else
|
|
54
54
|
ENV['USER'] ||= $USER
|
55
55
|
end
|
56
56
|
|
57
|
-
ENV['HOME']
|
58
|
-
|
57
|
+
$HOME = ENV['HOME']
|
58
|
+
$HOME ||= Dir.home($USER) rescue nil
|
59
|
+
$HOME ||= File.expand_path("~#{$USER}") rescue nil
|
60
|
+
$HOME = ENV['DOCUMENT_ROOT'] if not $HOME or not File.exist? $HOME
|
61
|
+
ENV['HOME'] = $HOME
|
59
62
|
|
60
63
|
at_exit do
|
61
64
|
if Wunderbar.queue.length > 0
|
data/lib/wunderbar/version.rb
CHANGED
data/wunderbar.gemspec
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "wunderbar"
|
5
|
-
s.version = "0.14.
|
5
|
+
s.version = "0.14.5"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Sam Ruby"]
|
9
|
-
s.date = "2012-05-
|
9
|
+
s.date = "2012-05-03"
|
10
10
|
s.description = " Wunderbar makes it easy to produce valid HTML5, wellformed XHTML, Unicode\n (utf-8), consistently indented, readable applications. This includes\n output that conforms to the Polyglot specification and the emerging\n results from the XML Error Recovery Community Group.\n"
|
11
11
|
s.email = "rubys@intertwingly.net"
|
12
|
-
s.files = ["wunderbar.gemspec", "README.md", "COPYING", "lib/wunderbar
|
12
|
+
s.files = ["wunderbar.gemspec", "README.md", "COPYING", "lib/wunderbar", "lib/wunderbar/logger.rb", "lib/wunderbar/rack.rb", "lib/wunderbar/sinatra.rb", "lib/wunderbar/cgi-methods.rb", "lib/wunderbar/cssproxy.rb", "lib/wunderbar/builder.rb", "lib/wunderbar/websocket.rb", "lib/wunderbar/installation.rb", "lib/wunderbar/version.rb", "lib/wunderbar/html-methods.rb", "lib/wunderbar/job-control.rb", "lib/wunderbar/rails.rb", "lib/wunderbar/environment.rb", "lib/wunderbar/server.rb", "lib/wunderbar.rb"]
|
13
13
|
s.homepage = "http://github.com/rubys/wunderbar"
|
14
14
|
s.require_paths = ["lib"]
|
15
15
|
s.rubygems_version = "1.8.21"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wunderbar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 45
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 14
|
9
|
-
-
|
10
|
-
version: 0.14.
|
9
|
+
- 5
|
10
|
+
version: 0.14.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sam Ruby
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-05-
|
18
|
+
date: 2012-05-03 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: builder
|
@@ -58,21 +58,21 @@ files:
|
|
58
58
|
- wunderbar.gemspec
|
59
59
|
- README.md
|
60
60
|
- COPYING
|
61
|
-
- lib/wunderbar.rb
|
62
|
-
- lib/wunderbar/installation.rb
|
63
|
-
- lib/wunderbar/html-methods.rb
|
64
|
-
- lib/wunderbar/job-control.rb
|
65
|
-
- lib/wunderbar/server.rb
|
66
61
|
- lib/wunderbar/logger.rb
|
67
62
|
- lib/wunderbar/rack.rb
|
68
|
-
- lib/wunderbar/builder.rb
|
69
|
-
- lib/wunderbar/websocket.rb
|
70
63
|
- lib/wunderbar/sinatra.rb
|
71
|
-
- lib/wunderbar/environment.rb
|
72
|
-
- lib/wunderbar/rails.rb
|
73
64
|
- lib/wunderbar/cgi-methods.rb
|
74
65
|
- lib/wunderbar/cssproxy.rb
|
66
|
+
- lib/wunderbar/builder.rb
|
67
|
+
- lib/wunderbar/websocket.rb
|
68
|
+
- lib/wunderbar/installation.rb
|
75
69
|
- lib/wunderbar/version.rb
|
70
|
+
- lib/wunderbar/html-methods.rb
|
71
|
+
- lib/wunderbar/job-control.rb
|
72
|
+
- lib/wunderbar/rails.rb
|
73
|
+
- lib/wunderbar/environment.rb
|
74
|
+
- lib/wunderbar/server.rb
|
75
|
+
- lib/wunderbar.rb
|
76
76
|
homepage: http://github.com/rubys/wunderbar
|
77
77
|
licenses: []
|
78
78
|
|