summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/activity_stream.html.tmpl50
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl95
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/header.html.tmpl2
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/user.html.tmpl6
-rw-r--r--extensions/BugModal/web/bug_modal.js101
-rw-r--r--extensions/BugModal/web/comments.js43
-rw-r--r--extensions/BugModal/web/dropdown.css52
-rw-r--r--extensions/BugModal/web/dropdown.js93
8 files changed, 286 insertions, 156 deletions
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 c658f0642..25198a7f2 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
@@ -12,23 +12,43 @@
[% ELSE %]
<button type="button" id="bottom-btn" class="minor">Bottom &darr;</button>
[% END %]
- <button type="button" id="comment-tags-btn" style="display:none" class="minor">Tags &#9662;</button>
- <button type="button" id="view-menu-btn" class="minor">View &#9662;</button>
+ <div class="dropdown">
+ <button type="button" id="comment-tags-btn" arai-haspopup="true" aria-label="Tags Menu"
+ aria-expanded="false" aria-controls="comment-tags-menu" class="dropdown-button minor">Tags &#9662;</button>
+ <ul id="comment-tags-menu" role="menu" tabindex="0" class="dropdown-content" style="display:none">
+ <li class="dropdown-separator" role="presentation">
+ <a role="menuitem" tabindex="-1" data-comment-tag="">Reset</a>
+ </li>
+ </ul>
+ </div>
+ <div class="dropdown">
+ <button type="button" id="view-menu-btn" arai-haspopup="true" aria-label="View Menu"
+ aria-expanded="false" aria-controls="view-menu" class="dropdown-button minor">View &#9662;</button>
+ <ul id="view-menu" role="menu" tabindex="0" class="dropdown-content" style="display:none">
+ <li class="dropdown-separator" role="presentation">
+ <a id="view-reset" role="menuitem" tabindex="-1">Reset</a>
+ </li>
+ <li role="presentation">
+ <a id="view-collapse-all" role="menuitem" tabindex="-1">Collapse All</a>
+ </li>
+ <li role="presentation">
+ <a id="view-expand-all" role="menuitem" tabindex="-1">Expand All</a>
+ </li>
+ <li class="dropdown-separator" role="presentation">
+ <a id="view-comments-only" role="menuitem" tabindex="-1">Comments Only</a>
+ </li>
+ <li role="presentation">
+ <a id="view-toggle-cc" role="menuitem" tabindex="-1">Show CC Changes</a>
+ </li>
+ [% IF treeherder %]
+ <li role="presentation">
+ <a id="view-toggle-treeherder" role="menuitem" data-userid="[% treeherder.id FILTER none %]">Hide Treeherder Comments</a>
+ </li>
+ [% END %]
+ </ul>
+ </div>
</div>
-<menu id="view-menu" type="context" style="display:none">
- <menuitem id="view-reset" label="Reset"></menuitem>
- <hr>
- <menuitem id="view-collapse-all" label="Collapse All"></menuitem>
- <menuitem id="view-expand-all" label="Expand All"></menuitem>
- <menuitem id="view-comments-only" label="Comments Only"></menuitem>
- <hr>
- <menuitem id="view-toggle-cc" label="Show CC Changes"></menuitem>
- [% IF treeherder %]
- <menuitem id="view-toggle-treeherder" label="Hide Treeherder Comments" data-userid="[% treeherder.id FILTER none %]"></menuitem>
- [% END %]
-</menu>
-
[%
PROCESS bug/time.html.tmpl;
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 4b23df786..e3854f2e2 100644
--- a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
@@ -308,19 +308,32 @@
[% is_cced ? "Stop Following" : "Follow" %]
</button>
[% END %]
- <button type="button" id="action-menu-btn" class="minor">&#9662;</button>
- <menu id="action-menu" type="context" style="display:none">
- <menuitem id="action-reset" label="Reset Sections"></menuitem>
- <menuitem id="action-expand-all" label="Expand All Sections"></menuitem>
- <menuitem id="action-collapse-all" label="Collapse All Sections"></menuitem>
- <hr>
- [% IF user.id %]
- <menuitem id="action-add-comment" label="Add Comment"></menuitem>
- [% END %]
- <menuitem id="action-last-comment" label="Last Comment"></menuitem>
- <hr>
- <menuitem id="action-history" label="History"></menuitem>
- </menu>
+ <div class="dropdown">
+ <button type="button" id="action-menu-btn" aria-haspopup="true" aria-label="Actions Menu"
+ aria-expanded="false" aria-controls="action-menu" class="dropdown-button minor">&#9662;</button>
+ <ul class="dropdown-content" id="action-menu" role="menu" style="display:none;">
+ <li role="presentation">
+ <a id="action-reset" role="menuitem" tabindex="-1">Reset Sections</a>
+ </li>
+ <li role="presentation">
+ <a id="action-expand-all" role="menuitem" tabindex="-1">Expand All Sections</a>
+ </li>
+ <li class="dropdown-separator" role="presentation">
+ <a id="action-collapse-all" role="menuitem" tabindex="-1">Collapse All Sections</a>
+ </li>
+ [% IF user.id %]
+ <li role="presentation">
+ <a id="action-add-comment" role="menuitem" tabindex="-1">Add Comment</a>
+ </li>
+ [% END %]
+ <li class="dropdown-separator" role="presentation">
+ <a id="action-last-comment" role="menuitem" tabindex="-1">Last Comment</a>
+ </li>
+ <li role="presentation">
+ <a id="action-history" role="menuitem" tabindex="-1">History</a>
+ </li>
+ </ul>
+ </div>
</div>
<div id="user-guide">
<a title="User guide for [% terms.Bugzilla %]" href="https://wiki.mozilla.org/BMO/UserGuide">Get help with this page</a>
@@ -1300,9 +1313,61 @@
<div id="bottom-actions">
<div id="bottom-right-actions">
<button type="button" id="top-btn" class="minor">Top &uarr;</button>
- <button type="button" id="format-btn" class="minor">Format &#9662;</button>
+ <div class="dropdown">
+ <button id="format-btn" aria-haspopup="true" aria-label="Format [% terms.Bug %] Menu"
+ aria-expanded="false" aria-controls="format-menu" class="dropdown-button minor">Format [% terms.Bug %] &#9652;</button>
+ <ul class="dropdown-content menu-up" id="format-menu" role="menu" style="display:none;">
+ <li role="presentation">
+ <a href="show_bug.cgi?format=multiple&amp;id=[% bug.id FILTER uri %]" role="menuitem" tabindex="-1">For Printing</a>
+ </li>
+ <li role="presentation">
+ <a href="show_bug.cgi?ctype=xml&amp;id=[% bug.id FILTER uri %]" role="menuitem" tabindex="-1">XML</a>
+ </li>
+ <li role="presentation">
+ <a href="show_bug.cgi?format=default&amp;id=[% bug.id FILTER uri %]" role="menuitem" tabindex="-1">Legacy</a>
+ </li>
+ [% IF bug.groups_in.size == 0 %]
+ <li role="presentation">
+ <a href="rest/bug/[% bug.id FILTER uri %]" role="menuitem" tabindex="-1">JSON</a>
+ </li>
+ [% END %]
+ </ul>
+ </div>
[% IF user.id %]
- <button type="button" id="new-bug-btn" class="minor">New/Clone [% terms.Bug %] &#9662;</button>
+ <div class="dropdown">
+ <button id="new-bug-btn" aria-haspopup="true" aria-label="New/Clone [% terms.Bug %] Menu"
+ aria-expanded="false" aria-controls="new-bug-menu" class="dropdown-button minor">New/Clone [% terms.Bug %] &#9652;</button>
+ <ul class="dropdown-content menu-up" id="new-bug-menu" role="menu" style="display:none;">
+ <li role="presentation">
+ <a href="enter_bug.cgi" role="menuitem" tabindex="-1" target="_blank">
+ Create a new [% terms.bug %]</a>
+ </li>
+ <li role="presentation">
+ <a href="enter_bug.cgi?product=[% bug.product FILTER uri %]"
+ role="menuitem" tabindex="-1" target="_blank">&#8230; in this product</a>
+ </li>
+ <li class="dropdown-separator" role="presentation">
+ <a href="enter_bug.cgi?product=[% bug.product FILTER uri %]&amp;component=[% bug.component FILTER uri %]"
+ role="menuitem" tabindex="-1" target="_blank">&#8230; in this component</a>
+ </li>
+ <li role="presentation">
+ <a href="enter_bug.cgi?format=__default__&amp;product=[% bug.product FILTER uri %]&amp;blocked=[% bug.id FILTER uri %]"
+ role="menuitem" tabindex="-1" target="_blank">&#8230; that blocks this [% terms.bug %]</a>
+ </li>
+ <li class="dropdown-separator" role="presentation">
+ <a href="enter_bug.cgi?format=__default__&amp;product=[% bug.product FILTER uri %]&amp;dependson=[% bug.id FILTER uri %]"
+ role="menuitem" tabindex="-1" target="_blank">&#8230; that depends on this [% terms.bug %]</a>
+ </li>
+ <li role="presentation">
+ <a href="enter_bug.cgi?format=__default__&amp;product=[% bug.product FILTER uri %]&amp;cloned_bug_id=[% bug.id FILTER uri %]"
+ role="menuitem" tabindex="-1" target="_blank">&#8230; as a clone of this [% terms.bug %]</a>
+ </li>
+ <li role="presentation">
+ <a href="enter_bug.cgi?format=__default__&amp;cloned_bug_id=[% terms.bug FILTER uri %]"
+ role="menuitem" tabindex="-1" target="_blank">&#8230; as a clone, in a different product</a>
+ </li>
+ </ul>
+ </div>
[% END %]
</div>
</div>
diff --git a/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl
index e5070bcf5..86d4773f2 100644
--- a/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl
@@ -52,6 +52,7 @@
"extensions/ProdCompSearch/web/js/prod_comp_search.js",
"extensions/BugModal/web/bug_modal.js",
"extensions/BugModal/web/comments.js",
+ "extensions/BugModal/web/dropdown.js",
"extensions/BugModal/web/ZeroClipboard/ZeroClipboard.min.js",
"js/bugzilla-readable-status-min.js",
"js/field.js",
@@ -65,6 +66,7 @@
);
style_urls.push(
"extensions/BugModal/web/bug_modal.css",
+ "extensions/BugModal/web/dropdown.css",
"skins/custom/bug_groups.css",
"js/jquery/plugins/datetimepicker/datetimepicker.css",
"js/jquery/plugins/contextMenu/contextMenu.css"
diff --git a/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
index 5c630ba07..d5c150690 100644
--- a/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
@@ -41,12 +41,12 @@ END;
width="[% gravatar_size FILTER none %]" height="[% gravatar_size FILTER none %]">
[% END %]
[% UNLESS gravatar_only %]
- <a class="email [%= "disabled" UNLESS u.is_enabled %] [%= "show_usermenu" IF user.id %]"
+ <a class="email [%= "disabled" UNLESS u.is_enabled %] [% "show_usermenu" IF user.id %]"
[% IF user.id %]
href="mailto:[% u.email FILTER html %]"
- data-user-id="[% u.id FILTER html %]"
data-user-email="[% u.email FILTER html %]"
- data-show-edit="[% user.in_group('editusers') || user.bless_groups.size > 9 ? 'true' : 'false' %]"
+ data-user-id="[% u.id FILTER html %]"
+ data-show-edit="[% user.in_group('editusers') || user.bless_groups.size > 0 ? 1 : 0 %]"
title="[% u.identity FILTER html %]"
[% ELSE %]
href="user_profile?user_id=[% u.id FILTER none %]"
diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js
index 894745016..f65c12be3 100644
--- a/extensions/BugModal/web/bug_modal.js
+++ b/extensions/BugModal/web/bug_modal.js
@@ -377,13 +377,7 @@ $(function() {
}
});
- // action button menu
-
- $.contextMenu({
- selector: '#action-menu-btn',
- trigger: 'left',
- items: $.contextMenu.fromMenu($('#action-menu'))
- });
+ // action button actions
// reset
$('#action-reset')
@@ -1006,99 +1000,6 @@ $(function() {
BUGZILLA.remaining_time = $('#remaining_time').val();
});
- // new bug button
- $.contextMenu({
- selector: '#new-bug-btn',
- trigger: 'left',
- items: [
- {
- name: 'Create a new Bug',
- callback: function() {
- window.open('enter_bug.cgi', '_blank');
- }
- },
- {
- name: '\u2026 in this product',
- callback: function() {
- window.open('enter_bug.cgi?product=' + encodeURIComponent($('#product').val()), '_blank');
- }
- },
- {
- name: '\u2026 in this component',
- callback: function() {
- window.open('enter_bug.cgi?' +
- 'product=' + encodeURIComponent($('#product').val()) +
- '&component=' + encodeURIComponent($('#component').val()), '_blank');
- }
- },
- {
- name: '\u2026 that blocks this bug',
- callback: function() {
- window.open('enter_bug.cgi?format=__default__' +
- '&product=' + encodeURIComponent($('#product').val()) +
- '&blocked=' + BUGZILLA.bug_id, '_blank');
- }
- },
- {
- name: '\u2026 that depends on this bug',
- callback: function() {
- window.open('enter_bug.cgi?format=__default__' +
- '&product=' + encodeURIComponent($('#product').val()) +
- '&dependson=' + BUGZILLA.bug_id, '_blank');
- }
- },
- {
- name: '\u2026 as a clone of this bug',
- callback: function() {
- window.open('enter_bug.cgi?format=__default__' +
- '&product=' + encodeURIComponent($('#product').val()) +
- '&cloned_bug_id=' + BUGZILLA.bug_id, '_blank');
- }
- },
- {
- name: '\u2026 as a clone, in a different product',
- callback: function() {
- window.open('enter_bug.cgi?format=__default__' +
- '&cloned_bug_id=' + BUGZILLA.bug_id, '_blank');
- }
- },
- ]
- });
-
- var format_items = [
- {
- name: 'For Printing',
- callback: function() {
- window.location.href = 'show_bug.cgi?format=multiple&id=' + BUGZILLA.bug_id;
- }
- },
- {
- name: 'XML',
- callback: function() {
- window.location.href = 'show_bug.cgi?ctype=xml&id=' + BUGZILLA.bug_id;
- }
- },
- {
- name: 'Legacy',
- callback: function() {
- window.location.href = 'show_bug.cgi?format=default&id=' + BUGZILLA.bug_id;
- }
- }
- ];
- if (!BUGZILLA.bug_secure) {
- format_items.push({
- name: 'JSON',
- callback: function() {
- window.location.href = 'rest/bug/' + BUGZILLA.bug_id;
- }
- });
- }
- $.contextMenu({
- selector: '#format-btn',
- trigger: 'left',
- items: format_items
- });
-
// "reset to default" checkboxes
$('#product, #component')
.change(function(event) {
diff --git a/extensions/BugModal/web/comments.js b/extensions/BugModal/web/comments.js
index 7eb933cfc..04894506e 100644
--- a/extensions/BugModal/web/comments.js
+++ b/extensions/BugModal/web/comments.js
@@ -189,12 +189,6 @@ $(function() {
}
});
- $.contextMenu({
- selector: '#view-menu-btn',
- trigger: 'left',
- items: $.contextMenu.fromMenu($('#view-menu'))
- });
-
function updateTagsMenu() {
var tags = [];
$('.comment-tags').each(function() {
@@ -218,21 +212,24 @@ $(function() {
}
btn.show();
- var menuItems = [
- { name: 'Reset', tag: '' },
- "--"
- ];
+ // clear out old li items. Always leave the first one (Reset)
+ var $li = $('#comment-tags-menu li');
+ for (var i = 1, l = $li.length; i < l; i++) {
+ $li.eq(i).remove();
+ }
+
+ // add new li items
$.each(tagNames, function(key, value) {
- menuItems.push({ name: value + ' (' + tags[value] + ')', tag: value });
+ $('#comment-tags-menu')
+ .append($('<li role="presentation">')
+ .append($('<a role="menuitem" tabindex="-1" data-comment-tag="' + value + '">')
+ .append(value + ' (' + tags[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;
+ $('a[data-comment-tag]').each(function() {
+ $(this).click(function() {
+ var $that = $(this);
+ var tag = $that.data('comment-tag');
if (tag === '') {
$('.change-spinner:visible').each(function() {
toggleChange($(this), 'reset');
@@ -241,17 +238,17 @@ $(function() {
}
var firstComment = false;
$('.change-spinner:visible').each(function() {
- var that = $(this);
- var commentTags = tagsFromDom(that.parents('.comment').find('.comment-tags'));
+ var $that = $(this);
+ var commentTags = tagsFromDom($that.parents('.comment').find('.comment-tags'));
var hasTag = $.inArrayIn(tag, commentTags) >= 0;
- toggleChange(that, hasTag ? 'show' : 'hide');
+ toggleChange($that, hasTag ? 'show' : 'hide');
if (hasTag && !firstComment) {
- firstComment = that;
+ firstComment = $that;
}
});
if (firstComment)
$.scrollTo(firstComment);
- }
+ });
});
}
diff --git a/extensions/BugModal/web/dropdown.css b/extensions/BugModal/web/dropdown.css
new file mode 100644
index 000000000..977a7a57f
--- /dev/null
+++ b/extensions/BugModal/web/dropdown.css
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This Source Code Form is "Incompatible With Secondary Licenses", as
+ * defined by the Mozilla Public License, v. 2.0. */
+
+/* The container <div> - needed to position the dropdown content */
+.dropdown {
+ position: relative;
+ display: inline-block;
+}
+
+/* Dropdown Content (Hidden by Default) */
+.dropdown-content {
+ position: absolute;
+ background-color: #eee;
+ min-width: 120px;
+ z-index: 1;
+ text-align: left;
+ margin: 0;
+ padding: 0;
+ border: 1px solid #ddd;
+ -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);
+ list-style: none;
+}
+
+.dropdown-content.menu-up {
+ bottom: 100%;
+}
+
+.dropdown-separator {
+ border-bottom: 1px solid #ddd;
+}
+
+/* Links inside the dropdown */
+.dropdown-content a {
+ white-space: nowrap;
+ background-color: #eee;
+ color: black !important;
+ padding: 4px 8px;
+ text-decoration: none !important;
+ display: block;
+}
+
+/* Change color of dropdown links on hover */
+.dropdown-content li .active {
+ text-decoration: none;
+ background-color: #39f;
+}
diff --git a/extensions/BugModal/web/dropdown.js b/extensions/BugModal/web/dropdown.js
new file mode 100644
index 000000000..181be9f73
--- /dev/null
+++ b/extensions/BugModal/web/dropdown.js
@@ -0,0 +1,93 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This Source Code Form is "Incompatible With Secondary Licenses", as
+ * defined by the Mozilla Public License, v. 2.0. */
+
+$(function() {
+ 'use strict';
+
+ $(window).click(function(e) {
+ // clicking dropdown button opens or closes the dropdown content
+ if (!$(e.target).hasClass('dropdown-button')) {
+ $('.dropdown-button').each(function() {
+ toggleDropDown(e, $(this), $('#' + $(this).attr('aria-controls')), 1);
+ });
+ }
+ }).keydown(function(e) {
+ // Escape key hides the dropdown if visible
+ if (e.keyCode == 27) {
+ $('.dropdown-button').each(function() {
+ var $button = $(this);
+ if ($button.siblings('.dropdown-content').is(':visible')) {
+ toggleDropDown(e, $button, $('#' + $button.attr('aria-controls')), 1);
+ $button.focus();
+ }
+ });
+ }
+ // allow arrow up and down keys to choose one of the dropdown items if menu visible
+ if (e.keyCode == 38 || e.keyCode == 40) {
+ $('.dropdown-content').each(function() {
+ var $content = $(this);
+ if ($content.is(':visible')) {
+ e.preventDefault();
+ e.stopPropagation();
+ var $li = $content.find('li');
+ // if none focused select the first or last
+ var $any_focused = $content.find('a:focus');
+ if ($any_focused.length == 0) {
+ var index = e.keyCode == 40 ? 0 : $li.length - 1;
+ var $link = $li.eq(index).find('a');
+ $link.addClass('active').focus();
+ return;
+ }
+ // otherwise move up or down the list based on arrow key pressed
+ var inc = e.keyCode == 40 ? 1 : -1;
+ var move = $content.find('a:focus').parent('li').index() + inc;
+ var $link = $li.eq(move % $li.length).find('a');
+ $content.find('a').removeClass('active');
+ $link.addClass('active').focus();
+ }
+ });
+ }
+
+ // enter clicks on a link
+ if (e.keyCode == 13) {
+ $('.dropdown-content:visible a.active').trigger('click');
+ }
+ });
+
+ $('.dropdown-content a').hover(
+ function(){ $(this).addClass('active') },
+ function(){ $(this).removeClass('active') }
+ );
+
+ $('.dropdown').each(function() {
+ var $div = $(this);
+ var $button = $div.find('.dropdown-button');
+ var $content = $div.find('.dropdown-content');
+ $button.click(function(e) {
+ toggleDropDown(e, $button, $content);
+ }).keydown(function(e) {
+ // allow enter to toggle menu
+ if (e.keyCode == 13) {
+ toggleDropDown(e, $button, $content);
+ }
+ });
+ });
+
+ function toggleDropDown(e, $button, $content, hide_only) {
+ // clear all active links
+ $content.find('a').removeClass('active');
+ if ($content.is(':visible')) {
+ $content.hide();
+ $button.attr('aria-expanded', false);
+ }
+ // if not using Escape or clicking outside the dropdown div, then we are hiding
+ else if (!hide_only) {
+ $content.show();
+ $button.attr('aria-expanded', true);
+ }
+ }
+});