wunderbar 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -21
- data/lib/wunderbar/asset.rb +5 -5
- data/lib/wunderbar/builder.rb +18 -6
- data/lib/wunderbar/cgi-methods.rb +1 -1
- data/lib/wunderbar/coderay.rb +0 -9
- data/lib/wunderbar/environment.rb +10 -34
- data/lib/wunderbar/html-methods.rb +5 -16
- data/lib/wunderbar/job-control.rb +1 -1
- data/lib/wunderbar/rack.rb +14 -2
- data/lib/wunderbar/rails.rb +2 -2
- data/lib/wunderbar/react.rb +6 -14
- data/lib/wunderbar/render.rb +6 -8
- data/lib/wunderbar/sinatra.rb +6 -15
- data/lib/wunderbar/version.rb +1 -1
- data/lib/wunderbar/vue.rb +17 -4
- data/wunderbar.gemspec +6 -4
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01faf4f44e9f567cf1ab080f8f4a54879c0eb6b5d07e0ad6d265ede2cbd4b86f
|
4
|
+
data.tar.gz: a0db8a63944a68305a337a1eb5cef8114f5f88034e7a9c451cd37228ad97bc40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d104318bd2e0e2ee9cd721c3b49790ede15b4459dbe253bc58b9108b6fc91fcb077e932a399b9194417a5dc31c62500684db424db534b4b72c1c709e2defedc1
|
7
|
+
data.tar.gz: e2d9ca6b2bec1fdb12a253e1ca9df2f73296388c60ee2b165c63305216a353fc0fe37e3ede10c48b6524b7391e060230ca53fa8f393b4d24b957f225da3363a2
|
data/README.md
CHANGED
@@ -366,26 +366,7 @@ Secure by default
|
|
366
366
|
|
367
367
|
Wunderbar will properly escape all HTML and JSON output, eliminating problems
|
368
368
|
of HTML or JavaScript injection. This includes calls to `_` to insert text
|
369
|
-
directly.
|
370
|
-
dependencies](#optional-dependencies) below), calls to insert markup
|
371
|
-
(`_{...}`) will escape the markup if the input is `tainted` and not explicitly
|
372
|
-
marked as `html-safe?` (when using Rails).
|
373
|
-
|
374
|
-
For Ruby version < 2.6.0:
|
375
|
-
|
376
|
-
> For all environments other than Rails, unless you call `Wunderbar.unsafe!` at
|
377
|
-
> the top of your script, Wunderbar will also set
|
378
|
-
> [`$SAFE=1`](http://www.ruby-doc.org/docs/ProgrammingRuby/html/taint.html)
|
379
|
-
> before processing requests. This means that you will need to
|
380
|
-
> [`untaint`](ruby-doc.org/core/Object.html#method-i-untaint) all inputs
|
381
|
-
> received from external sources before you make system calls or access the file
|
382
|
-
> system.
|
383
|
-
|
384
|
-
A special feature that effectively is only available in the Rails environment:
|
385
|
-
if the first argument to call that creates an element is `html_safe?`, then
|
386
|
-
that argument will be treated as a markup instead of as text. This allows one
|
387
|
-
to make calls like `_td link_to...` without placing the call to `link_to` in a
|
388
|
-
block.
|
369
|
+
directly.
|
389
370
|
|
390
371
|
Globals provided
|
391
372
|
---
|
@@ -454,7 +435,6 @@ The following gems, if installed, will produce cleaner and prettier output:
|
|
454
435
|
* `nokogumbo` also cleans up HTML fragments inserted via `<<` and `_{}`. If
|
455
436
|
this gem is available, it will be preferred over direct usage of `nokogiri`.
|
456
437
|
* `escape` prettier quoting of `system` commands
|
457
|
-
* `sanitize` will remove unsafe markup from tainted input
|
458
438
|
|
459
439
|
Related efforts
|
460
440
|
---
|
data/lib/wunderbar/asset.rb
CHANGED
@@ -30,14 +30,14 @@ module Wunderbar
|
|
30
30
|
return @path if @path or @contents
|
31
31
|
|
32
32
|
if @options[:name]
|
33
|
-
source =
|
33
|
+
source = @options[:file] || __FILE__
|
34
34
|
@mtime = File.mtime(source)
|
35
35
|
@path = @options[:name]
|
36
36
|
|
37
37
|
# look for asset in site
|
38
38
|
if ENV['DOCUMENT_ROOT']
|
39
|
-
root = File.join(ENV['DOCUMENT_ROOT'], 'assets')
|
40
|
-
dest = File.expand_path(@path, root)
|
39
|
+
root = File.join(ENV['DOCUMENT_ROOT'], 'assets')
|
40
|
+
dest = File.expand_path(@path, root)
|
41
41
|
if File.exist?(dest) and File.size(dest) == File.size(source)
|
42
42
|
@path = "/assets/#{@path}"
|
43
43
|
return @path
|
@@ -45,7 +45,7 @@ module Wunderbar
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# look for asset in app
|
48
|
-
dest = File.expand_path(@path, Asset.root)
|
48
|
+
dest = File.expand_path(@path, Asset.root)
|
49
49
|
if File.exist?(dest) and File.size(dest) == File.size(source)
|
50
50
|
return @path
|
51
51
|
end
|
@@ -103,7 +103,7 @@ module Wunderbar
|
|
103
103
|
@path = '../' * env['PATH_INFO'].to_s.count('/') + 'assets'
|
104
104
|
@root ||= nil
|
105
105
|
@root = File.dirname(env['SCRIPT_FILENAME']) if env['SCRIPT_FILENAME']
|
106
|
-
@root = File.expand_path((@root || Dir.pwd) + "/assets")
|
106
|
+
@root = File.expand_path((@root || Dir.pwd) + "/assets")
|
107
107
|
|
108
108
|
# Options: typically :name plus either :file or :contents
|
109
109
|
# :name => name to be used for the asset
|
data/lib/wunderbar/builder.rb
CHANGED
@@ -51,14 +51,14 @@ module Wunderbar
|
|
51
51
|
secret = command - flat
|
52
52
|
begin
|
53
53
|
# if available, use escape as it does prettier quoting
|
54
|
-
raise LoadError if
|
54
|
+
raise LoadError if not defined? Escape
|
55
55
|
require 'escape'
|
56
56
|
echo = Escape.shell_command(command.compact - secret)
|
57
57
|
rescue LoadError
|
58
58
|
# std-lib function that gets the job done
|
59
59
|
echo = Shellwords.join(command.compact - secret)
|
60
60
|
end
|
61
|
-
command = flat.compact
|
61
|
+
command = flat.compact
|
62
62
|
else
|
63
63
|
echo = command
|
64
64
|
command = [command]
|
@@ -461,8 +461,14 @@ module Wunderbar
|
|
461
461
|
output_prefix = opts[:prefix] || {}
|
462
462
|
output_prefix[:stdin] ||= '$ '
|
463
463
|
|
464
|
-
|
465
|
-
|
464
|
+
if Hash === args.last # support original code which needed two hashes
|
465
|
+
super do |kind, line|
|
466
|
+
@_target.puts "#{output_prefix[kind]}#{line}"
|
467
|
+
end
|
468
|
+
else
|
469
|
+
super(*args, opts) do |kind, line|
|
470
|
+
@_target.puts "#{output_prefix[kind]}#{line}"
|
471
|
+
end
|
466
472
|
end
|
467
473
|
end
|
468
474
|
|
@@ -587,8 +593,14 @@ module Wunderbar
|
|
587
593
|
@_target[transcript] = []
|
588
594
|
end
|
589
595
|
|
590
|
-
|
591
|
-
|
596
|
+
if Hash === args.last # support original code which needed two hashes
|
597
|
+
super do |kind, line|
|
598
|
+
@_target[transcript] << "#{output_prefix[kind]}#{line}"
|
599
|
+
end
|
600
|
+
else
|
601
|
+
super(*args, opts) do |kind, line|
|
602
|
+
@_target[transcript] << "#{output_prefix[kind]}#{line}"
|
603
|
+
end
|
592
604
|
end
|
593
605
|
end
|
594
606
|
|
@@ -120,7 +120,7 @@ module Wunderbar
|
|
120
120
|
# asset support for Rack
|
121
121
|
request = (scope.respond_to? :request) ? scope.request : nil
|
122
122
|
if request and request.path =~ %r{/assets/\w[-.\w]+}
|
123
|
-
path =
|
123
|
+
path = '.' + scope.request.path
|
124
124
|
headers = {'type' => 'text/plain'}
|
125
125
|
headers['type'] = 'application/javascript' if path =~ /\.js$/
|
126
126
|
out?(scope, headers) { File.read path if File.exist? path }
|
data/lib/wunderbar/coderay.rb
CHANGED
@@ -2,15 +2,6 @@ require 'wunderbar'
|
|
2
2
|
require 'coderay'
|
3
3
|
require 'nokogiri'
|
4
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
5
|
module Wunderbar
|
15
6
|
class HtmlMarkup
|
16
7
|
def _coderay(*args)
|
@@ -5,40 +5,6 @@ module Wunderbar
|
|
5
5
|
TEXT = ARGV.delete('--text')
|
6
6
|
end
|
7
7
|
|
8
|
-
# Ruby 2.6.0 gets rid of $SAFE > 1; unfortunately in the process it
|
9
|
-
# treats $SAFE = 1 as a higher level; @FAFE = 1 no longer is limited
|
10
|
-
# to taintness checks, it not treats all File operations as unsafe
|
11
|
-
@@unsafe = (RUBY_VERSION.split('.').map(&:to_i) <=> [2, 6, 0]) == 1
|
12
|
-
|
13
|
-
def self.unsafe!(mode=true)
|
14
|
-
@@unsafe=mode
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.safe?
|
18
|
-
if $SAFE == 0 and not @@unsafe
|
19
|
-
# some gems (e.g. em-websocket-0.3.6) insert unsafe entries into the
|
20
|
-
# path, and that prevents requires from succeeding. If it looks like
|
21
|
-
# we are about to make a transition to $SAFE=1, clean up that mess
|
22
|
-
# before proceeding.
|
23
|
-
#
|
24
|
-
# the goal of $SAFE is not to protect us against software which was
|
25
|
-
# installed by the owner of the site, but from injection attacks
|
26
|
-
# contained within data provided by users of the site.
|
27
|
-
$:.each_with_index do |path, index|
|
28
|
-
if path.tainted?
|
29
|
-
$:[index] = File.expand_path(path.dup.untaint).untaint
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# avoid: "Insecure PATH - (SecurityError)" when using Bundler
|
34
|
-
if defined? Bundler
|
35
|
-
ENV['PATH'] = ENV['PATH'].dup.untaint
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
not @@unsafe
|
40
|
-
end
|
41
|
-
|
42
8
|
class Scope
|
43
9
|
attr_accessor :env
|
44
10
|
def initialize(env)
|
@@ -47,11 +13,16 @@ module Wunderbar
|
|
47
13
|
end
|
48
14
|
|
49
15
|
@@templates = {}
|
16
|
+
@@files = {}
|
50
17
|
|
51
18
|
def self.templates
|
52
19
|
@@templates
|
53
20
|
end
|
54
21
|
|
22
|
+
def self.files
|
23
|
+
@@files
|
24
|
+
end
|
25
|
+
|
55
26
|
module API
|
56
27
|
def _html(*args, &block)
|
57
28
|
Wunderbar.html(*args, &block)
|
@@ -77,6 +48,11 @@ module Wunderbar
|
|
77
48
|
def _template(name, &block)
|
78
49
|
Wunderbar.templates[name.to_s.gsub('_','-')] = block
|
79
50
|
end
|
51
|
+
|
52
|
+
def _file(name, options={}, &block)
|
53
|
+
options[:source] = block if block
|
54
|
+
Wunderbar.files[name] = options
|
55
|
+
end
|
80
56
|
end
|
81
57
|
|
82
58
|
#
|
@@ -133,7 +133,7 @@ module Wunderbar
|
|
133
133
|
# * Proxied Rack server. Document base may be relate to the
|
134
134
|
# HTTP_X_WUNDERBAR_BASE
|
135
135
|
#
|
136
|
-
cwd = File.realpath(Dir.pwd
|
136
|
+
cwd = File.realpath(Dir.pwd)
|
137
137
|
base = @_scope.env['DOCUMENT_ROOT'] if @_scope.env.respond_to? :[]
|
138
138
|
base ||= cwd
|
139
139
|
href = (head.children[1].attrs[:href] || '')
|
@@ -189,8 +189,8 @@ module Wunderbar
|
|
189
189
|
name = name.to_s.gsub('_', '-')
|
190
190
|
|
191
191
|
if flag != '!'
|
192
|
-
if String === args.first
|
193
|
-
if
|
192
|
+
if String === args.first
|
193
|
+
if not block and args.first =~ /[>&]/
|
194
194
|
markup = args.shift
|
195
195
|
block = Proc.new {_ {markup}}
|
196
196
|
end
|
@@ -362,11 +362,7 @@ module Wunderbar
|
|
362
362
|
def _(text=nil, &block)
|
363
363
|
unless block
|
364
364
|
if text
|
365
|
-
|
366
|
-
_ {text}
|
367
|
-
else
|
368
|
-
@_x.indented_text! text.to_s
|
369
|
-
end
|
365
|
+
_ {text}
|
370
366
|
end
|
371
367
|
return @_x
|
372
368
|
end
|
@@ -374,20 +370,13 @@ module Wunderbar
|
|
374
370
|
children = instance_eval(&block)
|
375
371
|
|
376
372
|
if String === children
|
377
|
-
|
378
|
-
safe ||= children.html_safe? if children.respond_to? :html_safe?
|
379
|
-
safe &&= defined? Nokogiri
|
380
|
-
ok = safe || defined? Sanitize
|
381
|
-
safe = true
|
382
|
-
|
383
|
-
if ok and (children.include? '<' or children.include? '&')
|
373
|
+
if children.include? '<' or children.include? '&'
|
384
374
|
if defined? Nokogiri::HTML5.fragment
|
385
375
|
doc = Nokogiri::HTML5.fragment(children.to_s)
|
386
376
|
else
|
387
377
|
doc = Nokogiri::HTML.fragment(children.to_s)
|
388
378
|
end
|
389
379
|
|
390
|
-
Sanitize.new.clean_node! doc.dup.untaint if not safe
|
391
380
|
children = doc.children.to_a
|
392
381
|
|
393
382
|
# ignore leading whitespace
|
@@ -25,7 +25,7 @@ module Wunderbar
|
|
25
25
|
# clear environment of cgi cruft
|
26
26
|
require 'cgi'
|
27
27
|
ENV.keys.select {|key| key =~ /^HTTP_/}.each do |key|
|
28
|
-
ENV.delete key
|
28
|
+
ENV.delete key
|
29
29
|
end
|
30
30
|
::CGI::QueryExtension.public_instance_methods.each do |method|
|
31
31
|
ENV.delete method.to_s.upcase
|
data/lib/wunderbar/rack.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'wunderbar'
|
2
2
|
require 'rack'
|
3
|
+
require 'rack/media_type'
|
3
4
|
|
4
5
|
module Wunderbar
|
5
6
|
class RackApp
|
@@ -9,8 +10,13 @@ module Wunderbar
|
|
9
10
|
@_request = Rack::Request.new(env)
|
10
11
|
@_response = Rack::Response.new
|
11
12
|
Wunderbar.logger = @_request.logger
|
12
|
-
|
13
|
-
|
13
|
+
file = Wunderbar.files[env['PATH_INFO']]
|
14
|
+
|
15
|
+
if file
|
16
|
+
mime = file[:mime] ||
|
17
|
+
Rack::Mime::MIME_TYPES[File.extname(env['PATH_INFO'])]
|
18
|
+
@_response.set_header('Content-Type', mime) if mime
|
19
|
+
@_response.write(file[:content] || file[:source].call)
|
14
20
|
else
|
15
21
|
Wunderbar::CGI.call(self)
|
16
22
|
end
|
@@ -43,6 +49,12 @@ module Wunderbar
|
|
43
49
|
def response
|
44
50
|
@_response
|
45
51
|
end
|
52
|
+
|
53
|
+
%w(delete get head options post put trace).each do |http_method|
|
54
|
+
define_method "#{http_method}?" do
|
55
|
+
@_env['REQUEST_METHOD'].to_s.downcase == http_method
|
56
|
+
end
|
57
|
+
end
|
46
58
|
end
|
47
59
|
end
|
48
60
|
|
data/lib/wunderbar/rails.rb
CHANGED
@@ -7,7 +7,7 @@ module Wunderbar
|
|
7
7
|
cattr_accessor :default_format
|
8
8
|
self.default_format = Mime[:html]
|
9
9
|
|
10
|
-
def self.call(template)
|
10
|
+
def self.call(template, source=nil)
|
11
11
|
%{
|
12
12
|
compiled = Proc.new {#{template.source}}
|
13
13
|
x = Wunderbar::HtmlMarkup.new(self);
|
@@ -24,7 +24,7 @@ module Wunderbar
|
|
24
24
|
cattr_accessor :default_format
|
25
25
|
self.default_format = Mime[:json]
|
26
26
|
|
27
|
-
def self.call(template)
|
27
|
+
def self.call(template, source=nil)
|
28
28
|
%{
|
29
29
|
compiled = Proc.new {#{template.source}}
|
30
30
|
x = Wunderbar::JsonBuilder.new(self);
|
data/lib/wunderbar/react.rb
CHANGED
@@ -16,6 +16,12 @@ class Wunderbar::Render
|
|
16
16
|
"ReactDOMServer.renderToString(#{common})"
|
17
17
|
end
|
18
18
|
|
19
|
+
# return all nodes on server rendering, as there is no wrapper element
|
20
|
+
# like there is for vue
|
21
|
+
def self.extract(nodes)
|
22
|
+
nodes
|
23
|
+
end
|
24
|
+
|
19
25
|
def self.client(common, element, target)
|
20
26
|
"ReactDOM.render(#{common}, #{element})"
|
21
27
|
end
|
@@ -29,17 +35,3 @@ class Wunderbar::Render
|
|
29
35
|
"</pre>"
|
30
36
|
end
|
31
37
|
end
|
32
|
-
|
33
|
-
# Monkeypatch to address https://github.com/sstephenson/execjs/pull/180
|
34
|
-
require 'execjs'
|
35
|
-
class ExecJS::ExternalRuntime::Context
|
36
|
-
alias_method :w_write_to_tempfile, :write_to_tempfile
|
37
|
-
def write_to_tempfile(*args)
|
38
|
-
tmpfile = w_write_to_tempfile(*args).path.untaint
|
39
|
-
tmpfile = Struct.new(:path, :to_str).new(tmpfile, tmpfile)
|
40
|
-
def tmpfile.unlink
|
41
|
-
File.unlink path
|
42
|
-
end
|
43
|
-
tmpfile
|
44
|
-
end
|
45
|
-
end
|
data/lib/wunderbar/render.rb
CHANGED
@@ -82,14 +82,12 @@ class Wunderbar::XmlMarkup
|
|
82
82
|
|
83
83
|
src = File.join(base, src) if not base.empty?
|
84
84
|
src = src.sub(/\?.*$/, '') # strip queries (typically mtimes)
|
85
|
-
src.untaint
|
86
85
|
|
87
|
-
name = File.expand_path(src, @_scope.settings.public_folder
|
88
|
-
name.untaint unless src.tainted?
|
86
|
+
name = File.expand_path(src, @_scope.settings.public_folder)
|
89
87
|
if File.exist? name
|
90
88
|
result = File.read(name)
|
91
89
|
else
|
92
|
-
file = File.expand_path(src+'.rb', @_scope.settings.views
|
90
|
+
file = File.expand_path(src+'.rb', @_scope.settings.views)
|
93
91
|
result = Wunderbar::Asset.convert(file)
|
94
92
|
end
|
95
93
|
else
|
@@ -113,11 +111,11 @@ class Wunderbar::XmlMarkup
|
|
113
111
|
scripts.unshift script.contents
|
114
112
|
elsif script.path
|
115
113
|
if script.path.start_with? '/'
|
116
|
-
path =
|
114
|
+
path = ENV['DOCUMENT_ROOT'] + script.path
|
117
115
|
else
|
118
|
-
path = File.expand_path(script.path, Wunderbar::Asset.root)
|
116
|
+
path = File.expand_path(script.path, Wunderbar::Asset.root)
|
119
117
|
end
|
120
|
-
setup << File.read(script.options[:server]
|
118
|
+
setup << File.read(script.options[:server] || path)
|
121
119
|
end
|
122
120
|
end
|
123
121
|
|
@@ -131,7 +129,7 @@ class Wunderbar::XmlMarkup
|
|
131
129
|
html = Wunderbar::Render.eval(scripts, server)
|
132
130
|
|
133
131
|
# insert results into target
|
134
|
-
nodes = builder._ { html }
|
132
|
+
nodes = Wunderbar::Render.extract(builder._ { html })
|
135
133
|
|
136
134
|
begin
|
137
135
|
if nodes.length == 1
|
data/lib/wunderbar/sinatra.rb
CHANGED
@@ -82,22 +82,14 @@ module Wunderbar
|
|
82
82
|
builder.set_variables_from_params(locals)
|
83
83
|
|
84
84
|
if not block
|
85
|
-
builder.instance_eval(data
|
85
|
+
builder.instance_eval(data, eval_file)
|
86
86
|
elsif not data
|
87
87
|
builder.instance_eval(&block)
|
88
88
|
else
|
89
89
|
context = builder.get_binding do
|
90
90
|
builder.instance_eval {_(&block)}
|
91
91
|
end
|
92
|
-
context.eval(data
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def _evaluate_safely(*args, &block)
|
97
|
-
if Wunderbar.safe? and $SAFE==0
|
98
|
-
Proc.new { $SAFE=1; _evaluate(*args, &block) }.call
|
99
|
-
else
|
100
|
-
_evaluate(*args, &block)
|
92
|
+
context.eval(data, eval_file)
|
101
93
|
end
|
102
94
|
end
|
103
95
|
end
|
@@ -108,7 +100,7 @@ module Wunderbar
|
|
108
100
|
def evaluate(scope, locals, &block)
|
109
101
|
builder = HtmlMarkup.new(scope)
|
110
102
|
begin
|
111
|
-
|
103
|
+
_evaluate(builder, scope, locals, &block)
|
112
104
|
rescue Exception => exception
|
113
105
|
scope.response.status = Wunderbar::ServerError.status
|
114
106
|
builder.clear!
|
@@ -132,7 +124,7 @@ module Wunderbar
|
|
132
124
|
def evaluate(scope, locals, &block)
|
133
125
|
builder = JsonBuilder.new(scope)
|
134
126
|
begin
|
135
|
-
result =
|
127
|
+
result = _evaluate(builder, scope, locals, &block)
|
136
128
|
|
137
129
|
# if no output was produced, use the result
|
138
130
|
builder._! result if builder.target? == {} and result
|
@@ -154,7 +146,7 @@ module Wunderbar
|
|
154
146
|
def evaluate(scope, locals, &block)
|
155
147
|
builder = TextBuilder.new(scope)
|
156
148
|
begin
|
157
|
-
result =
|
149
|
+
result = _evaluate(builder, scope, locals, &block)
|
158
150
|
|
159
151
|
# if no output was produced, use the result
|
160
152
|
builder._ result.to_s if builder.target!.empty? and result
|
@@ -240,13 +232,12 @@ Tilt.register 'xhtml.rb', Wunderbar::Template::Xhtml
|
|
240
232
|
helpers Wunderbar::SinatraHelpers
|
241
233
|
|
242
234
|
if Dir.exist? settings.public_folder
|
243
|
-
Wunderbar::Asset.root = File.join(settings.public_folder, 'assets')
|
235
|
+
Wunderbar::Asset.root = File.join(settings.public_folder, 'assets')
|
244
236
|
end
|
245
237
|
|
246
238
|
Wunderbar::Asset.virtual = true
|
247
239
|
|
248
240
|
get "/#{Wunderbar::Asset.path}/:name" do |name|
|
249
|
-
name.untaint if name =~ /^([-\w]\.?)+$/
|
250
241
|
file = "#{Wunderbar::Asset.root}/#{name}"
|
251
242
|
_text do
|
252
243
|
if File.exist? file
|
data/lib/wunderbar/version.rb
CHANGED
data/lib/wunderbar/vue.rb
CHANGED
@@ -14,17 +14,30 @@ class Wunderbar::Render
|
|
14
14
|
path = `which nodejs`.chomp
|
15
15
|
path = `which node`.chomp if path.empty?
|
16
16
|
raise RuntimeError.new('Unable to locate nodejs') if path.empty?
|
17
|
-
@nodejs = path
|
17
|
+
@nodejs = path
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.server(common)
|
21
|
-
"VueServer.renderToString(new Vue({render: function($h) {
|
21
|
+
"VueServer.renderToString(new Vue({render: function($h) {
|
22
|
+
return $h('div', #{common})}}))"
|
23
|
+
end
|
24
|
+
|
25
|
+
# unwrap children from div wrapper inserted by self.server
|
26
|
+
def self.extract(nodes)
|
27
|
+
if
|
28
|
+
nodes.length == 1 and nodes.first.name == 'div' and
|
29
|
+
nodes.first.attrs['data-server-rendered'].to_s == 'true'
|
30
|
+
then
|
31
|
+
nodes.first.children
|
32
|
+
else
|
33
|
+
nodes
|
34
|
+
end
|
22
35
|
end
|
23
36
|
|
24
37
|
def self.client(common, element, target)
|
25
38
|
wrap = "$h(#{target.name.inspect}, " +
|
26
39
|
"{attrs: {#{target.attrs.map {|name, value|
|
27
|
-
"#{name}: #{value.inspect}"}.join(', ')}}},
|
40
|
+
"#{name}: #{value.inspect}"}.join(', ')}}}, #{common})"
|
28
41
|
"new Vue({el: #{element}, render: function($h) {return #{wrap}}})"
|
29
42
|
end
|
30
43
|
|
@@ -37,7 +50,7 @@ class Wunderbar::Render
|
|
37
50
|
stdout += "\n<pre>#{CGI.escapeHTML(stderr)}</pre>"
|
38
51
|
end
|
39
52
|
|
40
|
-
stdout
|
53
|
+
stdout
|
41
54
|
rescue => e
|
42
55
|
Wunderbar.error e
|
43
56
|
"<pre>#{CGI.escapeHTML(e.message)}</pre>"
|
data/wunderbar.gemspec
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
require 'wunderbar/version'
|
3
5
|
|
4
6
|
Gem::Specification.new do |s|
|
5
7
|
s.name = "wunderbar".freeze
|
6
|
-
s.version =
|
8
|
+
s.version = Wunderbar::VERSION::STRING
|
7
9
|
|
8
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
11
|
s.require_paths = ["lib".freeze]
|
10
12
|
s.authors = ["Sam Ruby".freeze]
|
11
|
-
s.date = "2019-
|
13
|
+
s.date = "2019-06-07"
|
12
14
|
s.description = " Wunderbar makes it easy to produce valid HTML5, wellformed XHTML, Unicode\n (utf-8), consistently indented, readable applications.'\n".freeze
|
13
15
|
s.email = "rubys@intertwingly.net".freeze
|
14
16
|
s.files = ["COPYING".freeze, "README.md".freeze, "lib/wunderbar".freeze, "lib/wunderbar.rb".freeze, "lib/wunderbar/asset.rb".freeze, "lib/wunderbar/backtick.rb".freeze, "lib/wunderbar/bootstrap".freeze, "lib/wunderbar/bootstrap.rb".freeze, "lib/wunderbar/bootstrap/theme.rb".freeze, "lib/wunderbar/builder.rb".freeze, "lib/wunderbar/cgi-methods.rb".freeze, "lib/wunderbar/coderay.rb".freeze, "lib/wunderbar/coffeescript.rb".freeze, "lib/wunderbar/cssproxy.rb".freeze, "lib/wunderbar/environment.rb".freeze, "lib/wunderbar/eventsource.rb".freeze, "lib/wunderbar/html-methods.rb".freeze, "lib/wunderbar/installation.rb".freeze, "lib/wunderbar/job-control.rb".freeze, "lib/wunderbar/jquery".freeze, "lib/wunderbar/jquery.rb".freeze, "lib/wunderbar/jquery/filter.rb".freeze, "lib/wunderbar/jquery/stupidtable.rb".freeze, "lib/wunderbar/listen.rb".freeze, "lib/wunderbar/logger.rb".freeze, "lib/wunderbar/markdown.rb".freeze, "lib/wunderbar/marked.rb".freeze, "lib/wunderbar/node.rb".freeze, "lib/wunderbar/pagedown.rb".freeze, "lib/wunderbar/polymer.rb".freeze, "lib/wunderbar/rack.rb".freeze, "lib/wunderbar/rails.rb".freeze, "lib/wunderbar/react.rb".freeze, "lib/wunderbar/render.rb".freeze, "lib/wunderbar/script.rb".freeze, "lib/wunderbar/server.rb".freeze, "lib/wunderbar/sinatra.rb".freeze, "lib/wunderbar/underscore.rb".freeze, "lib/wunderbar/vendor".freeze, "lib/wunderbar/vendor/Markdown.Converter.js".freeze, "lib/wunderbar/vendor/bootstrap-theme.min.css".freeze, "lib/wunderbar/vendor/bootstrap.min.css".freeze, "lib/wunderbar/vendor/bootstrap.min.js".freeze, "lib/wunderbar/vendor/eventsource.min.js".freeze, "lib/wunderbar/vendor/jquery-3.2.1.min.js".freeze, "lib/wunderbar/vendor/marked.min.js".freeze, "lib/wunderbar/vendor/polymer-v0.0.20131003.min.js".freeze, "lib/wunderbar/vendor/react-dom-server.min.js".freeze, "lib/wunderbar/vendor/react-dom.min.js".freeze, "lib/wunderbar/vendor/react-with-addons.min.js".freeze, "lib/wunderbar/vendor/stupidtable.min.js".freeze, "lib/wunderbar/vendor/underscore-min.js".freeze, "lib/wunderbar/vendor/vue-server.min.js".freeze, "lib/wunderbar/vendor/vue.min.js".freeze, "lib/wunderbar/version.rb".freeze, "lib/wunderbar/vue.rb".freeze, "lib/wunderbar/websocket.rb".freeze, "wunderbar.gemspec".freeze]
|
15
17
|
s.homepage = "http://github.com/rubys/wunderbar".freeze
|
16
18
|
s.licenses = ["MIT".freeze]
|
17
19
|
s.required_ruby_version = Gem::Requirement.new(">= 1.9.3".freeze)
|
18
|
-
s.rubygems_version = "
|
20
|
+
s.rubygems_version = "3.0.6".freeze
|
19
21
|
s.summary = "HTML Generator and CGI application support".freeze
|
20
22
|
|
21
23
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wunderbar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -105,8 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
105
|
- !ruby/object:Gem::Version
|
106
106
|
version: '0'
|
107
107
|
requirements: []
|
108
|
-
|
109
|
-
rubygems_version: 2.7.6
|
108
|
+
rubygems_version: 3.1.2
|
110
109
|
signing_key:
|
111
110
|
specification_version: 4
|
112
111
|
summary: HTML Generator and CGI application support
|