wunderbar 0.18.2 → 0.18.3

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.
@@ -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: