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>