1 package SL::Presenter::EscapedText;
 
   4 use Exporter qw(import);
 
   5 use Scalar::Util qw(looks_like_number);
 
   7 our @EXPORT_OK = qw(escape is_escaped escape_js escape_js_call);
 
   8 our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
 
  12 use overload '""' => \&escaped_text;
 
  24   my ($class, %params) = @_;
 
  26   return $params{text} if ref($params{text}) eq $class;
 
  28   my $self      = bless {}, $class;
 
  29   $self->{text} = $params{is_escaped} ? $params{text} : quote_html($params{text});
 
  35   return undef unless defined $_[0];
 
  36   (my $x = $_[0]) =~ s/(["'<>&])/$html_entities{$1}/ge;
 
  41   __PACKAGE__->new(text => $_[0]);
 
  45   __PACKAGE__->new(text => $_[0], is_escaped => 1);
 
  55   __PACKAGE__->new(text => $text, is_escaped => 1);
 
  59   my ($func, @args) = @_;
 
  67           : '"' . escape_js($_) . '"'
 
  91 SL::Presenter::EscapedText - Thin proxy object to invert the burden of escaping HTML output
 
  95   use SL::Presenter::EscapedText qw(escape is_escaped escape_js);
 
  99     return SL::Presenter::EscapedText->new(text => $text);
 
 102     # return escape($text);
 
 106     my $output_of_other_component = blackbox('Hello & Goodbye');
 
 108     # The following is safe, text will not be escaped twice:
 
 109     return SL::Presenter::EscapedText->new(text => $output_of_other_component);
 
 112   my $output = build_output();
 
 113   print "Yeah: $output\n";
 
 117 Sometimes it's nice to let a sub-component build its own
 
 118 representation. However, you always have to be very careful about
 
 119 whose responsibility escaping is. Only the building function knows
 
 120 enough about the structure to be able to HTML escape properly.
 
 122 But higher functions should not have to care if the output is already
 
 123 escaped -- they should be able to simply escape it again. Without
 
 124 producing stuff like '&amp;'.
 
 126 Stringification is overloaded. It will return the same as L<escaped_text>.
 
 128 This works together with the template plugin
 
 129 L<SL::Template::Plugin::P> and its C<escape> method.
 
 137 Creates an instance of C<EscapedText>.
 
 139 The parameter C<text> is the text to escape. If it is already an
 
 140 instance of C<EscapedText> then C<$params{text}> is returned
 
 143 Otherwise C<text> is HTML-escaped and stored in the new instance. This
 
 144 can be overridden by setting C<$params{is_escaped}> to a trueish
 
 147 =item C<escape $text>
 
 149 Static constructor, can be exported. Equivalent to calling C<< new(text => $text) >>.
 
 151 =item C<is_escaped $text>
 
 153 Static constructor, can be exported. Equivalent to calling C<< new(text => $text, escaped => 1) >>.
 
 155 =item C<escape_js $text>
 
 157 Static constructor, can be exported. Like C<escape> but also escapes Javascript.
 
 159 =item C<escape_js_call $func_name, @args>
 
 161 Static constructor, can be exported. Used to construct a javascript call than
 
 162 can be used for onclick handlers in other Presenter functions.
 
 167     P.escape_js_call("kivi.Package.some_func", arg_one, arg_two, arg_three)
 
 177 =item C<escaped_text>
 
 179 Returns the escaped string (not an instance of C<EscapedText> but an
 
 190 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>