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 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
- _ "<em>hello</em>!!!"
89
+ _{"<em>hello</em>!!!"}
86
90
 
87
- Text (markup is escaped):
91
+ Import of HTML/XML:
88
92
 
89
- _? "<3"
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
- * `_?`: insert text with indentation matching the current output
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 markup
329
- directly when the input is `tainted` and not explicitly marked as `html-safe?`
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
@@ -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
- if args.first.include? '>' or args.first.include? '&'
101
- markup = args.shift
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 _?(text)
192
- @x.indented_text! text.to_s
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 _(children=nil)
200
- return @x if children == nil
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? if children.respond_to? :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
- require = "require #{"./#{File.basename(main).sub(/\.rb$/,'')}".inspect}"
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
@@ -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
@@ -51,7 +51,7 @@ module Wunderbar
51
51
  builder.instance_eval(&block)
52
52
  else
53
53
  context = builder.get_binding do
54
- builder.instance_eval {_ block.call}
54
+ builder.instance_eval {_(&block)}
55
55
  end
56
56
  context.eval(data.untaint, eval_file)
57
57
  end
@@ -1,7 +1,7 @@
1
1
  module Wunderbar
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 15
4
+ MINOR = 16
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
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.15.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-13"
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: 35
4
+ hash: 95
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 15
8
+ - 16
9
9
  - 0
10
- version: 0.15.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-13 00:00:00 Z
18
+ date: 2012-05-17 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: builder