package SL::Template::Plugin::JavaScript;
-use base qw( Template::Plugin );
-use Template::Plugin;
+use base qw( Template::Plugin::Filter );
use strict;
+my $cached_instance;
+
sub new {
- my ($class, $context, @args) = @_;
+ my $class = shift;
+
+ return $cached_instance ||= $class->SUPER::new(@_);
+}
+
+sub init {
+ my $self = shift;
+
+ $self->install_filter($self->{ _ARGS }->[0] || 'js');
- return bless {
- CONTEXT => $context,
- }, $class;
+ return $self;
}
#
# public interface
#
+# see ecmascript spec section 7.8.4
+my @escape_chars = ('\\', '\'', '"');
+my %control_chars = (
+ "\n" => 'n',
+ "\t" => 't',
+ "\r" => 'r',
+ "\f" => 'f',
+ "\x08" => 'b',
+ "\x0B" => 'v', # noone uses vertical tab anyway...
+);
+my $re = join '', map { qr/($_)/s } join '|', keys(%control_chars), map { "\Q$_\E" } @escape_chars;
+
sub escape {
my $self = shift;
my $text = shift;
- $text =~ s|\\|\\\\|g;
- $text =~ s|\"|\\\"|g;
- $text =~ s|\n|\\n|g;
+ $text =~ s/$re/'\\' . ($control_chars{$1} || $1)/egs;
return $text;
}
+sub filter {
+ my ($self, $text) = @_;
+ return $self->escape($text);
+}
+
sub replace_with {
return _replace_helper('replaceWith', @_);
}
<input type="submit" value="Delete"
onclick="if (confirm('Do you really want to delete this: [% JavaScript.escape(obj.description) %]') return true; else return false;">
+You can also use the filter syntax instead:
+
+ <input type="submit" value="Delete"
+ onclick="if (confirm('Do you really want to delete this: [% obj.description | js %]') return true; else return false;">
+
=item C<replace_with $selector, $template, %locals>
Returns code replacing the DOM elements matched by C<$selector> with