From 907fbcfd19dfa436567bf4a75f566b8f81f43298 Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Fri, 5 Jun 2015 12:40:01 +0800 Subject: Bug 1146775: implement comment collapse all and by tag --- extensions/BugModal/web/bug_modal.css | 17 ++- extensions/BugModal/web/bug_modal.js | 45 +++---- extensions/BugModal/web/comments.js | 218 ++++++++++++++++++++++++++++++++-- 3 files changed, 245 insertions(+), 35 deletions(-) (limited to 'extensions/BugModal/web') diff --git a/extensions/BugModal/web/bug_modal.css b/extensions/BugModal/web/bug_modal.css index 0d34039af..e3070f2a6 100644 --- a/extensions/BugModal/web/bug_modal.css +++ b/extensions/BugModal/web/bug_modal.css @@ -325,8 +325,7 @@ input[type="number"] { /* actions */ #top-actions { - margin-top: 5px; - padding-bottom: 20px; + margin: 4px 0; } #top-actions .save-btn { @@ -465,13 +464,18 @@ td.flag-requestee { /* comments and activity */ +#comment-actions { + margin-top: 4px; + text-align: right; +} + .change-set { clear: both; -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.2); - margin-top: 20px; + margin-top: 8px; border: 1px solid #ddd; } @@ -488,10 +492,15 @@ td.flag-requestee { padding-left: 8px !important; } +.change-gravatar .vcard { + width: 36px; + text-align: center; +} + .change-author { width: 100%; vertical-align: top; - padding-top: 4px !important; + padding: 5px 0 !important; } .change-author .vcard { diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js index 473de438e..87cfcffdf 100644 --- a/extensions/BugModal/web/bug_modal.js +++ b/extensions/BugModal/web/bug_modal.js @@ -25,19 +25,6 @@ $(function() { // products with descriptions (also lazy-loaded) var products = []; - // scroll to an element - function scroll_to(el, complete) { - var offset = el.offset(); - $('html, body') - .animate({ - scrollTop: offset.top - 20, - scrollLeft: offset.left = 20 - }, - 200, - complete - ); - } - // expand/collapse module function slide_module(module, action, fast) { if (!module.attr('id')) @@ -120,7 +107,7 @@ $(function() { .click(function(event) { event.preventDefault(); var id = $('.comment:last')[0].parentNode.id; - scroll_to($('#' + id)); + $.scrollTo($('#' + id)); window.location.hash = id; }); @@ -128,7 +115,7 @@ $(function() { $('#top-btn') .click(function(event) { event.preventDefault(); - scroll_to($('body')); + $.scrollTo($('body')); }); // use non-native tooltips for relative times and bug summaries @@ -450,14 +437,14 @@ $(function() { event.preventDefault(); // focus first to grow the textarea, so we scroll to the correct location $('#comment').focus(); - scroll_to($('#bottom-save-btn')); + $.scrollTo($('#bottom-save-btn')); }); // needinfo in people section -> scroll to near-comment ui $('#needinfo-scroll') .click(function(event) { event.preventDefault(); - scroll_to($('#needinfo_role'), function() { $('#needinfo_role').focus(); }); + $.scrollTo($('#needinfo_role'), function() { $('#needinfo_role').focus(); }); }); // knob @@ -569,7 +556,7 @@ $(function() { if ($('#comment').val() != reply_text) { $('#comment').val($('#comment').val() + reply_text); } - scroll_to($('#comment'), function() { $('#comment').focus(); }); + $.scrollTo($('#comment'), function() { $('#comment').focus(); }); }); // add comment --> enlarge on focus @@ -606,10 +593,10 @@ $(function() { $('#resolution').val($(event.target).text()).change(); $('#top-save-btn').show(); if ($(event.target).text() == "DUPLICATE") { - scroll_to($('body')); + $.scrollTo($('body')); } else { - scroll_to($('body'), function() { $('#resolution').focus(); }); + $.scrollTo($('body'), function() { $('#resolution').focus(); }); } }); $('.status-btn') @@ -619,7 +606,7 @@ $(function() { $('#field-status-edit').show(); $('#bug_status').val($(event.target).data('status')).change(); $('#top-save-btn').show(); - scroll_to($('body'), function() { $('#bug_status').focus(); }); + $.scrollTo($('body'), function() { $('#bug_status').focus(); }); }); // vote button @@ -651,7 +638,7 @@ $(function() { if (current != text) { $('#comment').val(current + text); $('#comment').focus(); - scroll_to($('#bottom-save-btn')); + $.scrollTo($('#bottom-save-btn')); } }); @@ -1158,7 +1145,21 @@ function lb_close(event) { } // stick with inArray/indexOf and return -1 on no match return -1; + }, + + // Animated scroll to bring an element into view + scrollTo: function(el, complete) { + var offset = el.offset(); + $('html, body') + .animate({ + scrollTop: offset.top - 20, + scrollLeft: offset.left = 20 + }, + 200, + complete + ); } + }); })(jQuery); diff --git a/extensions/BugModal/web/comments.js b/extensions/BugModal/web/comments.js index 1f0b18696..f0d689b3e 100644 --- a/extensions/BugModal/web/comments.js +++ b/extensions/BugModal/web/comments.js @@ -9,22 +9,220 @@ $(function() { 'use strict'; // comment collapse/expand - $('.comment-spinner') - .click(function(event) { - event.preventDefault(); - var spinner = $(event.target); - var id = spinner.attr('id').match(/\d+$/)[0]; - // switch to full header for initially collapsed comments - if (spinner.attr('id').match(/^ccs-/)) { + + function toggleChange(spinner, forced) { + // find and cache the id + var id = spinner.data('cid'); + if (!id) { + id = spinner.attr('id').match(/\d+$/)[0]; + spinner.data('cid', id); + } + + // non-comment toggle + if (spinner.attr('id').substr(0, 1) == 'a') { + var changeSet = spinner.parents('.change-set'); + if (forced == 'hide') { + changeSet.find('.activity').hide(); + changeSet.find('.gravatar').css('width', '16px').css('height', '16px'); + $('#ar-' + id).hide(); + spinner.text('+'); + } + else if (forced == 'show' || forced == 'reset') { + changeSet.find('.activity').show(); + changeSet.find('.gravatar').css('width', '32px').css('height', '32px'); + $('#ar-' + id).show(); + spinner.text('-'); + } + else { + changeSet.find('.activity').slideToggle('fast', function() { + $('#ar-' + id).toggle(); + if (changeSet.find('.activity:visible').length) { + changeSet.find('.gravatar').css('width', '32px').css('height', '32px'); + spinner.text('-'); + } + else { + changeSet.find('.gravatar').css('width', '16px').css('height', '16px'); + spinner.text('+'); + } + }); + } + return; + } + + // find the "real spinner", which is the one on the non-default-collapsed block + var realSpinner = $('#cs-' + id); + var defaultCollapsed = realSpinner.data('ch'); + if (defaultCollapsed === undefined) { + defaultCollapsed = spinner.attr('id').substring(0, 4) === 'ccs-'; + realSpinner.data('ch', defaultCollapsed); + } + if (forced === 'reset') { + forced = defaultCollapsed ? 'hide' : 'show'; + } + + // comment toggle + if (forced === 'hide') { + if (defaultCollapsed) { + $('#ch-' + id).hide(); + $('#cc-' + id).show(); + } + $('#ct-' + id).hide(); + if (BUGZILLA.user.id !== 0) + $('#ctag-' + id).hide(); + $('#c' + id).find('.activity').hide(); + $('#c' + id).find('.comment-tags').hide(); + $('#c' + id).find('.comment-tags').hide(); + $('#c' + id).find('.gravatar').css('width', '16px').css('height', '16px'); + $('#cr-' + id).hide(); + spinner.text('+'); + } + else if (forced == 'show') { + if (defaultCollapsed) { $('#cc-' + id).hide(); $('#ch-' + id).show(); } - $('#ct-' + id + ', #ctag-' + id).slideToggle('fast', function() { + $('#ct-' + id).show(); + if (BUGZILLA.user.id !== 0) + $('#ctag-' + id).show(); + $('#c' + id).find('.activity').show(); + $('#c' + id).find('.comment-tags').show(); + $('#c' + id).find('.comment-tags').show(); + $('#c' + id).find('.gravatar').css('width', '32px').css('height', '32px'); + $('#cr-' + id).show(); + spinner.text('-'); + } + else { + $('#ct-' + id).slideToggle('fast', function() { $('#c' + id).find('.activity').toggle(); - spinner.text($('#ct-' + id + ':visible').length ? '-' : '+'); + $('#c' + id).find('.comment-tags').toggle(); + if ($('#ct-' + id + ':visible').length) { + spinner.text('-'); + $('#cr-' + id).show(); + if (BUGZILLA.user.id !== 0) + $('#ctag-' + id).show(); + $('#c' + id).find('.gravatar').css('width', '32px').css('height', '32px'); + if (defaultCollapsed) { + $('#cc-' + id).hide(); + $('#ch-' + id).show(); + } + } + else { + spinner.text('+'); + $('#cr-' + id).hide(); + if (BUGZILLA.user.id !== 0) + $('#ctag-' + id).hide(); + $('#c' + id).find('.gravatar').css('width', '16px').css('height', '16px'); + if (defaultCollapsed) { + $('#ch-' + id).hide(); + $('#cc-' + id).show(); + } + } }); + } + } + + $('.change-spinner') + .click(function(event) { + event.preventDefault(); + toggleChange($(this)); }); + // comment and tag menus + + $('#comment-reset') + .click(function() { + $('.change-spinner:visible').each(function() { + toggleChange($(this), 'reset'); + }); + }); + + $('#comment-collapse-all') + .click(function() { + $('.change-spinner:visible').each(function() { + toggleChange($(this), 'hide'); + }); + }); + + $('#comment-expand-all') + .click(function() { + $('.change-spinner:visible').each(function() { + toggleChange($(this), 'show'); + }); + }); + + $('#comments-only') + .click(function() { + $('.change-spinner:visible').each(function() { + toggleChange($(this), this.id.substr(0, 3) === 'cs-' ? 'show' : 'hide'); + }); + }); + + $.contextMenu({ + selector: '#comment-toggle-btn', + trigger: 'left', + items: $.contextMenu.fromMenu($('#comment-toggle-menu')) + }); + + function updateTagsMenu() { + var tags = []; + $('.comment-tags').each(function() { + $.each(tagsFromDom($(this)), function() { + var tag = this.toLowerCase(); + if (tag in tags) { + tags[tag]++; + } + else { + tags[tag] = 1; + } + }); + }); + var tagNames = Object.keys(tags); + tagNames.sort(); + + var btn = $('#comment-tags-btn'); + if (tagNames.length === 0) { + btn.hide(); + return; + } + btn.show(); + + var menuItems = [ + { name: 'Reset', tag: '' }, + "--" + ]; + $.each(tagNames, function(key, value) { + menuItems.push({ name: value + ' (' + tags[value] + ')', tag: value }); + }); + + $.contextMenu('destroy', '#comment-tags-btn'); + $.contextMenu({ + selector: '#comment-tags-btn', + trigger: 'left', + items: menuItems, + callback: function(key, opt) { + var tag = opt.commands[key].tag; + if (tag === '') { + $('.change-spinner:visible').each(function() { + toggleChange($(this), 'reset'); + }); + return; + } + var firstComment = false; + $('.change-spinner:visible').each(function() { + var that = $(this); + var commentTags = tagsFromDom(that.parents('.comment').find('.comment-tags')); + var hasTag = $.inArrayIn(tag, commentTags) >= 0; + toggleChange(that, hasTag ? 'show' : 'hide'); + if (hasTag && !firstComment) { + firstComment = that; + } + }); + if (firstComment) + $.scrollTo(firstComment); + } + }); + } + // // anything after this point is only executed for logged in users // @@ -259,4 +457,6 @@ $(function() { event.preventDefault(); $('#' + $(this).data('for')).hide(); }); + + updateTagsMenu(); }); -- cgit v1.2.3-24-g4f1b