どうもCatalyst::Plugin::FillInForm
でfillform
したときに不思議な出力をしていて、調べてみると 中のHTML::FillInForm
がcommentの部分をゴニョゴニョやっているあたりに問題があるようだった。
例えば、下記のようなコード。
#!/usr/bin/env perl use strict; use warnings; use HTML::FillInForm; my $data = join '', <DATA>; print HTML::FillInForm->new->fill( scalarref => \$data, fdata => {} ); __DATA__ <!DOCTYPE html> <html> <head> <title>title</title> </head> <body> <![if !IE]>hoge<![endif]> <!--[if !IE]>-->fuga<!--<![endif]--> <!piyo> </body> </html>
Catalyst::Plugin::FillInForm::fillform
でも、このようにHTML::FillInForm
をnew
してfill
を呼ぶ形になっていて、上記コードを実行すると下記のような結果になる。
<!DOCTYPE html> <html> <head> <title>title</title> </head> <body> <![if !IE]>hoge<![endif]> <![if !IE]>>fuga<!--<![endif]--> <!--piyo--> </body> </html>
"hoge"の行は"downlevel-revealed"と呼ばれるConditional Commentsという形式のもので、問題なくそのまま出力される。
"fuga"の行はそれをvalidation通すために使われる記法らしい。が、これが変な形で出力されてしまっている。
"piyo"の行は正しい形のHTMLコメントではないがHTML::FillInForm
によって正しい形式のコメントに変換されている。
About conditional comments (Internet Explorer)
条件付きコメント - Wikipedia
とにかく"fuga"の行がおかしくなってしまっている。HTML::FillInForm
を読むと、
sub comment { my ( $self, $text ) = @_; # if it begins with '[if ' and doesn't end with '<![endif]' # it's a "downlevel-revealed" conditional comment (stupid IE) # or # if it ends with '[endif]' then it's the end of a # "downlevel-revealed" conditional comment if( ( ( index($text, '[if ') == 0 ) && ( $text !~ /<!\[endif\]$/ ) ) || ( $text eq '[endif]' ) ) { $self->{output} .= '<!' . $text . '>'; } else { $self->{output} .= '<!--' . $text . '-->'; } }
という部分があり、どうやらHTML::FillInForm
の親クラスHTML::Parser
では<!-- ... -->
の形式以外でも<! ...>
のような形のものもコメントとして認識し、出力する際にConditional Commentかどうかを判別して完全なコメントアウトではなく<!...>
になるよう調整しているようだ。
ところがその除外ルールが<!--[if !IE]>-->
にも適用されてしまうため、上記の"fuga"の行がおかしなことになってしまうようだ。
$self->strict_comment(1);
で正しくない形式のコメントは無視してしまって
sub comment { my ( $self, $text ) = @_; $self->{output} .= '<!--' . $text . '-->'; }
とやってしまえば上記のような事態にはならずに済むけど、そういうわけにはいかないのだろうか? そうすることによってチェックされなくなってしまうものが出てしまうとまずいのかな…。