wunderbar 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
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