wunderbar 0.15.0 → 0.16.0
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.
- data/README.md +11 -6
- data/lib/wunderbar/builder.rb +86 -0
- data/lib/wunderbar/html-methods.rb +21 -72
- data/lib/wunderbar/installation.rb +5 -1
- data/lib/wunderbar/server.rb +11 -0
- data/lib/wunderbar/sinatra.rb +1 -1
- data/lib/wunderbar/version.rb +1 -1
- data/wunderbar.gemspec +2 -2
- metadata +4 -4
data/README.md
CHANGED
@@ -80,13 +80,17 @@ Element with optional (omitted) attributes:
|
|
80
80
|
|
81
81
|
_tr class: nil
|
82
82
|
|
83
|
+
Text (markup characters are escaped):
|
84
|
+
|
85
|
+
_ "<3"
|
86
|
+
|
83
87
|
Text (may contain markup):
|
84
88
|
|
85
|
-
_
|
89
|
+
_{"<em>hello</em>!!!"}
|
86
90
|
|
87
|
-
|
91
|
+
Import of HTML/XML:
|
88
92
|
|
89
|
-
_
|
93
|
+
_[Nokogiri::XML "<em>hello</em>"]
|
90
94
|
|
91
95
|
Mixed content (autospaced):
|
92
96
|
|
@@ -192,7 +196,7 @@ argument inserts markup, respecting indendation. Inserting markup without
|
|
192
196
|
reguard to indendatation is done using "`_ << text`". A number of other
|
193
197
|
convenience methods are defined:
|
194
198
|
|
195
|
-
* `_
|
199
|
+
* `_`: insert text with indentation matching the current output
|
196
200
|
* `_!`: insert text without indenting
|
197
201
|
* `_.post?` -- was this invoked via HTTP POST?
|
198
202
|
* `_.system` -- invokes a shell command, captures stdin, stdout, and stderr
|
@@ -325,8 +329,9 @@ Secure by default
|
|
325
329
|
---
|
326
330
|
|
327
331
|
Wunderbar will properly escape all HTML and JSON output, eliminating problems
|
328
|
-
of HTML or JavaScript injection. This includes calls to `_` to insert
|
329
|
-
directly
|
332
|
+
of HTML or JavaScript injection. This includes calls to `_` to insert text
|
333
|
+
directly. Even calls to insert markup (`_{...}`) will escape the markup if
|
334
|
+
the input is `tainted` and not explicitly marked as `html-safe?`
|
330
335
|
(when using Rails).
|
331
336
|
|
332
337
|
For all environments other than Rails, unless you call `Wunderbar.unsafe!` at
|
data/lib/wunderbar/builder.rb
CHANGED
@@ -142,6 +142,26 @@ module Wunderbar
|
|
142
142
|
|
143
143
|
# avoid method_missing overhead for the most common case
|
144
144
|
def tag!(sym, *args, &block)
|
145
|
+
if sym.respond_to? :children
|
146
|
+
node = sym
|
147
|
+
attributes = node.attributes
|
148
|
+
if node.attribute_nodes.any?(&:namespace)
|
149
|
+
attributes = Hash[node.attribute_nodes.map { |attr|
|
150
|
+
name = attr.name
|
151
|
+
name = "#{attr.namespace.prefix}:#{name}" if attr.namespace
|
152
|
+
[name, attr.value]
|
153
|
+
}]
|
154
|
+
end
|
155
|
+
attributes.merge!(node.namespaces) if node.namespaces
|
156
|
+
args.push attributes
|
157
|
+
if node.namespace and node.namespace.prefix
|
158
|
+
args.unshift node.name.to_sym
|
159
|
+
sym = node.namespace.prefix
|
160
|
+
else
|
161
|
+
sym = node.name
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
145
165
|
if !block and (args.empty? or args == [''])
|
146
166
|
CssProxy.new(@_builder, @_builder.target!, sym, args)
|
147
167
|
else
|
@@ -254,6 +274,72 @@ module Wunderbar
|
|
254
274
|
rescue LoadError
|
255
275
|
@_builder << data
|
256
276
|
end
|
277
|
+
|
278
|
+
def [](*children)
|
279
|
+
if children.length == 1 and children.first.respond_to? :root
|
280
|
+
children = [children.first.root]
|
281
|
+
end
|
282
|
+
|
283
|
+
# remove leading and trailing space
|
284
|
+
if children.first.text? and children.first.text.strip.empty?
|
285
|
+
children.shift
|
286
|
+
end
|
287
|
+
|
288
|
+
if not children.empty?
|
289
|
+
children.pop if children.last.text? and children.last.text.strip.empty?
|
290
|
+
end
|
291
|
+
|
292
|
+
children.each do |child|
|
293
|
+
if child.text? or child.cdata?
|
294
|
+
text = child.text
|
295
|
+
if text.strip.empty?
|
296
|
+
text! "\n" if text.count("\n")>1
|
297
|
+
elsif indentation_state!.first == 0
|
298
|
+
indented_text! text.gsub(/\s+/, ' ')
|
299
|
+
else
|
300
|
+
indented_text! text.strip
|
301
|
+
end
|
302
|
+
elsif child.comment?
|
303
|
+
comment! child.text.sub(/\A /,'').sub(/ \Z/, '')
|
304
|
+
elsif HtmlMarkup.flatten? child.children
|
305
|
+
block_element = Proc.new do |node|
|
306
|
+
node.element? and HtmlMarkup::HTML5_BLOCK.include?(node.name)
|
307
|
+
end
|
308
|
+
|
309
|
+
if child.children.any?(&block_element)
|
310
|
+
# indent children, but disable indentation on consecutive
|
311
|
+
# sequences of non-block-elements. Put another way: break
|
312
|
+
# out block elements to a new line.
|
313
|
+
tag!(child) do
|
314
|
+
children = child.children.to_a
|
315
|
+
while not children.empty?
|
316
|
+
stop = children.index(&block_element)
|
317
|
+
if stop == 0
|
318
|
+
self[children.shift]
|
319
|
+
else
|
320
|
+
disable_indentation! do
|
321
|
+
self[*children.shift(stop || children.length)]
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
else
|
327
|
+
# disable indentation on the entire element
|
328
|
+
disable_indentation! do
|
329
|
+
tag!(child) {self[*child.children]}
|
330
|
+
end
|
331
|
+
end
|
332
|
+
elsif child.children.empty? and HtmlMarkup::VOID.include? child.name
|
333
|
+
tag!(child)
|
334
|
+
elsif child.children.all?(&:text?)
|
335
|
+
tag!(child, child.text.strip)
|
336
|
+
elsif child.children.any?(&:cdata?) and child.text =~ /[<&]/
|
337
|
+
self << child
|
338
|
+
else
|
339
|
+
tag!(child) {self[*child.children]}
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
257
343
|
end
|
258
344
|
|
259
345
|
require 'stringio'
|
@@ -96,11 +96,9 @@ module Wunderbar
|
|
96
96
|
end
|
97
97
|
|
98
98
|
if String === args.first and args.first.respond_to? :html_safe?
|
99
|
-
if args.first.html_safe? and not block
|
100
|
-
|
101
|
-
|
102
|
-
block = Proc.new {_ markup}
|
103
|
-
end
|
99
|
+
if args.first.html_safe? and not block and args.first =~ /[>&]/
|
100
|
+
markup = args.shift
|
101
|
+
block = Proc.new {_ {markup}}
|
104
102
|
end
|
105
103
|
end
|
106
104
|
|
@@ -187,21 +185,32 @@ module Wunderbar
|
|
187
185
|
end
|
188
186
|
@x.tag! :math, *args, &block
|
189
187
|
end
|
190
|
-
|
191
|
-
def
|
192
|
-
@x.
|
188
|
+
|
189
|
+
def _pre(*args, &block)
|
190
|
+
@x.disable_indentation! { @x.tag! :pre, *args, &block }
|
193
191
|
end
|
194
192
|
|
195
193
|
def _!(text)
|
196
194
|
@x.text! text.to_s
|
197
195
|
end
|
198
196
|
|
199
|
-
def _(
|
200
|
-
|
197
|
+
def _(text=nil, &block)
|
198
|
+
unless block
|
199
|
+
if text
|
200
|
+
if text.respond_to? :html_safe? and text.html_safe?
|
201
|
+
_ {text}
|
202
|
+
else
|
203
|
+
@x.indented_text! text.to_s
|
204
|
+
end
|
205
|
+
end
|
206
|
+
return @x
|
207
|
+
end
|
208
|
+
|
209
|
+
children = block.call
|
201
210
|
|
202
211
|
if String === children
|
203
212
|
safe = !children.tainted?
|
204
|
-
safe ||= children.html_safe?
|
213
|
+
safe ||= children.html_safe? if children.respond_to? :html_safe?
|
205
214
|
|
206
215
|
if safe and (children.include? '<' or children.include? '&')
|
207
216
|
require 'nokogiri'
|
@@ -210,67 +219,7 @@ module Wunderbar
|
|
210
219
|
return @x.indented_text! children
|
211
220
|
end
|
212
221
|
end
|
213
|
-
|
214
|
-
# remove leading and trailing space
|
215
|
-
if children.first.text? and children.first.text.strip.empty?
|
216
|
-
children.shift
|
217
|
-
end
|
218
|
-
|
219
|
-
if not children.empty?
|
220
|
-
children.pop if children.last.text? and children.last.text.strip.empty?
|
221
|
-
end
|
222
|
-
|
223
|
-
children.each do |child|
|
224
|
-
if child.text? or child.cdata?
|
225
|
-
text = child.text
|
226
|
-
if text.strip.empty?
|
227
|
-
@x.text! "\n" if text.count("\n")>1
|
228
|
-
elsif @x.indentation_state!.first == 0
|
229
|
-
@x.indented_text! text.gsub(/\s+/, ' ')
|
230
|
-
else
|
231
|
-
@x.indented_text! text.strip
|
232
|
-
end
|
233
|
-
elsif child.comment?
|
234
|
-
@x.comment! child.text.sub(/\A /,'').sub(/ \Z/, '')
|
235
|
-
elsif self.class.flatten? child.children
|
236
|
-
block_element = Proc.new do |node|
|
237
|
-
node.element? and HTML5_BLOCK.include?(node.name)
|
238
|
-
end
|
239
|
-
|
240
|
-
if child.children.any?(&block_element)
|
241
|
-
# indent children, but disable indentation on consecutive
|
242
|
-
# sequences of non-block-elements. Put another way: break
|
243
|
-
# out block elements to a new line.
|
244
|
-
@x.tag!(child.name, child.attributes) do
|
245
|
-
children = child.children.to_a
|
246
|
-
while not children.empty?
|
247
|
-
stop = children.index(&block_element)
|
248
|
-
if stop == 0
|
249
|
-
_ [children.shift]
|
250
|
-
else
|
251
|
-
@x.disable_indentation! do
|
252
|
-
_ children.shift(stop || children.length)
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
else
|
258
|
-
# disable indentation on the entire element
|
259
|
-
@x.disable_indentation! do
|
260
|
-
@x.tag!(child.name, child.attributes) {_ child.children}
|
261
|
-
end
|
262
|
-
end
|
263
|
-
elsif child.children.empty? and VOID.include? child.name
|
264
|
-
@x.tag!(child.name, child.attributes)
|
265
|
-
elsif child.children.all? {|gchild| gchild.text?}
|
266
|
-
@x.tag!(child.name, child.text.strip, child.attributes)
|
267
|
-
elsif child.children.any? {|gchild| gchild.cdata?} and
|
268
|
-
(child.text.include? '<' or child.text.include? '&')
|
269
|
-
@x << child
|
270
|
-
else
|
271
|
-
@x.tag!(child.name, child.attributes) {_ child.children}
|
272
|
-
end
|
273
|
-
end
|
222
|
+
@x[*children]
|
274
223
|
end
|
275
224
|
|
276
225
|
def _coffeescript(text)
|
@@ -58,7 +58,11 @@ if install and ARGV.delete(install)
|
|
58
58
|
file.puts "\n#{Wunderbar.data}\n" if Object.const_defined? :DATA
|
59
59
|
|
60
60
|
# Load script
|
61
|
-
|
61
|
+
if main.end_with? '.rb'
|
62
|
+
require = "require #{"./#{File.basename(main).chomp('.rb')}".inspect}"
|
63
|
+
else
|
64
|
+
require = "load #{"./#{File.basename(main)}".inspect}"
|
65
|
+
end
|
62
66
|
if ARGV.delete('--rescue') or ARGV.delete('--backtrace')
|
63
67
|
file.puts <<-EOF.gsub(/^ {8}/,'')
|
64
68
|
begin
|
data/lib/wunderbar/server.rb
CHANGED
@@ -54,6 +54,17 @@ else
|
|
54
54
|
ENV['USER'] ||= $USER
|
55
55
|
end
|
56
56
|
|
57
|
+
if ENV['HTTP_AUTH']
|
58
|
+
# RewriteEngine on
|
59
|
+
# RewriteRule ^.*$ - [E=HTTP_AUTH:%{HTTP:Authorization}]
|
60
|
+
begin
|
61
|
+
require 'base64'
|
62
|
+
$PASSWORD = Base64.decode64(ENV['HTTP_AUTH'] \
|
63
|
+
[/^Basic ([A-Za-z0-9+\/=]+)$/,1])[/^#{$USER}:(.*)/,1]
|
64
|
+
rescue
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
57
68
|
$HOME = ENV['HOME']
|
58
69
|
$HOME ||= Dir.home($USER) rescue nil
|
59
70
|
$HOME ||= File.expand_path("~#{$USER}") rescue nil
|
data/lib/wunderbar/sinatra.rb
CHANGED
data/lib/wunderbar/version.rb
CHANGED
data/wunderbar.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "wunderbar"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.16.0"
|
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-17"
|
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
12
|
s.files = ["wunderbar.gemspec", "README.md", "COPYING", "lib/wunderbar.rb", "lib/wunderbar", "lib/wunderbar/installation.rb", "lib/wunderbar/html-methods.rb", "lib/wunderbar/job-control.rb", "lib/wunderbar/server.rb", "lib/wunderbar/logger.rb", "lib/wunderbar/rack.rb", "lib/wunderbar/builder.rb", "lib/wunderbar/websocket.rb", "lib/wunderbar/sinatra.rb", "lib/wunderbar/environment.rb", "lib/wunderbar/rails.rb", "lib/wunderbar/cgi-methods.rb", "lib/wunderbar/cssproxy.rb", "lib/wunderbar/version.rb"]
|
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: 95
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 16
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.16.0
|
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-17 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: builder
|