File Coverage

blib/lib/HTML/StripScripts/LibXML.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package HTML::StripScripts::LibXML;
2 3     3   139656 use strict;
  3         6  
  3         188  
3              
4 3     3   18 use vars qw($VERSION);
  3         8  
  3         266  
5             $VERSION = '0.12';
6              
7             =head1 NAME
8              
9             HTML::StripScripts::LibXML - XSS filter - outputs a LibXML Document or DocumentFragment
10              
11             =head1 SYNOPSIS
12              
13             use HTML::StripScripts::LibXML();
14              
15             my $hss = HTML::StripScripts::LibXML->new(
16              
17             {
18             Context => 'Document', ## HTML::StripScripts configuration
19             Rules => { ... },
20             },
21              
22             strict_comment => 1, ## HTML::Parser options
23             strict_names => 1,
24              
25             );
26              
27             $hss->parse_file("foo.html");
28             $xml_doc = $hss->filtered_document;
29              
30             OR
31              
32             $xml_doc = $hss->filter_html($html);
33              
34             =head1 DESCRIPTION
35              
36             This class provides an easy interface to C, using
37             C to parse the HTML, and returns an XML::LibXML::Document
38             or XML::LibXML::DocumentFragment.
39              
40             See L for details of how to customise how the raw HTML is parsed
41             into tags, and L for details of how to customise the way
42             those tags are filtered. This module is a subclass of
43             L.
44              
45             =cut
46              
47             =head1 DIFFERENCES FROM HTML::StripScripts
48              
49             =over
50              
51             =item CONTEXT
52              
53             HTML::StripScripts::LibXML still allows you to specify the C of the
54             HTML (Document, Flow, Inline, NoTags). If C is C, then it
55             returns an C object, otherwise it returns an
56             C object.
57              
58             =item TAG CALLBACKS
59              
60             HTML::StripScripts allows you to use tag callbacks, for instance:
61              
62             $hss = HTML::StripScripts->new({
63             Rules => { a => \&a_callback }
64             });
65              
66             sub a_callback {
67             my ($filter,$element) = @_;
68             # where $element = {
69             # tag => 'a',
70             # attr => { href => '/index.html' },
71             # content => 'Go to Home page',
72             # }
73             return 1;
74             }
75              
76             HTML::StripScripts::LibXML still gives you tag callbacks, but they look like
77             this:
78              
79             sub a_callback {
80             my ($filter,$element) = @_;
81             # where $element = {
82             # tag => 'a',
83             # attr => { href => '/index.html' },
84             # children => [
85             # XML::LibXML::Text --> 'Go to ',
86             # XML::LibXML::Element --> 'b'
87             # with child Text --> 'Home',
88             # XML::LibXML::Text --> ' page',
89             # ],
90             # }
91             return 1;
92             }
93              
94             =item SUBCLASSING
95              
96             The subs C, C and C are not called. Instead,
97             this module uses C which handles the tag callback, (and
98             depending on the result of the tag callback) creates an element and adds
99             its child nodes. Then it adds the element to the list of children for the
100             parent tag.
101              
102             =back
103              
104             =head1 CONSTRUCTORS
105              
106             =over
107              
108             =item new ( {CONFIG}, [PARSER_OPTIONS] )
109              
110             Creates a new C object.
111              
112             See L for details.
113              
114             =back
115              
116             =cut
117              
118 3     3   19 use base 'HTML::StripScripts::Parser';
  3         12  
  3         4191  
119 3     3   210285 use XML::LibXML();
  0            
  0            
120             use HTML::Entities();
121              
122             #===================================
123             sub output_start_document {
124             #===================================
125             my ($self) = @_;
126             $self->{_hsxXML} = XML::LibXML::Document->new();
127             return;
128             }
129              
130             #===================================
131             sub output_end_document {
132             #===================================
133             my ($self) = @_;
134             my $top = $self->{_hssStack}[0];
135             my $document = delete $self->{_hsxXML};
136              
137             if ( $top->{CTX} ne 'Document' ) {
138             $document = $document->createDocumentFragment();
139             }
140              
141             foreach my $child ( @{ $top->{CHILDREN} } ) {
142             $document->addChild($child);
143             }
144             $top->{CONTENT} = $document;
145             return;
146             }
147              
148             #===================================
149             sub output_start { }
150             *output_end = \&output_start;
151             *output_declaration = \&output_start;
152             *output_process = \&output_start;
153             *output = \&output_start;
154             #===================================
155              
156             #===================================
157             sub output_text {
158             #===================================
159             my ( $self, $text ) = @_;
160             HTML::Entities::decode_entities( $text);
161             utf8::upgrade($text);
162             push @{ $self->{_hssStack}[0]{CHILDREN} },
163             $self->{_hsxXML}->createTextNode($text);
164             return;
165             }
166              
167             #===================================
168             sub output_comment {
169             #===================================
170             my ( $self, $comment ) = @_;
171             $comment =~ s/^\s*\s*$//g;
173             push @{ $self->{_hssStack}[0]{CHILDREN} },
174             $self->{_hsxXML}->createComment($comment);
175             return;
176             }
177              
178             #===================================
179             sub output_stack_entry {
180             #===================================
181             my ( $self, $tag ) = @_;
182              
183             my %entry;
184             $tag->{CHILDREN} ||= [];
185             @entry{qw(tag attr children)} = @{$tag}{qw(NAME ATTR CHILDREN)};
186              
187             if ( my $tag_callback = $tag->{CALLBACK} ) {
188             $tag_callback->( $self, \%entry )
189             or return;
190             }
191              
192             if ( my $tagname = $entry{tag} ) {
193             my $element = $self->{_hsxXML}->createElement($tagname);
194             my $attrs = $entry{attr};
195             foreach my $name ( sort keys %$attrs ) {
196             $element->setAttribute( $name => $attrs->{$name} );
197             }
198             unless ( $tag->{CTX} eq 'EMPTY' ) {
199             foreach my $children ( @{ $entry{children} } ) {
200             $element->addChild($children);
201             }
202             }
203             push @{ $self->{_hssStack}[0]{CHILDREN} }, $element;
204             }
205             else {
206             push @{ $self->{_hssStack}[0]{CHILDREN} }, @{ $entry{children} };
207             }
208             $tag->{CHILDREN} = [];
209             }
210              
211             =head1 BUGS AND LIMITATIONS
212              
213             =over
214              
215             =item API - BETA
216              
217             This is the first draft of this module, and currently there are no configuration
218             options for the XML. I would welcome feedback from XML users as to how I could
219             improve the interface.
220              
221             For this reason, the API may change.
222              
223             =item REPORTING BUGS
224              
225             Please report any bugs or feature requests to
226             bug-html-stripscripts-libxml@rt.cpan.org, or through the web interface at
227             L.
228              
229             =back
230              
231             =head1 SEE ALSO
232              
233             L, L,
234             L
235              
236             =head1 AUTHOR
237              
238             Clinton Gormley Eclint@traveljury.comE
239              
240             =head1 COPYRIGHT
241              
242             Copyright (C) 2007 Clinton Gormley. All Rights Reserved.
243              
244             =head1 LICENSE
245              
246             This module is free software; you can redistribute it and/or modify it
247             under the same terms as Perl itself.
248              
249             =cut
250              
251             1;
252