Created
November 16, 2009 03:58
-
-
Save nerdEd/235715 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 | |
# A rack middleware for validating HTML via w3c validator | |
class Validate | |
def initialize( app ) | |
@app = app | |
end | |
def call( env ) | |
status, headers, response = @app.call( env ) | |
request = Rack::Request.new( env ) | |
if !request.params['rack-validate'].blank? | |
if headers['Content-Type'] =~ /text\/html|application\/xhtml\+xml/ | |
body = response.body | |
issues = Validator.validate( body ) | |
body.insert( 0, Validator.generate_report( issues ) ) | |
headers["Content-Length"] = body.length.to_s | |
response = [body] | |
end | |
end | |
[status, headers, response] | |
end | |
class Validator | |
include W3CValidators | |
def self.validate( response ) | |
validator = MarkupValidator.new | |
validator.validate_text( response ) | |
end | |
def self.generate_report( issues ) | |
report = "" | |
report << STYLES | |
report << SCRIPT | |
report << "<div id='message_toolbar'>" | |
report << '<div id="controls">' | |
summary = "<span>There were " + issues.errors.size.to_s + " errors and " + issues.warnings.size.to_s + " warnings</span><br/><br/>" | |
report << summary | |
report << LINKS | |
report << '</div>' | |
if !issues.errors.empty? | |
report << "<table id='errors_table' style='display:none;'>" | |
report << "<tr><td colspan='2' class='header_column'>Errors</td></tr>" | |
issues.errors.each do |item| | |
report << "<tr><td class='line_number_column'>Line #{item.line}</td><td class='message_column'>#{html_escape( item.message )}</td></tr>" | |
end | |
report << "</table>" | |
end | |
if !issues.warnings.empty? | |
report << "<table id='warnings_table' style='display:none;'>" | |
report << "<tr><td colspan='2' class='header_column'>Warnings</td></tr>" | |
issues.warnings.each do |item| | |
report << "<tr><td class='line_number_column'>--</td><td class='message_column'>#{html_escape( item.message )}</td></tr>" | |
end | |
report << "</table>" | |
end | |
report << "</div>" | |
end | |
private | |
# Stealing HTML escape method from rails | |
def self.html_escape( string ) | |
string.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] } | |
end | |
# Stealing HTML escape constant from rails | |
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' } | |
LINKS = <<-HERE | |
<a href="#" onclick="$( '#errors_table' ).toggle();updateText( this, 'Show Errors', 'Hide Errors' );">Show Errors</a> | |
<a href="#" onclick="$( '#warnings_table' ).toggle();updateText( this, 'Show Warnings', 'Hide Warnings' );">Show Warnings</a> | |
<a href="#" onclick="$( '#message_toolbar' ).toggle();">Close Toolbar</a> | |
HERE | |
SCRIPT = <<-HERE | |
<script src="http://www.google.com/jsapi"></script> | |
<script type="text/javascript"> | |
google.load("jquery", "1.3.2"); | |
google.load("jqueryui", "1.7.2"); | |
function updateText( element, textOne, textTwo ) { | |
if( element.innerHTML == textOne ) { | |
element.innerHTML = textTwo; | |
} | |
else { | |
element.innerHTML = textOne; | |
} | |
} | |
</script> | |
HERE | |
STYLES = <<-HERE | |
<style type='text/css'> | |
#message_toolbar { | |
width: 100%; | |
min-height: 50px; | |
background: black; | |
position: absolute; | |
top:0; | |
left:0; | |
-moz-opacity:.80; | |
filter:alpha(opacity=80); | |
opacity:.80; | |
font-size: smaller; | |
font-family: "Courier New"; | |
color: white; | |
text-align: center; | |
} | |
#message_toolbar a{ | |
color: white; | |
font-weight: bold; | |
} | |
.line_number_column { | |
text-align: left; | |
width: 100px; | |
} | |
.error_message_column { | |
text-align: left; | |
} | |
#errors_table, | |
#warnings_table { | |
width: 75%; | |
margin: 0 auto; | |
border: none; | |
color: white; | |
margin-top: 10px; | |
} | |
#errors_table .header_column, | |
#warnings_table .header_column { | |
text-align: center; | |
border-bottom: 2px dashed; | |
} | |
#errors_table .header_column { | |
border-color: red; | |
} | |
#warnings_table .header_column { | |
border-color: yellow; | |
} | |
</style> | |
HERE | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment