comments.html.tmpl 7.78 KB
[%# The contents of this file are subject to the Mozilla Public
  # License Version 1.1 (the "License"); you may not use this file
  # except in compliance with the License. You may obtain a copy of
  # the License at http://www.mozilla.org/MPL/
  #
  # Software distributed under the License is distributed on an "AS
  # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  # implied. See the License for the specific language governing
  # rights and limitations under the License.
  #
  # The Original Code is the Bugzilla Bug Tracking System.
  #
  # The Initial Developer of the Original Code is Netscape Communications
  # Corporation. Portions created by Netscape are
  # Copyright (C) 1998 Netscape Communications Corporation. All
  # Rights Reserved.
  #
  # Contributor(s): Gervase Markham <gerv@gerv.net>
  #                 Max Kanat-Alexander <mkanat@bugzilla.org>
  #                 Shane H. W. Travis <travis@sedsystems.ca>
  #%]

[% PROCESS bug/time.html.tmpl %]

  <script type="text/javascript">
  <!--
  function updateCommentPrivacy(checkbox, id) {
    var comment_elem = document.getElementById('comment_text_'+id).parentNode;
    if (checkbox.checked) {
      if (!comment_elem.className.match('bz_private')) {
        comment_elem.className = comment_elem.className.concat(' bz_private');
      }
    }
    else {
      comment_elem.className =
        comment_elem.className.replace(/(\s*|^)bz_private(\s*|$)/, '$2');
    }
  }

  /* The functions below expand and collapse comments  */

  function toggle_comment_display(link, comment_id) {
    var comment = document.getElementById('comment_text_' + comment_id);
    var re = new RegExp(/\bcollapsed\b/);
    if (comment.className.match(re))
        expand_comment(link, comment);
    else
        collapse_comment(link, comment);
  }

  function toggle_all_comments(action) {
    var num_comments = [% comments.size FILTER html %];

    // If for some given ID the comment doesn't exist, this doesn't mean
    // there are no more comments, but that the comment is private and
    // the user is not allowed to view it.

    for (var id = 0; id < num_comments; id++) {
        var comment = document.getElementById('comment_text_' + id);
        if (!comment)
            continue;

        var link = document.getElementById('comment_link_' + id);
        if (action == 'collapse')
            collapse_comment(link, comment);
        else
            expand_comment(link, comment);
    }
  }

  function collapse_comment(link, comment) {
    link.innerHTML = "(+)";
    link.title = "Expand the comment.";
    comment.className = "collapsed";
  }

  function expand_comment(link, comment) {
    link.innerHTML = "(-)";
    link.title = "Collapse the comment";
    comment.className = "";
  }

  /* This way, we are sure that browsers which do not support JS
   * won't display this link  */

  function addCollapseLink(count) {
    document.write(' <a href="#" id="comment_link_' + count +
                   '" onclick="toggle_comment_display(this, ' +  count +
                   '); return false;" title="Collapse the comment.">(-)</a> ');
  }
  //-->
  </script>


[% DEFAULT start_at = 0 mode = "show" %]
[% isinsider = Param("insidergroup") && user.in_group(Param("insidergroup")) %]
[% sort_order = user.settings.comment_sort_order.value %]

[%# NOTE: (start_at > 0) means we came here from a midair collision,
  #       in which case we don't care what the user's preference is.
 %]
[% IF (start_at > 0) %]
    [% sort_order = "oldest_to_newest" %]
[% END %]


[%# Set up the variables as needed, depending on the sort order %]
[% IF sort_order == "oldest_to_newest" %]
    [% count = 0 %]
    [% description = 0 %]
    [% increment = 1 %]
[% ELSE %]
    [% increment = -1 %]
    [% IF sort_order == "newest_to_oldest" %]
        [% count = comments.size - 1 %]
        [% description = 0 %]
    [% ELSIF sort_order == "newest_to_oldest_desc_first" %]
        [% count = comments.size %]
        [% description = comments.size %]
    [% END %]
[% END %]

[% IF mode == "edit" %]
  <a href="#" onclick="toggle_all_comments('collapse'); return false;">Collapse All Comments</a> -
  <a href="#" onclick="toggle_all_comments('expand'); return false;">Expand All Comments</a>
  <hr>
[% END %]

[% FOREACH comment = comments %]
  [% IF count >= start_at %]
    [% PROCESS a_comment %]
  [% END %]
  
  [% count = count + increment %]
[% END %]

[%# Note: this template is used in multiple places; if you use this hook,
  # make sure you are aware of this fact.
  #%]  
[% Hook.process("aftercomments") %]

[%############################################################################%]
[%# Block for individual comments                                            #%]
[%############################################################################%]

[% BLOCK a_comment %]
  [% IF NOT comment.isprivate || isinsider %]
    <div class="bz_comment[% " bz_private" IF comment.isprivate %]
                [% " bz_comment_hilite" IF marks.$count %]
                [% " bz_first_comment" IF count == description %]">
      [% IF count == description %]
        [% class_name = "bz_first_comment_head" %]
        [% comment_label = "" %]
        [% comment_link = "Description" %]
        [% decoration = "" %]
      [% ELSE %]
        [% class_name = "bz_comment_head" %]
        [% comment_label = "Comment" %]
        [% comment_link = "#" _ count %]
        [% decoration = '<span class="comment_rule">-------</span>' %]
      [% END %]

      <span class="[% class_name FILTER html %]">
        [%# Do not filter decoration as it's a real HTML tag. No XSS risk. %]
        [% decoration FILTER none %]
        <i>[% comment_label FILTER html %]
        <a name="c[% count %]" href="show_bug.cgi?id=[% bug.bug_id %]#c[% count %]">
          [% comment_link FILTER html %]</a> From
        <span class="vcard">
          <a class="fn email" href="mailto:[% comment.author.email FILTER html %]">
            [% (comment.author.name || comment.author.login) FILTER html %]
          </a>
        </span>
        [% FOREACH group = comment.author.direct_group_membership %]
          [% NEXT UNLESS group.icon_url %]
          <img src="[% group.icon_url FILTER html %]"
               alt="[% group.name FILTER html %]"
               title="[% group.name FILTER html %] - [% group.description FILTER html %]">
        [% END %]

        [%+ comment.time FILTER time %]</i>

        [% IF mode == "edit" %]
          <script type="text/javascript"><!--
            addCollapseLink([% count %]);
            addReplyLink([% count %], [% comment.id %]); //-->
          </script>
        [% END %]
        [%+ decoration FILTER none %]
      </span>

      [% IF mode == "edit" && isinsider %]
        <i>
          <input type="hidden" value="1"
                 name="defined_isprivate_[% comment.id %]">
          <input type="checkbox"
                 name="isprivate_[% comment.id %]" value="1"
                 id="isprivate_[% comment.id %]"
                 onClick="updateCommentPrivacy(this, [% count %])"
                 [% " checked=\"checked\"" IF comment.isprivate %]>
          <label for="isprivate_[% comment.id %]">Private</label>
        </i>
      [% END %]
      [% IF user.in_group(Param('timetrackinggroup')) &&
            (comment.work_time > 0 || comment.work_time < 0) %]
         <br>
         Additional hours worked: 
         [% PROCESS formattimeunit time_unit=comment.work_time %]
      [% END %]

[%# Don't indent the <pre> block, since then the spaces are displayed in the
  # generated HTML
  #%]
[% IF comment.already_wrapped %]
    [% wrapped_comment = comment.body %]
[% ELSE %]
    [% wrapped_comment = comment.body FILTER wrap_comment %]
[% END %]
<pre class="bz_comment_text" 
     [% ' id="comment_text_' _ count _ '"' IF mode == "edit" %]>
  [%- wrapped_comment FILTER quoteUrls(bug.bug_id) -%]
</pre>
    </div>
  [% END %]
[% END %]