wunderbar 0.18.2 → 0.18.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ /*
2
+ AngularJS v1.2.0
3
+ (c) 2010-2012 Google, Inc. http://angularjs.org
4
+ License: MIT
5
+ */
6
+ (function(H,h,C){'use strict';var x=h.$$minErr("$resource");h.module("ngResource",["ng"]).factory("$resource",["$http","$parse","$q",function(D,y,E){function n(h,k){this.template=h;this.defaults=k||{};this.urlParams={}}function t(e,k,f){function q(b,c){var d={};c=u({},k,c);r(c,function(a,c){s(a)&&(a=a());var m;a&&a.charAt&&"@"==a.charAt(0)?(m=a.substr(1),m=y(m)(b)):m=a;d[c]=m});return d}function d(b){return b.resource}function g(b){z(b||{},this)}var F=new n(e);f=u({},G,f);r(f,function(b,c){var A=
7
+ /^(POST|PUT|PATCH)$/i.test(b.method);g[c]=function(a,c,m,k){var p={},e,f,v;switch(arguments.length){case 4:v=k,f=m;case 3:case 2:if(s(c)){if(s(a)){f=a;v=c;break}f=c;v=m}else{p=a;e=c;f=m;break}case 1:s(a)?f=a:A?e=a:p=a;break;case 0:break;default:throw x("badargs",arguments.length);}var n=e instanceof g,l=n?e:b.isArray?[]:new g(e),w={},t=b.interceptor&&b.interceptor.response||d,y=b.interceptor&&b.interceptor.responseError||C;r(b,function(a,c){"params"!=c&&("isArray"!=c&&"interceptor"!=c)&&(w[c]=z(a))});
8
+ A&&(w.data=e);F.setUrlParams(w,u({},q(e,b.params||{}),p),b.url);p=D(w).then(function(c){var a=c.data,d=l.$promise;if(a){if(h.isArray(a)!==!!b.isArray)throw x("badcfg",b.isArray?"array":"object",h.isArray(a)?"array":"object");b.isArray?(l.length=0,r(a,function(a){l.push(new g(a))})):(z(a,l),l.$promise=d)}l.$resolved=!0;c.resource=l;return c},function(a){l.$resolved=!0;(v||B)(a);return E.reject(a)});p=p.then(function(a){var c=t(a);(f||B)(c,a.headers);return c},y);return n?p:(l.$promise=p,l.$resolved=
9
+ !1,l)};g.prototype["$"+c]=function(a,b,d){s(a)&&(d=b,b=a,a={});a=g[c](a,this,b,d);return a.$promise||a}});g.bind=function(b){return t(e,u({},k,b),f)};return g}var G={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},B=h.noop,r=h.forEach,u=h.extend,z=h.copy,s=h.isFunction;n.prototype={setUrlParams:function(e,k,f){var q=this,d=f||q.template,g,n,b=q.urlParams={};r(d.split(/\W/),function(c){if("hasOwnProperty"===c)throw x("badname");
10
+ !/^\d+$/.test(c)&&(c&&RegExp("(^|[^\\\\]):"+c+"(\\W|$)").test(d))&&(b[c]=!0)});d=d.replace(/\\:/g,":");k=k||{};r(q.urlParams,function(c,b){g=k.hasOwnProperty(b)?k[b]:q.defaults[b];h.isDefined(g)&&null!==g?(n=encodeURIComponent(g).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),d=d.replace(RegExp(":"+b+"(\\W|$)","g"),n+"$1")):d=d.replace(RegExp("(/?):"+b+"(\\W|$)","g"),function(a,
11
+ c,b){return"/"==b.charAt(0)?b:c+b})});d=d.replace(/\/+$/,"");d=d.replace(/\/\.(?=\w+($|\?))/,".");e.url=d.replace(/\/\\\./,"/.");r(k,function(c,b){q.urlParams[b]||(e.params=e.params||{},e.params[b]=c)})}};return t}])})(window,window.angular);
12
+ //# sourceMappingURL=angular-resource.min.js.map
@@ -0,0 +1,6 @@
1
+ require 'wunderbar/angularjs'
2
+ require 'ruby2js/filter/angular-resource'
3
+
4
+ source = File.expand_path('../angular-resource.min.js', __FILE__)
5
+
6
+ Wunderbar::Asset.script :name => 'angular-resource.min.js', :file => source
@@ -0,0 +1,14 @@
1
+ /*
2
+ AngularJS v1.2.0
3
+ (c) 2010-2012 Google, Inc. http://angularjs.org
4
+ License: MIT
5
+ */
6
+ (function(t,c,B){'use strict';function w(s,r,g,a,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(k,d,A){return function(u,k,d){function v(){l&&(l.$destroy(),l=null);m&&(h.leave(m),m=null)}function x(){var f=s.current&&s.current.locals,y=f&&f.$template;if(y){var z=u.$new();A(z,function(e){e.html(y);h.enter(e,null,m||k,function(){!c.isDefined(n)||n&&!u.$eval(n)||r()});v();var p=g(e.contents()),q=s.current;l=q.scope=z;m=e;if(q.controller){f.$scope=l;var d=a(q.controller,
7
+ f);q.controllerAs&&(l[q.controllerAs]=d);e.data("$ngControllerController",d);e.children().data("$ngControllerController",d)}p(l);l.$emit("$viewContentLoaded");l.$eval(b)})}else v()}var l,m,n=d.autoscroll,b=d.onload||"";u.$on("$routeChangeSuccess",x);x()}}}}t=c.module("ngRoute",["ng"]).provider("$route",function(){function s(a,h){return c.extend(new (c.extend(function(){},{prototype:a})),h)}function r(a,c){var k=c.caseInsensitiveMatch,d={originalPath:a,regexp:a},g=d.keys=[];a=a.replace(/([().])/g,
8
+ "\\$1").replace(/(\/)?:(\w+)([\?|\*])?/g,function(a,c,h,d){a="?"===d?d:null;d="*"===d?d:null;g.push({name:h,optional:!!a});c=c||"";return""+(a?"":c)+"(?:"+(a?c:"")+(d&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");d.regexp=RegExp("^"+a+"$",k?"i":"");return d}var g={};this.when=function(a,h){g[a]=c.extend({reloadOnSearch:!0},h,a&&r(a,h));if(a){var k="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[k]=c.extend({redirectTo:a},r(k,h))}return this};this.otherwise=function(a){this.when(null,
9
+ a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,h,k,d,r,u,t,w){function v(){var b=x(),f=n.current;if(b&&f&&b.$$route===f.$$route&&c.equals(b.pathParams,f.pathParams)&&!b.reloadOnSearch&&!m)f.params=b.params,c.copy(f.params,k),a.$broadcast("$routeUpdate",f);else if(b||f)m=!1,a.$broadcast("$routeChangeStart",b,f),(n.current=b)&&b.redirectTo&&(c.isString(b.redirectTo)?h.path(l(b.redirectTo,b.params)).search(b.params).replace():
10
+ h.url(b.redirectTo(b.pathParams,h.path(),h.search())).replace()),d.when(b).then(function(){if(b){var a=c.extend({},b.resolve),f,e;c.forEach(a,function(b,f){a[f]=c.isString(b)?r.get(b):r.invoke(b)});c.isDefined(f=b.template)?c.isFunction(f)&&(f=f(b.params)):c.isDefined(e=b.templateUrl)&&(c.isFunction(e)&&(e=e(b.params)),e=w.getTrustedResourceUrl(e),c.isDefined(e)&&(b.loadedTemplateUrl=e,f=u.get(e,{cache:t}).then(function(b){return b.data})));c.isDefined(f)&&(a.$template=f);return d.all(a)}}).then(function(d){b==
11
+ n.current&&(b&&(b.locals=d,c.copy(b.params,k)),a.$broadcast("$routeChangeSuccess",b,f))},function(c){b==n.current&&a.$broadcast("$routeChangeError",b,f,c)})}function x(){var b,a;c.forEach(g,function(d,l){var e;if(e=!a){var p=h.path();e=d.keys;var q={};if(d.regexp)if(p=d.regexp.exec(p)){for(var g=1,k=p.length;g<k;++g){var m=e[g-1],n="string"==typeof p[g]?decodeURIComponent(p[g]):p[g];m&&n&&(q[m.name]=n)}e=q}else e=null;else e=null;e=b=e}e&&(a=s(d,{params:c.extend({},h.search(),b),pathParams:b}),a.$$route=
12
+ d)});return a||g[null]&&s(g[null],{params:{},pathParams:{}})}function l(a,d){var g=[];c.forEach((a||"").split(":"),function(a,b){if(0===b)g.push(a);else{var c=a.match(/(\w+)(.*)/),h=c[1];g.push(d[h]);g.push(c[2]||"");delete d[h]}});return g.join("")}var m=!1,n={routes:g,reload:function(){m=!0;a.$evalAsync(v)}};a.$on("$locationChangeSuccess",v);return n}]});t.provider("$routeParams",function(){this.$get=function(){return{}}});t.directive("ngView",w);w.$inject=["$route","$anchorScroll","$compile","$controller",
13
+ "$animate"]})(window,window.angular);
14
+ //# sourceMappingURL=angular-route.min.js.map
@@ -0,0 +1,6 @@
1
+ require 'wunderbar/angularjs'
2
+ require 'ruby2js/filter/angular-route'
3
+
4
+ source = File.expand_path('../angular-route.min.js', __FILE__)
5
+
6
+ Wunderbar::Asset.script :name => 'angular-route.min.js', :file => source
@@ -1,20 +1,6 @@
1
- require 'wunderbar'
1
+ require 'wunderbar/script'
2
2
  require 'ruby2js/filter/angularrb'
3
3
 
4
4
  source = File.expand_path('../angular.min.js', __FILE__)
5
5
 
6
6
  Wunderbar::Asset.script :name => 'angular-min.js', :file => source
7
-
8
- module Wunderbar
9
- class HtmlMarkup
10
- def _script(*args, &block)
11
- if block
12
- args.unshift Ruby2JS.convert(block,
13
- filters: [Ruby2JS::Filter::AngularRB])
14
- super *args, &nil
15
- else
16
- super
17
- end
18
- end
19
- end
20
- end
@@ -239,30 +239,30 @@ module Wunderbar
239
239
 
240
240
  # insert verbatim
241
241
  def <<(data)
242
- if not String === data or data.include? '<' or data.include? '&'
243
- require 'nokogiri'
244
- data = Nokogiri::HTML::fragment(data.to_s).to_xml
245
-
246
- # fix CDATA in most cases (notably scripts)
247
- data.gsub!(/<!\[CDATA\[(.*?)\]\]>/m) do
248
- if $1.include? '<' or $1.include? '&'
249
- "//<![CDATA[\n#{$1}\n//]]>"
250
- else
251
- $1
242
+ if defined? Nokogiri
243
+ if not String === data or data.include? '<' or data.include? '&'
244
+ data = Nokogiri::HTML::fragment(data.to_s).to_xml
245
+
246
+ # fix CDATA in most cases (notably scripts)
247
+ data.gsub!(/<!\[CDATA\[(.*?)\]\]>/m) do
248
+ if $1.include? '<' or $1.include? '&'
249
+ "//<![CDATA[\n#{$1}\n//]]>"
250
+ else
251
+ $1
252
+ end
252
253
  end
253
- end
254
254
 
255
- # fix CDATA for style elements
256
- data.gsub!(/<style([^>])*>\/\/<!\[CDATA\[\n(.*?)\s+\/\/\]\]>/m) do
257
- if $2.include? '<' or $2.include? '&'
258
- "<style#{$1}>/*<![CDATA[*/\n#{$2.gsub("\n\Z",'')}\n/*]]>*/"
259
- else
260
- $1
255
+ # fix CDATA for style elements
256
+ data.gsub!(/<style([^>])*>\/\/<!\[CDATA\[\n(.*?)\s+\/\/\]\]>/m) do
257
+ if $2.include? '<' or $2.include? '&'
258
+ "<style#{$1}>/*<![CDATA[*/\n#{$2.gsub("\n\Z",'')}\n/*]]>*/"
259
+ else
260
+ $1
261
+ end
261
262
  end
262
263
  end
263
264
  end
264
- rescue LoadError
265
- ensure
265
+
266
266
  if String === data
267
267
  @node.children << data
268
268
  else
@@ -284,11 +284,13 @@ module Wunderbar
284
284
  children.pop if children.last.text? and children.last.text.strip.empty?
285
285
  end
286
286
 
287
- children.each do |child|
287
+ children.map do |child|
288
288
  if child.text? or child.cdata?
289
289
  text = child.text
290
- if text.strip.empty?
291
- text! "\n" if text.count("\n")>1
290
+ if not @indentation_enabled
291
+ text! text
292
+ elsif text.strip.empty?
293
+ text! "" if text.count("\n")>1
292
294
  else
293
295
  indented_text! text
294
296
  end
@@ -328,6 +330,17 @@ module Wunderbar
328
330
  tag!(child, child.text.strip)
329
331
  elsif child.children.any?(&:cdata?) and child.text =~ /[<&]/
330
332
  self << child
333
+ elsif child.name == 'pre'
334
+ compact!(nil) { tag!(child) {self[*child.children]} }
335
+ elsif child.name == 'head'
336
+ head = tag!(child) {self[*child.children]}
337
+ html = @doc.children.last
338
+ if html.name == :html
339
+ head.parent.children.pop
340
+ html.children.unshift head
341
+ head.parent = html
342
+ end
343
+ head
331
344
  else
332
345
  tag!(child) {self[*child.children]}
333
346
  end
@@ -0,0 +1,44 @@
1
+ require 'wunderbar'
2
+ require 'coderay'
3
+ require 'nokogiri'
4
+
5
+ # workaround for https://github.com/rubychan/coderay/pull/159
6
+ module CodeRay::PluginHost
7
+ alias_method :old_plugin_path, :plugin_path
8
+ def plugin_path *args
9
+ args.first.untaint if args.first == CodeRay::CODERAY_PATH
10
+ old_plugin_path *args
11
+ end
12
+ end
13
+
14
+ module Wunderbar
15
+ class HtmlMarkup
16
+ def _coderay(*args)
17
+
18
+ # allow arguments in any order, disambiguate based on type
19
+ lang, string, attrs = :ruby, '', {}
20
+ args.each do |arg|
21
+ case arg
22
+ when Symbol; lang = arg
23
+ when String; string = arg
24
+ when Hash; attrs = arg
25
+ end
26
+ end
27
+
28
+ base = _{ CodeRay.scan(CDATANode.normalize(string), lang).div }
29
+
30
+ # remove wrapping divs
31
+ while base.length == 1 and base.first.name == 'div'
32
+ div = base.first.parent.children.pop
33
+ div.children.each {|child| child.parent = base.first.parent}
34
+ base.first.parent.children += base.first.children
35
+ base = div.children
36
+ end
37
+
38
+ # add attrs provided to pre element
39
+ if base.length == 1 and base.first.name == 'pre'
40
+ base.first.attrs.merge! attrs
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,10 @@
1
+ require 'wunderbar'
2
+ require 'coffee-script'
3
+
4
+ module Wunderbar
5
+ class HtmlMarkup
6
+ def _coffeescript(text)
7
+ _script CoffeeScript.compile(text)
8
+ end
9
+ end
10
+ end
@@ -16,8 +16,9 @@ module Wunderbar
16
16
  def method_missing(id_or_class, *args, &block)
17
17
  empty = args.empty?
18
18
  attrs = @node.attrs
19
+ id_or_class = id_or_class.to_s.gsub('_', '-')
19
20
 
20
- if id_or_class.to_s =~ /(.*)!$/
21
+ if id_or_class =~ /(.*)!$/
21
22
  attrs[:id] = $1
22
23
  elsif attrs[:class]
23
24
  attrs[:class] = "#{attrs[:class]} #{id_or_class}"
@@ -34,6 +35,8 @@ module Wunderbar
34
35
  @builder.proxiable_tag! @node.name, *args
35
36
  elsif SpacedNode === @node
36
37
  @builder.__send__ "_#{@node.name}_", *args, &block
38
+ elsif CompactNode === @node and @node.name != :pre
39
+ @builder.__send__ "_#{@node.name}!", *args, &block
37
40
  else
38
41
  @builder.__send__ "_#{@node.name}", *args, &block
39
42
  end
@@ -43,23 +43,8 @@ module Wunderbar
43
43
  def self.templates
44
44
  @@templates
45
45
  end
46
- end
47
46
 
48
- require 'socket'
49
- $SERVER = ENV['HTTP_HOST'] || Socket::gethostname
50
-
51
- # set encoding to UTF-8
52
- ENV['LANG'] ||= "en_US.UTF-8"
53
- if defined? Encoding
54
- Encoding.default_external = Encoding::UTF_8
55
- Encoding.default_internal = Encoding::UTF_8
56
- else
57
- $KCODE = 'U'
58
- end
59
-
60
- # Add methods to the 'main' object
61
- if self.to_s == 'main'
62
- class << self
47
+ module API
63
48
  def _html(*args, &block)
64
49
  Wunderbar.html(*args, &block)
65
50
  end
@@ -84,6 +69,25 @@ if self.to_s == 'main'
84
69
  def _template(name, &block)
85
70
  Wunderbar.templates[name.to_s.gsub('_','-')] = block
86
71
  end
72
+ end
73
+ end
74
+
75
+ require 'socket'
76
+ $SERVER = ENV['HTTP_HOST'] || Socket::gethostname
77
+
78
+ # set encoding to UTF-8
79
+ ENV['LANG'] ||= "en_US.UTF-8"
80
+ if defined? Encoding
81
+ Encoding.default_external = Encoding::UTF_8
82
+ Encoding.default_internal = Encoding::UTF_8
83
+ else
84
+ $KCODE = 'U'
85
+ end
86
+
87
+ # Add methods to the 'main' object
88
+ if self.to_s == 'main'
89
+ class << self
90
+ include Wunderbar::API
87
91
 
88
92
  def env
89
93
  ENV
@@ -110,6 +110,11 @@ module Wunderbar
110
110
  head.add_child Node.new('title', h1.text) if h1 and h1.text
111
111
  end
112
112
 
113
+ title = head.children.index {|child| child.name == 'title'}
114
+ if title and title > 1
115
+ head.children.insert 1, head.children.delete_at(title)
116
+ end
117
+
113
118
  bom + @x.target!
114
119
  end
115
120
 
@@ -261,7 +266,7 @@ module Wunderbar
261
266
 
262
267
  def _pre(*args, &block)
263
268
  args.first.chomp! if String === args.first and args.first.end_with? "\n"
264
- @x.compact!(@_width) { tag! :pre, *args, &block }
269
+ @x.compact!(nil) { tag! :pre, *args, &block }
265
270
  end
266
271
 
267
272
  def _ul(*args, &block)
@@ -315,14 +320,35 @@ module Wunderbar
315
320
  if String === children
316
321
  safe = !children.tainted?
317
322
  safe ||= children.html_safe? if children.respond_to? :html_safe?
323
+ safe &&= defined? Nokogiri
318
324
 
319
325
  if safe and (children.include? '<' or children.include? '&')
320
- require 'nokogiri'
321
- children = Nokogiri::HTML::fragment(children.to_s).children
326
+ children = Nokogiri::HTML::fragment(children.to_s).children.to_a
327
+
328
+ # ignore leading whitespace
329
+ while not children.empty? and children.first.text?
330
+ break unless children.first.text.strip.empty?
331
+ children.shift
332
+ end
333
+
334
+ # gather up candidate head elements
335
+ pending_head = []
336
+ while not children.empty? and children.first.element?
337
+ break unless (HEAD+['script']).include? children.first.name
338
+ pending_head << children.shift
339
+ end
340
+
341
+ # rebuild head element if any candidates were found
342
+ unless pending_head.empty?
343
+ head = Nokogiri::XML::Node.new('head', pending_head.first.document)
344
+ pending_head.each {|child| head << child}
345
+ children.unshift head
346
+ end
322
347
  else
323
348
  return @x.indented_text! children
324
349
  end
325
350
  end
351
+
326
352
  @x[*children]
327
353
  end
328
354
 
@@ -335,13 +361,6 @@ module Wunderbar
335
361
  end
336
362
  end
337
363
 
338
- def _coffeescript(text)
339
- require 'coffee-script'
340
- _script CoffeeScript.compile(text)
341
- rescue LoadError
342
- _script text, :lang => 'text/coffeescript'
343
- end
344
-
345
364
  def clear!
346
365
  @x.clear!
347
366
  end
@@ -1,5 +1,10 @@
1
1
  require 'wunderbar'
2
2
 
3
+ begin
4
+ require 'ruby2js/filter/jquery'
5
+ rescue LoadError
6
+ end
7
+
3
8
  source = Dir[File.expand_path('../jquery-*.min.js', __FILE__)].
4
9
  sort_by {|name| name[/-([.\d]*)\.min.js$/,1].split('.').map(&:to_i)}.last
5
10
 
@@ -0,0 +1,11 @@
1
+ require 'wunderbar'
2
+ require 'kramdown'
3
+ require 'nokogiri'
4
+
5
+ module Wunderbar
6
+ class HtmlMarkup
7
+ def _markdown(string)
8
+ _{ Kramdown::Document.new(CDATANode.normalize(string)).to_html }
9
+ end
10
+ end
11
+ end
@@ -88,7 +88,7 @@ module Wunderbar
88
88
  (work+["</#{name}>"]).each do |node|
89
89
  if line.length + node.length > @width
90
90
  result << line.rstrip
91
- line = indent
91
+ line = indent.to_s
92
92
  end
93
93
  line += node
94
94
  end
@@ -132,7 +132,7 @@ module Wunderbar
132
132
  end
133
133
 
134
134
  class CDATANode < Node
135
- def self.normalize(data, indent)
135
+ def self.normalize(data, indent='')
136
136
  data = data.sub(/\n\s*\Z/, '').sub(/\A\s*\n/, '')
137
137
 
138
138
  unindent = data.sub(/s+\Z/,'').scan(/^ *\S/).map(&:length).min || 0
@@ -1,3 +1,6 @@
1
+ require 'wunderbar'
2
+ require 'rack'
3
+
1
4
  module Wunderbar
2
5
  class RackApp
3
6
  # entry point for Rack
@@ -42,3 +45,12 @@ module Wunderbar
42
45
  end
43
46
  end
44
47
  end
48
+
49
+ class Rack::Builder
50
+ include Wunderbar::API
51
+
52
+ def _app
53
+ Wunderbar::RackApp.new
54
+ end
55
+ end
56
+
@@ -0,0 +1,74 @@
1
+ require 'wunderbar'
2
+ require 'ruby2js'
3
+
4
+ # convert script blocks to JavaScript. If binding_of_caller is available,
5
+ # full access to all variables defined in the callers scope may be made
6
+ # by execute strings (`` or %x()).
7
+
8
+ module Wunderbar
9
+ class HtmlMarkup
10
+ def _script(*args, &block)
11
+ if block
12
+ if binding.respond_to? :of_caller
13
+ # provided by require 'binding_of_caller'
14
+ args.unshift Ruby2JS.convert(block, binding: binding.of_caller(1))
15
+ else
16
+ args.unshift Ruby2JS.convert(block, binding: binding)
17
+ end
18
+ super *args, &nil
19
+ else
20
+ super
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ module Wunderbar
27
+ module API
28
+ def _js(*args, &block)
29
+ Wunderbar.ruby2js(*args, &block)
30
+ end
31
+ end
32
+
33
+ def self.ruby2js(*args, &block)
34
+ callback = Proc.new do |scope, args, block|
35
+ ruby2js(scope, *args, &block)
36
+ end
37
+ @queue << [callback, args, block]
38
+ end
39
+
40
+ class CGI
41
+ def ruby2js(scope, *args, &block)
42
+ headers = { 'type' => 'application/javascript', 'charset' => 'UTF-8' }
43
+
44
+ begin
45
+ output = Ruby2JS.convert(block) + "\n"
46
+ rescue ::Exception => exception
47
+ headers['status'] = "500 Internal Server Error"
48
+ output = "// Internal Server Error\n#{exception}\n"
49
+ end
50
+
51
+ out?(scope, headers) { output }
52
+ end
53
+ end
54
+
55
+ module Template
56
+ module Js
57
+ def self.ext; :_js; end
58
+ def self.mime; 'application/javascript'; end
59
+
60
+ def evaluate(scope, locals, &block)
61
+ scope.content_type self.class.default_mime_type, charset: 'utf-8'
62
+ begin
63
+ Ruby2JS.convert(data)
64
+ rescue Exception => exception
65
+ scope.response.status = 500
66
+ "// Internal Server Error\n#{exception}\n"
67
+ end
68
+ end
69
+ end
70
+
71
+ register Js if respond_to? :register
72
+ end
73
+ end
74
+
@@ -14,21 +14,22 @@ end
14
14
 
15
15
  port = ARGV.find {|arg| arg =~ /--port=(.*)/}
16
16
  if port and ARGV.delete(port)
17
- port = $1.to_i
18
- ENV['SERVER_PORT'] = port.to_s
17
+ ENV['SERVER_PORT'] = port.split('=').last
19
18
 
20
19
  # Evaluate optional data from the script (after __END__)
21
20
  eval Wunderbar.data if Object.const_defined? :DATA
22
21
 
23
22
  # Allow optional environment override
24
23
  environment = ARGV.find {|arg| arg =~ /--environment=(.*)/}
25
- ENV['RACK_ENV'] = environment if environment and ARGV.delete(environment)
24
+ if environment and ARGV.delete(environment)
25
+ ENV['RACK_ENV'] = environment.split('=').last
26
+ end
26
27
 
27
28
  at_exit do
28
29
  # start the server
29
- require 'rack'
30
30
  require 'wunderbar/rack'
31
31
 
32
+ # whenever reloading adds to the queue, cull old entries
32
33
  class QueueCleanup
33
34
  def initialize(app)
34
35
  @app = app
@@ -44,10 +45,15 @@ if port and ARGV.delete(port)
44
45
  end
45
46
  end
46
47
 
47
- app = Rack::Lock.new(Wunderbar::RackApp.new)
48
- app = Rack::Reloader.new(QueueCleanup.new(app), 0)
49
- Rack::Server.start :app => app, :Port => port,
50
- :environment => (ENV['RACK_ENV'] || 'development')
48
+ # avoid Ruby 1.9.3 bug if var names match those used to extract from ARGV
49
+ app_port = ENV['SERVER_PORT'].to_i
50
+ app_env = (ENV['RACK_ENV'] || 'development')
51
+
52
+ app = Wunderbar::RackApp.new
53
+ app = QueueCleanup.new(app)
54
+ app = Rack::Reloader.new(app, 0) if app_env == 'development'
55
+
56
+ Rack::Handler.default.run app, environment: app_env, Port: app_port
51
57
  end
52
58
 
53
59
  elsif defined? Sinatra
@@ -58,6 +64,10 @@ elsif defined? ActionView::Template
58
64
 
59
65
  require 'wunderbar/rails'
60
66
 
67
+ elsif defined? Rack
68
+
69
+ require 'wunderbar/rack'
70
+
61
71
  else
62
72
 
63
73
  require 'etc'
@@ -3,7 +3,38 @@ require 'wunderbar'
3
3
  require 'digest/md5'
4
4
  require 'nokogiri'
5
5
 
6
+ begin
7
+ require "sinatra/reloader" if development? # gem install sinatra-contrib
8
+ rescue LoadError
9
+ end
10
+
6
11
  module Wunderbar
12
+ module SinatraHelpers
13
+ def _html(*args, &block)
14
+ if block
15
+ Wunderbar::Template::Html.evaluate('_html', self) do
16
+ _html(*args) { instance_eval &block }
17
+ end
18
+ else
19
+ Wunderbar::Template::Html.evaluate('_html', self, *args)
20
+ end
21
+ end
22
+
23
+ def _xhtml(*args, &block)
24
+ if env['HTTP_ACCEPT'] and not env['HTTP_ACCEPT'].include? 'xhtml'
25
+ return _html(*args, &block)
26
+ end
27
+
28
+ if block
29
+ Wunderbar::Template::Xhtml.evaluate('_xhtml', self) do
30
+ _xhtml(*args) { instance_eval &block }
31
+ end
32
+ else
33
+ Wunderbar::Template::Xhtml.evaluate('_xhtml', self, *args)
34
+ end
35
+ end
36
+ end
37
+
7
38
  # Tilt template implementation
8
39
  module Template
9
40
  class Base < Tilt::Template
@@ -90,8 +121,9 @@ module Wunderbar
90
121
  self.default_mime_type = 'application/xhtml+xml'
91
122
  end
92
123
 
93
- class Json < Base
94
- self.default_mime_type = 'application/json'
124
+ module Json
125
+ def self.ext; :_json; end
126
+ def self.mime; 'application/json'; end
95
127
 
96
128
  def evaluate(scope, locals, &block)
97
129
  builder = JsonBuilder.new(scope)
@@ -106,8 +138,9 @@ module Wunderbar
106
138
  end
107
139
  end
108
140
 
109
- class Text < Base
110
- self.default_mime_type = 'text/plain'
141
+ module Text
142
+ def self.ext; :_text; end
143
+ def self.mime; 'text/plain'; end
111
144
 
112
145
  def evaluate(scope, locals, &block)
113
146
  builder = TextBuilder.new(scope)
@@ -122,47 +155,29 @@ module Wunderbar
122
155
  builder.target!
123
156
  end
124
157
  end
125
- end
126
158
 
127
- module SinatraHelpers
128
- def _html(*args, &block)
129
- if block
130
- Wunderbar::Template::Html.evaluate('_html', self) do
131
- _html(*args) { instance_eval &block }
132
- end
133
- else
134
- Wunderbar::Template::Html.evaluate('_html', self, *args)
159
+ def self.register(language, base=Base)
160
+ template = Class.new(Template::Base) do
161
+ self.default_mime_type = language.mime
162
+ include language
135
163
  end
136
- end
137
164
 
138
- def _xhtml(*args, &block)
139
- if env['HTTP_ACCEPT'] and not env['HTTP_ACCEPT'].include? 'xhtml'
140
- return _html(*args, &block)
141
- end
142
-
143
- if block
144
- Wunderbar::Template::Xhtml.evaluate('_xhtml', self) do
145
- _xhtml(*args) { instance_eval &block }
146
- end
147
- else
148
- Wunderbar::Template::Xhtml.evaluate('_xhtml', self, *args)
165
+ SinatraHelpers.send :define_method, language.ext do |*args, &block|
166
+ template.evaluate(language.ext, self, *args, &block)
149
167
  end
150
- end
151
168
 
152
- def _json(*args, &block)
153
- Wunderbar::Template::Json.evaluate('_json', self, *args, &block)
169
+ Tilt.register language.ext.to_s, template
154
170
  end
155
171
 
156
- def _text(*args, &block)
157
- Wunderbar::Template::Text.evaluate('_text', self, *args, &block)
172
+ constants.each do |language|
173
+ language = const_get(language)
174
+ register language if language.respond_to? :mime
158
175
  end
159
176
  end
160
177
  end
161
178
 
162
179
  Tilt.register '_html', Wunderbar::Template::Html
163
180
  Tilt.register '_xhtml', Wunderbar::Template::Xhtml
164
- Tilt.register '_json', Wunderbar::Template::Json
165
- Tilt.register '_text', Wunderbar::Template::Text
166
181
 
167
182
  helpers Wunderbar::SinatraHelpers
168
183
 
@@ -2,7 +2,7 @@ module Wunderbar
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 18
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
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.18.2"
5
+ s.version = "0.18.3"
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 = "2013-11-12"
9
+ s.date = "2013-12-01"
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", "lib/wunderbar/asset.rb", "lib/wunderbar/environment.rb", "lib/wunderbar/angular.min.js", "lib/wunderbar/installation.rb", "lib/wunderbar/websocket.rb", "lib/wunderbar/opal.rb", "lib/wunderbar/jquery.rb", "lib/wunderbar/sinatra.rb", "lib/wunderbar/node.rb", "lib/wunderbar/polymer-v0.0.20131003.min.js", "lib/wunderbar/opal-jquery.rb", "lib/wunderbar/angularjs.rb", "lib/wunderbar/logger.rb", "lib/wunderbar/job-control.rb", "lib/wunderbar/rack.rb", "lib/wunderbar/polymer.rb", "lib/wunderbar/cgi-methods.rb", "lib/wunderbar/cssproxy.rb", "lib/wunderbar/version.rb", "lib/wunderbar/jquery-1.10.2.min.js", "lib/wunderbar/html-methods.rb", "lib/wunderbar/rails.rb", "lib/wunderbar/opal-browser.rb", "lib/wunderbar/builder.rb", "lib/wunderbar/server.rb", "lib/wunderbar.rb"]
12
+ s.files = ["wunderbar.gemspec", "README.md", "COPYING", "lib/wunderbar", "lib/wunderbar/asset.rb", "lib/wunderbar/script.rb", "lib/wunderbar/environment.rb", "lib/wunderbar/angular.min.js", "lib/wunderbar/angular-route.min.js", "lib/wunderbar/installation.rb", "lib/wunderbar/websocket.rb", "lib/wunderbar/opal.rb", "lib/wunderbar/angular-route.rb", "lib/wunderbar/coffeescript.rb", "lib/wunderbar/jquery.rb", "lib/wunderbar/sinatra.rb", "lib/wunderbar/node.rb", "lib/wunderbar/polymer-v0.0.20131003.min.js", "lib/wunderbar/opal-jquery.rb", "lib/wunderbar/angularjs.rb", "lib/wunderbar/logger.rb", "lib/wunderbar/job-control.rb", "lib/wunderbar/rack.rb", "lib/wunderbar/polymer.rb", "lib/wunderbar/cgi-methods.rb", "lib/wunderbar/cssproxy.rb", "lib/wunderbar/version.rb", "lib/wunderbar/coderay.rb", "lib/wunderbar/jquery-1.10.2.min.js", "lib/wunderbar/html-methods.rb", "lib/wunderbar/rails.rb", "lib/wunderbar/opal-browser.rb", "lib/wunderbar/angular-resource.rb", "lib/wunderbar/builder.rb", "lib/wunderbar/markdown.rb", "lib/wunderbar/server.rb", "lib/wunderbar/angular-resource.min.js", "lib/wunderbar.rb"]
13
13
  s.homepage = "http://github.com/rubys/wunderbar"
14
14
  s.licenses = ["MIT"]
15
15
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wunderbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.18.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-12 00:00:00.000000000 Z
12
+ date: 2013-12-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &14226580 !ruby/object:Gem::Requirement
16
+ requirement: &11779760 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *14226580
24
+ version_requirements: *11779760
25
25
  description: ! " Wunderbar makes it easy to produce valid HTML5, wellformed XHTML,
26
26
  Unicode\n (utf-8), consistently indented, readable applications. This includes\n
27
27
  \ output that conforms to the Polyglot specification and the emerging\n results
@@ -35,11 +35,15 @@ files:
35
35
  - README.md
36
36
  - COPYING
37
37
  - lib/wunderbar/asset.rb
38
+ - lib/wunderbar/script.rb
38
39
  - lib/wunderbar/environment.rb
39
40
  - lib/wunderbar/angular.min.js
41
+ - lib/wunderbar/angular-route.min.js
40
42
  - lib/wunderbar/installation.rb
41
43
  - lib/wunderbar/websocket.rb
42
44
  - lib/wunderbar/opal.rb
45
+ - lib/wunderbar/angular-route.rb
46
+ - lib/wunderbar/coffeescript.rb
43
47
  - lib/wunderbar/jquery.rb
44
48
  - lib/wunderbar/sinatra.rb
45
49
  - lib/wunderbar/node.rb
@@ -53,12 +57,16 @@ files:
53
57
  - lib/wunderbar/cgi-methods.rb
54
58
  - lib/wunderbar/cssproxy.rb
55
59
  - lib/wunderbar/version.rb
60
+ - lib/wunderbar/coderay.rb
56
61
  - lib/wunderbar/jquery-1.10.2.min.js
57
62
  - lib/wunderbar/html-methods.rb
58
63
  - lib/wunderbar/rails.rb
59
64
  - lib/wunderbar/opal-browser.rb
65
+ - lib/wunderbar/angular-resource.rb
60
66
  - lib/wunderbar/builder.rb
67
+ - lib/wunderbar/markdown.rb
61
68
  - lib/wunderbar/server.rb
69
+ - lib/wunderbar/angular-resource.min.js
62
70
  - lib/wunderbar.rb
63
71
  homepage: http://github.com/rubys/wunderbar
64
72
  licenses: