wunderbar 0.18.2 → 0.18.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/wunderbar/angular-resource.min.js +12 -0
- data/lib/wunderbar/angular-resource.rb +6 -0
- data/lib/wunderbar/angular-route.min.js +14 -0
- data/lib/wunderbar/angular-route.rb +6 -0
- data/lib/wunderbar/angularjs.rb +1 -15
- data/lib/wunderbar/builder.rb +35 -22
- data/lib/wunderbar/coderay.rb +44 -0
- data/lib/wunderbar/coffeescript.rb +10 -0
- data/lib/wunderbar/cssproxy.rb +4 -1
- data/lib/wunderbar/environment.rb +20 -16
- data/lib/wunderbar/html-methods.rb +29 -10
- data/lib/wunderbar/jquery.rb +5 -0
- data/lib/wunderbar/markdown.rb +11 -0
- data/lib/wunderbar/node.rb +2 -2
- data/lib/wunderbar/rack.rb +12 -0
- data/lib/wunderbar/script.rb +74 -0
- data/lib/wunderbar/server.rb +18 -8
- data/lib/wunderbar/sinatra.rb +47 -32
- data/lib/wunderbar/version.rb +1 -1
- data/wunderbar.gemspec +3 -3
- metadata +12 -4
@@ -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,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
|
data/lib/wunderbar/angularjs.rb
CHANGED
@@ -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
|
data/lib/wunderbar/builder.rb
CHANGED
@@ -239,30 +239,30 @@ module Wunderbar
|
|
239
239
|
|
240
240
|
# insert verbatim
|
241
241
|
def <<(data)
|
242
|
-
if
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
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
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
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
|
-
|
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.
|
287
|
+
children.map do |child|
|
288
288
|
if child.text? or child.cdata?
|
289
289
|
text = child.text
|
290
|
-
if
|
291
|
-
text!
|
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
|
data/lib/wunderbar/cssproxy.rb
CHANGED
@@ -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
|
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
|
-
|
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!(
|
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
|
-
|
321
|
-
|
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
|
data/lib/wunderbar/jquery.rb
CHANGED
data/lib/wunderbar/node.rb
CHANGED
@@ -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
|
data/lib/wunderbar/rack.rb
CHANGED
@@ -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
|
+
|
data/lib/wunderbar/server.rb
CHANGED
@@ -14,21 +14,22 @@ end
|
|
14
14
|
|
15
15
|
port = ARGV.find {|arg| arg =~ /--port=(.*)/}
|
16
16
|
if port and ARGV.delete(port)
|
17
|
-
|
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
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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'
|
data/lib/wunderbar/sinatra.rb
CHANGED
@@ -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
|
-
|
94
|
-
self.
|
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
|
-
|
110
|
-
self.
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
-
|
139
|
-
|
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
|
-
|
153
|
-
Wunderbar::Template::Json.evaluate('_json', self, *args, &block)
|
169
|
+
Tilt.register language.ext.to_s, template
|
154
170
|
end
|
155
171
|
|
156
|
-
|
157
|
-
|
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
|
|
data/lib/wunderbar/version.rb
CHANGED
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.
|
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-
|
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.
|
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-
|
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: &
|
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: *
|
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:
|