Upgrade to 4.2.8
[usit-rt.git] / share / html / Elements / MakeClicky
CommitLineData
84fb5b46
MKG
1%# BEGIN BPS TAGGED BLOCK {{{
2%#
3%# COPYRIGHT:
4%#
3ffc5f4f 5%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
84fb5b46
MKG
6%# <sales@bestpractical.com>
7%#
8%# (Except where explicitly superseded by other copyright notices)
9%#
10%#
11%# LICENSE:
12%#
13%# This work is made available to you under the terms of Version 2 of
14%# the GNU General Public License. A copy of that license should have
15%# been provided with this software, but in any event can be snarfed
16%# from www.gnu.org.
17%#
18%# This work is distributed in the hope that it will be useful, but
19%# WITHOUT ANY WARRANTY; without even the implied warranty of
20%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21%# General Public License for more details.
22%#
23%# You should have received a copy of the GNU General Public License
24%# along with this program; if not, write to the Free Software
25%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26%# 02110-1301 or visit their web page on the internet at
27%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28%#
29%#
30%# CONTRIBUTION SUBMISSION POLICY:
31%#
32%# (The following paragraph is not intended to limit the rights granted
33%# to you to modify and distribute this software under the terms of
34%# the GNU General Public License and is only of importance to you if
35%# you choose to contribute your changes and enhancements to the
36%# community by submitting them to Best Practical Solutions, LLC.)
37%#
38%# By intentionally submitting any modifications, corrections or
39%# derivatives to this work, or any other work intended for use with
40%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41%# you are the copyright holder for those contributions and you grant
42%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43%# royalty-free, perpetual, license to use, copy, create derivative
44%# works based on those contributions, and sublicense and distribute
45%# those contributions and any derivatives thereof.
46%#
47%# END BPS TAGGED BLOCK }}}
48<%ONCE>
49use Regexp::Common qw(URI);
50
5b0d0914
MKG
51my $escaper = sub {
52 my $content = shift;
3ffc5f4f 53 RT::Interface::Web::EscapeHTML( \$content );
5b0d0914
MKG
54 return $content;
55};
56
84fb5b46
MKG
57my %actions = (
58 default => sub {
59 my %args = @_;
5b0d0914 60 return $escaper->($args{value});
84fb5b46
MKG
61 },
62 url => sub {
63 my %args = @_;
3ffc5f4f
MKG
64 my $post = "";
65 $post = ")" if $args{value} !~ /\(/ and $args{value} =~ s/\)$//;
5b0d0914 66 $args{value} = $escaper->($args{value});
84fb5b46 67 my $result = qq{[<a target="new" href="$args{value}">}. loc('Open URL') .qq{</a>]};
3ffc5f4f 68 return $args{value} . qq{ <span class="clickylink">$result</span>$post};
84fb5b46
MKG
69 },
70 url_overwrite => sub {
71 my %args = @_;
3ffc5f4f
MKG
72 my $post = "";
73 $post = ")" if $args{value} !~ /\(/ and $args{value} =~ s/\)$//;
5b0d0914
MKG
74 $args{value} = $escaper->($args{value});
75 my $result = qq{<a target="new" href="$args{value}">$args{value}</a>};
3ffc5f4f 76 return qq{<span class="clickylink">$result</span>$post};
84fb5b46
MKG
77 },
78);
79
80my @types = (
81 {
82 name => "httpurl",
3ffc5f4f 83 regex => qr/$RE{URI}{HTTP}{-keep}{-scheme => 'https?'}(?:#[^\s<]+)?(?<![.?!,;:])/,
84fb5b46
MKG
84 action => "url",
85 },
86 {
87 name => "httpurl_overwrite",
3ffc5f4f 88 regex => qr/$RE{URI}{HTTP}{-keep}{-scheme => 'https?'}(?:#[^\s<]+)?(?<![.?!,;:])/,
84fb5b46
MKG
89 action => "url_overwrite",
90 },
91);
92
93my $handle = sub {
94 my %args = @_;
95 for my $rec( @types ) {
96 return $rec->{action}->(
97 %args,
98 all_matches => [ $args{value}, $1, $2, $3, $4, $5, $6, $7, $8, $9 ],
99 ) if $args{value} =~ $rec->{regex};
100 }
101};
102
3ffc5f4f
MKG
103my $cache; # only defined via callback
104
84fb5b46
MKG
105# Hook to add more Clicky types
106# XXX Have to have Page argument, as Mason gets caller wrong in Callback?
107# This happens as we are in <%ONCE> block
108$m->callback(
109 CallbackPage => "/Elements/MakeClicky",
110 types => \@types,
111 actions => \%actions,
112 handle => \$handle,
3ffc5f4f 113 cache => \$cache,
84fb5b46
MKG
114);
115
116
117# Filter
118my %active;
119$active{$_}++ for RT->Config->Get('Active_MakeClicky');
120@types = grep $active{$_->{name}}, @types;
121
122# Build up the whole match
123my $regexp = join "|", map $_->{regex}, @types;
124
125# Make sure we have a default
126$actions{default} ||= sub {};
127
128# Anchor the regexes and look up the actions
129foreach my $type ( @types ) {
130 $type->{regex} = qr/^$type->{regex}$/;
131 $type->{action} = $actions{$type->{action}} || $actions{default};
132}
133
134</%ONCE>
135<%ARGS>
136$content => undef
137$html => undef
138</%ARGS>
139<%INIT>
140return unless defined $$content;
3ffc5f4f
MKG
141if ( defined $cache ) {
142 my $cached_content = $cache->(fetch => $content);
143 if ( $cached_content ) {
144 RT->Logger->debug("Found MakeClicky cache");
145 $$content = $cached_content;
146 return;
147 }
148}
149
84fb5b46 150unless ( $regexp ) {
3ffc5f4f 151 RT::Interface::Web::EscapeHTML( $content ) unless $html;
84fb5b46
MKG
152 return;
153}
154
155my $pos = 0;
156while ( $$content =~ /($regexp)/gsio ) {
157 my $match = $1;
3ffc5f4f 158 next if $` =~ /\w+=(?:&quot;|")$/;
84fb5b46
MKG
159 my $skipped_len = pos($$content) - $pos - length($match);
160 if ( $skipped_len > 0 ) {
161 my $plain;
162 if ( $html ) {
163 $plain = substr( $$content, $pos, $skipped_len );
164 }
165 else {
166 $plain = $escaper->( substr( $$content, $pos, $skipped_len ) )
167 }
168 substr( $$content, $pos, $skipped_len ) = $plain;
169 $pos += length($plain);
170 }
171 my $plain = $handle->(
172 %ARGS,
173 value => $match,
174 all_matches => [ $1, $2, $3, $4, $5, $6, $7, $8, $9 ],
175 );
176 substr( $$content, $pos, length($match) ) = $plain;
177 pos($$content) = ( $pos += length($plain) );
178
179}
180substr( $$content, $pos ) = $escaper->( substr( $$content, $pos ) ) unless
181($pos == length $$content) || $html;
182
183pos($$content) = 0;
3ffc5f4f 184$cache->(store => $content) if defined $cache;
84fb5b46
MKG
185
186</%INIT>