diff options
31 files changed, 99 insertions, 429 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 9c820eedc..ee48ed7a2 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -732,7 +732,7 @@ sub _preload_referenced_bugs { } else { # bugs referenced in comments - Bugzilla::Template::renderComment($comment->body, undef, undef, 1, + Bugzilla::Template::quoteUrls($comment->body, undef, undef, undef, sub { my $bug_id = $_[0]; push @referenced_bug_ids, $bug_id @@ -999,7 +999,6 @@ sub create { # We now have a bug id so we can fill this out $creation_comment->{'bug_id'} = $bug->id; - $creation_comment->{'is_markdown'} = 1; # Insert the comment. We always insert a comment on bug creation, # but sometimes it's blank. @@ -2663,8 +2662,7 @@ sub set_all { # there are lots of things that want to check if we added a comment. $self->add_comment($params->{'comment'}->{'body'}, { isprivate => $params->{'comment'}->{'is_private'}, - work_time => $params->{'work_time'}, - is_markdown => 1 }); + work_time => $params->{'work_time'} }); } if (defined $params->{comment_tags} && Bugzilla->user->can_tag_comments()) { @@ -3145,7 +3143,7 @@ sub remove_cc { @$cc_users = grep { $_->id != $user->id } @$cc_users; } -# $bug->add_comment("comment", {isprivate => 1, work_time => 10.5, is_markdown => 1, +# $bug->add_comment("comment", {isprivate => 1, work_time => 10.5, # type => CMT_NORMAL, extra_data => $data}); sub add_comment { my ($self, $comment, $params) = @_; diff --git a/Bugzilla/Comment.pm b/Bugzilla/Comment.pm index 937cd1203..f9a6f7d3a 100644 --- a/Bugzilla/Comment.pm +++ b/Bugzilla/Comment.pm @@ -45,7 +45,6 @@ use constant DB_COLUMNS => qw( already_wrapped type extra_data - is_markdown ); use constant UPDATE_COLUMNS => qw( @@ -68,7 +67,6 @@ use constant VALIDATORS => { work_time => \&_check_work_time, thetext => \&_check_thetext, isprivate => \&_check_isprivate, - is_markdown => \&Bugzilla::Object::check_boolean, extra_data => \&_check_extra_data, type => \&_check_type, }; @@ -235,7 +233,6 @@ sub body { return $_[0]->{'thetext'}; } sub bug_id { return $_[0]->{'bug_id'}; } sub creation_ts { return $_[0]->{'bug_when'}; } sub is_private { return $_[0]->{'isprivate'}; } -sub is_markdown { return $_[0]->{'is_markdown'}; } sub work_time { # Work time is returned as a string (see bug 607909) return 0 if $_[0]->{'work_time'} + 0 == 0; @@ -579,10 +576,6 @@ C<string> Time spent as related to this comment. C<boolean> Comment is marked as private. -=item C<is_markdown> - -C<boolean> Whether this comment needs Markdown rendering to be applied. - =item C<already_wrapped> If this comment is stored in the database word-wrapped, this will be C<1>. diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index d27468f55..bed6a53b0 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -438,6 +438,12 @@ Sometimes this is C<undef>, meaning that we are parsing text that is not a bug comment (but could still be some other part of a bug, like the summary line). +=item C<user> + +The L<Bugzilla::User> object representing the user who will see the text. +This is useful to determine how much confidential information can be displayed +to the user. + =back =head2 bug_start_of_update diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index f74565302..299734d64 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -130,20 +130,17 @@ sub get_format { }; } -# This routine renderComment contains inspirations from the HTML::FromText CPAN +# This routine quoteUrls contains inspirations from the HTML::FromText CPAN # module by Gareth Rees <garethr@cre.canon.co.uk>. It has been heavily hacked, # all that is really recognizable from the original is bits of the regular # expressions. # This has been rewritten to be faster, mainly by substituting 'as we go'. # If you want to modify this routine, read the comments carefully -# Renamed from 'quoteUrls' to 'renderComment' after markdown support was added. -sub renderComment { - my ($text, $bug, $comment, $skip_markdown, $bug_link_func) = @_; +sub quoteUrls { + my ($text, $bug, $comment, $user, $bug_link_func) = @_; return $text unless $text; - my $anon_user = Bugzilla::User->new; - # We choose to render markdown by default, unless the comment explicitly isn't. - $skip_markdown ||= $comment && !$comment->is_markdown; + $user ||= Bugzilla->user; $bug_link_func ||= \&get_bug_link; # We use /g for speed, but uris can have other things inside them @@ -176,7 +173,7 @@ sub renderComment { my @hook_regexes; Bugzilla::Hook::process('bug_format_comment', { text => \$text, bug => $bug, regexes => \@hook_regexes, - comment => $comment, user => undef }); + comment => $comment, user => $user }); foreach my $re (@hook_regexes) { my ($match, $replace) = @$re{qw(match replace)}; @@ -196,47 +193,37 @@ sub renderComment { # Provide tooltips for full bug links (Bug 74355) my $urlbase_re = '(' . quotemeta(Bugzilla->localconfig->{urlbase}) . ')'; $text =~ s~\b(${urlbase_re}\Qshow_bug.cgi?id=\E([0-9]+)(\#c([0-9]+))?)\b - ~($things[$count++] = $bug_link_func->($3, $1, { comment_num => $5, user => $anon_user })) && + ~($things[$count++] = $bug_link_func->($3, $1, { comment_num => $5, user => $user })) && ("\x{FDD2}" . ($count-1) . "\x{FDD3}") ~egox; - - if ($skip_markdown) { - # non-mailto protocols - my $safe_protocols = SAFE_URL_REGEXP(); - $text =~ s~\b($safe_protocols) + # non-mailto protocols + my $safe_protocols = SAFE_URL_REGEXP(); + $text =~ s~\b($safe_protocols) ~($tmp = html_quote($1)) && ($things[$count++] = "<a rel=\"nofollow\" href=\"$tmp\">$tmp</a>") && ("\x{FDD2}" . ($count-1) . "\x{FDD3}") ~egox; - # We have to quote now, otherwise the html itself is escaped - # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH - $text = html_quote($text); + # We have to quote now, otherwise the html itself is escaped + # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH - # Color quoted text - $text =~ s~^(>.+)$~<span class="quote">$1</span >~mg; - $text =~ s~</span >\n<span class="quote">~\n~g; + $text = html_quote($text); - # mailto: - # Use |<nothing> so that $1 is defined regardless - # @ is the encoded '@' character. - $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+&\#64;[\w\-]+(?:\.[\w\-]+)+)\b - ~<a href=\"mailto:$2\">$1$2</a>~igx; - } - else { - # We intentionally disable all html tags. Users should use markdown syntax. - # This prevents things like inline styles on anchor tags, which otherwise would be valid. - $text =~ s/([<])/</g; + # Color quoted text + $text =~ s~^(>.+)$~<span class="quote">$1</span >~mg; + $text =~ s~</span >\n<span class="quote">~\n~g; - # As a preference, we opt into all new line breaks being rendered as a new line. - $text =~ s/(\r?\n)/ $1/g; - } + # mailto: + # Use |<nothing> so that $1 is defined regardless + # @ is the encoded '@' character. + $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+&\#64;[\w\-]+(?:\.[\w\-]+)+)\b + ~<a href=\"mailto:$2\">$1$2</a>~igx; # attachment links # BMO: don't make diff view the default for patches (Bug 652332) $text =~ s~\b(attachment$s*\#?$s*(\d+)(?:$s+\[diff\])?(?:\s+\[details\])?) - ~($things[$count++] = get_attachment_link($2, $1, $anon_user)) && + ~($things[$count++] = get_attachment_link($2, $1, $user)) && ("\x{FDD2}" . ($count-1) . "\x{FDD3}") ~egmxi; @@ -253,7 +240,7 @@ sub renderComment { $text =~ s~\b($bug_re(?:$s*,?$s*$comment_re)?|$comment_re) ~ # We have several choices. $1 here is the link, and $2-4 are set # depending on which part matched - (defined($2) ? $bug_link_func->($2, $1, { comment_num => $3, user => $anon_user }) : + (defined($2) ? $bug_link_func->($2, $1, { comment_num => $3, user => $user }) : "<a href=\"$current_bugurl#c$4\">$1</a>") ~egx; @@ -262,7 +249,7 @@ sub renderComment { $text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ ) (\d+) (?=\ \*\*\*\Z) - ~$bug_link_func->($1, $1, { user => $anon_user }) + ~$bug_link_func->($1, $1, { user => $user }) ~egmx; # Now remove the encoding hacks in reverse order @@ -270,12 +257,7 @@ sub renderComment { $text =~ s/\x{FDD2}($i)\x{FDD3}/$things[$i]/eg; } - if ($skip_markdown) { - return $text; - } - else { - return Bugzilla->markdown_parser->render_html($text); - } + return $text; } # Creates a link to an attachment, including its title. @@ -289,17 +271,11 @@ sub get_attachment_link { if ($attachment) { my $title = ""; my $className = ""; - my $linkClass = ""; - if ($user->can_see_bug($attachment->bug_id) && (!$attachment->isprivate || $user->is_insider)) { $title = $attachment->description; } - else{ - $linkClass = "bz_private_link"; - } - if ($attachment->isobsolete) { $className = "bz_obsolete"; } @@ -320,7 +296,7 @@ sub get_attachment_link { # Whitespace matters here because these links are in <pre> tags. return qq|<span class="$className">| - . qq|<a href="${linkval}" class="$linkClass" name="attach_${attachid}" title="$title">$link_text</a>| + . qq|<a href="${linkval}" name="attach_${attachid}" title="$title">$link_text</a>| . qq| <a href="${linkval}&action=edit" title="$title">[details]</a>| . qq|${patchlink}| . qq|</span>|; @@ -730,11 +706,11 @@ sub create { # Removes control characters and trims extra whitespace. clean_text => \&Bugzilla::Util::clean_text , - renderComment => [ sub { - my ($context, $bug, $comment, $skip_markdown) = @_; + quoteUrls => [ sub { + my ($context, $bug, $comment, $user) = @_; return sub { my $text = shift; - return renderComment($text, $bug, $comment, $skip_markdown); + return quoteUrls($text, $bug, $comment, $user); }; }, 1 diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index d14300f6f..feb541c2e 100644 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -362,7 +362,7 @@ sub render_comment { Bugzilla->switch_to_shadow_db(); my $bug = $params->{id} ? Bugzilla::Bug->check($params->{id}) : undef; - my $html = Bugzilla::Template::renderComment($params->{text}, $bug); + my $html = Bugzilla::Template::quoteUrls($params->{text}, $bug); return { html => $html }; } @@ -381,7 +381,6 @@ sub _translate_comment { time => $self->type('dateTime', $comment->creation_ts), creation_time => $self->type('dateTime', $comment->creation_ts), is_private => $self->type('boolean', $comment->is_private), - is_markdown => $self->type('boolean', $comment->is_markdown), text => $self->type('string', $comment->body_full), attachment_id => $self->type('int', $attach_id), count => $self->type('int', $comment->count), @@ -1113,11 +1112,9 @@ sub add_comment { if (defined $params->{private}) { $params->{is_private} = delete $params->{private}; } - # Append comment $bug->add_comment($comment, { isprivate => $params->{is_private}, - work_time => $params->{work_time}, - is_markdown => 1 }); + work_time => $params->{work_time} }); # Add comment tags $bug->set_all({ comment_tags => $params->{comment_tags} }) diff --git a/attachment.cgi b/attachment.cgi index 4aeba58c5..875de6a50 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -600,7 +600,6 @@ sub insert { my $comment = $cgi->param('comment'); $comment = '' unless defined $comment; $bug->add_comment($comment, { isprivate => $attachment->isprivate, - is_markdown => 1, type => CMT_ATTACHMENT_CREATED, extra_data => $attachment->id }); @@ -746,7 +745,6 @@ sub update { my $comment = $cgi->param('comment'); if (defined $comment && trim($comment) ne '') { $bug->add_comment($comment, { isprivate => $attachment->isprivate, - is_markdown => 1, type => CMT_ATTACHMENT_UPDATED, extra_data => $attachment->id }); } diff --git a/docs/en/rst/api/core/v1/comment.rst b/docs/en/rst/api/core/v1/comment.rst index 69508a364..2e6ca1e29 100644 --- a/docs/en/rst/api/core/v1/comment.rst +++ b/docs/en/rst/api/core/v1/comment.rst @@ -98,11 +98,10 @@ creation_time datetime This is exactly same as the ``time`` key. Use this For compatibility, ``time`` is still usable. However, please note that ``time`` may be deprecated and removed in a future release. + is_private boolean ``true`` if this comment is private (only visible to a certain group called the "insidergroup"), ``false`` otherwise. -is_markdown boolean ``true`` if this comment is markdown. ``false`` if this - comment is plaintext. ============= ======== ======================================================== **Errors** @@ -124,8 +123,7 @@ it can also throw the following errors: Create Comments --------------- -This allows you to add a comment to a bug in Bugzilla. All comments created via the -API will be considered Markdown (specifically GitHub Flavored Markdown). +This allows you to add a comment to a bug in Bugzilla. **Request** diff --git a/extensions/BMO/template/en/default/email/bugmail.html.tmpl b/extensions/BMO/template/en/default/email/bugmail.html.tmpl index 5ca2c2a1b..0b08e4a86 100644 --- a/extensions/BMO/template/en/default/email/bugmail.html.tmpl +++ b/extensions/BMO/template/en/default/email/bugmail.html.tmpl @@ -50,12 +50,7 @@ at [% comment.creation_ts FILTER time(undef, to_user.timezone) %] </b> [% END %] - [% IF comment.is_markdown %] - [% comment_tag = 'div' %] - [% ELSE %] - [% comment_tag = 'pre' %] - [% END %] - <[% comment_tag FILTER none %] class="comment" style="font-size: initial">[% comment.body_full({ wrap => 1 }) FILTER renderComment(bug, comment) %]</[% comment_tag FILTER none %]> + <pre class="comment" style="font-size: initial">[% comment.body_full({ wrap => 1 }) FILTER quoteUrls(bug, comment) %]</pre> </div> [% END %] </div> diff --git a/extensions/BugModal/template/en/default/bug_modal/activity_stream.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/activity_stream.html.tmpl index 340bb6f81..08c6b5b64 100644 --- a/extensions/BugModal/template/en/default/bug_modal/activity_stream.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/activity_stream.html.tmpl @@ -244,17 +244,8 @@ [% END %] [% BLOCK comment_body %] - [% IF comment.is_markdown %] - [% comment_tag = 'div' %] - [% ELSE %] - [% comment_tag = 'pre' %] - [% END %] - - <[% comment_tag FILTER none %] class="comment-text [%= "bz_private" IF comment.is_private %]" - id="ct-[% comment.count FILTER none %]" - data-uniqueid="[% comment.id FILTER none %]" - [% IF comment.is_markdown +%] data-ismarkdown="true" [% END ~%] - [% IF comment.collapsed +%] style="display:none"[% END ~%] + <pre class="comment-text [%= "bz_private" IF comment.is_private %]" id="ct-[% comment.count FILTER none %]" + [% IF comment.collapsed +%] style="display:none"[% END ~%] >[% FILTER collapse %] [% IF comment.is_about_attachment && comment.attachment.is_image ~%] <a href="attachment.cgi?id=[% comment.attachment.id FILTER none %]" @@ -262,7 +253,7 @@ class="lightbox"><img src="extensions/BugModal/web/image.png" width="16" height="16"></a> [% END %] [% END %] - [%~ comment.body_full FILTER renderComment(bug, comment) ~%]</[% comment_tag FILTER none %]> + [%~ comment.body_full FILTER quoteUrls(bug, comment) ~%]</pre> [% END %] [% diff --git a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl index e2e8bc124..e926c04b4 100644 --- a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl @@ -202,7 +202,7 @@ no_label = 1 hide_on_edit = 1 %] - <h1 id="field-value-short_desc">[% bug.short_desc FILTER renderComment(bug, undef, 1) FILTER wbr %]</h1> + <h1 id="field-value-short_desc">[% bug.short_desc FILTER quoteUrls(bug) FILTER wbr %]</h1> [% END %] [%# alias %] @@ -1191,7 +1191,7 @@ [% END %] </div> [% END %] - <div id="user-story" class="comment-text">[% bug.cf_user_story FILTER renderComment(bug, undef) %]</div> + <pre id="user-story">[% bug.cf_user_story FILTER quoteUrls(bug) %]</pre> [% IF user.id %] <textarea id="cf_user_story" name="cf_user_story" style="display:none" rows="10" cols="80"> [%~ bug.cf_user_story FILTER html ~%] diff --git a/extensions/BugModal/template/en/default/bug_modal/new_comment.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/new_comment.html.tmpl index 63c8cf197..63663b4d5 100644 --- a/extensions/BugModal/template/en/default/bug_modal/new_comment.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/new_comment.html.tmpl @@ -45,19 +45,12 @@ <textarea rows="5" cols="80" name="comment" id="comment" aria-labelledby="comment-edit-tab"></textarea> </div> <div id="comment-preview-tabpanel" class="comment-tabpanel" role="tabpanel" aria-labelledby="comment-preview-tab" style="display:none"> - <div id="comment-preview" class="comment-text"></div> + <pre id="comment-preview" class="comment-text"></pre> </div> - <div id="add-comment-tips"> - <div id="comment-markdown-tip"> - <img src="extensions/BMO/web/images/notice.png" width="16" height="16"> - <a href="https://guides.github.com/features/mastering-markdown/" target="_blank">Markdown styling now supported</a> - </div> - - <div id="bugzilla-etiquette"> - <a href="page.cgi?id=etiquette.html" target="_blank" tabindex="-1"> - Comments Subject to Etiquette and Contributor Guidelines</a> - </div> + <div id="bugzilla-etiquette"> + <a href="page.cgi?id=etiquette.html" target="_blank" tabindex="-1"> + Comments Subject to Etiquette and Contributor Guidelines</a> </div> <div id="after-comment-commit-button"> diff --git a/extensions/BugModal/web/bug_modal.css b/extensions/BugModal/web/bug_modal.css index bf291d3b6..ee50c6b77 100644 --- a/extensions/BugModal/web/bug_modal.css +++ b/extensions/BugModal/web/bug_modal.css @@ -296,6 +296,7 @@ input[type="number"] { #user-story { margin: 0; + white-space: pre-wrap; min-height: 2em; } @@ -629,8 +630,7 @@ body.platform-Win32 .comment-text, body.platform-Win64 .comment-text { font-family: "Fira Mono", monospace; } -.comment-text span.quote, .comment-text span.quote_wrapped, -div.comment-text pre { +.comment-text span.quote, .comment-text span.quote_wrapped { background: #eee !important; color: #444 !important; display: block !important; @@ -644,40 +644,6 @@ div.comment-text pre { border: 1px dashed darkred; } -/* Markdown comments */ -div.comment-text { - white-space: normal; - padding: 0 8px 0 8px; - font-family: inherit !important; -} - -div.comment-text code { - color: #444; - background-color: #eee; - font-size: 13px; - font-family: "Fira Mono","Droid Sans Mono",Menlo,Monaco,"Courier New",monospace; -} - -div.comment-text table { - border-collapse: collapse; -} - -div.comment-text th, div.comment-text td { - padding: 5px 10px; - border: 1px solid #ccc; -} - -div.comment-text hr { - display: block !important; -} - -div.comment-text blockquote { - background: #fcfcfc; - border-left: 5px solid #ccc; - margin: 1.5em 10px; - padding: 0.5em 10px; -} - .comment-tags { padding: 0 8px 2px 8px !important; } @@ -751,16 +717,11 @@ div.comment-text blockquote { margin-top: 20px; } -#add-comment-private { +#add-comment-private, +#bugzilla-etiquette { float: right; } -#add-comment-tips { - display: flex; - justify-content: space-between; - margin-bottom: 1em; -} - #comment { border: 1px solid #ccc; } @@ -769,7 +730,7 @@ div.comment-text blockquote { clear: both; width: 100%; box-sizing: border-box !important; - margin: 0 0 0.5em; + margin: 0 0 1em; max-width: 1024px; } diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js index 19b5bfa2f..a4ae83d72 100644 --- a/extensions/BugModal/web/bug_modal.js +++ b/extensions/BugModal/web/bug_modal.js @@ -858,54 +858,31 @@ $(function() { var prefix = "(In reply to " + comment_author + " from comment #" + comment_id + ")\n"; var reply_text = ""; - - var quoteMarkdown = function($comment) { - const uid = $comment.data('uniqueid'); - bugzilla_ajax( - { - url: `rest/bug/comment/${uid}`, - }, - (data) => { - const quoted = data['comments'][uid]['text'].replace(/\n/g, "\n > "); - reply_text = `${prefix}\n > ${quoted}`; - populateNewComment(); - } - ); + if (BUGZILLA.user.settings.quote_replies == 'quoted_reply') { + var text = $('#ct-' + comment_id).text(); + reply_text = prefix + wrapReplyText(text); + } else if (BUGZILLA.user.settings.quote_replies == 'simply_reply') { + reply_text = prefix; } - var populateNewComment = function() { - // quoting a private comment, check the 'private' cb - $('#add-comment-private-cb').prop('checked', - $('#add-comment-private-cb:checked').length || $('#is-private-' + comment_id + ':checked').length); + // quoting a private comment, check the 'private' cb + $('#add-comment-private-cb').prop('checked', + $('#add-comment-private-cb:checked').length || $('#is-private-' + comment_id + ':checked').length); - // remove embedded links to attachment details - reply_text = reply_text.replace(/(attachment\s+\d+)(\s+\[[^\[\n]+\])+/gi, '$1'); + // remove embedded links to attachment details + reply_text = reply_text.replace(/(attachment\s+\d+)(\s+\[[^\[\n]+\])+/gi, '$1'); - $.scrollTo($('#comment'), function() { - if ($('#comment').val() != reply_text) { - $('#comment').val($('#comment').val() + reply_text); - } - - if (BUGZILLA.user.settings.autosize_comments) { - autosize.update($('#comment')); - } - - $('#comment').trigger('input').focus(); - }); - } + $.scrollTo($('#comment'), function() { + if ($('#comment').val() != reply_text) { + $('#comment').val($('#comment').val() + reply_text); + } - if (BUGZILLA.user.settings.quote_replies == 'quoted_reply') { - var $comment = $('#ct-' + comment_id); - if ($comment.attr('data-ismarkdown')) { - quoteMarkdown($comment); - } else { - reply_text = prefix + wrapReplyText($comment.text()); - populateNewComment(); + if (BUGZILLA.user.settings.autosize_comments) { + autosize.update($('#comment')); } - } else if (BUGZILLA.user.settings.quote_replies == 'simply_reply') { - reply_text = prefix; - populateNewComment(); - } + + $('#comment').focus(); + }); }); if (BUGZILLA.user.settings.autosize_comments) { @@ -1343,163 +1320,12 @@ $(function() { saveBugComment(event.target.value); }); - function smartLinkPreviews() { - const filterUnique = (value, index, array) => value && array.indexOf(value) === index; - const reduceListToMap = (all, one) => { all[one['id']] = one; return all; }; - - const getResourceId = anchor => { - if (['/bug/', '/attachment/'].some((path) => anchor.pathname.startsWith(path))) { - return anchor.pathname.split('/')[2]; - } else { - return (new URL(anchor.href)).searchParams.get("id"); - } - }; - - const findLinkElements = pathnames => { - return ( - Array - .from(document.querySelectorAll('.comment-text a')) - .filter(anchor => { - return ( - `${anchor.origin}/` === BUGZILLA.constant.URL_BASE && - pathnames.some((p) => anchor.pathname.startsWith(p)) && - /^\d+$/.test(getResourceId(anchor)) - ) - }) - .filter(anchor => - // Get only links created by markdown or private links. - !anchor.hasAttribute('title') || anchor.classList.contains('bz_private_link') - ) - .map(anchor => { - return { - id: getResourceId(anchor), - element: anchor - } - }) - ) - }; - - const enhanceBugLinks = () => { - let bugLinks = findLinkElements(['/show_bug.cgi', '/bug/']); - let bugIds = bugLinks.map((bug) => parseInt(bug['id'])).filter(filterUnique).join(','); - let params = $.param({ - Bugzilla_api_token: BUGZILLA.api_token, - id: bugIds, - include_fields: 'id,summary,status,resolution,is_open' - }); - - if(!bugIds) return; - - fetch(`/rest/bug?${params}`) - .then(response => { - if(response.ok){ - return response.json(); - } - throw new Error(`/rest/bug?ids=${bugIds} response not ok`); - }) - .then(responseJson => { - return responseJson.bugs.reduce(reduceListToMap, {}); - }) - .then(bugs => { - bugLinks.forEach(bugLink => { - let bug = bugs[bugLink['id']]; - if(!bug) return; - - bugLink.element.setAttribute( - "title", `${bug.status} ${bug.resolution} - ${bug.summary}` - ); - bugLink.element.classList.add('bz_bug_link'); - bugLink.element.classList.add(`bz_status_${bug.status}`); - if(!bug.is_open) { - bugLink.element.classList.add('bz_closed'); - } - $(bugLink.element).tooltip({ - position: { my: "left top+8", at: "left bottom", collision: "flipfit" }, - show: { effect: 'none' }, - hide: { effect: 'none' } - }); - }); - }) - .catch(e => console.log(e)); - }; - - const enhanceAttachmentLinks = () => { - let attachmentLinks = findLinkElements(['/attachment.cgi']); - let attachmentIds = ( - attachmentLinks.map(attachment => parseInt(attachment['id'])).filter(filterUnique) - ); - let params = $.param({ - Bugzilla_api_token: BUGZILLA.api_token, - include_fields: 'id,description,is_obsolete' - }); - - if(!attachmentIds) return; - - // Fetch all attachments for this bug only. This endpoint filters out - // attachments the user can't see for us (e.g. ones marked private). - // This one request will likely retrieve most of the attachments we need. - fetch(`/rest/bug/${BUGZILLA.bug_id}/attachment?${params}`) - .then(response => { - if(response.ok){ - return response.json(); - } - throw Error(`/rest/bug/${BUGZILLA.bug_id}/attachment response not ok`); - }) - .then(responseJson => { - return responseJson['bugs'][BUGZILLA.bug_id] || []; - }) - .then(attachments => { - // The BMO rest API that lets us batch request attachment ids unfortunatley - // fails the whole batch if the user is unable to view any of the attachments. - // So, we query each attachment id individually and group them as a promsie. - let missingAttachments = ( - attachmentIds - .filter(id => !attachments.map(attachment => attachment.id).includes(id)) - .map(attachmentId => { - return ( - fetch(`/rest/bug/attachment/${attachmentId}?${params}`) - .then((response) => { - // It's ok if the request failed. - return response.json(); - }) - .then(responseJson => { - // May be undefined. - return responseJson['attachments'][attachmentId]; - }) - ); - }) - ); - return Promise.all(attachments.concat(missingAttachments)); - }) - .then(attachments => { - // Remove undefined attachments and convert from list to dictonary mapped by id. - return attachments.filter(filterUnique).reduce(reduceListToMap, {}); - }) - .then(attachments => { - // Now we have all attachment data the user is able to see. - attachmentLinks.forEach(attachmentLink => { - let attachment = attachments[attachmentLink.id]; - if(!attachment) return; - - attachmentLink.element.setAttribute("title", attachment.description); - if(attachment.is_obsolete){ - attachmentLink.element.classList.add('bz_obsolete'); - } - }); - }) - .catch(e => console.log(e)); - }; - enhanceBugLinks(); - enhanceAttachmentLinks(); - } - // finally switch to edit mode if we navigate back to a page that was editing $(window).on('pageshow', restoreEditMode); $(window).on('pageshow', restoreSavedBugComment); $(window).on('focus', restoreSavedBugComment); restoreEditMode(); restoreSavedBugComment(); - smartLinkPreviews(); }); function confirmUnsafeURL(url) { diff --git a/extensions/EditComments/template/en/default/pages/editcomments.html.tmpl b/extensions/EditComments/template/en/default/pages/editcomments.html.tmpl index b38a6dc0b..13364f5b1 100644 --- a/extensions/EditComments/template/en/default/pages/editcomments.html.tmpl +++ b/extensions/EditComments/template/en/default/pages/editcomments.html.tmpl @@ -34,7 +34,7 @@ </div> </div> <pre class="bz_comment_text"> - [%- a.original ? a.body : a.new FILTER renderComment(bug) -%] + [%- a.original ? a.body : a.new FILTER quoteUrls(bug) -%] </pre> [% END %] diff --git a/extensions/ShadowBugs/template/en/default/hook/bug/comments-aftercomments.html.tmpl b/extensions/ShadowBugs/template/en/default/hook/bug/comments-aftercomments.html.tmpl index 6270bd76c..3b04475fb 100644 --- a/extensions/ShadowBugs/template/en/default/hook/bug/comments-aftercomments.html.tmpl +++ b/extensions/ShadowBugs/template/en/default/hook/bug/comments-aftercomments.html.tmpl @@ -64,7 +64,7 @@ </div> <pre class="bz_comment_text"> - [%- comment_text FILTER renderComment(public_bug, comment) -%] + [%- comment_text FILTER quoteUrls(public_bug, comment) -%] </pre> </div> [% END %] diff --git a/extensions/UserStory/template/en/default/hook/bug/comments-comment_banner.html.tmpl b/extensions/UserStory/template/en/default/hook/bug/comments-comment_banner.html.tmpl index cbc4fe951..e063ac942 100644 --- a/extensions/UserStory/template/en/default/hook/bug/comments-comment_banner.html.tmpl +++ b/extensions/UserStory/template/en/default/hook/bug/comments-comment_banner.html.tmpl @@ -43,9 +43,9 @@ [% IF bug.cf_user_story != "" %] <div id="user_story_readonly" class="bz_comment"> - <div id="user-story" class="bz_comment_text"> - [%- bug.cf_user_story FILTER renderComment(bug, undef) -%] - </div> + <pre id="user-story" class="bz_comment_text"> + [%- bug.cf_user_story FILTER quoteUrls(bug) -%] + </pre> </div> [% ELSE %] <br id="user_story_readonly"> diff --git a/process_bug.cgi b/process_bug.cgi index eec5bbabf..df7dc57d9 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -266,7 +266,6 @@ if (should_set('comment')) { $set_all_fields{comment} = { body => scalar $cgi->param('comment'), is_private => scalar $cgi->param('comment_is_private'), - is_markdown => 1, }; } if (should_set('see_also')) { diff --git a/qa/t/test_time_summary.t b/qa/t/test_time_summary.t index 334b9a9f7..504c864f2 100644 --- a/qa/t/test_time_summary.t +++ b/qa/t/test_time_summary.t @@ -36,9 +36,7 @@ $sel->click_ok("link=bug $test_bug_1"); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_like(qr/^$test_bug_1/, "Display bug $test_bug_1"); $sel->is_text_present_ok("I did some work"); -# Test below is broken after adding support for Markdown. -# Manually verified that this works properly...could be a bug with selenium. -# $sel->is_text_present_ok("Hours Worked: 2.6"); +$sel->is_text_present_ok("Hours Worked: 2.6"); # Let's call summarize_time.cgi directly, with no parameters. diff --git a/skins/standard/global.css b/skins/standard/global.css index bf95dd84f..e7028f892 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -909,12 +909,7 @@ input.required, select.required, span.required_explanation { } #comment { - margin: 0px 0px 0.5em 0px; -} - -#comment-markdown-tip { - display: flex; - align-items: center; + margin: 0px 0px 1em 0px; } /*******************/ @@ -1416,8 +1411,7 @@ table.edit_form hr { left: 16px; } -.bz_comment_text span.quote, .bz_comment_text span.quote_wrapped, -div.bz_comment_text pre { +.bz_comment_text span.quote, .bz_comment_text span.quote_wrapped { background: #eee !important; color: #444 !important; display: block !important; @@ -1427,40 +1421,6 @@ div.bz_comment_text pre { padding: 5px !important; } -/* Markdown comments */ -div.bz_comment_text { - white-space: normal; - padding: 0 8px 0 8px; - font-family: inherit !important; -} - -div.bz_comment_text code { - color: #444; - background-color: #eee; - font-size: 13px; - font-family: "Fira Mono","Droid Sans Mono",Menlo,Monaco,"Courier New",monospace; -} - -div.bz_comment_text table { - border-collapse: collapse; -} - -div.bz_comment_text th, div.bz_comment_text td { - padding: 5px 10px; - border: 1px solid #ccc; -} - -div.bz_comment_text hr { - display: block !important; -} - -div.bz_comment_text blockquote { - background: #fcfcfc; - border-left: 5px solid #ccc; - margin: 1.5em 10px; - padding: 0.5em 10px; -} - .bz_comment_tags { background: #eee; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); diff --git a/t/004template.t b/t/004template.t index 8b063a366..909f1a231 100644 --- a/t/004template.t +++ b/t/004template.t @@ -76,7 +76,7 @@ foreach my $include_path (@include_paths) { url_quote => sub { return $_ } , css_class_quote => sub { return $_ } , xml => sub { return $_ } , - renderComment => sub { return $_ } , + quoteUrls => sub { return $_ } , bug_link => [ sub { return sub { return $_; } }, 1] , csv => sub { return $_ } , unitconvert => sub { return $_ }, diff --git a/t/008filter.t b/t/008filter.t index 050cf1ef3..443fb2b4f 100644 --- a/t/008filter.t +++ b/t/008filter.t @@ -214,7 +214,7 @@ sub directive_ok { # Note: If a single directive prints two things, and only one is # filtered, we may not catch that case. return 1 if $directive =~ /FILTER\ (html|csv|js|base64|css_class_quote|ics| - renderComment|time|uri|xml|lower|html_light| + quoteUrls|time|uri|xml|lower|html_light| obsolete|inactive|closed|unitconvert| txt|html_linebreak|none|json|null|id| markdown)\b/x; diff --git a/t/bmo/comments.t b/t/bmo/comments.t index f4064a7fc..4b0bb8177 100644 --- a/t/bmo/comments.t +++ b/t/bmo/comments.t @@ -61,7 +61,7 @@ my $bug_2 = Bugzilla::Bug->create( my $bug_2_id = $bug_2->id; -Bugzilla::Template::renderComment( +Bugzilla::Template::quoteUrls( $bug_2->comments->[0]->body, undef, undef, undef, sub { my $bug_id = $_[0]; diff --git a/template/en/default/bug/comment.html.tmpl b/template/en/default/bug/comment.html.tmpl index 9b0deecc4..e3cd382fd 100644 --- a/template/en/default/bug/comment.html.tmpl +++ b/template/en/default/bug/comment.html.tmpl @@ -37,11 +37,6 @@ <div id="comment_preview" class="bz_default_hidden bz_comment"> <div id="comment_preview_loading" class="bz_default_hidden">Generating Preview...</div> <div id="comment_preview_error" class="bz_default_hidden"></div> - <div id="comment_preview_text" class="bz_comment_text"></div> + <pre id="comment_preview_text" class="bz_comment_text"></pre> </div> [% END %] - -<div id="comment-markdown-tip"> - <img src="extensions/BMO/web/images/notice.png" width="16" height="16"> - <a href="https://guides.github.com/features/mastering-markdown/" target="_blank">Markdown styling now supported</a> -</div> diff --git a/template/en/default/bug/comments.html.tmpl b/template/en/default/bug/comments.html.tmpl index 98ab4645e..7af08efde 100644 --- a/template/en/default/bug/comments.html.tmpl +++ b/template/en/default/bug/comments.html.tmpl @@ -283,22 +283,15 @@ </div> [% END %] - -[% IF comment.is_markdown %] - [% comment_tag = 'div' %] -[% ELSE %] - [% comment_tag = 'pre' %] -[% END %] - -[%# Don't indent incaase it's a <pre> block, since then the spaces are - # displayed in the generated HTML +[%# Don't indent the <pre> block, since then the spaces are displayed in the + # generated HTML #%] -<[% comment_tag FILTER none %] class="bz_comment_text[% " collapsed" IF comment.collapsed %]" +<pre class="bz_comment_text[% " collapsed" IF comment.collapsed %]" [% IF mode == "edit" || comment.collapsed %] id="comment_text_[% comment.count FILTER none %]" [% END %]> - [%- comment_text FILTER renderComment(bug, comment) -%] -</[% comment_tag FILTER none %]> + [%- comment_text FILTER quoteUrls(bug, comment) -%] +</pre> [% Hook.process('a_comment-end', 'bug/comments.html.tmpl') %] </div> [% END %] diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl index 69edfeb00..445e5fe0d 100644 --- a/template/en/default/bug/edit.html.tmpl +++ b/template/en/default/bug/edit.html.tmpl @@ -253,7 +253,7 @@ (<span id="alias_nonedit_display">[% bug.alias FILTER html %]</span>) [% END %] [% END %] - <span role="heading" aria-level="1" id="short_desc_nonedit_display">[% bug.short_desc FILTER renderComment(bug, undef, 1) FILTER wbr %]</span> + <span role="heading" aria-level="1" id="short_desc_nonedit_display">[% bug.short_desc FILTER quoteUrls(bug) FILTER wbr %]</span> [% IF bug.check_can_change_field('short_desc', 0, 1) || bug.check_can_change_field('alias', 0, 1) %] <small class="editme">(<a href="#" id="editme_action">edit</a>)</small> diff --git a/template/en/default/bug/link.html.tmpl b/template/en/default/bug/link.html.tmpl index 17b85589c..dc09848da 100644 --- a/template/en/default/bug/link.html.tmpl +++ b/template/en/default/bug/link.html.tmpl @@ -56,8 +56,7 @@ <a class="bz_bug_link bz_status_[% bug.bug_status FILTER css_class_quote %] - [% ' bz_closed' IF !bug.isopened %] - [% ' bz_private_link' IF !user.can_see_bug(bug) %]" + [% ' bz_closed' IF !bug.isopened %]" title="[% link_title FILTER collapse FILTER html %]" href="[% urlbase FILTER html IF full_url %]show_bug.cgi?id= [%~ bug.id FILTER uri %][% anchor FILTER html %]"> diff --git a/template/en/default/bug/new_bug.html.tmpl b/template/en/default/bug/new_bug.html.tmpl index 185ae771b..ef5e361c0 100644 --- a/template/en/default/bug/new_bug.html.tmpl +++ b/template/en/default/bug/new_bug.html.tmpl @@ -244,7 +244,7 @@ <textarea rows="5" name="comment" id="comment" aria-labelledby="comment-edit-tab"></textarea> </div> <div id="comment-preview-tabpanel" class="comment-tabpanel" role="tabpanel" aria-labelledby="comment-preview-tab" style="display:none"> - <div id="comment-preview" class="comment-text"></div> + <pre id="comment-preview" class="comment-text"></pre> </div> </div> [% END %] diff --git a/template/en/default/email/bugmail.html.tmpl b/template/en/default/email/bugmail.html.tmpl index cdcb3d13d..8b567b691 100644 --- a/template/en/default/email/bugmail.html.tmpl +++ b/template/en/default/email/bugmail.html.tmpl @@ -38,12 +38,7 @@ on [% "$terms.bug $bug.id" FILTER bug_link(bug, { full_url => 1, user => to_user }) FILTER none %] from [% INCLUDE global/user.html.tmpl user = to_user, who = comment.author %]</b> [% END %] - [% IF comment.is_markdown %] - [% comment_tag = 'div' %] - [% ELSE %] - [% comment_tag = 'pre' %] - [% END %] - <[% comment_tag FILTER none %]>[% comment.body_full({ wrap => 1 }) FILTER renderComment(bug, comment) %]</[% comment_tag FILTER none %]> + <pre>[% comment.body_full({ wrap => 1 }) FILTER quoteUrls(bug, comment, to_user) %]</pre> </div> [% END %] </p> diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index 07211ad29..39f064035 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -34,7 +34,7 @@ # [% foo.push() %] # TT loop variables - [% loop.count %] # Already-filtered stuff - [% wibble FILTER html %] -# where the filter is one of html|csv|js|renderComment|time|uri|xml|none +# where the filter is one of html|csv|js|quoteUrls|time|uri|xml|none %::safe = ( diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl index 426742495..bd9ec8bcb 100644 --- a/template/en/default/global/header.html.tmpl +++ b/template/en/default/global/header.html.tmpl @@ -112,7 +112,6 @@ }, constant => { COMMENT_COLS => constants.COMMENT_COLS, - URL_BASE => urlbase, }, string => { # Please keep these in alphabetical order. diff --git a/template/en/default/pages/linked.html.tmpl b/template/en/default/pages/linked.html.tmpl index aa519f9ac..b5d850627 100644 --- a/template/en/default/pages/linked.html.tmpl +++ b/template/en/default/pages/linked.html.tmpl @@ -31,7 +31,7 @@ <p> <pre class="bz_comment_text"> -[%- cgi.param("text") FILTER renderComment FILTER html -%] +[%- cgi.param("text") FILTER quoteUrls FILTER html -%] </pre> </p> @@ -46,7 +46,7 @@ <p> <pre class="bz_comment_text"> -[%- cgi.param("text") FILTER renderComment -%] +[%- cgi.param("text") FILTER quoteUrls -%] </pre> </p> |