File Coverage

blib/lib/Plack/Middleware/Debug/W3CValidate.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Plack::Middleware::Debug::W3CValidate;
2              
3             our $VERSION = '0.04';
4 2     2   110912 use 5.008;
  2         7  
  2         76  
5 2     2   11 use strict;
  2         3  
  2         67  
6 2     2   23 use warnings;
  2         4  
  2         65  
7 2     2   972 use parent qw(Plack::Middleware::Debug::Base);
  2         316  
  2         16  
8              
9 2     2   57063 use XML::XPath;
  0            
  0            
10             use WebService::Validator::HTML::W3C;
11             use Plack::Util::Accessor qw(validator_uri);
12              
13             my $table_template = __PACKAGE__->build_template(<<'TABLETMPL');
14             % my $errs = shift @_;
15            
20            
21            
22            
23             Line
24             Column
25             Message
26             Source
27            
28            
29            
30             % my $i = 0;
31             % for my $error (@$errs) {
32            
33             <%= $error->{line} %>
34             <%= $error->{col} %>
35             <%= $error->{msg} %>
36             <%= Text::MicroTemplate::encoded_string($error->{source}) %>
37            
38             % }
39            
40            
41             TABLETMPL
42              
43             sub get_validator {
44             my $self = shift @_;
45             my %opts = ($self->validator_uri ? (validator_uri=>$self->validator_uri) : ());
46             return WebService::Validator::HTML::W3C->new(detailed=>1, %opts);
47             }
48              
49             sub flatten_body {
50             my ($self, $res) = @_;
51             my $body = $res->[2];
52             if(ref $body eq 'ARRAY') {
53             return join "", @$body;
54             } elsif(defined $body) {
55             my $slurped;
56             while (defined(my $line = $body->getline)) {
57             $slurped .= $line if length $line;
58             }
59             return $slurped;
60             }
61             }
62              
63             ## Until (and if) WebService::Validator::HTML::W3C parses for source
64             sub parse_for_errors {
65             my ($self, $xml) = @_;
66             my $xp = XML::XPath->new(xml => $xml);
67             my @messages = $xp->findnodes( '/env:Envelope/env:Body/m:markupvalidationresponse/m:errors/m:errorlist/m:error' );
68              
69             my @errs;
70             foreach my $msg ( @messages ) {
71             my $err = {
72             line => $xp->find( './m:line', $msg )->get_node(1)->getChildNode(1)->getValue,
73             col => $xp->find( './m:col', $msg )->get_node(1)->getChildNode(1)->getValue,
74             msg => $xp->find( './m:message', $msg )->get_node(1)->getChildNode(1)->getValue,
75             source => $xp->find( './m:source', $msg )->get_node(1)->getChildNode(1)->getValue,
76             };
77             push @errs, $err;
78             }
79             return @errs;
80             }
81              
82             sub run {
83             my($self, $env, $panel) = @_;
84             $panel->title("W3C Validation");
85             $panel->nav_title("W3C Validation");
86             return sub {
87             my $res = shift @_;
88             my $v = $self->get_validator;
89             my $slurped_body = $self->flatten_body($res);
90             if($v->validate_markup($slurped_body)) {
91             if ( $v->is_valid ) {
92             $panel->nav_subtitle("Page validated.");
93             $panel->content(sub { "

No Errors on Page

" });
94             } else {
95             $panel->nav_subtitle('Not valid. Error Count: '.$v->num_errors);
96             my @errs = $self->parse_for_errors($v->_content());
97             $panel->content(sub {
98             "

Errors

".
99             $self->render($table_template, \@errs);
100             });
101             }
102             } else {
103             $panel->content(sub {
104             $self->render_lines([
105             "Failed to validate the website: ". $v->validator_error,
106             ]);
107             });
108             }
109             }
110             }
111              
112             1;
113              
114             =head1 NAME
115              
116             Plack::Middleware::Debug::W3CValidate - Validate your Response Content
117              
118             =head2 SYNOPSIS
119              
120             use Plack::Builder;
121              
122             my $app = ...; ## Build your Plack App
123              
124             builder {
125             enable 'Debug', panels =>['W3CValidate'];
126             $app;
127             };
128              
129             =head1 DESCRIPTION
130              
131             Adds a debug panel that runs your response body through the W3C validator and
132             returns a list of errors.
133              
134             =head1 OPTIONS
135              
136             This debug panel defines the following options.
137              
138             =head2 validator_uri
139              
140             Takes the url of the W3C validator. Defaults to the common validator, but if
141             you plan to pound this it would be polite to setup your own and point to that
142             instead. Please see L for more.
143              
144             Since this panel needs to read and submit the response body to a POST service
145             it will definitely increase the time it takes to load the page.
146              
147             =head1 SEE ALSO
148              
149             L
150              
151             =head1 AUTHOR
152              
153             John Napiorkowski, C<< >>
154              
155             =head1 COPYRIGHT & LICENSE
156              
157             This program is free software; you can redistribute it and/or modify
158             it under the same terms as Perl itself.
159              
160             =cut
161