Created
November 14, 2009 11:43
-
-
Save Stanley/234485 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Rack | |
class ChromeFrame | |
def initialize(app, options={}) | |
@app = app | |
@options = options | |
end | |
def call(env) | |
if env['HTTP_USER_AGENT'] =~ /MSIE/ | |
if env['HTTP_USER_AGENT'] =~ /chromeframe/ | |
status, headers, response = @app.call(env) | |
new_body = insert_tag(build_response_body(response)) | |
new_headers = recalculate_body_length(headers, new_body) | |
return [status, new_headers, new_body] | |
elsif @options[:minimum].nil? or ie_version(env['HTTP_USER_AGENT']) < @options[:minimum] | |
html = <<-HTML | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
<head> | |
<meta http-equiv="content-type" content="text/html;charset=UTF-8" /> | |
<title>You must install chromeframe in order to see this page!</title> | |
</head> | |
<body> | |
<div id="cf-placeholder"></div> | |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script> | |
<script>CFInstall.check({ node: "cf-placeholder" #{', destination: "' + @options[:destination] + '" ' if @options[:destination]}});</script> | |
</body> | |
</html> | |
HTML | |
return [200, {'Content-Type' => 'text/html', 'Content-Length' => html.size.to_s}, Rack::Response.new([html])] | |
end | |
end | |
@app.call(env) | |
end | |
def build_response_body(response) | |
response_body = "" | |
response.each { |part| response_body += part } | |
response_body | |
end | |
def recalculate_body_length(headers, body) | |
new_headers = headers | |
new_headers["Content-Length"] = body.length.to_s | |
new_headers | |
end | |
def insert_tag(body) | |
head = <<-HEAD | |
<meta http-equiv="X-UA-Compatible" content="chrome=1"> | |
HEAD | |
body.gsub!('<head>', "<head>\n" + head ) | |
body | |
end | |
def ie_version(ua_string) | |
ua_string.match(/MSIE (\S+)/)[1].to_f | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.dirname(__FILE__) + '/helper' | |
describe "Rack::ChromeFrame" do | |
before do | |
@app = lambda { |env| [200, {'Content-Type' => 'text/html'}, simple_html] } | |
@request = Rack::MockRequest.new(Rack::ChromeFrame.new(@app, {:minimum => 8.0})) | |
end | |
shared_examples_for "nothing happens" do | |
it "should change nothing" do | |
@response.body.should eql(simple_html) | |
end | |
end | |
context "not IE:" do | |
before do | |
@response = @request.get('/') | |
end | |
it_should_behave_like "nothing happens" | |
end | |
context "IE:" do | |
context "chromeframe installed" do | |
before do | |
@response = @request.get('/', {'HTTP_USER_AGENT' => 'MSIE 6.0; chromeframe' }) | |
end | |
it "should add meta tag" do | |
@response.body.should include(chrome_frame_meta_tag) | |
end | |
end | |
context "chromeframe not installed" do | |
context "but satisfactory IE version installed" do | |
before do | |
@response = @request.get('/', {'HTTP_USER_AGENT' => 'MSIE 8.0' }) | |
end | |
it_should_behave_like "nothing happens" | |
end | |
context "but not satisfactory IE version installed" do | |
before do | |
@response = @request.get('/', {'HTTP_USER_AGENT' => 'MSIE 7.0' }) | |
end | |
it "should suggest chromeframe installation" do | |
@response.body.gsub(/\n( )*/, '').should include(chrome_frame_installation_script) | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment