diff options
Diffstat (limited to 'rt/share/html')
98 files changed, 461 insertions, 667 deletions
diff --git a/rt/share/html/Admin/Articles/Elements/Topics b/rt/share/html/Admin/Articles/Elements/Topics index 96ddaf00c..43ca9562c 100644 --- a/rt/share/html/Admin/Articles/Elements/Topics +++ b/rt/share/html/Admin/Articles/Elements/Topics @@ -105,7 +105,7 @@ $topic % } % if ($Action) { % unless ($Action eq "Move" and grep {$_->getNodeValue->Id == $Modify} $Element->getAllChildren) { -<li><input type="submit" name="<%$Prefix%>-<%$topic eq "root" ? 0 : $topic->Id%>" value="<&|/l&><%$Action%> here</&>" /></li> +<li><input type="submit" name="<%$Prefix%>-<%$topic eq "root" ? 0 : $topic->Id%>" value="<% $Action eq 'Move' ? loc('Move here') : loc('Add here') %>" /></li> % } % } </ul> diff --git a/rt/share/html/Admin/CustomFields/Modify.html b/rt/share/html/Admin/CustomFields/Modify.html index 20c3e9c4e..4ed86b60b 100644 --- a/rt/share/html/Admin/CustomFields/Modify.html +++ b/rt/share/html/Admin/CustomFields/Modify.html @@ -113,7 +113,7 @@ <div class="hints"> <&|/l&>RT can make this custom field's values into hyperlinks to another service.</&> <&|/l&>Fill in this field with a URL.</&> -<&|/l, '<tt>__id__</tt>', '<tt>__CustomField__</tt>' &>RT will replace [_1] and [_2] with the record's id and the custom field's value, respectively.</&> +<&|/l_unsafe, '<tt>__id__</tt>', '<tt>__CustomField__</tt>' &>RT will replace [_1] and [_2] with the record's id and the custom field's value, respectively.</&> </div></td></tr> <tr><td class="label"><&|/l&>Include page</&></td><td> @@ -121,7 +121,7 @@ <div class="hints"> <&|/l&>RT can include content from another web service when showing this custom field.</&> <&|/l&>Fill in this field with a URL.</&> -<&|/l, '<tt>__id__</tt>', '<tt>__CustomField__</tt>' &>RT will replace [_1] and [_2] with the record's id and the custom field's value, respectively.</&> +<&|/l_unsafe, '<tt>__id__</tt>', '<tt>__CustomField__</tt>' &>RT will replace [_1] and [_2] with the record's id and the custom field's value, respectively.</&> <i><&|/l&>Some browsers may only load content from the same domain as your RT server.</&></i> </div></td></tr> diff --git a/rt/share/html/Admin/Elements/EditCustomFields b/rt/share/html/Admin/Elements/EditCustomFields index aa7b62204..d9d9134e7 100755 --- a/rt/share/html/Admin/Elements/EditCustomFields +++ b/rt/share/html/Admin/Elements/EditCustomFields @@ -128,6 +128,7 @@ if ( $MoveCustomFieldDown ) { { if ( $UpdateCFs ) { foreach my $cf_id ( @AddCustomField ) { my $CF = RT::CustomField->new( $session{'CurrentUser'} ); + $CF->SetContextObject( $Object ); $CF->Load( $cf_id ); unless ( $CF->id ) { push @results, loc("Couldn't load CustomField #[_1]", $cf_id); @@ -138,6 +139,7 @@ if ( $UpdateCFs ) { } foreach my $cf_id ( @RemoveCustomField ) { my $CF = RT::CustomField->new( $session{'CurrentUser'} ); + $CF->SetContextObject( $Object ); $CF->Load( $cf_id ); unless ( $CF->id ) { push @results, loc("Couldn't load CustomField #[_1]", $cf_id); @@ -153,6 +155,7 @@ $m->callback(CallbackName => 'UpdateExtraFields', Results => \@results, Object = my $applied_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); $applied_cfs->LimitToLookupType($lookup); $applied_cfs->LimitToGlobalOrObjectId($id); +$applied_cfs->SetContextObject( $Object ); $applied_cfs->ApplySortOrder; my $not_applied_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); diff --git a/rt/share/html/Admin/Elements/EditRights b/rt/share/html/Admin/Elements/EditRights index e5b9908b5..e67359313 100644 --- a/rt/share/html/Admin/Elements/EditRights +++ b/rt/share/html/Admin/Elements/EditRights @@ -110,13 +110,13 @@ for my $category (@$Principals) { id="AddPrincipalForRights-<% lc $AddPrincipal %>" /> <script type="text/javascript"> jQuery(function() { - jQuery("#AddPrincipalForRights-<% lc $AddPrincipal %>").keyup(function(){ + jQuery("#AddPrincipalForRights-"+<% lc $AddPrincipal |n,j%>).keyup(function(){ toggle_addprincipal_validity(this, true); }); % if (lc $AddPrincipal eq 'group') { - jQuery("#AddPrincipalForRights-<% lc $AddPrincipal %>").autocomplete({ - source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Groups", + jQuery("#AddPrincipalForRights-"+<% lc $AddPrincipal |n,j%>).autocomplete({ + source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Groups", select: addprincipal_onselect, change: addprincipal_onchange }); diff --git a/rt/share/html/Admin/Elements/Portal b/rt/share/html/Admin/Elements/Portal index d5e75c598..821ed5728 100644 --- a/rt/share/html/Admin/Elements/Portal +++ b/rt/share/html/Admin/Elements/Portal @@ -47,6 +47,6 @@ %# END BPS TAGGED BLOCK }}} <div id="rt-portal"> <&| /Widgets/TitleBox, title => 'RT Portal' &> -<iframe src="http://bestpractical.com/rt/integration/news?utm_source=rt&utm_medium=iframe&utm_campaign=<%$RT::VERSION%>"></iframe> +<iframe src="https://bestpractical.com/rt/integration/news?utm_source=rt&utm_medium=iframe&utm_campaign=<%$RT::VERSION%>"></iframe> </&> </div> diff --git a/rt/share/html/Admin/Elements/SelectNewGroupMembers b/rt/share/html/Admin/Elements/SelectNewGroupMembers index f386ba551..8778daec0 100755 --- a/rt/share/html/Admin/Elements/SelectNewGroupMembers +++ b/rt/share/html/Admin/Elements/SelectNewGroupMembers @@ -50,8 +50,8 @@ <input type="text" value="" name="<% $Name %>Users" id="<% $Name %>Users" /><br /> <script type="text/javascript"> jQuery(function(){ - jQuery("#<% $Name %>Users").autocomplete({ - source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Users?return=Name;privileged=1;exclude=<% $user_ids |u %>", + jQuery("#"+<% $Name |n,j%>+"Users").autocomplete({ + source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Users?return=Name;privileged=1;exclude="+<% $user_ids |n,u,j %>, // Auto-submit once a user is chosen select: function( event, ui ) { jQuery(event.target).val(ui.item.value); @@ -67,8 +67,8 @@ jQuery(function(){ <input type="text" value="" name="<% $Name %>Groups" id="<% $Name %>Groups" /><br /> <script type="text/javascript"> jQuery(function(){ - jQuery("#<% $Name %>Groups").autocomplete({ - source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Groups?exclude=<% $group_ids |u %>", + jQuery("#"+<% $Name |n,j%>+"Groups").autocomplete({ + source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Groups?exclude="+<% $group_ids |n,u,j %>, // Auto-submit once a user is chosen select: function( event, ui ) { jQuery(event.target).val(ui.item.value); diff --git a/rt/share/html/Admin/Groups/index.html b/rt/share/html/Admin/Groups/index.html index bd07b736a..ef7395f3e 100755 --- a/rt/share/html/Admin/Groups/index.html +++ b/rt/share/html/Admin/Groups/index.html @@ -57,7 +57,7 @@ <script type="text/javascript"> jQuery(function(){ jQuery("#autocomplete-GroupString").autocomplete({ - source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Groups", + source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Groups", // Auto-submit once a group is chosen select: function( event, ui ) { jQuery(event.target).val(ui.item.value); diff --git a/rt/share/html/Admin/Tools/Queries.html b/rt/share/html/Admin/Tools/Queries.html index 2fe2d5ac1..dbc6fc5fe 100644 --- a/rt/share/html/Admin/Tools/Queries.html +++ b/rt/share/html/Admin/Tools/Queries.html @@ -79,7 +79,7 @@ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'Super <li> <tt><% $request->{Path} %></tt> - <i><&|/l, sprintf('%.4f', $seconds) &>[_1]s</&></i> - <a href="#" onclick="return hideshow('queries-<%$r%>');"><&|/l, $count &>Toggle [quant,_1,query,queries]</&></a> + <a href="#" onclick="return hideshow(<% "queries-$r" |n,j%>);"><&|/l, $count &>Toggle [quant,_1,query,queries]</&></a> <table id="queries-<%$r%>" class="tablesorter hidden"> <thead> <tr> @@ -115,7 +115,7 @@ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'Super <br><tt>[<% join(", ", @$b) %>]</tt> % } % } - <a class="query-stacktrace-toggle" href="#" onclick="return hideshow('trace-<%$r%>-<%$s%>');"><&|/l &>Toggle stack trace</&></a> + <a class="query-stacktrace-toggle" href="#" onclick="return hideshow(<% "trace-$r-$s" |n,j%>);"><&|/l &>Toggle stack trace</&></a> <pre id="trace-<%$r%>-<%$s%>" class="hidden"><% $trace %></pre> </td> </tr> diff --git a/rt/share/html/Admin/Tools/Shredder/Dumps/dhandler b/rt/share/html/Admin/Tools/Shredder/Dumps/dhandler index 8b84cf4d9..0d24fa0af 100644 --- a/rt/share/html/Admin/Tools/Shredder/Dumps/dhandler +++ b/rt/share/html/Admin/Tools/Shredder/Dumps/dhandler @@ -48,9 +48,6 @@ <%ATTR> AutoFlush => 0 </%ATTR> -<%FLAGS> -inherit => undef -</%FLAGS> <%INIT> my $arg = $m->dhandler_arg; $m->abort(404) if $arg =~ m{\.\.|/|\\}; @@ -64,5 +61,5 @@ my $buf; while( read $fh, $buf, 1024*1024 ) { $m->out($buf); } -return 0; +$m->abort; </%INIT> diff --git a/rt/share/html/Admin/Tools/Shredder/Elements/Error/NoStorage b/rt/share/html/Admin/Tools/Shredder/Elements/Error/NoStorage index ce934111c..ae3b96e9b 100644 --- a/rt/share/html/Admin/Tools/Shredder/Elements/Error/NoStorage +++ b/rt/share/html/Admin/Tools/Shredder/Elements/Error/NoStorage @@ -52,5 +52,5 @@ $Path => '' <& /Elements/Tabs &> <div class="error"> % my $path_tag = q{<span class="file-path">} . $m->interp->apply_escapes($Path, 'h') . q{</span>}; -<&|/l, $path_tag &>Shredder needs a directory to write dumps to. Please ensure that the directory [_1] exists and that it is writable by your web server.</&> +<&|/l_unsafe, $path_tag &>Shredder needs a directory to write dumps to. Please ensure that the directory [_1] exists and that it is writable by your web server.</&> </div> diff --git a/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment b/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment index 11b876bf2..0da910d77 100644 --- a/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment +++ b/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment @@ -49,6 +49,6 @@ $Object => undef </%ARGS> % my $name = (defined $Object->Filename and length $Object->Filename) ? $Object->Filename : loc("(no value)"); -<a href="<% RT->Config->Get('WebURL') %>/Ticket/Attachment/<% $Object->TransactionId %>/<% $Object->id %>/"> +<a href="<% RT->Config->Get('WebPath') %>/Ticket/Attachment/<% $Object->TransactionId %>/<% $Object->id %>/"> <% loc('Attachment') %>(<% loc('id') %>:<% $Object->id %>, <% loc('Filename') %>: <% $name %>) </a> diff --git a/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Ticket b/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Ticket index 13547ad30..35f1aa8d8 100644 --- a/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Ticket +++ b/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--Ticket @@ -48,6 +48,6 @@ <%ARGS> $Object => undef </%ARGS> -<a href="<% RT->Config->Get('WebURL') %>/Ticket/Display.html?id=<% $Object->id %>"> +<a href="<% RT->Config->Get('WebPath') %>/Ticket/Display.html?id=<% $Object->id %>"> <% loc('Ticket') %>(<% loc('id') %>:<% $Object->id %>, <% loc('Subject') %>: <% substr($Object->Subject, 0, 30) %>...) </a> diff --git a/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--User b/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--User index f77169a6f..d7627eb14 100644 --- a/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--User +++ b/rt/share/html/Admin/Tools/Shredder/Elements/Object/RT--User @@ -48,6 +48,6 @@ <%ARGS> $Object => undef </%ARGS> -<a href="<% RT->Config->Get('WebURL') %>/Admin/Users/Modify.html?id=<% $Object->id %>"> +<a href="<% RT->Config->Get('WebPath') %>/Admin/Users/Modify.html?id=<% $Object->id %>"> <% loc('User') %>(<% loc('id') %>:<% $Object->id %>, <% loc('Name') %>: <% $Object->Name %>) </a> diff --git a/rt/share/html/Admin/Users/Modify.html b/rt/share/html/Admin/Users/Modify.html index b14f936f4..05dde17f2 100755 --- a/rt/share/html/Admin/Users/Modify.html +++ b/rt/share/html/Admin/Users/Modify.html @@ -203,7 +203,7 @@ % if ($UserObj->id) { <& /Elements/EditCustomField, %ARGS, Object => $UserObj, CustomField => $CF &> % } else { -<& /Elements/EditCustomField, %ARGS, NamePrefix => 'Object-RT::User-new-CustomField-', CustomField => $CF &> +<& /Elements/EditCustomField, %ARGS, NamePrefix => 'Object-RT::User--CustomField-', CustomField => $CF &> % } </td></tr> % } @@ -282,12 +282,6 @@ else { if ($val) { push @results, $msg; - foreach my $key ( keys %ARGS) { - # Convert custom fields on the "new" object to custom fields on the one we've just created - if ($key =~ /^Object-RT::User-new-CustomField-(.*)$/) { - $ARGS{'Object-RT::User-'.$val.'-CustomField-'.$1} = delete $ARGS{$key}; - } - } push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj ); } else { push @results, loc('User could not be created: [_1]', $msg); diff --git a/rt/share/html/Admin/Users/index.html b/rt/share/html/Admin/Users/index.html index a1e3facd7..adcfeb5b9 100755 --- a/rt/share/html/Admin/Users/index.html +++ b/rt/share/html/Admin/Users/index.html @@ -62,7 +62,7 @@ <script type="text/javascript"> jQuery(function(){ jQuery("#autocomplete-UserString").autocomplete({ - source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Users?return=Name", + source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Users?return=Name", // Auto-submit once a user is chosen select: function( event, ui ) { jQuery(event.target).val(ui.item.value); diff --git a/rt/share/html/Approvals/Elements/PendingMyApproval b/rt/share/html/Approvals/Elements/PendingMyApproval index 75ad5e1ab..d2061da84 100755 --- a/rt/share/html/Approvals/Elements/PendingMyApproval +++ b/rt/share/html/Approvals/Elements/PendingMyApproval @@ -63,9 +63,9 @@ <input type="checkbox" class="checkbox" value="1" name="ShowRejected" <% defined($ARGS{'ShowRejected'}) && $ARGS{'ShowRejected'} && qq[checked="checked"] |n%> /> <&|/l&>Show denied requests</&><br /> <input type="checkbox" class="checkbox" value="1" name="ShowDependent" <% defined($ARGS{'ShowDependent'}) && $ARGS{'ShowDependent'} && qq[checked="checked"] |n%> /> <&|/l&>Show requests awaiting other approvals</&><br /> -<&|/l, qq{<input size='15' class="ui-datepicker" value='}.($created_before->Unix > 0 &&$created_before->ISO(Timezone => 'user'))."' name='CreatedBefore' id='CreatedBefore' />"&>Only show approvals for requests created before [_1]</&><br /> +<&|/l_unsafe, qq{<input size='15' class="ui-datepicker" value='}.($created_before->Unix > 0 &&$created_before->ISO(Timezone => 'user'))."' name='CreatedBefore' id='CreatedBefore' />"&>Only show approvals for requests created before [_1]</&><br /> -<&|/l, qq{<input size='15' class="ui-datepicker" value='}.( $created_after->Unix >0 && $created_after->ISO(Timezone => 'user'))."' name='CreatedAfter' id='CreatedAfter' />"&>Only show approvals for requests created after [_1]</&> +<&|/l_unsafe, qq{<input size='15' class="ui-datepicker" value='}.( $created_after->Unix >0 && $created_after->ISO(Timezone => 'user'))."' name='CreatedAfter' id='CreatedAfter' />"&>Only show approvals for requests created after [_1]</&> </&> <%init> diff --git a/rt/share/html/Articles/Article/Edit.html b/rt/share/html/Articles/Article/Edit.html index 756aa2cc9..d14c33076 100644 --- a/rt/share/html/Articles/Article/Edit.html +++ b/rt/share/html/Articles/Article/Edit.html @@ -157,6 +157,7 @@ elsif ( $id eq 'new' ) { my $cfid = $1; my $cf = RT::CustomField->new( $session{'CurrentUser'} ); + $cf->SetContextObject( $ArticleObj ); $cf->Load( $cfid ); unless ( $cf->id ) { $RT::Logger->error( "Couldn't load custom field #". $cfid ); diff --git a/rt/share/html/Articles/Article/Elements/EditTopics b/rt/share/html/Articles/Article/Elements/EditTopics index 807360bf2..82e907135 100644 --- a/rt/share/html/Articles/Article/Elements/EditTopics +++ b/rt/share/html/Articles/Article/Elements/EditTopics @@ -47,35 +47,32 @@ %# END BPS TAGGED BLOCK }}} <input type="hidden" name="EditTopics" value="1" /> <select multiple size="10" name="Topics"> -<%perl> -if (@Classes) { - $m->print("<optgroup label=\"Current classes (".join (' ',map {$_->Name} @Classes).")\">") - unless $OnlyThisClass; - $inTree->traverse(sub { - my $tree = shift; - my $topic = $tree->getNodeValue; - $m->print("<option value=\"".$topic->Id."\"" - .(exists $topics{$topic->Id} ? " selected" : "").">" - .(" " x ($tree->getDepth*5)).($topic->Name || loc("(no name)"))."</option>\n"); - }); -} -unless ($OnlyThisClass) { - my $class = $Classes[-1]->Id; - $otherTree->traverse(sub { - my $tree = shift; - my $topic = $tree->getNodeValue; - unless ($topic->ObjectId == $class) { - $class = $topic->ObjectId; - $m->print("</optgroup>\n"); - my $c = RT::Class->new($session{'CurrentUser'}); - $c->Load($topic->ObjectId); - $m->print("<optgroup label=\"".$c->Name."\">\n"); - } - $m->print("<option value=\"".$topic->Id."\"" - .(exists $topics{$topic->Id} ? " selected" : "").">" - .(" " x ($tree->getDepth*5)).($topic->Name || loc("(no name)"))."</option>\n"); - }); -</%perl> +% if (@Classes) { +% unless ($OnlyThisClass) { +<optgroup label="Current classes (<% join(" ", map {$_->Name} @Classes) %>)"> +% } +% $inTree->traverse(sub { +% my $tree = shift; +% my $topic = $tree->getNodeValue; +<option value="<% $topic->Id %>" <% exists $topics{$topic->Id} ? "selected" : "" %> >\ +<% " " x ($tree->getDepth*5) |n %><% $topic->Name || loc("(no name)") %></option> +% }); +% } +% unless ($OnlyThisClass) { +% my $class = $Classes[-1]->Id; +% $otherTree->traverse(sub { +% my $tree = shift; +% my $topic = $tree->getNodeValue; +% unless ($topic->ObjectId == $class) { +% $class = $topic->ObjectId; +</optgroup> +% my $c = RT::Class->new($session{'CurrentUser'}); +% $c->Load($topic->ObjectId); +<optgroup label="<% $c->Name %>"> +% } +<option value="<% $topic->Id %>" <% exists $topics{$topic->Id} ? "selected" : "" %> >\ +<% " " x ($tree->getDepth*5) |n %><% $topic->Name || loc("(no name)") %></option> +% }); </optgroup> % } </select> diff --git a/rt/share/html/Articles/Article/ExtractIntoClass.html b/rt/share/html/Articles/Article/ExtractIntoClass.html index adf23fc0f..f3618feda 100644 --- a/rt/share/html/Articles/Article/ExtractIntoClass.html +++ b/rt/share/html/Articles/Article/ExtractIntoClass.html @@ -54,7 +54,7 @@ % my $Classes = RT::Classes->new($session{'CurrentUser'}); % $Classes->LimitToEnabled(); % while (my $Class = $Classes->Next) { -<li><a href="ExtractIntoTopic.html?Ticket=<%$Ticket%>&Class=<%$Class->Id%>" onclick="document.getElementById('topics-<% $Class->Id %>').style.display = (document.getElementById('topics-<% $Class->Id %>').style.display == 'block') ? 'none' : 'block'; return false;"><%$Class->Name%></a>: +<li><a href="ExtractIntoTopic.html?Ticket=<%$Ticket%>&Class=<%$Class->Id%>" onclick="document.getElementById('topics-'+<% $Class->Id |n,j%>).style.display = (document.getElementById('topics-'+<% $Class->Id |n,j%>).style.display == 'block') ? 'none' : 'block'; return false;"><%$Class->Name%></a>: <%$Class->Description%> <div id="topics-<%$Class->Id%>" style="display: none"> <form action="ExtractFromTicket.html"> diff --git a/rt/share/html/Articles/Topics.html b/rt/share/html/Articles/Topics.html index 9a07c089a..5187315f7 100644 --- a/rt/share/html/Articles/Topics.html +++ b/rt/share/html/Articles/Topics.html @@ -48,7 +48,6 @@ <& /Elements/Header, Title => loc('Browse by topic') &> <& /Elements/Tabs &> -<& /Elements/ListActions, actions => \@Actions &> <a href="Topics.html"><&|/l&>All topics</&></a> % if (defined $class) { > <a href="Topics.html?class=<%$currclass_id%>"><% $currclass_name %></a> @@ -59,71 +58,41 @@ % } <br /> <h1><&|/l&>Browse by topic</&></h1> -<%perl> -if (defined $class) { - $m->print('<h2>'.'<a href="'. - RT->Config->Get('WebPath')."/Articles/Topics.html?class=" . $currclass_id - .'">'.$currclass_name."</a></h2>\n"); - ProduceTree(\@Actions, $currclass, $currclass_id, $currclass_name, 0, $id); -} else { - $m->print("<ul>\n"); - while (my $c = $Classes->Next) { - $m->print('<li><h2>'.'<a href="'. - RT->Config->Get('WebPath')."/Articles/Topics.html?class=" . $c->Id - .'">'.$c->Name."</a></h2>\n"); - $m->print("\n</li>\n"); - } - $m->print(qq|<li><h2><a href="|.RT->Config->Get('WebPath').qq|/Articles/Topics.html?class=0">|.loc('Global Topics').qq|</a></h2></li>\n|); - $m->print("</ul>\n"); -} -</%perl> +% if (defined $class) { +<h2><a href="<% RT->Config->Get('WebPath') %>/Articles/Topics.html?class=<% $currclass_id %>"><% $currclass_name %></a></h2> +% my $rtopic = RT::Topic->new( $session{'CurrentUser'} ); +% $rtopic->Load($id); +% unless ( $rtopic->Id() +% && $rtopic->ObjectId() == $currclass->Id ) +% { +% # Show all of them +% $ProduceTree->( 0 ); +% } else { +% my @showtopics = ( $rtopic ); +% my $parent = $rtopic->ParentObj; +% while ( $parent->Id ) { +% unshift @showtopics, $parent; +% $parent = $parent->ParentObj; +% } +% # List the topics. +% for my $t ( @showtopics ) { +<ul><li><& /Articles/Elements/ShowTopicLink, Topic => $t, Class => $currclass_id &> +% $ProduceTree->( $id ) if $t->Id == $id; +% } +% for ( @showtopics ) { + </li></ul> +% } +% } +% } else { +<ul> +% while (my $c = $Classes->Next) { +<li><h2><a href="<% RT->Config->Get('WebPath') %>/Articles/Topics.html?class=<% $c->Id %>"><% $c->Name %></a></h2></li> +% } +<li><h2><a href="<% RT->Config->Get('WebPath') %>/Articles/Topics.html?class=0"><&|/l&>Global Topics</&></a></h2></li> +</ul> +% } <br /> -<%perl> -my @articles; -if ($id or $showall) { - my $Articles = RT::ObjectTopics->new($session{'CurrentUser'}); - $Articles->Limit(FIELD => 'ObjectType', VALUE => 'RT::Article'); - if ($id) { - $Articles->Limit(FIELD => 'Topic', VALUE => $id, ENTRYAGGREGATOR => 'OR'); - if ($showall) { - my $kids = $currtopic->Children; - while (my $k = $kids->Next) { - $Articles->Limit(FIELD => 'Topic', VALUE => $k->Id, - ENTRYAGGREGATOR => 'OR'); - } - } - } - @articles = map {$a = RT::Article->new($session{'CurrentUser'}); $a->Load($_->ObjectId); $a} @{$Articles->ItemsArrayRef} -} elsif ($class) { - my $Articles = RT::Articles->new($session{'CurrentUser'}); - my $TopicsAlias = $Articles->Join( - TYPE => 'left', - ALIAS1 => 'main', - FIELD1 => 'id', - TABLE2 => 'ObjectTopics', - FIELD2 => 'ObjectId', - ); - $Articles->Limit( - LEFTJOIN => $TopicsAlias, - FIELD => 'ObjectType', - VALUE => 'RT::Article', - ); - $Articles->Limit( - ALIAS => $TopicsAlias, - FIELD => 'Topic', - OPERATOR => 'IS', - VALUE => 'NULL', - QUOTEVALUE => 0, - ); - $Articles->Limit( - FIELD => 'Class', - OPERATOR => '=', - VALUE => $class, - ); - @articles = @{$Articles->ItemsArrayRef}; -} -</%perl> % if (@articles) { % if ($id) { @@ -139,7 +108,6 @@ if ($id or $showall) { % } <%init> -my @Actions; my $Classes; my $currclass; my $currclass_id; @@ -167,106 +135,65 @@ if ($id) { $currtopic->Load($id); } -# A subroutine that iterates through topics and their children, producing -# the necessary ul, li, and href links for the table of contents. Thank -# heaven for query caching. The $restrict variable is used to display only -# the branch of the hierarchy which contains that topic ID. - -sub ProduceTree { - my ( $Actions, $currclass, $currclass_id, $currclass_name, $parentid, $restrictid ) = @_; - $parentid = 0 unless $parentid; - - # Deal with tree restriction, if any. - if ($restrictid) { - my $rtopic = RT::Topic->new( $session{'CurrentUser'} ); - $rtopic->Load($restrictid); - unless ( $rtopic->Id() - && $rtopic->ObjectId() == $currclass_id ) - { - push( @{$Actions},"Could not restrict view to topic $restrictid"); - - # Start over, without the restriction. - &ProduceTree( $Actions, $currclass, $currclass_id, $currclass_name, $parentid, undef ); - } else { - my @showtopics; - push( @showtopics, $rtopic ); - my $parent = $rtopic->ParentObj; - while ( $parent->Id ) { - push( @showtopics, $parent ); - my $newparent = $parent->ParentObj; - $parent = $newparent; - } - - # List the topics. - my $indents = @showtopics; - while ( my $t = pop @showtopics ) { - print "<ul>"; - print &MakeLinks( $t, $currclass, $currclass_id, $currclass_name, $t->Children->Count ); - if ( $t->Id == $restrictid ) { - &ProduceTree( $Actions, $currclass, $currclass_id, $currclass_name, $restrictid, undef ); - } - } - print "</ul>" x $indents; - } - } else { - - # No restriction in place. Build the entire tree. - my $topics = RT::Topics->new( $session{'CurrentUser'} ); - $topics->LimitToObject($currclass); - $topics->LimitToKids($parentid); - $topics->OrderBy( FIELD => 'Name' ); - print "<ul>" if $topics->Count; - while ( my $t = $topics->Next ) { - if ( $t->Children->Count ) { - print &MakeLinks( $t, $currclass, $currclass_id, $currclass_name, 1 ); - &ProduceTree( $Actions, $currclass, $currclass_id, $currclass_name, $t->Id ); - } else { - print &MakeLinks( $t, $currclass, $currclass_id, $currclass_name, 0 ); - } - } - print "</ul>\n" if $topics->Count; +my $ProduceTree; +$ProduceTree = sub { + my ( $parentid ) = @_; + my $topics = RT::Topics->new( $session{'CurrentUser'} ); + $topics->LimitToObject($currclass); + $topics->LimitToKids($parentid || 0); + $topics->OrderBy( FIELD => 'Name' ); + return unless $topics->Count; + $m->out("<ul>"); + while ( my $t = $topics->Next ) { + $m->out("<li>"); + $m->comp("/Articles/Elements/ShowTopicLink", + Topic => $t, + Class => $currclass_id, + ); + $ProduceTree->( $t->Id ) if $t->Children->Count; + $m->out("</li>"); } -} - -sub MakeLinks { - my ( $topic, $currclass, $currclass_id, $currclass_name, $haschild ) = @_; - my $query; - my $output; - - if ( ref($topic) eq 'RT::Topic' ) { - - my $topic_info = $topic->Name() || loc("(no name)"); - $topic_info .= ": " . $topic->Description() if $topic->Description; - - if ($haschild) { # has topics below it - $query = "Topics.html?id=" . $topic->Id . "&class=" . $currclass_id; - $output = qq(<li><a href="$query">$topic_info</a>); - } else { - $output = qq(<li>$topic_info); - } + $m->out("</ul>"); +}; - my $Articles = RT::ObjectTopics->new( $session{'CurrentUser'} ); - $Articles->Limit( FIELD => 'ObjectType', VALUE => 'RT::Article' ); - $Articles->Limit( FIELD => 'Topic', VALUE => $topic->Id ); - if ( $Articles->Count ) { - my $article_text = " (" . loc( "[quant,_1,article]", $Articles->Count ) . ")"; - my $query = "Topics.html?id=" . $topic->Id . "&class=$currclass_id&showall=1"; - $output .= qq(<a href="$query">$article_text</a>); - } - - $output .= "</li>\n"; - - } else { - - # This builds a link for the class specified, with no particular topic. - $query = "Topics.html?class=" . $currclass_id; - $output = "<li><a href=\"$query\">" . $currclass_name . "</a>"; - $output .= ": " . $currclass->Description if $currclass->Description; +my @articles; +if ($id) { + my $Articles = RT::ObjectTopics->new($session{'CurrentUser'}); + $Articles->Limit(FIELD => 'ObjectType', VALUE => 'RT::Article'); + $Articles->Limit(FIELD => 'Topic', VALUE => $id); + while (my $objtopic = $Articles->Next) { + my $a = RT::Article->new($session{'CurrentUser'}); + $a->Load($objtopic->ObjectId); + push @articles, $a; } - - return $output; +} elsif ($class) { + my $Articles = RT::Articles->new($session{'CurrentUser'}); + my $TopicsAlias = $Articles->Join( + TYPE => 'left', + ALIAS1 => 'main', + FIELD1 => 'id', + TABLE2 => 'ObjectTopics', + FIELD2 => 'ObjectId', + ); + $Articles->Limit( + LEFTJOIN => $TopicsAlias, + FIELD => 'ObjectType', + VALUE => 'RT::Article', + ); + $Articles->Limit( + ALIAS => $TopicsAlias, + FIELD => 'Topic', + OPERATOR => 'IS', + VALUE => 'NULL', + QUOTEVALUE => 0, + ); + $Articles->Limit( + FIELD => 'Class', + OPERATOR => '=', + VALUE => $class, + ); + @articles = @{$Articles->ItemsArrayRef}; } - </%init> <%args> diff --git a/rt/share/html/Elements/CollectionAsTable/Header b/rt/share/html/Elements/CollectionAsTable/Header index 81d8bbb27..20586f9c3 100644 --- a/rt/share/html/Elements/CollectionAsTable/Header +++ b/rt/share/html/Elements/CollectionAsTable/Header @@ -129,11 +129,11 @@ foreach my $col ( @Format ) { if $OrderBy[0] && ($OrderBy[0] eq $attr or "$attr|$OrderBy[0]" =~ /^(Created|id)\|(Created|id)$/); $m->out( - '<a href="' . $BaseURL + '<a href="' . $m->interp->apply_escapes($BaseURL . $m->comp( '/Elements/QueryString', %$generic_query_args, OrderBy => $attr, Order => $new_order - ) + ), 'h') . '">'. loc($title) .'</a>' ); } diff --git a/rt/share/html/Elements/CollectionList b/rt/share/html/Elements/CollectionList index 0c816fe2f..402a272b4 100644 --- a/rt/share/html/Elements/CollectionList +++ b/rt/share/html/Elements/CollectionList @@ -68,7 +68,7 @@ if ( $Rows ) { # collection is ordered or not if ( @OrderBy && ($AllowSorting || !$Collection->{'order_by'}) ) { if ( $OrderBy[0] =~ /\|/ ) { - @OrderBy = split /\|/, $OrderBy[0]; + @OrderBy = grep length($_), split /\|/, $OrderBy[0]; @Order = split /\|/,$Order[0]; } $Collection->OrderByCols( diff --git a/rt/share/html/Elements/CollectionListPaging b/rt/share/html/Elements/CollectionListPaging index b1faa2101..26c082348 100644 --- a/rt/share/html/Elements/CollectionListPaging +++ b/rt/share/html/Elements/CollectionListPaging @@ -55,22 +55,24 @@ $URLParams => undef </%ARGS> <%INIT> +$BaseURL = $m->interp->apply_escapes($BaseURL, 'h'); + $m->out(qq{<div class="paging">}); if ($Pages == 1) { $m->out(loc('Page 1 of 1')); } else{ $m->out(loc('Page') . ' '); -my $prev = $m->comp( +my $prev = $m->interp->apply_escapes($m->comp( '/Elements/QueryString', %$URLParams, Page => ( $CurrentPage - 1 ) - ); -my $next = $m->comp( + ), 'h'); +my $next = $m->interp->apply_escapes($m->comp( '/Elements/QueryString', %$URLParams, Page => ( $CurrentPage + 1 ) - ); + ), 'h'); my %show; $show{1} = 1; $show{$_} = 1 for (($CurrentPage - 2)..($CurrentPage + 2)); @@ -81,7 +83,7 @@ for my $number ( 1 .. $Pages ) { if ( $show{$number} ) { $dots = undef; my $qs = - $m->comp( '/Elements/QueryString', %$URLParams, Page => $number ); + $m->interp->apply_escapes($m->comp( '/Elements/QueryString', %$URLParams, Page => $number ), 'h'); $m->out(qq{<span class="pagenum">}); if ( $number == $CurrentPage ) { $m->out(qq{<span class="currentpage">$number</span> }); diff --git a/rt/share/html/Elements/ColumnMap b/rt/share/html/Elements/ColumnMap index 745e57f83..b9c3b4bc8 100644 --- a/rt/share/html/Elements/ColumnMap +++ b/rt/share/html/Elements/ColumnMap @@ -120,14 +120,16 @@ my $COLUMN_MAP = { my $name = $_[1] || 'SelectedTickets'; my $checked = $m->request_args->{ $name .'All' }? 'checked="checked"': ''; - return \qq{<input type="checkbox" name="${name}All" value="1" $checked - onclick="setCheckbox(this.form, '$name', this.checked)" />}; + return \qq{<input type="checkbox" name="}, $name, \qq{All" value="1" $checked + onclick="setCheckbox(this.form, }, + $m->interp->apply_escapes($name,'j'), + \qq{, this.checked)" />}; }, value => sub { my $id = $_[0]->id; my $name = $_[2] || 'SelectedTickets'; - return \qq{<input type="checkbox" name="$name" value="$id" checked="checked" />} + return \qq{<input type="checkbox" name="}, $name, \qq{" value="$id" checked="checked" />} if $m->request_args->{ $name . 'All'}; my $arg = $m->request_args->{ $name }; @@ -138,7 +140,7 @@ my $COLUMN_MAP = { elsif ( $arg ) { $checked = 'checked="checked"' if $arg == $id; } - return \qq{<input type="checkbox" name="$name" value="$id" $checked />} + return \qq{<input type="checkbox" name="}, $name, \qq{" value="$id" $checked />} }, }, RadioButton => { diff --git a/rt/share/html/Elements/CreateTicket b/rt/share/html/Elements/CreateTicket index 6e541db9b..6702abcbf 100755 --- a/rt/share/html/Elements/CreateTicket +++ b/rt/share/html/Elements/CreateTicket @@ -51,7 +51,7 @@ % my $button_start = '<input type="submit" class="button" value="'; % my $button_end = '" />'; % my $queue_selector = $m->scomp('/Elements/SelectNewTicketQueue', OnChange => 'document.CreateTicketInQueue.submit()', SendTo => $SendTo ); -<&|/l, $button_start, $button_end, $queue_selector &>[_1]New ticket in[_2] [_3]</&> +<&|/l_unsafe, $button_start, $button_end, $queue_selector &>[_1]New ticket in[_2] [_3]</&> % $m->callback(CallbackName => 'BeforeFormEnd'); </form> <%ARGS> diff --git a/rt/share/html/Elements/EditCustomField b/rt/share/html/Elements/EditCustomField index c7c8bfa36..b74c4844e 100644 --- a/rt/share/html/Elements/EditCustomField +++ b/rt/share/html/Elements/EditCustomField @@ -85,7 +85,7 @@ if ($MaxValues == 1 && $Values) { } # The "Magic" hidden input causes RT to know that we were trying to edit the field, even if # we don't see a value later, since browsers aren't compelled to submit empty form fields -$m->out("\n".'<input type="hidden" class="hidden" name="'.$NamePrefix.$CustomField->Id.'-Values-Magic" value="1" />'."\n"); +$m->out("\n".'<input type="hidden" class="hidden" name="'.$m->interp->apply_escapes($NamePrefix, 'h').$CustomField->Id.'-Values-Magic" value="1" />'."\n"); my $EditComponent = "EditCustomField$Type"; $m->callback( %ARGS, CallbackName => 'EditComponentName', Name => \$EditComponent, CustomField => $CustomField, Object => $Object ); diff --git a/rt/share/html/Elements/EditCustomFieldAutocomplete b/rt/share/html/Elements/EditCustomFieldAutocomplete index aaf551716..911e60707 100644 --- a/rt/share/html/Elements/EditCustomFieldAutocomplete +++ b/rt/share/html/Elements/EditCustomFieldAutocomplete @@ -49,10 +49,10 @@ <textarea cols="<% $Cols %>" rows="<% $Rows %>" name="<% $name %>-Values" id="<% $name %>-Values" class="CF-<%$CustomField->id%>-Edit"><% $Default || '' %></textarea> <script type="text/javascript"> -var id = '<% $name . '-Values' %>'; +var id = <% "$name-Values" |n,j%>; id = id.replace(/:/g,'\\:'); jQuery('#'+id).autocomplete( { - source: "<%RT->Config->Get('WebPath')%>/Helpers/Autocomplete/CustomFieldValues?<% $name . '-Values' %>", + source: <%RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/CustomFieldValues?"+<% $Context |n,j %>+<% "$name-Values" |n,u,j%>, focus: function () { // prevent value inserted on focus return false; @@ -73,10 +73,10 @@ jQuery('#'+id).autocomplete( { % } else { <input type="text" id="<% $name %>-Value" name="<% $name %>-Value" class="CF-<%$CustomField->id%>-Edit" value="<% $Default || '' %>"/> <script type="text/javascript"> -var id = '<% $name . '-Value' %>'; +var id = <% "$name-Value" |n,j%>; id = id.replace(/:/g,'\\:'); jQuery('#'+id).autocomplete( { - source: "<%RT->Config->Get('WebPath')%>/Helpers/Autocomplete/CustomFieldValues?<% $name . '-Value' %>" + source: <%RT->Config->Get('WebPath')|n,j%>+"/Helpers/Autocomplete/CustomFieldValues?"+<% $Context |n,j %>+<% "$name-Value" |n,u,j%> } ); % } @@ -92,6 +92,11 @@ if ( $Multiple and $Values ) { $Default .= $value->Content ."\n"; } } +my $Context = ""; +if ($CustomField->ContextObject) { + $Context .= "ContextId=" . $CustomField->ContextObject->Id . "&"; + $Context .= "ContextType=". ref($CustomField->ContextObject) . "&"; +} </%INIT> <%ARGS> $CustomField => undef diff --git a/rt/share/html/Elements/EditCustomFieldSelect b/rt/share/html/Elements/EditCustomFieldSelect index b3fefbd49..ed6bb146f 100644 --- a/rt/share/html/Elements/EditCustomFieldSelect +++ b/rt/share/html/Elements/EditCustomFieldSelect @@ -55,7 +55,7 @@ % if (!$HideCategory and @category and not $CustomField->BasedOnObj->id) { <script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/cascaded.js"></script> %# XXX - Hide this select from w3m? - <select onchange="filter_cascade('<% $id %>-Values', this.value)" name="<% $id %>-Category" class="CF-<%$CustomField->id%>-Edit"> + <select onchange="filter_cascade(<% "$id-Values" |n,j%>, this.value)" name="<% $id %>-Category" class="CF-<%$CustomField->id%>-Edit"> <option value=""<% !$selected && qq[ selected="selected"] |n %>><&|/l&>-</&></option> % foreach my $cat (@category) { % my ($depth, $name) = @$cat; @@ -66,12 +66,12 @@ <script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/cascaded.js"></script> <script type="text/javascript"><!-- jQuery( function () { - var basedon = document.getElementById('<% $NamePrefix . $CustomField->BasedOnObj->id %>-Values'); + var basedon = document.getElementById(<% $NamePrefix . $CustomField->BasedOnObj->id . "-Values" |n,j%>); if (basedon != null) { var oldchange = basedon.onchange; basedon.onchange = function () { filter_cascade( - '<% $id %>-Values', + <% "$id-Values" |n,j%>, basedon.value, 1 ); diff --git a/rt/share/html/Elements/Error b/rt/share/html/Elements/Error index 50f3b775c..87dfd0245 100755 --- a/rt/share/html/Elements/Error +++ b/rt/share/html/Elements/Error @@ -81,7 +81,7 @@ Encode::_utf8_off($error); $RT::Logger->error($error); -if ( defined $session{'SessionType'} && $session{'SessionType'} eq 'REST' ) { +if ( $session{'REST'} ) { $r->content_type('text/plain'); $m->out( "Error: " . $Why . "\n" ); $m->out( $Details . "\n" ) if defined $Details && length $Details; diff --git a/rt/share/html/Elements/Header b/rt/share/html/Elements/Header index 5d89fe690..1830c4bf2 100755 --- a/rt/share/html/Elements/Header +++ b/rt/share/html/Elements/Header @@ -87,7 +87,8 @@ my $head = ''; #XXX $head .= <& /Elements/Framekiller &>; if ($Refresh && $Refresh =~ /^(\d+)/ && $1 > 0) { - $head .= qq( <meta http-equiv="refresh" content="$Refresh" /> ); + my $URL = $m->notes->{RefreshURL}; $URL = $URL ? ";URL=$URL" : ""; + $head .= qq( <meta http-equiv="refresh" content="$1$URL" /> ); } my $WebPath = RT->Config->Get('WebPath'); diff --git a/rt/share/html/Elements/HeaderJavascript b/rt/share/html/Elements/HeaderJavascript index e392ac262..28788db57 100644 --- a/rt/share/html/Elements/HeaderJavascript +++ b/rt/share/html/Elements/HeaderJavascript @@ -60,14 +60,14 @@ $onload => undef <script type="text/javascript"><!-- jQuery( loadTitleBoxStates ); % if ( $focus ) { - jQuery(function () { focusElementById('<% $focus %>') }); + jQuery(function () { focusElementById(<% $focus |n,j%>) }); % } % if ( $onload ) { jQuery( <% $onload |n %> ); % } % if ( $RichText and RT->Config->Get('MessageBoxRichText', $session{'CurrentUser'})) { - jQuery().ready(function () { ReplaceAllTextareas('<%$m->request_args->{'CKeditorEncoded'} || 0 %>') }); + jQuery().ready(function () { ReplaceAllTextareas(<%$m->request_args->{'CKeditorEncoded'} || 0 |n,j%>) }); % } --></script> <%ARGS> diff --git a/rt/share/html/Elements/MessageBox b/rt/share/html/Elements/MessageBox index 2943cab4e..61995e057 100755 --- a/rt/share/html/Elements/MessageBox +++ b/rt/share/html/Elements/MessageBox @@ -45,7 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<textarea autocomplete="off" class="messagebox" <% $cols |n %> rows="<% $Height %>" <% $wrap_type |n %> name="<% $Name %>" id="<% $Name %>">\ +<textarea autocomplete="off" class="messagebox" <% $width_attr %>="<% $Width %>" rows="<% $Height %>" <% $wrap_type |n %> name="<% $Name %>" id="<% $Name %>">\ % $m->comp('/Articles/Elements/IncludeArticle', %ARGS); % $m->callback( %ARGS, SignatureRef => \$signature ); <% $Default || '' %><% $message %><% $signature %></textarea> @@ -68,13 +68,16 @@ if ( $IncludeSignature and my $text = $session{'CurrentUser'}->UserObj->Signatur # wrap="something" seems to really break IE + richtext my $wrap_type = ''; if ( not RT->Config->Get('MessageBoxRichText', $session{'CurrentUser'}) ) { - $wrap_type = qq(wrap="$Wrap"); + $wrap_type = 'wrap="' . $m->interp->apply_escapes($Wrap, 'h') . '"'; } -# If there's no cols specified, we want to set the width to 100% -my $cols = 'style="width: 100%"'; -if ( defined $Width and length $Width ) { - $cols = qq(cols="$Width"); +# If there's no cols specified, we want to set the width to 100% in CSS +my $width_attr; +if ($Width) { + $width_attr = 'cols'; +} else { + $width_attr = 'style'; + $Width = 'width: 100%'; } </%INIT> diff --git a/rt/share/html/Elements/RT__CustomField/ColumnMap b/rt/share/html/Elements/RT__CustomField/ColumnMap index 06e2674ca..ecb219d9e 100644 --- a/rt/share/html/Elements/RT__CustomField/ColumnMap +++ b/rt/share/html/Elements/RT__CustomField/ColumnMap @@ -120,8 +120,10 @@ my $COLUMN_MAP = { my $name = 'RemoveCustomField'; my $checked = $m->request_args->{ $name .'All' }? 'checked="checked"': ''; - return \qq{<input type="checkbox" name="${name}All" value="1" $checked - onclick="setCheckbox(this.form, '$name', this.checked)" />}; + return \qq{<input type="checkbox" name="}, $name, \qq{All" value="1" $checked + onclick="setCheckbox(this.form, }, + $m->interp->apply_escapes($name,'j'), + \qq{, this.checked)" />}; }, value => sub { my $id = $_[0]->id; @@ -137,7 +139,7 @@ my $COLUMN_MAP = { elsif ( $arg ) { $checked = 'checked="checked"' if $arg == $id; } - return \qq{<input type="checkbox" name="$name" value="$id" $checked />} + return \qq{<input type="checkbox" name="}, $name, \qq{" value="$id" $checked />} }, }, MoveCF => { diff --git a/rt/share/html/Elements/RT__Dashboard/ColumnMap b/rt/share/html/Elements/RT__Dashboard/ColumnMap index 8bc4383d8..6c366ec78 100644 --- a/rt/share/html/Elements/RT__Dashboard/ColumnMap +++ b/rt/share/html/Elements/RT__Dashboard/ColumnMap @@ -111,7 +111,7 @@ my $COLUMN_MAP = { } } - return \('<a href="'.$url.'">'.$frequency.'</a>'); + return \'<a href="', $url, \'">', $frequency, \'</a>'; }, }, ShowURL => { diff --git a/rt/share/html/Elements/RT__Queue/ColumnMap b/rt/share/html/Elements/RT__Queue/ColumnMap index 00655c5eb..e08dd7c91 100644 --- a/rt/share/html/Elements/RT__Queue/ColumnMap +++ b/rt/share/html/Elements/RT__Queue/ColumnMap @@ -84,12 +84,16 @@ my $COLUMN_MAP = { title => 'Encrypt', # loc value => sub { return $_[0]->Encrypt? $_[0]->loc('yes') : $_[0]->loc('no') }, }, + Lifecycle => { + title => 'Lifecycle', + attribute => 'Lifecycle', + value => sub { return $_[0]->Lifecycle->Name }, + }, }; foreach my $field (qw( Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn - Lifecycle )) { $COLUMN_MAP->{$field} = { title => $field, diff --git a/rt/share/html/Elements/SelectOwner b/rt/share/html/Elements/SelectOwner index cc64e247b..37a5971ac 100755 --- a/rt/share/html/Elements/SelectOwner +++ b/rt/share/html/Elements/SelectOwner @@ -59,8 +59,12 @@ if ($TicketObj) { @objects = ($TicketObj); } elsif ($QueueObj) { @objects = ($QueueObj); -} elsif ($cfqueues) { - @objects = keys %{$cfqueues}; +} elsif (%Queues) { + for my $name (keys %Queues) { + my $q = RT::Queue->new($session{'CurrentUser'}); + $q->Load($name); + push @objects, $q; + } } else { # Let's check rights on an empty queue object. that will do a search # for any queue. @@ -77,5 +81,5 @@ $m->callback( <%ARGS> $TicketObj => undef $QueueObj => undef -$cfqueues => undef +%Queues => () </%ARGS> diff --git a/rt/share/html/Elements/SelectOwnerAutocomplete b/rt/share/html/Elements/SelectOwnerAutocomplete index cf2010a80..81b38386c 100644 --- a/rt/share/html/Elements/SelectOwnerAutocomplete +++ b/rt/share/html/Elements/SelectOwnerAutocomplete @@ -78,7 +78,7 @@ my $query = $m->comp('/Elements/QueryString', <script type="text/javascript"> jQuery(function() { var cache = {}; - jQuery("#<% $Name %>").autocomplete({ + jQuery("#"+<% $Name |n,j%>).autocomplete({ minLength: 2, source: function(request, response) { if ( request.term in cache ) { @@ -86,7 +86,7 @@ my $query = $m->comp('/Elements/QueryString', } else { jQuery.ajax({ - url: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Owners?<% $query|n %>", + url: <% RT->Config->Get('WebPath')|n,j%>+"/Helpers/Autocomplete/Owners?"+<% $query|n,j %>, dataType: "json", data: request, success: function( data ) { diff --git a/rt/share/html/Elements/SelectStatus b/rt/share/html/Elements/SelectStatus index e571baf63..af1ff615f 100755 --- a/rt/share/html/Elements/SelectStatus +++ b/rt/share/html/Elements/SelectStatus @@ -66,6 +66,8 @@ if ( @Statuses ) { } elsif ( $TicketObj ) { my $current = $TicketObj->Status; + push @status, $current; + my $lifecycle = $TicketObj->QueueObj->Lifecycle; my %has = (); @@ -78,8 +80,15 @@ elsif ( $TicketObj ) { } elsif ( $QueueObj ) { @status = $QueueObj->Lifecycle->Transitions(''); -} -else { +} elsif ( %Queues ) { + for my $id (keys %Queues) { + my $queue = RT::Queue->new($session{'CurrentUser'}); + $queue->Load($id); + push @status, $queue->Lifecycle->Valid if $queue->id; + } + my %seen; + @status = grep { not $seen{$_}++ } @status; +} else { @status = RT::Queue->Lifecycle->Valid; } </%INIT> @@ -89,6 +98,7 @@ $Name => undef @Statuses => () $TicketObj => undef $QueueObj => undef +%Queues => () $Default => '' $SkipDeleted => 0 diff --git a/rt/share/html/Elements/ShowCustomFields b/rt/share/html/Elements/ShowCustomFields index fcd530e95..6059f4ee7 100644 --- a/rt/share/html/Elements/ShowCustomFields +++ b/rt/share/html/Elements/ShowCustomFields @@ -114,12 +114,12 @@ my $print_value = sub { my $vid = $value->id; $m->out( '<div class="object_cf_value_include" id="object_cf_value_'. $vid .'">' ); $m->out( loc("See also:") ); - $m->out( '<a href="'. $value->IncludeContentForValue .'">' ); - $m->out( $value->IncludeContentForValue ); + $m->out( '<a href="'. $m->interp->apply_escapes($value->IncludeContentForValue, 'h') .'">' ); + $m->out( $m->interp->apply_escapes($value->IncludeContentForValue, 'h') ); $m->out( qq{</a></div>\n} ); - $m->out( qq{<script><!--\njQuery('#object_cf_value_$vid').load('} ); - $m->out( $value->IncludeContentForValue ); - $m->out( qq{');\n--></script>\n} ); + $m->out( qq{<script><!--\njQuery('#object_cf_value_$vid').load(} ); + $m->out( $m->interp->apply_escapes($value->IncludeContentForValue, 'j') ); + $m->out( qq{);\n--></script>\n} ); } }; diff --git a/rt/share/html/Elements/ShowLink b/rt/share/html/Elements/ShowLink index 8913a32fb..1727fa397 100644 --- a/rt/share/html/Elements/ShowLink +++ b/rt/share/html/Elements/ShowLink @@ -45,7 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<a href="<%$URI->Resolver->HREF%>"> +<a href="<% $href %>"> % if ($URI->IsLocal) { % my $member = $URI->Object; % my $has_name = UNIVERSAL::can($member, 'Name') || (UNIVERSAL::can($member, '_Accessible') && $member->_Accessible('Name', 'read')); @@ -69,3 +69,12 @@ <%ARGS> $URI => undef </%ARGS> + +<%INIT> +my $href = $URI->Resolver->HREF; +if ( $URI->IsLocal ) { + my $base = RT->Config->Get('WebBaseURL'); + # URI->rel doesn't contain the leading '/' + $href = '/' . URI->new($href)->rel($base); +} +</%INIT> diff --git a/rt/share/html/Elements/ShowSearch b/rt/share/html/Elements/ShowSearch index 2b23181c2..4b96bbfda 100644 --- a/rt/share/html/Elements/ShowSearch +++ b/rt/share/html/Elements/ShowSearch @@ -64,12 +64,12 @@ my $query_link_url = RT->Config->Get('WebPath').'/Search/Results.html'; if ($SavedSearch) { my ( $container_object, $search_id ) = _parse_saved_search($SavedSearch); unless ( $container_object ) { - $m->out(loc("Either you have no rights to view saved search [_1] or identifier is incorrect", $SavedSearch)); + $m->out(loc("Either you have no rights to view saved search [_1] or identifier is incorrect", $m->interp->apply_escapes($SavedSearch, 'h'))); return; } $search = $container_object->Attributes->WithId($search_id); unless ( $search->Id && ref( $SearchArg = $search->Content ) eq 'HASH' ) { - $m->out(loc("Saved Search [_1] not found", $SavedSearch)) unless $IgnoreMissing; + $m->out(loc("Saved Search [_1] not found", $m->interp->apply_escapes($SavedSearch, 'h'))) unless $IgnoreMissing; return; } $SearchArg->{'SavedSearchId'} ||= $SavedSearch; @@ -79,7 +79,7 @@ if ($SavedSearch) { # XXX: dispatch to different handler here $query_display_component = '/Search/Elements/' . $SearchArg->{SearchType}; - $query_link_url = RT->Config->Get('WebURL') . "/Search/$SearchArg->{SearchType}.html"; + $query_link_url = RT->Config->Get('WebPath') . "/Search/$SearchArg->{SearchType}.html"; } elsif ($ShowCustomize) { $customize = RT->Config->Get('WebPath') . '/Search/Build.html?' . $m->comp( '/Elements/QueryString', @@ -93,7 +93,7 @@ if ($SavedSearch) { if ($custom->Description eq $Name) { $search = $custom; last } } unless ($search && $search->id) { - $m->out("Predefined search $Name not found"); + $m->out(loc("Predefined search [_1] not found", $m->interp->apply_escapes($Name, 'h'))); return; } } diff --git a/rt/share/html/Elements/ShowUser b/rt/share/html/Elements/ShowUser index 044ec4c84..365497765 100644 --- a/rt/share/html/Elements/ShowUser +++ b/rt/share/html/Elements/ShowUser @@ -51,7 +51,7 @@ # $Address is Email::Address object my $comp = '/Elements/ShowUser'. ucfirst lc $style; -unless ( $m->comp_exists( $comp ) ) { +unless ( RT::Interface::Web->ComponentPathIsSafe($comp) and $m->comp_exists( $comp ) ) { $RT::Logger->error( 'Either system config or user #' . $session{'CurrentUser'}->id diff --git a/rt/share/html/Elements/Submit b/rt/share/html/Elements/Submit index cbf3f58e8..b7840d34b 100755 --- a/rt/share/html/Elements/Submit +++ b/rt/share/html/Elements/Submit @@ -52,10 +52,10 @@ id="<%$id%>" > <div class="extra-buttons"> % if ($CheckAll) { - <input type="button" value="<%$CheckAllLabel%>" onclick="setCheckbox(this.form, <% length $CheckboxName ? qq{'$CheckboxName'} : length $CheckboxNameRegex ? $CheckboxNameRegex : q{''} %>, true);return false;" class="button" /> + <input type="button" value="<%$CheckAllLabel%>" onclick="setCheckbox(this.form, <% $match %>, true);return false;" class="button" /> % } % if ($ClearAll) { - <input type="button" value="<%$ClearAllLabel%>" onclick="setCheckbox(this.form, <% length $CheckboxName ? qq{'$CheckboxName'} : length $CheckboxNameRegex ? $CheckboxNameRegex : q{''} %>, false);return false;" class="button" /> + <input type="button" value="<%$ClearAllLabel%>" onclick="setCheckbox(this.form, <% $match %>, false);return false;" class="button" /> % } % if ($Reset) { <input type="reset" value="<%$ResetLabel%>" class="button" /> @@ -115,3 +115,13 @@ $ResetLabel => loc('Reset') $SubmitId => undef $id => undef </%ARGS> +<%init> +my $match; +if (length $CheckboxName) { + $match = $m->interp->apply_escapes($CheckboxName,'j'); +} elsif (length $CheckboxNameRegex) { + $match = $CheckboxNameRegex; +} else { + $match = q{''}; +} +</%init> diff --git a/rt/share/html/Elements/Tabs b/rt/share/html/Elements/Tabs index 75b8160da..3193b488d 100755 --- a/rt/share/html/Elements/Tabs +++ b/rt/share/html/Elements/Tabs @@ -734,6 +734,9 @@ my $build_main_nav = sub { $current_search_menu->child( bulk => title => loc('Bulk Update'), path => "/Search/Bulk.html$args" ); $current_search_menu->child( chart => title => loc('Chart'), path => "/Search/Chart.html$args" ); + #formerly Callbacks/RTx-Calendar/Ticket/Element/Tabs/Default + $current_search_menu->child( calendar => title => loc('Calendar'), path => "/Search/Calendar.html$args" ); + my $more = $current_search_menu->child( more => title => loc('Feeds') ); $more->child( tsv => title => loc('TSV'), path => "/Search/Results.tsv$args" ); diff --git a/rt/share/html/Helpers/Autocomplete/CustomFieldValues b/rt/share/html/Helpers/Autocomplete/CustomFieldValues index b8b21e4fe..887302f0c 100644 --- a/rt/share/html/Helpers/Autocomplete/CustomFieldValues +++ b/rt/share/html/Helpers/Autocomplete/CustomFieldValues @@ -52,6 +52,17 @@ # Only autocomplete the last value my $term = (split /\n/, $ARGS{term} || '')[-1]; +my $abort = sub { + $r->content_type('application/json'); + $m->out(JSON::to_json( [] )); + $m->abort; +}; + +unless ( exists $ARGS{ContextType} and exists $ARGS{ContextId} ) { + RT->Logger->debug("No context provided"); + $abort->(); +} + my $CustomField; for my $k ( keys %ARGS ) { next unless $k =~ /^Object-.*?-\d*-CustomField-(\d+)-Values?$/; @@ -59,9 +70,38 @@ for my $k ( keys %ARGS ) { last; } -$m->abort unless $CustomField; +unless ( $CustomField ) { + RT->Logger->debug("No CustomField provided"); + $abort->(); +} + +my $SystemCustomFieldObj = RT::CustomField->new( RT->SystemUser ); +my ($id, $msg) = $SystemCustomFieldObj->LoadById( $CustomField ) ; +unless ( $id ) { + RT->Logger->debug("Invalid CustomField provided: $msg"); + $abort->(); +} + +my $context_object = $SystemCustomFieldObj->LoadContextObject( + $ARGS{ContextType}, $ARGS{ContextId} ); +$abort->() unless $context_object; + my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} ); -$CustomFieldObj->Load( $CustomField ); +if ( $SystemCustomFieldObj->ValidateContextObject($context_object) ) { + # drop our privileges that came from calling LoadContextObject as the System User + $context_object->new($session{'CurrentUser'}); + $context_object->LoadById($ARGS{ContextId}); + $CustomFieldObj->SetContextObject( $context_object ); +} else { + RT->Logger->debug("Invalid Context Object ".$context_object->id." for Custom Field ".$SystemCustomFieldObj->id); + $abort->(); +} + +($id, $msg) = $CustomFieldObj->LoadById( $CustomField ); +unless ( $CustomFieldObj->Name ) { + RT->Logger->debug("Current User cannot see this Custom Field, terminating"); + $abort->(); +} my $values = $CustomFieldObj->Values; $values->Limit( diff --git a/rt/share/html/Helpers/Toggle/ShowRequestor b/rt/share/html/Helpers/Toggle/ShowRequestor index bb90b9887..68e8a0517 100644 --- a/rt/share/html/Helpers/Toggle/ShowRequestor +++ b/rt/share/html/Helpers/Toggle/ShowRequestor @@ -47,7 +47,9 @@ %# END BPS TAGGED BLOCK }}} <%INIT> my $TicketTemplate = "/Ticket/Elements/ShowRequestorTickets$Status"; -$TicketTemplate = "/Ticket/Elements/ShowRequestorTicketsActive" unless $m->comp_exists($TicketTemplate); +$TicketTemplate = "/Ticket/Elements/ShowRequestorTicketsActive" + unless RT::Interface::Web->ComponentPathIsSafe($TicketTemplate) + and $m->comp_exists($TicketTemplate); my $user_obj = RT::User->new($session{CurrentUser}); my ($val, $msg) = $user_obj->Load($Requestor); unless ($val) { diff --git a/rt/share/html/Install/DatabaseType.html b/rt/share/html/Install/DatabaseType.html index 3312b57ec..68f8a67ed 100644 --- a/rt/share/html/Install/DatabaseType.html +++ b/rt/share/html/Install/DatabaseType.html @@ -58,7 +58,7 @@ <&|/l&>SQLite is a database that doesn't need a server or any configuration whatsoever. RT's authors recommend it for testing, demoing and development, but it's not quite right for a high-volume production RT server.</&> </b></p> <p> -<&|/l, '<a href="http://search.cpan.org" target="_new">CPAN</a>' &>If your preferred database isn't listed in the dropdown below, that means RT couldn't find a <i>database driver</i> for it installed locally. You may be able to remedy this by using [_1] to download and install DBD::MySQL, DBD::Oracle or DBD::Pg.</&> +<&|/l_unsafe, '<a href="http://search.cpan.org" target="_new">CPAN</a>' &>If your preferred database isn't listed in the dropdown below, that means RT couldn't find a <i>database driver</i> for it installed locally. You may be able to remedy this by using [_1] to download and install DBD::MySQL, DBD::Oracle or DBD::Pg.</&> </p> </div> diff --git a/rt/share/html/Install/Finish.html b/rt/share/html/Install/Finish.html index ee81e70e4..24ac0ff71 100644 --- a/rt/share/html/Install/Finish.html +++ b/rt/share/html/Install/Finish.html @@ -53,7 +53,7 @@ </p> <p> -<&|/l, '<tt>root</tt>' &>You should be taken directly to a login page. You'll be able to log in with username of [_1] and the password you set earlier.</&> +<&|/l_unsafe, '<tt>root</tt>' &>You should be taken directly to a login page. You'll be able to log in with username of [_1] and the password you set earlier.</&> </p> <p> diff --git a/rt/share/html/Install/Initialize.html b/rt/share/html/Install/Initialize.html index 47d7616a1..0cc39aff6 100644 --- a/rt/share/html/Install/Initialize.html +++ b/rt/share/html/Install/Initialize.html @@ -125,7 +125,7 @@ if ( $Run ) { $RT::Handle = RT::Handle->new; RT::Init(); my $file = $RT::EtcPath . "/initialdata"; - ($status, $msg) = $RT::Handle->InsertData( $file ); + ($status, $msg) = $RT::Handle->InsertData( $file, undef, disconnect_after => 0 ); } unless ( $status ) { push @errors, loc('ERROR: [_1]', $msg); diff --git a/rt/share/html/Install/index.html b/rt/share/html/Install/index.html index 61fb89e39..78069afe3 100644 --- a/rt/share/html/Install/index.html +++ b/rt/share/html/Install/index.html @@ -92,7 +92,7 @@ my @errors; my $locked; -my $file = File::Spec->catfile( $RT::EtcPath, 'RT_SiteConfig.pm' ); +my $file = RT::Installer->ConfigFile; if ( ! -e $file ) { # write a blank RT_SiteConfig.pm diff --git a/rt/share/html/NoAuth/Logout.html b/rt/share/html/NoAuth/Logout.html index b8e119af5..20024ccec 100755 --- a/rt/share/html/NoAuth/Logout.html +++ b/rt/share/html/NoAuth/Logout.html @@ -81,5 +81,5 @@ if (keys %session) { } $m->callback( %ARGS, CallbackName => 'AfterSessionDelete' ); -$m->notes->{LogoutURL} = $URL; +$m->notes->{RefreshURL} = $URL; </%INIT> diff --git a/rt/share/html/NoAuth/css/aileron/InHeader b/rt/share/html/NoAuth/css/aileron/InHeader index aff24d8a6..e6d4cb311 100644 --- a/rt/share/html/NoAuth/css/aileron/InHeader +++ b/rt/share/html/NoAuth/css/aileron/InHeader @@ -45,9 +45,6 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<!--[if (lt IE 9)&(gt IE 6)]> -<link rel="stylesheet" href="<%RT->Config->Get('WebPath')%>/NoAuth/css/aileron/msie-pie.css" type="text/css" media="all" /> -<![endif]--> <!--[if lt IE 8]> <link rel="stylesheet" href="<%RT->Config->Get('WebPath')%>/NoAuth/css/aileron/msie.css" type="text/css" media="all" /> <![endif]--> diff --git a/rt/share/html/NoAuth/css/aileron/boxes.css b/rt/share/html/NoAuth/css/aileron/boxes.css index f90ac9f77..ed6623cba 100644 --- a/rt/share/html/NoAuth/css/aileron/boxes.css +++ b/rt/share/html/NoAuth/css/aileron/boxes.css @@ -91,6 +91,10 @@ .titlebox .titlebox-title { position: relative; + /* This is for [rt3 #19044]. Move it to an IE-specific file if it causes + * problems. If we remove CSS3PIE, it can also probably go away, although it + * probably won't hurt. */ + z-index: 1; } .titlebox .titlebox-title a { diff --git a/rt/share/html/NoAuth/css/aileron/msie-pie.css b/rt/share/html/NoAuth/css/aileron/msie-pie.css deleted file mode 100644 index baa9ebed3..000000000 --- a/rt/share/html/NoAuth/css/aileron/msie-pie.css +++ /dev/null @@ -1,58 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -.search-result-views, -.ticket-transaction div.metadata span.actions, -div#ticket-history div.downloadattachment, -.ticket-transaction div.metadata span.type, -.titlebox, -.titlebox .titlebox-title .right, -.titlebox .titlebox-title .left, -div#footer, -div#body { - behavior: url(<%RT->Config->Get('WebPath')%>/NoAuth/css/images/PIE.htc); -} diff --git a/rt/share/html/NoAuth/css/images/PIE.htc b/rt/share/html/NoAuth/css/images/PIE.htc deleted file mode 100644 index 6a40cef47..000000000 --- a/rt/share/html/NoAuth/css/images/PIE.htc +++ /dev/null @@ -1,77 +0,0 @@ -<!-- -PIE: CSS3 rendering for IE -Version 1.0beta2 -http://css3pie.com -Dual-licensed for use under the Apache License Version 2.0 or the General Public License (GPL) Version 2. ---> -<PUBLIC:COMPONENT lightWeight="true"> - <PUBLIC:ATTACH EVENT="onresize" FOR="element" ONEVENT="update()" /> - <PUBLIC:ATTACH EVENT="onresize" FOR="window" ONEVENT="update()" /> - <PUBLIC:ATTACH EVENT="onmove" FOR="element" ONEVENT="update()" /> - <PUBLIC:ATTACH EVENT="onpropertychange" FOR="element" ONEVENT="propChanged()" /> - <PUBLIC:ATTACH EVENT="onmouseenter" FOR="element" ONEVENT="mouseEntered()" /> - <PUBLIC:ATTACH EVENT="onmouseleave" FOR="element" ONEVENT="mouseLeft()" /> - <PUBLIC:ATTACH EVENT="oncontentready" FOR="element" ONEVENT="update()" /> - <PUBLIC:ATTACH EVENT="ondocumentready" FOR="element" ONEVENT="update()" /> - <PUBLIC:ATTACH EVENT="ondetach" FOR="element" ONEVENT="cleanup()" /> - - <script type="text/javascript"> -function i(){return function(){}}var D=window.PIE; -if(!D){D=window.PIE={T:"-pie-",Ma:"Pie",Ka:"pie_"};if(!window.XMLHttpRequest){D.Yb=true;D.T=D.T.replace(/^-/,"")}D.oa=element.document.documentMode;D.Da=!!D.oa;if(D.oa===8){D.Ca={ya:{},add:function(a){this.ya[a.id||(a.id=""+(new Date).getTime()+Math.random())]=a},remove:function(a){delete this.ya[a.id]},Tb:function(){var a=this.ya,b;for(b in a)a.hasOwnProperty(b)&&a[b]()}};setInterval(function(){D.Ca.Tb()},250)}D.q={ja:function(a){var b=D.Gb;if(!b){b=D.Gb=element.document.createDocumentFragment(); -b.namespaces.add("css3vml","urn:schemas-microsoft-com:vml")}return b.createElement("css3vml:"+a)},Fa:function(a){var b,c,d,e,f=arguments;b=1;for(c=f.length;b<c;b++){e=f[b];for(d in e)if(e.hasOwnProperty(d))a[d]=e[d]}return a},ib:function(a,b,c){var d=D.Ab||(D.Ab={}),e=d[a],f;if(e)b.call(c,e);else{f=new Image;f.onload=function(){e=d[a]={v:f.width,i:f.height};b.call(c,e);f.onload=null};f.src=a}}};D.g=function(){function a(b){this.F=b}a.prototype={Ga:/(px|em|ex|mm|cm|in|pt|pc|%)$/,Va:function(){var b= -this.Bb;if(b===undefined)b=this.Bb=parseFloat(this.F);return b},Aa:function(){var b=this.ua;if(!b)b=this.ua=(b=this.F.match(this.Ga))&&b[0]||"px";return b},a:function(b,c){var d=this.Va(),e=this.Aa();switch(e){case "px":return d;case "%":return d*(typeof c==="function"?c():c)/100;case "em":return d*this.Ua(b);case "ex":return d*this.Ua(b)/2;default:return d*a.Ob[e]}},Ua:function(b){var c=b.currentStyle.fontSize,d;if(c.indexOf("px")>0)return parseFloat(c);else{c=this.Fb;if(!c){c=this.Fb=b.document.createElement("length-calc"); -d=c.style;d.width="1em";d.position="absolute";d.top=d.left=-9999}b.appendChild(c);d=c.offsetWidth;b.removeChild(c);return d}}};a.Ob=function(){for(var b=["mm","cm","in","pt","pc"],c={},d=element.parentNode,e=0,f=b.length,j,g,h;e<f;e++){j=b[e];g=element.document.createElement("length-calc");h=g.style;h.position="absolute";h.top=h.left=-9999;h.width="100"+j;d.appendChild(g);c[j]=g.offsetWidth/100;d.removeChild(g)}return c}();a.Oa=new a("0");return a}();D.ra=function(){function a(b){this.C=b}a.prototype= -{Vb:function(){if(!this.Qa){var b=this.C,c=b.length,d=D.g.Oa,e=new D.g("50%"),f=D.k.Y.V,j={top:1,center:1,bottom:1},g={left:1,center:1,right:1};d=["left",d,"top",d];if(c===1){b.push({type:f,value:"center"});c++}if(c===2){f&(b[0].type|b[1].type)&&b[0].value in j&&b[1].value in g&&b.push(b.shift());if(b[0].type&f)if(b[0].value==="center")d[1]=e;else d[0]=b[0].value;else if(b[0].J())d[1]=new D.g(b[0].value);if(b[1].type&f)if(b[1].value==="center")d[3]=e;else d[2]=b[1].value;else if(b[1].J())d[3]=new D.g(b[1].value)}this.Qa= -d}return this.Qa},coords:function(b,c,d){var e=this.Vb(),f=e[1].a(b,c);b=e[3].a(b,d);return{x:Math.round(e[0]==="right"?c-f:f),y:Math.round(e[2]==="bottom"?d-b:b)}}};return a}();D.kb=function(){function a(b){this.F=b}a.prototype={Ga:/[a-z]+$/i,Aa:function(){return this.ua||(this.ua=this.F.match(this.Ga)[0].toLowerCase())},Pb:function(){var b=this.zb,c;if(b===undefined){b=this.Aa();c=parseFloat(this.F,10);b=this.zb=b==="deg"?c:b==="rad"?c/Math.PI*180:b==="grad"?c/400*360:b==="turn"?c*360:0}return b}}; -return a}();D.U=function(){function a(b){this.F=b}a.ec=/\s*rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d+|\d*\.\d+)\s*\)\s*/;a.prototype={parse:function(){if(!this.ha){var b=this.F,c=b.match(a.ec);if(c){this.ha="rgb("+c[1]+","+c[2]+","+c[3]+")";this.Pa=parseFloat(c[4])}else{this.ha=b;this.Pa=1}}},value:function(b){this.parse();return this.ha==="currentColor"?b.currentStyle.color:this.ha},Ra:function(){this.parse();return this.Pa}};return a}();D.k=function(){function a(c){this.ka=c; -this.ch=0;this.C=[];this.ea=0}var b=a.Y={fa:1,Ja:2,S:4,ub:8,La:16,V:32,n:64,W:128,X:256,ga:512,wb:1024,URL:2048};a.Na=function(c,d){this.type=c;this.value=d};a.Na.prototype={Ea:function(){return this.type&b.n||this.type&b.W&&this.value==="0"},J:function(){return this.Ea()||this.type&b.ga}};a.prototype={mc:/\s/,$b:/^[\+\-]?(\d*\.)?\d+/,url:/^url\(\s*("([^"]*)"|'([^']*)'|([!#$%&*-~]*))\s*\)/i,Ya:/^\-?[_a-z][\w-]*/i,hc:/^("([^"]*)"|'([^']*)')/,Wb:/^#([\da-f]{6}|[\da-f]{3})/i,kc:{px:b.n,em:b.n,ex:b.n, -mm:b.n,cm:b.n,"in":b.n,pt:b.n,pc:b.n,deg:b.fa,rad:b.fa,grad:b.fa},Lb:{aqua:1,black:1,blue:1,fuchsia:1,gray:1,green:1,lime:1,maroon:1,navy:1,olive:1,purple:1,red:1,silver:1,teal:1,white:1,yellow:1,currentColor:1},Kb:{rgb:1,rgba:1,hsl:1,hsla:1},next:function(c){function d(n,p){n=new a.Na(n,p);if(!c){k.C.push(n);k.ea++}return n}function e(){k.ea++;return null}var f,j,g,h,k=this;if(this.ea<this.C.length)return this.C[this.ea++];for(;this.mc.test(this.ka.charAt(this.ch));)this.ch++;if(this.ch>=this.ka.length)return e(); -j=this.ch;f=this.ka.substring(this.ch);g=f.charAt(0);switch(g){case "#":if(h=f.match(this.Wb)){this.ch+=h[0].length;return d(b.S,h[0])}break;case '"':case "'":if(h=f.match(this.hc)){this.ch+=h[0].length;return d(b.wb,h[2]||h[3]||"")}break;case "/":case ",":this.ch++;return d(b.X,g);case "u":if(h=f.match(this.url)){this.ch+=h[0].length;return d(b.URL,h[2]||h[3]||h[4]||"")}}if(h=f.match(this.$b)){g=h[0];this.ch+=g.length;if(f.charAt(g.length)==="%"){this.ch++;return d(b.ga,g+"%")}if(h=f.substring(g.length).match(this.Ya)){g+= -h[0];this.ch+=h[0].length;return d(this.kc[h[0].toLowerCase()]||b.ub,g)}return d(b.W,g)}if(h=f.match(this.Ya)){g=h[0];this.ch+=g.length;if(g.toLowerCase()in this.Lb)return d(b.S,g);if(f.charAt(g.length)==="("){this.ch++;if(g.toLowerCase()in this.Kb){f=function(n){return n&&n.type&b.W};h=function(n){return n&&n.type&(b.W|b.ga)};var o=function(n,p){return n&&n.value===p},m=function(){return k.next(1)};if((g.charAt(0)==="r"?h(m()):f(m()))&&o(m(),",")&&h(m())&&o(m(),",")&&h(m())&&(g==="rgb"||g==="hsa"|| -o(m(),",")&&f(m()))&&o(m(),")"))return d(b.S,this.ka.substring(j,this.ch));return e()}return d(b.La,g+"(")}return d(b.V,g)}this.ch++;return d(b.Ja,g)},m:function(){return this.C[this.ea-- -2]},all:function(){for(;this.next(););return this.C},R:function(c,d){for(var e=[],f,j;f=this.next();){if(c(f)){j=true;this.m();break}e.push(f)}return d&&!j?null:e}};return a}();D.w={M:function(a){function b(c){this.element=c}D.q.Fa(b.prototype,D.w,a);return b},f:function(){if(this.j())this.Eb=this.N(this.yb=this.ba()); -return this.Eb},ba:function(){var a=this.element,b=a.style;a=a.currentStyle;var c=this.aa,d=this.da,e=this.Cb||(this.Cb=D.T+c),f=this.Db||(this.Db=D.Ma+d.charAt(0).toUpperCase()+d.substring(1));return b[f]||a.getAttribute(e)||b[d]||a.getAttribute(c)},d:function(){return!!this.f()},j:function(){return this.yb!==this.ba()}};D.mb=D.w.M({aa:D.T+"background",da:D.Ma+"Background",Ib:{scroll:1,fixed:1,local:1},qa:{"repeat-x":1,"repeat-y":1,repeat:1,"no-repeat":1},ac:{"padding-box":1,"border-box":1,"content-box":1}, -Jb:{"padding-box":1,"border-box":1},dc:{top:1,right:1,bottom:1,left:1,center:1},fc:{contain:1,cover:1},N:function(a){function b(q){return q.J()||q.type&h&&q.value in n}function c(q){return q.J()&&new D.g(q.value)||q.value==="auto"&&"auto"}var d=this.element.currentStyle,e,f,j=D.k.Y,g=j.X,h=j.V,k=j.S,o,m,n=this.dc,p,t,r=null;if(this.za()){a=new D.k(a);r={images:[]};for(f={};e=a.next();){o=e.type;m=e.value;if(!f.type&&o&j.La&&m==="linear-gradient("){p={P:[],type:"linear-gradient"};for(t={};e=a.next();){o= -e.type;m=e.value;if(o&j.Ja&&m===")"){t.color&&p.P.push(t);p.P.length>1&&D.q.Fa(f,p);break}if(o&k){if(p.wa||p.Ba){e=a.m();if(e.type!==g)break;a.next()}t={color:new D.U(m)};e=a.next();if(e.J())t.Za=new D.g(e.value);else a.m()}else if(o&j.fa&&!p.wa&&!t.color&&!p.P.length)p.wa=new D.kb(e.value);else if(b(e)&&!p.Ba&&!t.color&&!p.P.length){a.m();p.Ba=new D.ra(a.R(function(q){return!b(q)},false))}else if(o&g&&m===","){if(t.color){p.P.push(t);t={}}}else break}}else if(!f.type&&o&j.URL){f.url=m;f.type="image"}else if(b(e)&& -!f.size){a.m();f.position=new D.ra(a.R(function(q){return!b(q)},false))}else if(o&h)if(m in this.qa)f.repeat=m;else if(m in this.ac){f.origin=m;if(m in this.Jb)f.clip=m}else{if(m in this.Ib)f.rc=m}else if(o&k&&!r.color)r.color=new D.U(m);else if(o&g)if(m==="/"){e=a.next();o=e.type;m=e.value;if(o&h&&m in this.fc)f.size=m;else if(m=c(e))f.size={v:m,i:c(a.next())||a.m()&&m}}else{if(m===","&&f.type){r.images.push(f);f={}}}else return null}f.type&&r.images.push(f)}else this.gb(function(){var q=d.backgroundPositionX, -w=d.backgroundPositionY,l=d.backgroundImage,u=d.backgroundColor;r={};if(u!=="transparent")r.color=new D.U(u);if(l!=="none")r.images=[{type:"image",url:(new D.k(l)).next().value,repeat:d.backgroundRepeat,position:new D.ra((new D.k(q+" "+w)).all())}]});return r},gb:function(a){var b=this.element.runtimeStyle,c=b.backgroundImage,d=b.backgroundColor;b.backgroundImage=b.backgroundColor="";a=a.call(this);b.backgroundImage=c;b.backgroundColor=d;return a},ba:function(){var a=this.element.currentStyle;return this.za()|| -this.gb(function(){return a.backgroundColor+" "+a.backgroundImage+" "+a.backgroundRepeat+" "+a.backgroundPositionX+" "+a.backgroundPositionY})},za:function(){var a=this.element;return a.style[this.da]||a.currentStyle.getAttribute(this.aa)},d:function(){return this.za()&&!!this.f()}});D.qb=D.w.M({bb:["Top","Right","Bottom","Left"],Zb:{uc:"1px",sc:"3px",tc:"5px"},N:function(){var a={},b={},c={},d=false,e=true,f=true,j=true;this.hb(function(){for(var g=this.element.currentStyle,h=0,k,o,m,n,p,t,r;h<4;h++){m= -this.bb[h];r=m.charAt(0).toLowerCase();k=b[r]=g["border"+m+"Style"];o=g["border"+m+"Color"];m=g["border"+m+"Width"];if(h>0){if(k!==n)f=false;if(o!==p)e=false;if(m!==t)j=false}n=k;p=o;t=m;c[r]=new D.U(o);m=a[r]=new D.g(b[r]==="none"?"0":this.Zb[m]||m);if(m.a(this.element)>0)d=true}});return d?{fb:a,ic:b,Mb:c,nc:j,Nb:e,jc:f}:null},ba:function(){var a=this.element.currentStyle,b;this.hb(function(){b=a.borderWidth+"|"+a.borderStyle+"|"+a.borderColor});return b},hb:function(a){var b=this.element.runtimeStyle, -c=b.borderWidth,d=b.borderStyle,e=b.borderColor;b.borderWidth=b.borderStyle=b.borderColor="";a=a.call(this);b.borderWidth=c;b.borderStyle=d;b.borderColor=e;return a}});(function(){D.sa=D.w.M({aa:"border-radius",da:"borderRadius",N:function(b){var c=null,d,e,f,j,g=false;if(b){e=new D.k(b);var h=function(){for(var k=[],o;(f=e.next())&&f.J();){j=new D.g(f.value);o=j.Va();if(o<0)return null;if(o>0)g=true;k.push(j)}return k.length>0&&k.length<5?{tl:k[0],tr:k[1]||k[0],br:k[2]||k[0],bl:k[3]||k[1]||k[0]}: -null};if(b=h()){if(f){if(f.type&D.k.Y.X&&f.value==="/")d=h()}else d=b;if(g&&b&&d)c={x:b,y:d}}}return c}});var a=D.g.Oa;a={tl:a,tr:a,br:a,bl:a};D.sa.jb={x:a,y:a}})();D.ob=D.w.M({aa:"border-image",da:"borderImage",qa:{stretch:1,round:1,repeat:1,space:1},N:function(a){var b=null,c,d,e,f,j,g,h=0,k,o=D.k.Y,m=o.V,n=o.W,p=o.n,t=o.ga;if(a){c=new D.k(a);b={};for(var r=function(l){return l&&l.type&o.X&&l.value==="/"},q=function(l){return l&&l.type&m&&l.value==="fill"},w=function(){f=c.R(function(l){return!(l.type& -(n|t))});if(q(c.next())&&!b.fill)b.fill=true;else c.m();if(r(c.next())){h++;j=c.R(function(){return!(d.type&(n|t|p))&&!(d.type&m&&d.value==="auto")});if(r(c.next())){h++;g=c.R(function(){return!(d.type&(n|p))})}}else c.m()};d=c.next();){a=d.type;e=d.value;if(a&(n|t)&&!f){c.m();w()}else if(q(d)&&!b.fill){b.fill=true;w()}else if(a&m&&this.qa[e]&&!b.repeat){b.repeat={i:e};if(d=c.next())if(d.type&m&&this.qa[d.value])b.repeat.Ha=d.value;else c.m()}else if(a&o.URL&&!b.src)b.src=e;else return null}if(!b.src|| -!f||f.length<1||f.length>4||j&&j.length>4||h===1&&j.length<1||g&&g.length>4||h===2&&g.length<1)return null;if(!b.repeat)b.repeat={i:"stretch"};if(!b.repeat.Ha)b.repeat.Ha=b.repeat.i;a=function(l,u){return{Q:u(l[0]),O:u(l[1]||l[0]),H:u(l[2]||l[0]),K:u(l[3]||l[1]||l[0])}};b.slice=a(f,function(l){return new D.g(l.type&n?l.value+"px":l.value)});b.width=j&&j.length>0?a(j,function(l){return l.type&(p|t)?new D.g(l.value):l.value}):(k=this.element.currentStyle)&&{Q:new D.g(k.borderTopWidth),O:new D.g(k.borderRightWidth), -H:new D.g(k.borderBottomWidth),K:new D.g(k.borderLeftWidth)};b.ca=a(g||[0],function(l){return l.type&p?new D.g(l.value):l.value})}return b}});D.tb=D.w.M({aa:"box-shadow",da:"boxShadow",N:function(a){var b,c=D.g,d=D.k.Y,e;if(a){e=new D.k(a);b={ca:[],pa:[]};for(a=function(){for(var f,j,g,h,k,o;f=e.next();){g=f.value;j=f.type;if(j&d.X&&g===",")break;else if(f.Ea()&&!k){e.m();k=e.R(function(m){return!m.Ea()})}else if(j&d.S&&!h)h=g;else if(j&d.V&&g==="inset"&&!o)o=true;else return false}f=k&&k.length; -if(f>1&&f<5){(o?b.pa:b.ca).push({oc:new c(k[0].value),qc:new c(k[1].value),blur:new c(k[2]?k[2].value:"0"),gc:new c(k[3]?k[3].value:"0"),color:new D.U(h||"currentColor")});return true}return false};a(););}return b&&(b.pa.length||b.ca.length)?b:null}});D.xb=D.w.M({ba:function(){var a=this.element.currentStyle;return a.visibility+"|"+a.display},N:function(){var a=this.element,b=a.runtimeStyle;a=a.currentStyle;var c=b.visibility,d;b.visibility="";d=a.visibility;b.visibility=c;return{lc:d!=="hidden", -Qb:a.display!=="none"}},d:function(){return false}});D.p={L:function(a){function b(c,d,e){this.element=c;this.e=d;this.parent=e}D.q.Fa(b.prototype,D.p,a);return b},B:function(){return false},D:i(),cb:i(),u:i(),va:function(a,b){this.ab(a);for(var c=this.Z||(this.Z=[]),d=a+1,e=c.length,f;d<e;d++)if(f=c[d])break;c[a]=b;this.o().insertBefore(b,f||null)},ma:function(a){var b=this.Z;return b&&b[a]||null},ab:function(a){var b=this.ma(a),c=this.G;if(b&&c){c.removeChild(b);this.Z[a]=null}},na:function(a,b, -c,d){var e=this.ta||(this.ta={}),f=e[a];if(!f){f=e[a]=D.q.ja("shape");if(b)f.appendChild(f[b]=D.q.ja(b));if(d){c=this.ma(d);if(!c){this.va(d,this.element.document.createElement("group"+d));c=this.ma(d)}}c.appendChild(f);a=f.style;a.position="absolute";a.left=a.top=0;a.behavior="url(#default#VML)"}return f},xa:function(a){var b=this.ta,c=b&&b[a];if(c){c.parentNode.removeChild(c);delete b[a]}return!!c},Wa:function(a){var b=this.element,c=b.offsetWidth,d=b.offsetHeight,e,f,j,g,h,k,o;e=a.x.tl.a(b,c); -f=a.y.tl.a(b,d);j=a.x.tr.a(b,c);g=a.y.tr.a(b,d);h=a.x.br.a(b,c);k=a.y.br.a(b,d);o=a.x.bl.a(b,c);a=a.y.bl.a(b,d);c=Math.min(c/(e+j),d/(g+k),c/(o+h),d/(f+a));if(c<1){e*=c;f*=c;j*=c;g*=c;h*=c;k*=c;o*=c;a*=c}return{x:{tl:e,tr:j,br:h,bl:o},y:{tl:f,tr:g,br:k,bl:a}}},la:function(a,b,c){b=b||1;var d,e,f=this.element;e=f.offsetWidth*b;f=f.offsetHeight*b;var j=this.e.s,g=Math.floor,h=Math.ceil,k=a?a.Q*b:0,o=a?a.O*b:0,m=a?a.H*b:0;a=a?a.K*b:0;var n,p,t,r,q;if(c||j.d()){d=this.Wa(c||j.f());c=d.x.tl*b;j=d.y.tl* -b;n=d.x.tr*b;p=d.y.tr*b;t=d.x.br*b;r=d.y.br*b;q=d.x.bl*b;b=d.y.bl*b;e="m"+g(a)+","+g(j)+"qy"+g(c)+","+g(k)+"l"+h(e-n)+","+g(k)+"qx"+h(e-o)+","+g(p)+"l"+h(e-o)+","+h(f-r)+"qy"+h(e-t)+","+h(f-m)+"l"+g(q)+","+h(f-m)+"qx"+g(a)+","+h(f-b)+" x e"}else e="m"+g(a)+","+g(k)+"l"+h(e-o)+","+g(k)+"l"+h(e-o)+","+h(f-m)+"l"+g(a)+","+h(f-m)+"xe";return e},o:function(){var a=this.parent.ma(this.zIndex),b;if(!a){a=this.element.document.createElement(this.ia);b=a.style;b.position="absolute";b.top=b.left=0;this.parent.va(this.zIndex, -a)}return a},h:function(){this.parent.ab(this.zIndex);delete this.ta;delete this.Z}};D.vb=D.p.L({d:function(){var a=this.e;for(var b in a)if(a.hasOwnProperty(b)&&a[b].d())return true;return false},B:function(){return this.e.eb.j()},cb:function(){if(this.d()){var a=this.element,b=a,c,d,e=this.o().style,f=0;c=0;do b=b.offsetParent;while(b&&b.currentStyle.position==="static");c=a.getBoundingClientRect();if(b){d=b.getBoundingClientRect();b=b.currentStyle;f=c.left-d.left-(parseFloat(b.borderLeftWidth)|| -0);c=c.top-d.top-(parseFloat(b.borderTopWidth)||0)}else{b=a.document.documentElement;f=c.left+b.scrollLeft-b.clientLeft;c=c.top+b.scrollTop-b.clientTop}e.left=f;e.top=c;e.zIndex=a.currentStyle.position==="static"?-1:a.currentStyle.zIndex}},u:i(),db:function(){var a=this.e.eb.f();this.o().style.display=a.lc&&a.Qb?"":"none"},D:function(){this.d()?this.db():this.h()},o:function(){var a=this.G,b,c;if(!a){b=this.element;a=this.G=b.document.createElement("css3-container");c=a.style;c.position=b.currentStyle.position=== -"fixed"?"fixed":"absolute";this.db();b.parentNode.insertBefore(a,b)}return a},h:function(){var a=this.G;a&&a.parentNode&&a.parentNode.removeChild(a);delete this.G;delete this.Z}});D.lb=D.p.L({zIndex:2,ia:"background",B:function(){var a=this.e;return a.I.j()||a.s.j()},d:function(){var a=this.e,b=this.element;return b.offsetWidth&&b.offsetHeight&&(a.z.d()||a.s.d()||a.I.d()||a.A.d()&&a.A.f().pa)},u:function(){this.d()&&this.Sa()},D:function(){this.h();this.d()&&this.Sa()},Sa:function(){this.Rb();this.Sb()}, -Rb:function(){var a=this.e.I.f(),b=this.element,c=a&&a.color&&a.color.value(b),d,e,f;if(c&&c!=="transparent"){this.Xa();d=this.na("bgColor","fill",this.o(),1);e=b.offsetWidth;b=b.offsetHeight;d.stroked=false;d.coordsize=e*2+","+b*2;d.coordorigin="1,1";d.path=this.la(null,2);f=d.style;f.width=e;f.height=b;d.fill.color=c;a=a.color.Ra();if(a<1)d.fill.opacity=a}else this.xa("bgColor")},Sb:function(){var a=this.e.I.f();a=a&&a.images;var b,c,d,e,f,j;if(a){this.Xa();b=this.element;d=b.offsetWidth;e=b.offsetHeight; -for(j=a.length;j--;){b=a[j];c=this.na("bgImage"+j,"fill",this.o(),2);c.stroked=false;c.fill.type="tile";c.fillcolor="none";c.coordsize=d*2+","+e*2;c.coordorigin="1,1";c.path=this.la(0,2);f=c.style;f.width=d;f.height=e;if(b.type==="linear-gradient")this.Hb(c,b);else{c.fill.src=b.url;this.cc(c,j)}}}for(j=a?a.length:0;this.xa("bgImage"+j++););},cc:function(a,b){D.q.ib(a.fill.src,function(c){var d=a.fill,e=this.element,f=e.offsetWidth,j=e.offsetHeight,g=this.e,h=g.$.f(),k=h&&h.fb;h=k?k.t.a(e):0;var o= -k?k.r.a(e):0,m=k?k.b.a(e):0;k=k?k.l.a(e):0;g=g.I.f().images[b];e=g.position?g.position.coords(e,f-c.v-k-o,j-c.i-h-m):{x:0,y:0};g=g.repeat;m=o=0;var n=f+1,p=j+1,t=D.Da?0:1;k=e.x+k+0.5;h=e.y+h+0.5;d.position=k/f+","+h/j;if(g&&g!=="repeat"){if(g==="repeat-x"||g==="no-repeat"){o=h+1;p=h+c.i+t}if(g==="repeat-y"||g==="no-repeat"){m=k+1;n=k+c.v+t}a.style.clip="rect("+o+"px,"+n+"px,"+p+"px,"+m+"px)"}},this)},Hb:function(a,b){function c(x,y,v,C,G){if(v===0||v===180)return[C,y];else if(v===90||v===270)return[x, -G];else{v=Math.tan(-v*m/180);x=v*x-y;y=-1/v;C=y*C-G;G=y-v;return[(C-x)/G,(v*C-y*x)/G]}}function d(){q=h>=90&&h<270?j:0;w=h<180?g:0;l=j-q;u=g-w}function e(x,y){var v=y[0]-x[0];x=y[1]-x[1];return Math.abs(v===0?x:x===0?v:Math.sqrt(v*v+x*x))}var f=this.element,j=f.offsetWidth,g=f.offsetHeight;a=a.fill;var h=b.wa,k=b.Ba;b=b.P;var o=b.length,m=Math.PI,n,p,t,r,q,w,l,u,s,z,B,A;if(k){k=k.coords(f,j,g);n=k.x;p=k.y}if(h){h=h.Pb();if(h<0)h+=360;h%=360;d();if(!k){n=q;p=w}k=c(n,p,h,l,u);t=k[0];r=k[1]}else if(k){t= -j-n;r=g-p}else{n=p=t=0;r=g}k=t-n;s=r-p;if(h===undefined){h=-Math.atan2(s,k)/m*180;if(h<0)h+=360;h%=360;d()}k=Math.atan2(k*j/g,s)/m*180;k+=180;k%=360;z=e([n,p],[t,r]);t=e([q,w],c(q,w,h,l,u));r=[];p=e([n,p],c(n,p,h,q,w))/t*100;n=[];for(s=0;s<o;s++)n.push(b[s].Za?b[s].Za.a(f,z):s===0?0:s===o-1?z:null);for(s=1;s<o;s++){if(n[s]===null){B=n[s-1];z=s;do A=n[++z];while(A===null);n[s]=B+(A-B)/(z-s+1)}n[s]=Math.max(n[s],n[s-1])}for(s=0;s<o;s++)r.push(p+n[s]/t*100+"% "+b[s].color.value(f));a.angle=k;a.type= -"gradient";a.method="sigma";a.color=b[0].color.value(f);a.color2=b[o-1].color.value(f);a.colors.value=r.join(",")},Xa:function(){var a=this.element.runtimeStyle;a.backgroundImage="url(about:blank)";a.backgroundColor="transparent"},h:function(){D.p.h.call(this);var a=this.element.runtimeStyle;a.backgroundImage=a.backgroundColor=""}});D.pb=D.p.L({zIndex:4,ia:"border",B:function(){var a=this.e;return a.$.j()||a.s.j()},d:function(){var a=this.e;return a.z.d()||a.s.d()||a.I.d()},u:function(){this.d()&& -this.Ta()},D:function(){this.h();this.d()&&this.Ta()},Ta:function(){var a=this.element,b=a.offsetWidth,c=a.offsetHeight,d,e,f,j,g,h;if(this.e.$.f()){this.Xb();f=this.Ub(2);g=0;for(h=f.length;g<h;g++){j=f[g];d=this.na("borderPiece"+g,j.stroke?"stroke":"fill",this.o());d.coordsize=b*2+","+c*2;d.coordorigin="1,1";d.path=j.path;e=d.style;e.width=b;e.height=c;d.filled=!!j.fill;d.stroked=!!j.stroke;if(j.stroke){d=d.stroke;d.weight=j.Ia+"px";d.color=j.color.value(a);d.dashstyle=j.stroke==="dashed"?"2 2": -j.stroke==="dotted"?"1 1":"solid";d.linestyle=j.stroke==="double"&&j.Ia>2?"ThinThin":"Single"}else d.fill.color=j.fill.value(a)}for(;this.xa("borderPiece"+g++););}},Xb:function(){var a=this.element,b=a.currentStyle,c=a.runtimeStyle,d=a.tagName,e;if(d==="BUTTON"||d==="INPUT"&&a.type in{submit:1,button:1,reset:1}){c.borderWidth="";a=this.e.$.bb;for(e=a.length;e--;){d=a[e];c["padding"+d]="";c["padding"+d]=parseInt(b["padding"+d])+parseInt(b["border"+d+"Width"])+(!D.Da&&e%2?1:0)}c.borderWidth=0}else if(D.Yb){if(a.childNodes.length!== -1||a.firstChild.tagName!=="ie6-mask"){b=a.document.createElement("ie6-mask");d=b.style;d.visibility="visible";for(d.zoom=1;d=a.firstChild;)b.appendChild(d);a.appendChild(b);c.visibility="hidden"}}else c.borderColor="transparent"},Ub:function(a){var b=this.element,c,d,e=this.e.$,f=[],j,g,h,k,o,m,n,p;if(e.d()){e=e.f();m=e.fb;n=e.ic;p=e.Mb;if(e.nc&&e.jc&&e.Nb){e=m.t.a(b);h=e/2;f.push({path:this.la({Q:h,O:h,H:h,K:h},a),stroke:n.t,color:p.t,Ia:e})}else{a=a||1;c=b.offsetWidth;d=b.offsetHeight;e=m.t.a(b); -h=m.r.a(b);k=m.b.a(b);b=m.l.a(b);var t={t:e,r:h,b:k,l:b};b=this.e.s;if(b.d())o=this.Wa(b.f());j=Math.floor;g=Math.ceil;var r=function(l,u){return o?o[l][u]:0},q=function(l,u,s,z,B,A){var x=r("x",l),y=r("y",l),v=l.charAt(1)==="r";l=l.charAt(0)==="b";return x>0&&y>0?(A?"al":"ae")+(v?g(c-x):j(x))*a+","+(l?g(d-y):j(y))*a+","+(j(x)-u)*a+","+(j(y)-s)*a+","+z*65535+","+2949075*(B?1:-1):(A?"m":"l")+(v?c-u:u)*a+","+(l?d-s:s)*a},w=function(l,u,s,z){var B=l==="t"?j(r("x","tl"))*a+","+g(u)*a:l==="r"?g(c-u)*a+ -","+j(r("y","tr"))*a:l==="b"?g(c-r("x","br"))*a+","+j(d-u)*a:j(u)*a+","+g(d-r("y","bl"))*a;l=l==="t"?g(c-r("x","tr"))*a+","+g(u)*a:l==="r"?g(c-u)*a+","+g(d-r("y","br"))*a:l==="b"?j(r("x","bl"))*a+","+j(d-u)*a:j(u)*a+","+j(r("y","tl"))*a;return s?(z?"m"+l:"")+"l"+B:(z?"m"+B:"")+"l"+l};b=function(l,u,s,z,B,A){var x=l==="l"||l==="r",y=t[l],v,C;if(y>0&&n[l]!=="none"){v=t[x?l:u];u=t[x?u:l];C=t[x?l:s];s=t[x?s:l];if(n[l]==="dashed"||n[l]==="dotted"){f.push({path:q(z,v,u,A+45,0,1)+q(z,0,0,A,1,0),fill:p[l]}); -f.push({path:w(l,y/2,0,1),stroke:n[l],Ia:y,color:p[l]});f.push({path:q(B,C,s,A,0,1)+q(B,0,0,A-45,1,0),fill:p[l]})}else f.push({path:q(z,v,u,A+45,0,1)+w(l,y,0,0)+q(B,C,s,A,0,0)+(n[l]==="double"&&y>2?q(B,C-j(C/3),s-j(s/3),A-45,1,0)+w(l,g(y/3*2),1,0)+q(z,v-j(v/3),u-j(u/3),A,1,0)+"x "+q(z,j(v/3),j(u/3),A+45,0,1)+w(l,j(y/3),1,0)+q(B,j(C/3),j(s/3),A,0,0):"")+q(B,0,0,A-45,1,0)+w(l,0,1,0)+q(z,0,0,A,1,0),fill:p[l]})}};b("t","l","r","tl","tr",90);b("r","t","b","tr","br",0);b("b","r","l","br","bl",-90);b("l", -"b","t","bl","tl",-180)}}return f},h:function(){D.p.h.call(this);this.element.runtimeStyle.borderColor=""}});D.nb=D.p.L({zIndex:5,bc:["t","tr","r","br","b","bl","l","tl","c"],B:function(){var a=this.e;return a.z.j()||a.z.j()},d:function(){return this.e.z.d()},u:function(){if(this.d()){var a=this.e.z.f();this.o();var b=this.element,c=this.$a;D.q.ib(a.src,function(d){function e(q,w,l,u,s){q=c[q].style;q.width=w;q.height=l;q.left=u;q.top=s}function f(q,w,l){for(var u=0,s=q.length;u<s;u++)c[q[u]].imagedata[w]= -l}var j=b.offsetWidth,g=b.offsetHeight,h=a.width,k=h.Q.a(b),o=h.O.a(b),m=h.H.a(b);h=h.K.a(b);var n=a.slice,p=n.Q.a(b),t=n.O.a(b),r=n.H.a(b);n=n.K.a(b);e("tl",h,k,0,0);e("t",j-h-o,k,h,0);e("tr",o,k,j-o,0);e("r",o,g-k-m,j-o,k);e("br",o,m,j-o,g-m);e("b",j-h-o,m,h,g-m);e("bl",h,m,0,g-m);e("l",h,g-k-m,0,k);e("c",j-h-o,g-k-m,h,k);f(["tl","t","tr"],"cropBottom",(d.i-p)/d.i);f(["tl","l","bl"],"cropRight",(d.v-n)/d.v);f(["bl","b","br"],"cropTop",(d.i-r)/d.i);f(["tr","r","br"],"cropLeft",(d.v-t)/d.v);if(a.repeat.Ha=== -"stretch"){f(["l","r","c"],"cropTop",p/d.i);f(["l","r","c"],"cropBottom",r/d.i)}if(a.repeat.i==="stretch"){f(["t","b","c"],"cropLeft",n/d.v);f(["t","b","c"],"cropRight",t/d.v)}c.c.style.display=a.fill?"":"none"},this)}else this.h()},D:function(){this.h();this.d()&&this.u()},o:function(){var a=this.G,b,c,d,e=this.bc,f=e.length;if(!a){a=this.G=this.element.document.createElement("border-image");b=a.style;b.position="absolute";this.$a={};for(d=0;d<f;d++){c=this.$a[e[d]]=D.q.ja("rect");c.appendChild(D.q.ja("imagedata")); -b=c.style;b.behavior="url(#default#VML)";b.position="absolute";b.top=b.left=0;c.imagedata.src=this.e.z.f().src;c.stroked=false;c.filled=false;a.appendChild(c)}this.parent.va(this.zIndex,a)}return a}});D.sb=D.p.L({zIndex:1,ia:"outset-box-shadow",B:function(){var a=this.e;return a.A.j()||a.s.j()},d:function(){var a=this.e.A;return a.d()&&a.f().ca[0]},u:function(){if(this.d()){var a=this,b=this.element,c=this.o(),d=this.e,e=d.A.f().ca;d=d.s.f();for(var f=e.length,j=f,g,h=b.offsetWidth,k=b.offsetHeight, -o=D.Da?1:0,m=["tl","tr","br","bl"],n,p,t,r,q,w,l,u,s,z,B,A,x,y=function(v,C,G,O,P,Q,R){v=a.na("shadow"+v+C,"fill",c,f-v);C=v.style;var I=v.fill;C.left=G;C.top=O;v.coordsize=h*2+","+k*2;v.coordorigin="1,1";v.stroked=false;v.filled=true;I.color=P.value(b);if(Q){I.type="gradienttitle";I.color2=I.color;I.opacity=0}v.path=R;C.width=h;C.height=k;return v};j--;){p=e[j];r=p.oc.a(b);q=p.qc.a(b);g=p.gc.a(b);w=p.blur.a(b);p=p.color;l=-g-w;if(!d&&w)d=D.sa.jb;l=this.la({Q:l,O:l,H:l,K:l},2,d);if(w){u=(g+w)*2+h; -s=(g+w)*2+k;z=w*2/u;B=w*2/s;if(w-g>h/2||w-g>k/2)for(g=4;g--;){n=m[g];A=n.charAt(0)==="b";x=n.charAt(1)==="r";n=y(j,n,r,q,p,w,l);t=n.fill;t.focusposition=(x?1-z:z)+","+(A?1-B:B);t.focussize="0,0";n.style.clip="rect("+((A?s/2:0)+o)+"px,"+(x?u:u/2)+"px,"+(A?s:s/2)+"px,"+((x?u/2:0)+o)+"px)"}else{n=y(j,"",r,q,p,w,l);t=n.fill;t.focusposition=z+","+B;t.focussize=1-z*2+","+(1-B*2)}}else{n=y(j,"",r,q,p,w,l);r=p.Ra();if(r<1)n.fill.opacity=r}}}else this.h()},D:function(){this.h();this.u()}});D.rb=D.p.L({zIndex:3, -ia:"inset-box-shadow",B:function(){var a=this.e;return a.A.j()||a.s.j()},d:function(){var a=this.e.A;return a.d()&&a.f().pa[0]},u:i(),D:i()})}var E,F,H,J,K,L,M;function update(){init();var a=element.getBoundingClientRect(),b=a.left,c=a.top,d=a.right-b;a=a.bottom-c;var e,f;if(b!==H||c!==J){e=0;for(f=K.length;e<f;e++)K[e].cb();H=b;J=c}if(d!==E||a!==F){e=0;for(f=K.length;e<f;e++)K[e].u();E=d;F=a}} -function propChanged(){init();var a,b,c=[];a=0;for(b=K.length;a<b;a++)K[a].B()&&c.push(K[a]);a=0;for(b=c.length;a<b;a++)c[a].D()}function mouseEntered(){event.srcElement.className+=" "+D.Ka+"hover";setTimeout(propChanged,0)}function mouseLeft(){var a=event.srcElement;a.className=a.className.replace(new RegExp("\\b"+D.Ka+"hover\\b","g"),"");setTimeout(propChanged,0)}function N(){var a=event.propertyName;if(a==="className"||a==="id")propChanged()} -function cleanup(){var a,b;if(K){a=0;for(b=K.length;a<b;a++)K[a].h();K=null}L=null;if(M){a=0;for(b=M.length;a<b;a++){M[a].detachEvent("onpropertychange",N);M[a].detachEvent("onmouseenter",mouseEntered);M[a].detachEvent("onmouseleave",mouseLeft)}M=null}D.oa===8&&D.Ca.remove(update)} -function init(){if(!K){var a=element;a.runtimeStyle.zoom=1;L={I:new D.mb(a),$:new D.qb(a),z:new D.ob(a),s:new D.sa(a),A:new D.tb(a),eb:new D.xb(a)};var b=new D.vb(a,L);K=[b,new D.sb(a,L,b),new D.lb(a,L,b),new D.rb(a,L,b),new D.pb(a,L,b),new D.nb(a,L,b)];var c=element;if(a=c.currentStyle.getAttribute(D.T+"watch-ancestors")){M=[];a=parseInt(a,10);b=0;for(c=c.parentNode;c&&(a==="NaN"||b++<a);){M.push(c);c.attachEvent("onpropertychange",N);c.attachEvent("onmouseenter",mouseEntered);c.attachEvent("onmouseleave", -mouseLeft);c=c.parentNode}}D.oa===8&&D.Ca.add(update)}}element.readyState==="complete"&&update(); - </script> - -</PUBLIC:COMPONENT> diff --git a/rt/share/html/NoAuth/css/web2/InHeader b/rt/share/html/NoAuth/css/web2/InHeader index 408a541ea..a083eec21 100644 --- a/rt/share/html/NoAuth/css/web2/InHeader +++ b/rt/share/html/NoAuth/css/web2/InHeader @@ -73,6 +73,3 @@ jQuery(document).ready(function(){ jQuery("#prefs-menu").addClass("sf-menu sf-js-enabled").supersubs().superfish().supposition({ speed: 'fast' }); }); </script> -<!--[if (lt IE 9)&(gt IE 6)]> -<link rel="stylesheet" href="<%RT->Config->Get('WebPath')%>/NoAuth/css/web2/msie-pie.css" type="text/css" media="all" /> -<![endif]--> diff --git a/rt/share/html/NoAuth/css/web2/msie-pie.css b/rt/share/html/NoAuth/css/web2/msie-pie.css deleted file mode 100644 index 73d76d091..000000000 --- a/rt/share/html/NoAuth/css/web2/msie-pie.css +++ /dev/null @@ -1,60 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%# 02110-1301 or visit their web page on the internet at -%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -%# -%# -%# CONTRIBUTION SUBMISSION POLICY: -%# -%# (The following paragraph is not intended to limit the rights granted -%# to you to modify and distribute this software under the terms of -%# the GNU General Public License and is only of importance to you if -%# you choose to contribute your changes and enhancements to the -%# community by submitting them to Best Practical Solutions, LLC.) -%# -%# By intentionally submitting any modifications, corrections or -%# derivatives to this work, or any other work intended for use with -%# Request Tracker, to Best Practical Solutions, LLC, you confirm that -%# you are the copyright holder for those contributions and you grant -%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -%# royalty-free, perpetual, license to use, copy, create derivative -%# works based on those contributions, and sublicense and distribute -%# those contributions and any derivatives thereof. -%# -%# END BPS TAGGED BLOCK }}} -.search-result-views, -.ticket-transaction div.metadata span.actions, -div#ticket-history div.downloadattachment, -.ticket-transaction div.metadata span.type, -.titlebox, -.titlebox .titlebox-title .right, -.titlebox .titlebox-title .left, -div#footer, -#main-navigation, -#page-navigation, -div#body { - behavior: url(<%RT->Config->Get('WebPath')%>/NoAuth/css/images/PIE.htc); -} diff --git a/rt/share/html/NoAuth/js/titlebox-state.js b/rt/share/html/NoAuth/js/titlebox-state.js index 51996377e..a5e5dac20 100644 --- a/rt/share/html/NoAuth/js/titlebox-state.js +++ b/rt/share/html/NoAuth/js/titlebox-state.js @@ -46,7 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} function createCookie(name,value,days) { - var path = "<%RT->Config->Get('WebPath')%>" ? "<%RT->Config->Get('WebPath')%>" : "/"; + var path = <%RT->Config->Get('WebPath')|n,j%> ? <%RT->Config->Get('WebPath')|n,j%> : "/"; if (days) { var date = new Date(); diff --git a/rt/share/html/NoAuth/js/userautocomplete.js b/rt/share/html/NoAuth/js/userautocomplete.js index db244d16c..b4f678c76 100644 --- a/rt/share/html/NoAuth/js/userautocomplete.js +++ b/rt/share/html/NoAuth/js/userautocomplete.js @@ -70,7 +70,7 @@ jQuery(function() { continue; var options = { - source: "<% RT->Config->Get('WebPath')%>/Helpers/Autocomplete/Users" + source: <% RT->Config->Get('WebPath') |n,j%>+"/Helpers/Autocomplete/Users" }; var queryargs = []; diff --git a/rt/share/html/NoAuth/js/util.js b/rt/share/html/NoAuth/js/util.js index 62ee922f9..5bfce411d 100644 --- a/rt/share/html/NoAuth/js/util.js +++ b/rt/share/html/NoAuth/js/util.js @@ -294,8 +294,8 @@ function ReplaceAllTextareas(encoded) { textArea.parentNode.appendChild(typeField); - CKEDITOR.replace(textArea.name,{width:'100%',height:'<% RT->Config->Get('MessageBoxRichTextHeight') %>'}); - CKEDITOR.basePath = "<%RT->Config->Get('WebPath')%>/NoAuth/RichText/"; + CKEDITOR.replace(textArea.name,{width:'100%',height:<% RT->Config->Get('MessageBoxRichTextHeight') |n,j%>}); + CKEDITOR.basePath = <%RT->Config->Get('WebPath')|n,j%>+"/NoAuth/RichText/"; jQuery("#" + textArea.name + "___Frame").addClass("richtext-editor"); } diff --git a/rt/share/html/Prefs/Search.html b/rt/share/html/Prefs/Search.html index fdd9c17dd..42aa16bbf 100644 --- a/rt/share/html/Prefs/Search.html +++ b/rt/share/html/Prefs/Search.html @@ -95,7 +95,7 @@ $ARGS{'OrderBy'} = join '|', grep defined && /\S/, (ref $ARGS{'OrderBy'})? @{$AR my ( $AvailableColumns, $CurrentFormat ); ( $ARGS{Format}, $AvailableColumns, $CurrentFormat ) = $m->comp( '/Search/Elements/BuildFormatString', - cfqueues => {}, %ARGS + %ARGS ); if ($ARGS{'Save'}) { diff --git a/rt/share/html/REST/1.0/Forms/ticket/default b/rt/share/html/REST/1.0/Forms/ticket/default index 9ae803d89..9a2212b55 100755 --- a/rt/share/html/REST/1.0/Forms/ticket/default +++ b/rt/share/html/REST/1.0/Forms/ticket/default @@ -149,10 +149,16 @@ else { } # Set custom field elsif ($k =~ /^$cf_spec/) { - my $cf = RT::CustomField->new( RT->SystemUser ); - my $cfk = $1 || $2; - unless($cf->LoadByName( Name => $cfk )) { - push @comments, "# Invalid custom field name ($cfk)"; + my $key = $1 || $2; + + my $cf = RT::CustomField->new( $session{CurrentUser} ); + $cf->LoadByName( Name => $key, Queue => $data{Queue} || $v{Queue} ); + unless ( $cf->id ) { + $cf->LoadByName( Name => $key, Queue => 0 ); + } + + if (not $cf->id) { + push @comments, "# Invalid custom field name ($key)"; delete $data{$k}; next; } @@ -348,9 +354,15 @@ else { } # Set custom field elsif ($key =~ /^$cf_spec/) { - my $cf = RT::CustomField->new( RT->SystemUser ); $key = $1 || $2; - if (not $cf->LoadByName( Name => $key )) { + + my $cf = RT::CustomField->new( $session{CurrentUser} ); + $cf->LoadByName( Name => $key, Queue => $ticket->Queue ); + unless ( $cf->id ) { + $cf->LoadByName( Name => $key, Queue => 0 ); + } + + if (not $cf->id) { $n = 0; $s = "Unknown custom field."; } diff --git a/rt/share/html/REST/1.0/Forms/ticket/links b/rt/share/html/REST/1.0/Forms/ticket/links index e2e1830fe..bf4f2575c 100755 --- a/rt/share/html/REST/1.0/Forms/ticket/links +++ b/rt/share/html/REST/1.0/Forms/ticket/links @@ -100,7 +100,8 @@ if ($changes) { my $tick = RT::Ticket->new($session{CurrentUser}); $tick->Load($nkey); if ($tick->Id) { - $nkey = $uri->FromObject($tick); + $uri->FromObject($tick); + $nkey = $uri->URI; } else { $n = 0; diff --git a/rt/share/html/REST/1.0/Forms/transaction/default b/rt/share/html/REST/1.0/Forms/transaction/default index 1ffa2b2a5..2e45f6707 100644 --- a/rt/share/html/REST/1.0/Forms/transaction/default +++ b/rt/share/html/REST/1.0/Forms/transaction/default @@ -49,7 +49,6 @@ %# <%ARGS> $id -$args => undef $format => undef $fields => undef </%ARGS> @@ -57,8 +56,6 @@ $fields => undef my $trans = RT::Transactions->new($session{CurrentUser}); my ($c, $o, $k, $e) = ("", [], {} , ""); -chomp $args; -my @arglist = split('/', $args); my $tid = $id; $trans->Limit(FIELD => 'Id', OPERATOR => '=', VALUE => $tid); diff --git a/rt/share/html/REST/1.0/ticket/link b/rt/share/html/REST/1.0/ticket/link index aa80b0de4..8d3345fa0 100755 --- a/rt/share/html/REST/1.0/ticket/link +++ b/rt/share/html/REST/1.0/ticket/link @@ -81,10 +81,9 @@ if ($id && $object && $id != $object) { goto OUTPUT; } $id ||= $object; -unless ($id =~ /^\d+$/ && $to =~ /^\d+$/) { - my $bad = ($id !~ /^\d+$/) ? $id : $to; +unless ($id =~ /^\d+$/) { $output = $r->path_info. "\n"; - $output .= "Invalid ticket id: '$bad'.\n"; + $output .= "Invalid ticket id: '$id'.\n"; $status = "400 Bad Request"; goto OUTPUT; } diff --git a/rt/share/html/Search/Build.html b/rt/share/html/Search/Build.html index ae4c7ba78..b200f9050 100644 --- a/rt/share/html/Search/Build.html +++ b/rt/share/html/Search/Build.html @@ -78,7 +78,7 @@ <div id="pick-criteria"> - <& Elements/PickCriteria, query => $query{'Query'}, cfqueues => $queues &> + <& Elements/PickCriteria, query => $query{'Query'}, queues => $queues &> <& /Elements/Submit, Label => loc('Add these terms'), SubmitId => 'AddClause', Name => 'AddClause'&> <& /Elements/Submit, Label => loc('Add these terms and Search'), SubmitId => 'DoSearch', Name => 'DoSearch'&> </div> @@ -275,7 +275,7 @@ my ( $AvailableColumns, $CurrentFormat ); ( $query{'Format'}, $AvailableColumns, $CurrentFormat ) = $m->comp( 'Elements/BuildFormatString', %ARGS, - cfqueues => $queues, + queues => $queues, Format => $query{'Format'}, ); @@ -308,7 +308,7 @@ if ( $ARGS{'DoSearch'} ) { SavedChartSearchId => $ARGS{'SavedChartSearchId'}, SavedSearchId => $saved_search{'Id'}, ); - RT::Interface::Web::Redirect(RT->Config->Get('WebPath') . '/Search/Results.html?' . $redir_query_string); + RT::Interface::Web::Redirect(RT->Config->Get('WebURL') . 'Search/Results.html?' . $redir_query_string); $m->abort; } diff --git a/rt/share/html/Search/Chart.html b/rt/share/html/Search/Chart.html index 884d1838a..070ce7cf7 100644 --- a/rt/share/html/Search/Chart.html +++ b/rt/share/html/Search/Chart.html @@ -124,7 +124,7 @@ my %query; <input type="hidden" class="hidden" name="Query" value="<% $ARGS{Query} %>" /> <input type="hidden" class="hidden" name="SavedChartSearchId" value="<% $saved_search->{SearchId} || 'new' %>" /> -<&|/l, $m->scomp('Elements/SelectChartType', Name => 'ChartStyle', Default => $ChartStyle), $m->scomp('Elements/SelectGroupBy', Name => 'PrimaryGroupBy', Query => $ARGS{Query}, Default => $PrimaryGroupBy) +<&|/l_unsafe, $m->scomp('Elements/SelectChartType', Name => 'ChartStyle', Default => $ChartStyle), $m->scomp('Elements/SelectGroupBy', Name => 'PrimaryGroupBy', Query => $ARGS{Query}, Default => $PrimaryGroupBy) &>[_1] chart by [_2]</&><input type="submit" class="button" value="<%loc('Update Chart')%>" /> </form> </&> diff --git a/rt/share/html/Search/Elements/BuildFormatString b/rt/share/html/Search/Elements/BuildFormatString index 376997229..a39287bff 100644 --- a/rt/share/html/Search/Elements/BuildFormatString +++ b/rt/share/html/Search/Elements/BuildFormatString @@ -48,7 +48,7 @@ <%ARGS> $Format => RT->Config->Get('DefaultSearchResultFormat') -%cfqueues => () +%queues => () $Face => undef $Size => undef @@ -111,17 +111,11 @@ my @fields = ( $m->callback( CallbackOnce => 1, CallbackName => 'SetFieldsOnce', Fields => \@fields ); my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'}); -foreach my $id (keys %cfqueues) { +foreach my $id (keys %queues) { # Gotta load up the $queue object, since queues get stored by name now. my $id my $queue = RT::Queue->new($session{'CurrentUser'}); $queue->Load($id); - unless ($queue->id) { - # XXX TODO: This ancient code dates from a former developer - # we have no idea what it means or why cfqueues are so encoded. - $id =~ s/^.'*(.*).'*$/$1/; - $queue->Load($id); - } - $CustomFields->LimitToQueue($queue->Id); + $CustomFields->LimitToQueue($queue->Id) if $queue->Id; } $CustomFields->LimitToGlobal; diff --git a/rt/share/html/Search/Elements/Chart b/rt/share/html/Search/Elements/Chart index 01b78c712..be05da315 100644 --- a/rt/share/html/Search/Elements/Chart +++ b/rt/share/html/Search/Elements/Chart @@ -130,10 +130,10 @@ my ($i,$total); ); </%perl> <td class="label collection-as-table"> -<a href=<% RT->Config->Get('WebURL') %>Search/Results.html?<%$QueryString%>><%$key%></a> +<a href=<% RT->Config->Get('WebPath') %>/Search/Results.html?<%$QueryString%>><%$key%></a> </td> <td class="value collection-as-table"> -<a href=<% RT->Config->Get('WebURL') %>Search/Results.html?<%$QueryString%>><%$value%></a> +<a href=<% RT->Config->Get('WebPath') %>/Search/Results.html?<%$QueryString%>><%$value%></a> </td> % } else { <td class="label collection-as-table"><% $key %></td> diff --git a/rt/share/html/Search/Elements/PickBasics b/rt/share/html/Search/Elements/PickBasics index 7223b75dc..db7d9f5c1 100644 --- a/rt/share/html/Search/Elements/PickBasics +++ b/rt/share/html/Search/Elements/PickBasics @@ -103,7 +103,7 @@ my @lines = ( Value => { Type => 'component', Path => '/Elements/SelectStatus', - Arguments => { SkipDeleted => 1 }, + Arguments => { SkipDeleted => 1, Queues => \%queues }, }, }, { @@ -124,7 +124,7 @@ my @lines = ( Value => { Type => 'component', Path => '/Elements/SelectOwner', - Arguments => { ValueAttribute => 'Name' }, + Arguments => { ValueAttribute => 'Name', Queues => \%queues }, }, }, { @@ -214,3 +214,6 @@ my @lines = ( $m->callback( Conditions => \@lines ); </%INIT> +<%ARGS> +%queues => () +</%ARGS> diff --git a/rt/share/html/Search/Elements/PickCFs b/rt/share/html/Search/Elements/PickCFs index 4b9a88b77..f2dc21f68 100644 --- a/rt/share/html/Search/Elements/PickCFs +++ b/rt/share/html/Search/Elements/PickCFs @@ -50,21 +50,11 @@ % } <%INIT> my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'}); -foreach my $id (keys %cfqueues) { - # Gotta load up the $queue object, since queues get stored by name now. my $id +foreach my $id (keys %queues) { + # Gotta load up the $queue object, since queues get stored by name now. my $queue = RT::Queue->new($session{'CurrentUser'}); $queue->Load($id); - unless ($queue->id) { - # XXX TODO: This ancient code dates from a former developer - # we have no idea what it means or why cfqueues are so encoded. - $id =~ s/^.'*(.*).'*$/$1/; - - # unescape internal quotes - $id =~ s/(\\(.))/$2 eq "'" ? "'" : $1/eg; - - $queue->Load($id); - } - $CustomFields->LimitToQueue($queue->Id); + $CustomFields->LimitToQueue($queue->Id) if $queue->Id; } $CustomFields->LimitToGlobal; $m->callback( @@ -124,10 +114,10 @@ while ( my $CustomField = $CustomFields->Next ) { push @lines, \%line; } -$m->callback( Conditions => \@lines, Queues => \%cfqueues ); +$m->callback( Conditions => \@lines, Queues => \%queues ); </%INIT> <%ARGS> -%cfqueues => undef +%queues => () </%ARGS> diff --git a/rt/share/html/Search/Elements/PickCriteria b/rt/share/html/Search/Elements/PickCriteria index 5d0b8af5e..74547c7da 100644 --- a/rt/share/html/Search/Elements/PickCriteria +++ b/rt/share/html/Search/Elements/PickCriteria @@ -53,7 +53,7 @@ <& PickBasics &> <& PickCustomerFields &> -<& PickCFs, cfqueues => \%cfqueues &> +<& PickCFs, queues => \%queues &> <tr class="separator"><td colspan="3"><hr /></td></tr> <tr> @@ -69,5 +69,5 @@ <%ARGS> $addquery => 0 $query => undef -%cfqueues => undef +%queues => () </%ARGS> diff --git a/rt/share/html/Search/Results.html b/rt/share/html/Search/Results.html index 0040d2a77..171b38d92 100755 --- a/rt/share/html/Search/Results.html +++ b/rt/share/html/Search/Results.html @@ -46,7 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => $title, - Refresh => $session{'tickets_refresh_interval'} || RT->Config->Get('SearchResultsRefreshInterval', $session{'CurrentUser'} ), + Refresh => $refresh, LinkRel => \%link_rel &> <& /Elements/Tabs &> <& /Elements/CollectionList, @@ -148,6 +148,16 @@ if ($ARGS{'TicketsRefreshInterval'}) { $session{'tickets_refresh_interval'} = $ARGS{'TicketsRefreshInterval'}; } +my $refresh = $session{'tickets_refresh_interval'} + || RT->Config->Get('SearchResultsRefreshInterval', $session{'CurrentUser'} ); + +if (RT->Config->Get('RestrictReferrer') and $refresh and not $m->request_args->{CSRF_Token}) { + my $token = RT::Interface::Web::StoreRequestToken( $session{'CurrentSearchHash'} ); + $m->notes->{RefreshURL} = RT->Config->Get('WebURL') + . "Search/Results.html?CSRF_Token=" + . $token; +} + my %link_rel; my $genpage = sub { return $m->comp( diff --git a/rt/share/html/Search/Simple.html b/rt/share/html/Search/Simple.html index 07bd2f4dc..4d7b1e3c5 100644 --- a/rt/share/html/Search/Simple.html +++ b/rt/share/html/Search/Simple.html @@ -60,7 +60,7 @@ % my @strong = qw(<strong> </strong>); -<p><&|/l, @strong &>Search for tickets by entering [_1]id[_2] numbers, subject words [_1]"in quotes"[_2], [_1]queues[_2] by name, Owners by [_1]username[_2], Requestors by [_1]email address[_2], and ticket [_1]statuses[_2].</&></p> +<p><&|/l_unsafe, @strong &>Search for tickets by entering [_1]id[_2] numbers, subject words [_1]"in quotes"[_2], [_1]queues[_2] by name, Owners by [_1]username[_2], Requestors by [_1]email address[_2], and ticket [_1]statuses[_2].</&></p> <p><&|/l&>Any word not recognized by RT is searched for in ticket subjects.</&></p> @@ -74,7 +74,7 @@ % } % } -<p><&|/l, map { "<strong>$_</strong>" } qw(initial active inactive any) &>Entering [_1], [_2], [_3], or [_4] limits results to tickets with one of the respective types of statuses. Any individual status name limits results to just the statuses named.</&> +<p><&|/l_unsafe, map { "<strong>$_</strong>" } qw(initial active inactive any) &>Entering [_1], [_2], [_3], or [_4] limits results to tickets with one of the respective types of statuses. Any individual status name limits results to just the statuses named.</&> % if (RT->Config->Get('OnlySearchActiveTicketsInSimpleSearch', $session{'CurrentUser'})) { % my $status_str = join ', ', map { loc($_) } RT::Queue->ActiveStatusArray; @@ -82,13 +82,13 @@ % } </p> -<p><&|/l, map { "<strong>$_</strong>" } 'queue:"Example Queue"', 'owner:email@example.com' &>Start the search term with the name of a supported field followed by a colon, as in [_1] and [_2], to explicitly specify the search type.</&></p> +<p><&|/l_unsafe, map { "<strong>$_</strong>" } 'queue:"Example Queue"', 'owner:email@example.com' &>Start the search term with the name of a supported field followed by a colon, as in [_1] and [_2], to explicitly specify the search type.</&></p> -<p><&|/l, '<strong>cf.Name:value</strong>' &>CFs may be searched using a similar syntax as above with [_1].</&></p> +<p><&|/l_unsafe, '<strong>cf.Name:value</strong>' &>CFs may be searched using a similar syntax as above with [_1].</&></p> % my $link_start = '<a href="' . RT->Config->Get('WebPath') . '/Search/Build.html">'; % my $link_end = '</a>'; -<p><&|/l, $link_start, $link_end &>For the full power of RT's searches, please visit the [_1]search builder interface[_2].</&></p> +<p><&|/l_unsafe, $link_start, $link_end &>For the full power of RT's searches, please visit the [_1]search builder interface[_2].</&></p> </form> diff --git a/rt/share/html/SelfService/Elements/MyRequests b/rt/share/html/SelfService/Elements/MyRequests index 549d45839..76accfc9b 100755 --- a/rt/share/html/SelfService/Elements/MyRequests +++ b/rt/share/html/SelfService/Elements/MyRequests @@ -45,42 +45,34 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<&| /Widgets/TitleBox, title => $title &> +<&| /Widgets/TitleBox, title => $title &> <& /Elements/CollectionList, Title => $title, Format => $Format, Query => $Query, Order => @Order, OrderBy => @OrderBy, BaseURL => $BaseURL, - GenericQueryArgs => $GenericQueryArgs, - AllowSorting => $AllowSorting, + AllowSorting => 1, Class => 'RT::Tickets', Rows => $Rows, Page => $Page &> </&> <%INIT> +my $title = loc("My [_1] tickets", $friendly_status); my $id = $session{'CurrentUser'}->id; -my $Query = "( " - . join( ' OR ', map "$_.id = $id", @roles ) - . ")"; +my $Query = "( Watcher.id = $id )"; if ( @status ) { - $Query .= " AND ( " - . join( ' OR ', map "Status = '$_'", @status ) - . " )"; + @status = map {s/(['\\])/\\$1/g; "Status = '$_'"} @status; + $Query .= " AND ( " . join(' OR ', @status ) . " )"; } my $Format = RT->Config->Get('DefaultSelfServiceSearchResultFormat'); - </%INIT> <%ARGS> $friendly_status => loc('open') -$title => loc("My [_1] tickets", $friendly_status) -@roles => ('Watcher') -@status => RT::Queue->ActiveStatusArray() +@status => () $BaseURL => undef $Page => 1 -$GenericQueryArgs => undef -$AllowSorting => 1 @Order => ('ASC') @OrderBy => ('Created') $Rows => 50 diff --git a/rt/share/html/SelfService/index.html b/rt/share/html/SelfService/index.html index a89296b19..29accf551 100755 --- a/rt/share/html/SelfService/index.html +++ b/rt/share/html/SelfService/index.html @@ -48,6 +48,8 @@ <& /SelfService/Elements/Header, Title => loc('Open tickets') &> <& /SelfService/Elements/MyRequests, %ARGS, + status => [ RT::Queue->ActiveStatusArray() ], + friendly_status => loc('open'), BaseURL => RT->Config->Get('WebPath') ."/SelfService/?", Page => $Page, &> diff --git a/rt/share/html/Ticket/Create.html b/rt/share/html/Ticket/Create.html index 9fb2b2bc5..f29dfbbcf 100755 --- a/rt/share/html/Ticket/Create.html +++ b/rt/share/html/Ticket/Create.html @@ -110,7 +110,7 @@ <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1 &> </table> </&> -% $m->callback( CallbackName => 'AfterBasics', QueueObj => $QueueObj ); +% $m->callback( CallbackName => 'AfterBasics', QueueObj => $QueueObj, ARGSRef => \%ARGS ); </div> <div id="ticket-create-message"> @@ -304,41 +304,30 @@ if ($CloneTicket) { my $members = $CloneTicketObj->Members; my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by ); my $refers = $CloneTicketObj->RefersTo; + my $get_link_value = sub { + my ($link, $type) = @_; + my $uri_method = $type . 'URI'; + my $local_method = 'Local' . $type; + my $uri = $link->$uri_method; + return if $uri->IsLocal and + $uri->Object and + $uri->Object->isa('RT::Ticket') and + $uri->Object->Type eq 'reminder'; + + return $link->$local_method || $uri->URI; + }; while ( my $refer = $refers->Next ) { - push @refers, $refer->LocalTarget; + my $refer_value = $get_link_value->($refer, 'Target'); + push @refers, $refer_value if defined $refer_value; } $clone->{'new-RefersTo'} = join ' ', @refers; my $refers_by = $CloneTicketObj->ReferredToBy; while ( my $refer_by = $refers_by->Next ) { - push @refers_by, $refer_by->LocalBase; + my $refer_by_value = $get_link_value->($refer_by, 'Base'); + push @refers_by, $refer_by_value if defined $refer_by_value; } $clone->{'RefersTo-new'} = join ' ', @refers_by; - if (0) { # Temporarily disabled - my $depends = $CloneTicketObj->DependsOn; - while ( my $depend = $depends->Next ) { - push @depends, $depend->LocalTarget; - } - $clone->{'new-DependsOn'} = join ' ', @depends; - - my $depends_by = $CloneTicketObj->DependedOnBy; - while ( my $depend_by = $depends_by->Next ) { - push @depends_by, $depend_by->LocalBase; - } - $clone->{'DependsOn-new'} = join ' ', @depends_by; - - while ( my $member = $members->Next ) { - push @members, $member->LocalBase; - } - $clone->{'MemberOf-new'} = join ' ', @members; - - my $members_of = $CloneTicketObj->MemberOf; - while ( my $member_of = $members_of->Next ) { - push @members_of, $member_of->LocalTarget; - } - $clone->{'new-MemberOf'} = join ' ', @members_of; - - } my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields(); while ( my $cf = $cfs->Next ) { diff --git a/rt/share/html/Ticket/Display.html b/rt/share/html/Ticket/Display.html index 6deb65cac..0a29c9763 100755 --- a/rt/share/html/Ticket/Display.html +++ b/rt/share/html/Ticket/Display.html @@ -55,7 +55,7 @@ <& /Elements/ListActions, actions => \@Actions &> <& Elements/ShowUpdateStatus, Ticket => $TicketObj &> -% $m->callback( %ARGS, Ticket => $TicketObj, CallbackName => 'BeforeShowSummary' ); +% $m->callback( %ARGS, Ticket => $TicketObj, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowSummary' ); <div class="summary"> <&| /Widgets/TitleBox, title => loc('Ticket metadata') &> <& /Ticket/Elements/ShowSummary, Ticket => $TicketObj, Attachments => $attachments &> @@ -63,7 +63,7 @@ </div> <br /> -% $m->callback( Ticket => $TicketObj, %ARGS, CallbackName => 'BeforeShowHistory' ); +% $m->callback( Ticket => $TicketObj, %ARGS, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowHistory' ); % if (not $ForceShowHistory and RT->Config->Get( 'DeferTransactionLoading', $session{'CurrentUser'} )) { <& /Ticket/Elements/ClickToShowHistory, @@ -83,6 +83,8 @@ % $m->callback( %ARGS, % Ticket => $TicketObj, +% Transactions => $transactions, +% Attachments => $attachments, % CallbackName => 'AfterShowHistory', % ); diff --git a/rt/share/html/Ticket/Elements/Bookmark b/rt/share/html/Ticket/Elements/Bookmark index 83931918d..30c9a4356 100644 --- a/rt/share/html/Ticket/Elements/Bookmark +++ b/rt/share/html/Ticket/Elements/Bookmark @@ -83,7 +83,7 @@ $Toggle => 0 </%ARGS> <span class="toggle-bookmark-<% $id %>"> % my $url = RT->Config->Get('WebPath') ."/Helpers/Toggle/TicketBookmark?id=". $id; -<a align="right" href="<% $url %>" onclick="jQuery('.toggle-bookmark-<% $id |n%>').load('<% $url |n %>'); return false;" > +<a align="right" href="<% $url %>" onclick="jQuery('.toggle-bookmark-'+<% $id |n,j%>).load(<% $url |n,j %>); return false;" > % if ( $bookmarked ) { <img src="<% RT->Config->Get('WebPath') %>/NoAuth/images/star.gif" alt="<% loc('Remove Bookmark') %>" style="border-style: none" /> % } else { diff --git a/rt/share/html/Ticket/Elements/ClickToShowHistory b/rt/share/html/Ticket/Elements/ClickToShowHistory index 4461b9af6..5a9a477e0 100644 --- a/rt/share/html/Ticket/Elements/ClickToShowHistory +++ b/rt/share/html/Ticket/Elements/ClickToShowHistory @@ -47,7 +47,7 @@ %# END BPS TAGGED BLOCK }}} <div id="deferred_ticket_history"> <& /Widgets/TitleBoxStart, title => 'History' &> - <a href="<% $display %>" onclick="jQuery('#deferred_ticket_history').text('<% loc('Loading...') %>').load('<% $url |n %>'); return false;" ><% loc('Show ticket history') %></a> + <a href="<% $display %>" onclick="jQuery('#deferred_ticket_history').text(<% loc('Loading...') |n,j%>).load(<% $url |n,j %>); return false;" ><% loc('Show ticket history') %></a> <& /Widgets/TitleBoxEnd &> </div> <%ARGS> diff --git a/rt/share/html/Ticket/Elements/FoldStanzaJS b/rt/share/html/Ticket/Elements/FoldStanzaJS index be6b2648c..4b0b4c466 100644 --- a/rt/share/html/Ticket/Elements/FoldStanzaJS +++ b/rt/share/html/Ticket/Elements/FoldStanzaJS @@ -47,4 +47,4 @@ %# END BPS TAGGED BLOCK }}} <span class="message-stanza-folder closed" - onclick="fold_message_stanza(this, '<%loc('Show quoted text')%>', '<%loc('Hide quoted text')%>');"><%loc('Show quoted text')%></span><br />\ + onclick="fold_message_stanza(this, <%loc('Show quoted text') |n,j%>, <%loc('Hide quoted text') |n,j%>);"><%loc('Show quoted text')%></span><br />\ diff --git a/rt/share/html/Ticket/Elements/Reminders b/rt/share/html/Ticket/Elements/Reminders index 563b0f0cd..36d0d8e35 100644 --- a/rt/share/html/Ticket/Elements/Reminders +++ b/rt/share/html/Ticket/Elements/Reminders @@ -54,13 +54,14 @@ $Edit => 0 <%init> $Ticket = LoadTicket($id) if ($id); +my $resolve_status = $Ticket->QueueObj->Lifecycle->ReminderStatusOnResolve; my $count_reminders = RT::Reminders->new($session{'CurrentUser'}); $count_reminders->Ticket($Ticket->id); my $count_tickets = $count_reminders->Collection; if (!$ShowCompleted) { # XXX: don't break encapsulation if we can avoid it - $count_tickets->FromSQL('Type = "reminder" AND RefersTo = "'.$Ticket->id.'" AND Status != "resolved"'); + $count_tickets->FromSQL(q{Type = "reminder" AND RefersTo = "} . $Ticket->id . qq{" AND Status != "$resolve_status" }); } my $has_reminders = $count_tickets->Count; @@ -85,7 +86,7 @@ my $reminder_collection = $count_reminders->Collection; % my $visible = 0; % while ( my $reminder = $reminder_collection->Next ) { % $i++; -% if ( $reminder->Status eq 'resolved' && !$ShowCompleted ) { +% if ( $reminder->Status eq $resolve_status && !$ShowCompleted ) { <tr class="hidden"><td><input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /></td></tr> % $i++; % } elsif ($Edit) { @@ -105,7 +106,7 @@ my $reminder_collection = $count_reminders->Collection; %# we must always include resolved reminders due to the browser %# checkbox-with-false-value issue % while ( my $reminder = $reminder_collection->Next ) { -% if ( $reminder->Status eq 'resolved' && !$ShowCompleted ) { +% if ( $reminder->Status eq $resolve_status && !$ShowCompleted ) { <input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /> % } % } @@ -139,7 +140,7 @@ $Ticket $Index </%args> <tr class="<% $Index%2 ? 'oddline' : 'evenline' %>"> -<td class="entry"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' |n %> /></td> +<td class="entry"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->QueueObj->Lifecycle->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> /></td> <td class="label"><&|/l&>Subject</&>:</td> <td class="entry" colspan="3"><input type="text" size="50" name="Reminder-Subject-<% $Reminder->id %>" value="<% $Reminder->Subject %>" /></td> </tr> @@ -160,7 +161,7 @@ $Index % my $dueobj = $Reminder->DueObj; % my $overdue = $dueobj->Unix > 0 && $dueobj->Diff < 0 ? 1 : 0; <tr class="<% $Index%2 ? 'oddline' : 'evenline' %>"> -<td class="collection-as-table"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq 'resolved' ? 'checked="checked"' : '' |n %> /></td> +<td class="collection-as-table"><input type="checkbox" value="1" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->QueueObj->Lifecycle->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> /></td> <td class="collection-as-table"><% $Reminder->Subject %></td> <td class="collection-as-table"><% $overdue ? '<span class="overdue">' : '' |n %><% $dueobj->AgeAsString || loc('Not set') %><% $overdue ? '</span>' : '' |n %></td> <td class="collection-as-table"><& /Elements/ShowUser, User => $Reminder->OwnerObj &></td> diff --git a/rt/share/html/Ticket/Elements/ShowHistory b/rt/share/html/Ticket/Elements/ShowHistory index b5e009c34..909ea01ee 100755 --- a/rt/share/html/Ticket/Elements/ShowHistory +++ b/rt/share/html/Ticket/Elements/ShowHistory @@ -60,11 +60,12 @@ if ($ShowDisplayModes or $ShowTitle) { if ($ShowDisplayModes) { $titleright = ''; - my $open_all = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' ); - my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'h' ); + my $open_all = $m->interp->apply_escapes( loc("Show all quoted text"), 'j' ); + my $open_html = $m->interp->apply_escapes( loc("Show all quoted text"), 'h' ); + my $close_all = $m->interp->apply_escapes( loc("Hide all quoted text"), 'j' ); $titleright .= '<a href="#" data-direction="open" ' - . qq{onclick='return toggle_all_folds(this, "$open_all", "$close_all");'} - . ">$open_all</a> — "; + . qq{onclick="return toggle_all_folds(this, $open_all, $close_all);"} + . ">$open_html</a> — "; if ($ShowHeaders) { $titleright .= qq{<a href="$URIFile?id=} . diff --git a/rt/share/html/Ticket/Elements/ShowRequestor b/rt/share/html/Ticket/Elements/ShowRequestor index 3e5f41fb9..8a8eef62c 100755 --- a/rt/share/html/Ticket/Elements/ShowRequestor +++ b/rt/share/html/Ticket/Elements/ShowRequestor @@ -175,7 +175,9 @@ unless ( $DefaultTicketsTab eq 'None' ) { } my $TicketTemplate = "ShowRequestorTickets$DefaultTicketsTab"; -$TicketTemplate = "ShowRequestorTicketsActive" unless $m->comp_exists($TicketTemplate); +$TicketTemplate = "ShowRequestorTicketsActive" + unless RT::Interface::Web->ComponentPathIsSafe($TicketTemplate) + and $m->comp_exists($TicketTemplate); </%INIT> <%ARGS> $Ticket=>undef diff --git a/rt/share/html/Ticket/Elements/UpdateCc b/rt/share/html/Ticket/Elements/UpdateCc index 392ee86b1..d062156c7 100644 --- a/rt/share/html/Ticket/Elements/UpdateCc +++ b/rt/share/html/Ticket/Elements/UpdateCc @@ -61,8 +61,7 @@ class="onetime onetimecc" type="checkbox" % my $clean_addr = $txn_addresses{$addr}->format; -% $clean_addr =~ s/'/\\'/g; - onClick="checkboxToInput('UpdateCc', 'UpdateCc-<%$addr%>','<%$clean_addr%>' );" + onClick="checkboxToInput('UpdateCc', <% "UpdateCc-$addr" |n,j%>, <%$clean_addr|n,j%> );" <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> > <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> %} </td></tr> @@ -77,8 +76,7 @@ class="onetime onetimebcc" type="checkbox" % my $clean_addr = $txn_addresses{$addr}->format; -% $clean_addr =~ s/'/\\'/g; - onClick="checkboxToInput('UpdateBcc', 'UpdateBcc-<%$addr%>','<%$clean_addr%>' );" + onClick="checkboxToInput('UpdateBcc', <% "UpdateBcc-$addr" |n,j%>, <%$clean_addr|n,j%> );" <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%>> <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> %} diff --git a/rt/share/html/Ticket/GnuPG.html b/rt/share/html/Ticket/GnuPG.html index 6269907ca..d15ce720a 100644 --- a/rt/share/html/Ticket/GnuPG.html +++ b/rt/share/html/Ticket/GnuPG.html @@ -51,7 +51,7 @@ % $m->callback( CallbackName => 'BeforeActionList', %ARGS, Actions => \@results, ARGSRef => \%ARGS ); <& /Elements/ListActions, actions => \@results &> <form method="post" action="<% RT->Config->Get('WebPath') . $m->request_comp->path %>?id=<% $id %>"> -<a href="<% RT->Config->Get('WebURL') %>Ticket/Display.html?id=<% $txn->Ticket %>#txn-<% $id %>"> +<a href="<% RT->Config->Get('WebPath') %>/Ticket/Display.html?id=<% $txn->Ticket %>#txn-<% $id %>"> <% loc('Return back to the ticket') %> </a> <& /Elements/Submit, diff --git a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties index e68aaed55..c5479e3f0 100644 --- a/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties +++ b/rt/share/html/Ticket/Graphs/Elements/EditGraphProperties @@ -151,7 +151,7 @@ my $class = ''; $class = 'class="hidden"' if $Level != 1 && !@Default; </%INIT> <% loc('Show Tickets Properties on [_1] level', $Level) %> -(<small><a href="#" onclick="hideshow('<% $id %>'); return false;"><% loc('open/close') %></a></small>): +(<small><a href="#" onclick="hideshow(<% $id |n,j%>); return false;"><% loc('open/close') %></a></small>): <table id="<% $id %>" <% $class |n %>> % while ( my ($group, $list) = (splice @Available, 0, 2) ) { <tr><td><% loc($group) %>:</td><td> diff --git a/rt/share/html/Ticket/Graphs/Elements/ShowGraph b/rt/share/html/Ticket/Graphs/Elements/ShowGraph index 967a5e4aa..2163b81a8 100644 --- a/rt/share/html/Ticket/Graphs/Elements/ShowGraph +++ b/rt/share/html/Ticket/Graphs/Elements/ShowGraph @@ -66,6 +66,7 @@ $ARGS{'id'} = $id = $ticket->id; require RT::Graph::Tickets; my $graph = RT::Graph::Tickets->TicketLinks( %ARGS, + Graph => undef, Ticket => $ticket, ); </%INIT> diff --git a/rt/share/html/Ticket/Graphs/dhandler b/rt/share/html/Ticket/Graphs/dhandler index ba41445d0..89b1f37e1 100644 --- a/rt/share/html/Ticket/Graphs/dhandler +++ b/rt/share/html/Ticket/Graphs/dhandler @@ -65,6 +65,7 @@ unless ( $ticket->id ) { require RT::Graph::Tickets; my $graph = RT::Graph::Tickets->TicketLinks( %ARGS, + Graph => undef, Ticket => $ticket, ); diff --git a/rt/share/html/Ticket/ModifyLinks.html b/rt/share/html/Ticket/ModifyLinks.html index 28942e060..9dceb2a7a 100755 --- a/rt/share/html/Ticket/ModifyLinks.html +++ b/rt/share/html/Ticket/ModifyLinks.html @@ -51,7 +51,7 @@ % $m->callback(CallbackName => 'BeforeActionList', Actions => \@results, ARGSRef => \%ARGS, Ticket => $Ticket); <& /Elements/ListActions, actions => \@results &> -<form action="ModifyLinks.html" method="post"> +<form action="ModifyLinks.html" name="ModifyLinks" method="post"> <input type="hidden" class="hidden" name="id" value="<%$Ticket->id%>" /> % $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS ); % my (@extra); diff --git a/rt/share/html/Widgets/ComboBox b/rt/share/html/Widgets/ComboBox index 238087f0a..69ac0793b 100644 --- a/rt/share/html/Widgets/ComboBox +++ b/rt/share/html/Widgets/ComboBox @@ -56,7 +56,7 @@ my $z_index = 9999; <div id="<% $Name %>_Container" class="combobox <%$Class%>" style="z-index: <%$z_index--%>"> <input name="<% $Name %>" id="<% $Name %>" class="combo-text" value="<% $Default || '' %>" type="text" <% $Size ? "size='$Size'" : '' |n %> autocomplete="off" /> -<br style="display: none" /><span id="<% $Name %>_Button" class="combo-button">▼</span><select name="List-<% $Name %>" id="<% $Name %>_List" class="combo-list" onchange="ComboBox_SimpleAttach(this, this.form['<% $Name %>']); " size="<% $Rows %>"> +<br style="display: none" /><span id="<% $Name %>_Button" class="combo-button">▼</span><select name="List-<% $Name %>" id="<% $Name %>_List" class="combo-list" onchange="ComboBox_SimpleAttach(this, this.form[<% $Name |n,j%>]); " size="<% $Rows %>"> <option style="display: none" value="">-</option> % foreach my $value (@Values) { <option value="<%$value%>"><% $value%></option> @@ -64,7 +64,7 @@ my $z_index = 9999; </select> </div> <script language="javascript"><!-- -ComboBox_InitWith('<% $Name %>'); +ComboBox_InitWith(<% $Name |n,j %>); //--></script> </nobr> <%ARGS> diff --git a/rt/share/html/Widgets/TitleBoxStart b/rt/share/html/Widgets/TitleBoxStart index a03147785..cbcc5c3d5 100755 --- a/rt/share/html/Widgets/TitleBoxStart +++ b/rt/share/html/Widgets/TitleBoxStart @@ -48,7 +48,7 @@ <div class="titlebox<% $class ? " $class " : '' %><% $rolledup ? " rolled-up" : ""%>" id="<% $id %>"> <div class="titlebox-title<% $title_class ? " $title_class" : ''%>"> % if ($hideable) { - <span class="widget"><a href="#" onclick="return rollup('<%$tid%>');" title="Toggle visibility"></a></span> + <span class="widget"><a href="#" onclick="return rollup(<%$tid|n,j%>);" title="Toggle visibility"></a></span> % } <span class="left"><% $title_href ? qq[<a href="$title_href">] : '' | n diff --git a/rt/share/html/index.html b/rt/share/html/index.html index c24b6cdf4..d6e0b79b5 100755 --- a/rt/share/html/index.html +++ b/rt/share/html/index.html @@ -126,7 +126,7 @@ if ( $ARGS{'QuickCreate'} ) { if ( $ARGS{'q'} ) { - RT::Interface::Web::Redirect(RT->Config->Get('WebURL')."Search/Simple.html?q=".$m->interp->apply_escapes($ARGS{q})); + RT::Interface::Web::Redirect(RT->Config->Get('WebURL')."Search/Simple.html?q=".$m->interp->apply_escapes($ARGS{q}, 'u')); } </%init> diff --git a/rt/share/html/l b/rt/share/html/l index 6396bc640..9f1b34365 100755 --- a/rt/share/html/l +++ b/rt/share/html/l @@ -47,6 +47,6 @@ %# END BPS TAGGED BLOCK }}} <%init> my $hand = ($session{'CurrentUser'} ||= RT::CurrentUser->new)->LanguageHandle; - $m->print($hand->maketext($m->content,@_)); + $m->print($hand->maketext($m->content,map { $m->interp->apply_escapes($_, 'h') } @_)); return(1); </%init> diff --git a/rt/share/html/m/_elements/footer b/rt/share/html/m/_elements/footer index f3e0837cc..e0c023c9a 100644 --- a/rt/share/html/m/_elements/footer +++ b/rt/share/html/m/_elements/footer @@ -1,11 +1 @@ <& /elements/footer.html &> -% if ( 0 ) { - <div id="bpscredits"> - <& /Elements/Logo, ShowName => 0 &> - <div id="copyright"> -<&|/l, '', '', '2010', '<a href="http://www.bestpractical.com?rt='.$RT::VERSION.'">Best Practical Solutions, LLC</a>', &>[_1] RT [_2] Copyright 1996-[_3] [_4].</&> -</div> -</div> -</body> -</html> -% } diff --git a/rt/share/html/m/ticket/create b/rt/share/html/m/ticket/create index 7c23194c4..052a1a55f 100644 --- a/rt/share/html/m/ticket/create +++ b/rt/share/html/m/ticket/create @@ -6,6 +6,7 @@ $CloneTicket => undef $m->callback( CallbackName => "Init", ARGSRef => \%ARGS ); my $Queue = $ARGS{Queue}; +my $escape = sub { $m->interp->apply_escapes(shift, 'h') }; my $showrows = sub { my @pairs = @_; @@ -45,41 +46,30 @@ if ($CloneTicket) { my $members = $CloneTicketObj->Members; my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by ); my $refers = $CloneTicketObj->RefersTo; + my $get_link_value = sub { + my ($link, $type) = @_; + my $uri_method = $type . 'URI'; + my $local_method = 'Local' . $type; + my $uri = $link->$uri_method; + return if $uri->IsLocal and + $uri->Object and + $uri->Object->isa('RT::Ticket') and + $uri->Object->Type eq 'reminder'; + + return $link->$local_method || $uri->URI; + }; while ( my $refer = $refers->Next ) { - push @refers, $refer->LocalTarget; + my $refer_value = $get_link_value->($refer, 'Target'); + push @refers, $refer_value if defined $refer_value; } $clone->{'new-RefersTo'} = join ' ', @refers; my $refers_by = $CloneTicketObj->ReferredToBy; while ( my $refer_by = $refers_by->Next ) { - push @refers_by, $refer_by->LocalBase; + my $refer_by_value = $get_link_value->($refer_by, 'Base'); + push @refers_by, $refer_by_value if defined $refer_by_value; } $clone->{'RefersTo-new'} = join ' ', @refers_by; - if (0) { # Temporarily disabled - my $depends = $CloneTicketObj->DependsOn; - while ( my $depend = $depends->Next ) { - push @depends, $depend->LocalTarget; - } - $clone->{'new-DependsOn'} = join ' ', @depends; - - my $depends_by = $CloneTicketObj->DependedOnBy; - while ( my $depend_by = $depends_by->Next ) { - push @depends_by, $depend_by->LocalBase; - } - $clone->{'DependsOn-new'} = join ' ', @depends_by; - - while ( my $member = $members->Next ) { - push @members, $member->LocalBase; - } - $clone->{'MemberOf-new'} = join ' ', @members; - - my $members_of = $CloneTicketObj->MemberOf; - while ( my $member_of = $members_of->Next ) { - push @members_of, $member_of->LocalTarget; - } - $clone->{'new-MemberOf'} = join ' ', @members_of; - - } my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields(); while ( my $cf = $cfs->Next ) { @@ -218,7 +208,7 @@ if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} e <%perl> $showrows->( - loc("Subject") => '<input name="Subject" size="30" maxsize="200" value="'.($ARGS{Subject} || '').'" />'); + loc("Subject") => '<input name="Subject" size="30" maxsize="200" value="'.$escape->($ARGS{Subject} || '').'" />'); </%perl> <span class="content-label label"><%loc("Describe the issue below")%></span> <& /Elements/MessageBox, exists $ARGS{Content} ? (Default => $ARGS{Content}, IncludeSignature => 0 ) : ( QuoteTransaction => $QuoteTransaction ), Height => 5 &> @@ -382,12 +372,12 @@ $showrows->( <%perl> $showrows->( - loc("Depends on") => '<input size="10" name="new-DependsOn" value="' . ($ARGS{'new-DependsOn'} || '' ). '" />', - loc("Depended on by") => '<input size="10" name="DependsOn-new" value="' . ($ARGS{'DependsOn-new'} || '' ) . '" />', - loc("Parents") => '<input size="10" name="new-MemberOf" value="' . ($ARGS{'new-MemberOf'} || '') . '" />', - loc("Children") => '<input size="10" name="MemberOf-new" value="' . ($ARGS{'MemberOf-new'} || '') . '" />', - loc("Refers to") => '<input size="10" name="new-RefersTo" value="' . ($ARGS{'new-RefersTo'} || '') . '" />', - loc("Referred to by") => '<input size="10" name="RefersTo-new" value="' . ($ARGS{'RefersTo-new'} || ''). '" />' + loc("Depends on") => '<input type="text" size="10" name="new-DependsOn" value="' . $escape->($ARGS{'new-DependsOn'} || '' ). '" />', + loc("Depended on by") => '<input type="text" size="10" name="DependsOn-new" value="' . $escape->($ARGS{'DependsOn-new'} || '' ) . '" />', + loc("Parents") => '<input type="text" size="10" name="new-MemberOf" value="' . $escape->($ARGS{'new-MemberOf'} || '') . '" />', + loc("Children") => '<input type="text" size="10" name="MemberOf-new" value="' . $escape->($ARGS{'MemberOf-new'} || '') . '" />', + loc("Refers to") => '<input type="text" size="10" name="new-RefersTo" value="' . $escape->($ARGS{'new-RefersTo'} || '') . '" />', + loc("Referred to by") => '<input type="text" size="10" name="RefersTo-new" value="' . $escape->($ARGS{'RefersTo-new'} || ''). '" />' ); </%perl> diff --git a/rt/share/html/m/ticket/show b/rt/share/html/m/ticket/show index e979da3e6..4190bd349 100644 --- a/rt/share/html/m/ticket/show +++ b/rt/share/html/m/ticket/show @@ -145,18 +145,18 @@ my $print_value = sub { } $m->out('</a>') if defined $linked && length $linked; - # This section automatically populates a<div with the "IncludeContentForValue" for this custom + # This section automatically populates a div with the "IncludeContentForValue" for this custom # field if it's been defined if ( $cf->IncludeContentForValue ) { my $vid = $value->id; $m->out( '<div class="object_cf_value_include" id="object_cf_value_'. $vid .'">' ); $m->print( loc("See also:") ); - $m->out( '<a href="'. $value->IncludeContentForValue .'">' ); - $m->print( $value->IncludeContentForValue ); + $m->out( '<a href="'. $m->interp->apply_escapes($value->IncludeContentForValue, 'h') .'">' ); + $m->out( $m->interp->apply_escapes($value->IncludeContentForValue, 'h') ); $m->out( qq{</a></div>\n} ); - $m->out( qq{<script><!--\nahah('} ); - $m->print( $value->IncludeContentForValue ); - $m->out( qq{', 'object_cf_value_$vid');\n--></script>\n} ); + $m->out( qq{<script><!--\njQuery('#object_cf_value_$vid').load(} ); + $m->out( $m->interp->apply_escapes($value->IncludeContentForValue, 'j') ); + $m->out( qq{);\n--></script>\n} ); } }; diff --git a/rt/share/html/m/tickets/search b/rt/share/html/m/tickets/search index 16864b4d3..e688ea821 100644 --- a/rt/share/html/m/tickets/search +++ b/rt/share/html/m/tickets/search @@ -31,7 +31,7 @@ my $search; if ( $custom->Description eq $name ) { $search = $custom; last } } unless ( $search && $search->id ) { - $m->out("Predefined search $name not found"); + $m->out(loc("Predefined search [_1] not found", $m->interp->apply_escapes($name, 'h'))); return; } } |