rt 4.2.15
[freeside.git] / rt / share / html / Elements / ShowMessageStanza
1 %# BEGIN BPS TAGGED BLOCK {{{
2 %#
3 %# COPYRIGHT:
4 %#
5 %# This software is Copyright (c) 1996-2018 Best Practical Solutions, LLC
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 <%INIT>
49 my $plain_text_mono
50     = RT->Config->Get( 'PlainTextMono', $session{'CurrentUser'} );
51 my $Depth = 0;
52
53 my $object = $Transaction ? $Transaction->Object : undef;
54
55 my $print_content = sub {
56     my $ref = shift;
57     return unless defined $$ref && length $$ref;
58
59     $m->callback( content => $ref, %ARGS );
60     if ( $ContentType eq 'text/plain' ) {
61         $m->comp( '/Elements/MakeClicky',
62                   content => $ref,
63                   object  => $object,
64                   %ARGS
65                 );
66
67         if ( defined $$ref && !$plain_text_mono ) {
68             $$ref =~ s{(\r?\n)}{<br />}g;
69         }
70     } else {
71         if ( defined $$ref ) {
72             $$ref =~ s/^[\r\n]+//g;
73         }
74     }
75     $m->out($$ref);
76 };
77
78 $m->out(   '<div class="message-stanza'
79          . ( ($ContentType eq 'text/plain' &&  $plain_text_mono) ? ' plain-text-white-space' : '' ) . '"'
80          . '>' );
81
82 if ( ref $Message ) {
83     my @stack;
84     my $para = '';
85     my $i    = 0;
86
87 AGAIN: foreach ( ; $i < @$Message; $i++ ) {
88         my $stanza = $Message->[$i];
89         if ( ref $stanza eq "HASH" ) {
90             # Fix message stanza nesting for Outlook's quoting styles
91             if (     $stanza->{raw}
92                  and not $stanza->{_outlooked}
93                  and $stanza->{raw} =~ /^               # start of an internal line
94                                         \s*             # optional whitespace
95                                         (?:
96                                             -{3,}       # at least three hyphens
97                                             \s*         # whitespace varies between Outlook versions
98                                                         # don't trigger on PGP signed message or signature blocks
99                                             (?!(?:BEGIN|END)\s+PGP)
100                                             \w          # at least one word character
101                                             [\w\s]{3,}? # the rest of the word(s), totalling at least 5 characters,
102                                                         #    loose to get different languages
103                                             \w          # at least one ending word character
104                                             \s*         # whitespace varies between Outlook versions
105                                             -{3,}       # at least three hyphens again
106                                           |
107                                             _{6,}       # OR: six or more underscores
108                                         )
109                                         \s*$            # optional whitespace until the end of the line
110                                        /xm )
111             {
112                 # There's content before the quoted message, but in the
113                 # same stanza.  Break it out!
114                 if ( my $start = $-[0] ) {
115                     my %preceding = %$stanza;
116
117                     # We don't process $stanza->{text} because we don't use it
118                     # and it isn't given to us by HTML::Quoted.  If we ever
119                     # need to, we can process it the same way as 'raw'.
120                     $preceding{raw} = substr($stanza->{raw}, 0, $start, '');
121
122                     # Replace the current stanza with the two we just created
123                     splice @$Message, $i, 1, \%preceding, $stanza;
124
125                     # Try it again from the top now that we've rejiggered our
126                     # stanzas.  We'll process the Outlook stanza again, and hit
127                     # the else below this time.
128                     redo;
129                 } else {
130                     # Nest the current stanza and everything that follows
131                     $stanza->{_outlooked}++;
132                     $stanza = $Message->[ $i ] = [ splice @$Message, $i ];
133                 }
134             }
135             else {
136                 $para .= ( defined $stanza->{raw} ? $stanza->{raw} : '' )."\n";
137             }
138         }
139         next unless ref $stanza eq "ARRAY";
140
141         $print_content->( \$para );
142         $para = '';
143
144         $Depth++;
145         push @stack, [ $Message, $i + 1 ];
146         ( $Message, $i ) = ( $stanza, -1 );
147
148         if ( $Depth == 1 ) {
149             $m->comp('FoldStanzaJS');
150         }
151         my @classes = ('message-stanza');
152         push @classes, $Depth == 1 ? 'closed' : 'open';
153         $m->out(   '<div class="' . join(" ", @classes) . '">' );
154     }
155     if ( length $para ) {
156         $print_content->( \$para );
157         $para = '';
158     }
159
160     if (@stack) {
161         ( $Message, $i ) = @{ pop @stack };
162         $Depth--;
163         $m->out('</div>');
164         goto AGAIN;
165     }
166 } else {
167     $print_content->( \$Message );
168 }
169
170 $m->out('</div>');
171 </%INIT>
172 <%ARGS>
173 $Message => undef
174 $Transaction => undef
175 $ContentType => 'text/plain'
176 </%ARGS>