blob: a2ce39d268e90323b1b78329a7b0fb057b2bb59a [file] [log] [blame]
# Monkeypatch to address https://github.com/sstephenson/execjs/pull/180
require 'execjs'
class ExecJS::ExternalRuntime::Context
alias_method :w_write_to_tempfile, :write_to_tempfile
def write_to_tempfile(*args)
tmpfile = w_write_to_tempfile(*args).path.untaint
tmpfile = Struct.new(:path, :to_str).new(tmpfile, tmpfile)
def tmpfile.unlink
File.unlink path
end
tmpfile
end
end
# Proof of concept implementation of React.render method; needs to be
# cleaned up, generalized, and have tests written for it before it can
# be added to Wunderbar proper.
Wunderbar::CALLERS_TO_IGNORE.clear
require 'nokogumbo'
class Wunderbar::XmlMarkup
def render container, &block
csspath = Wunderbar::Node.parse_css_selector(container)
root = @node.root
# find the scripts and target on the page
scripts = root.search('script')
target = root.at(container)
# compute client side container
element = "document.querySelector(#{container.inspect})"
if csspath.length == 1 and csspath[0].length == 1
value = csspath[0].values.first
case csspath[0].keys.first
when :id
element = "document.getElementById(#{value.inspect})"
when :class
value = value.join(' ')
element = "document.getElementsByClassName(#{value.inspect})[0]"
when :name
element = "document.getElementsByName(#{value.inspect})[0]"
end
end
# build client and server scripts
common = Ruby2JS.convert(block, scope: @_scope)
server = "React.renderToString(#{common})"
client = "React.render(#{common}, #{element})"
# extract content of scripts
scripts.map! do |script|
result = nil
if script.attrs[:src]
src = script.attrs[:src]
name = File.join(@_scope.settings.public_folder, src)
if File.exist? name
result = File.read(name)
else
name = File.join(@_scope.settings.views, src+'.rb')
result = Ruby2JS.convert(File.read(name)) if File.exist? name
end
end
result
end
# concatenate and execute scripts on server
scripts.compact!
scripts.unshift 'global=this'
context = ExecJS.compile(scripts.join(";\n"))
# insert results into target
builder = Wunderbar::HtmlMarkup.new({})
target.children += builder._ { context.eval(server) }
# add client side script
tag! 'script', Wunderbar::ScriptNode, client
end
end
get %r{^/([-\w]+)\.js$} do |script|
_js :"#{script}"
end