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