require 'rack-ajax/decision_tree'
require 'rack-ajax/parser'
require 'json'
require 'yaml'
require 'yaml/encoding' unless RUBY_VERSION.to_f == 1.9
module Rack
class Ajax
extend Rack::Ajax::DecisionTree
cattr_accessor :decision_tree
attr_accessor :user, :request, :params
# If called with a block, executes that block as the "decision tree".
# This is useful when testing.
#
# To integrate Rack::Ajax into your app you should store the decision
# tree in a class-attribute decision_tree.
#
# The default_decision_tree is used if no other is provided.
def initialize(app)
@app = app
@decision_tree = block_given? ? Proc.new : (self.class.decision_tree || self.class.default_decision_tree)
end
def call(env)
return @app.call(env) unless ::Ajax.is_enabled?
# Parse the Ajax-Info header
env["Ajax-Info"] = ::Ajax.unserialize_hash(env['HTTP_AJAX_INFO'])
@parser = Parser.new(env)
rack_response = @parser.instance_eval(&@decision_tree)
# Clear the value of session[:redirected_to]
unless env['rack.session'].nil?
env['rack.session']['redirected_to'] = env['rack.session'][:redirected_to] = nil
end
# If we are testing our Rack::Ajax middleware, return
# a Rack response now rather than falling through
# to the application.
#
# To test rewrites, return a 200 response with
# the modified request environment encoded as Yaml.
#
# The Ajax::RSpec::Helpers module includes a helper
# method to test the result of a rewrite.
if ::Ajax.is_mocked?
rack_response.nil? ? Rack::Ajax::Parser.rack_response(encode_env(env)) : rack_response
elsif !rack_response.nil?
rack_response
else
# Fallthrough to the app.
@app.call(env)
end
end
protected
# Convert the environment hash to yaml so it can be unserialized later
def encode_env(env)
env['rack.session'] = env['rack.session'].to_hash if env['rack.session'].is_a?(Hash)
env.to_yaml(:Encoding => :Utf8)
end
end
end