diff options
31 files changed, 614 insertions, 537 deletions
diff --git a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl index 6e62f4762..45dd5bd65 100644 --- a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl +++ b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl @@ -23,7 +23,7 @@ [% PROCESS global/header.html.tmpl title = "Bugzilla Etiquette" - style = "li { margin: 5px } .heading { font-weight: bold }" %] + style = "#bugzilla-body li { margin: 5px } .heading { font-weight: bold }" %] <h1>Bugzilla Etiquette</h1> diff --git a/extensions/BugModal/template/en/default/bug_modal/common_header.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/common_header.html.tmpl index 814464f27..ccc974a23 100644 --- a/extensions/BugModal/template/en/default/bug_modal/common_header.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/common_header.html.tmpl @@ -38,7 +38,6 @@ "extensions/ProdCompSearch/web/js/prod_comp_search.js", "extensions/BugModal/web/common_bug_modal.js", "extensions/BugModal/web/comments.js", - "extensions/BugModal/web/dropdown.js", "js/bugzilla-readable-status-min.js", "js/field.js", "js/comments.js", @@ -51,7 +50,6 @@ ); style_urls.unshift( "extensions/BugModal/web/common_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/header.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl index d92ad455d..38b6b572f 100644 --- a/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/header.html.tmpl @@ -53,7 +53,6 @@ "extensions/ProdCompSearch/web/js/prod_comp_search.js", "extensions/BugModal/web/bug_modal.js", "extensions/BugModal/web/comments.js", - "extensions/BugModal/web/dropdown.js", "js/bugzilla-readable-status-min.js", "js/field.js", "js/comments.js", @@ -65,7 +64,6 @@ ); style_urls.push( "extensions/BugModal/web/bug_modal.css", - "extensions/BugModal/web/dropdown.css", "skins/standard/bug_groups.css", "js/jquery/plugins/contextMenu/contextMenu.css" ); diff --git a/extensions/BugModal/web/dropdown.css b/extensions/BugModal/web/dropdown.css deleted file mode 100644 index e9a363c11..000000000 --- a/extensions/BugModal/web/dropdown.css +++ /dev/null @@ -1,53 +0,0 @@ -/* 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; - right: 0px; -} - -.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/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl b/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl index 5fcf5d72b..965e29639 100644 --- a/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl +++ b/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl @@ -8,7 +8,7 @@ [% USE Bugzilla %] [% IF Param('user_info_class').split(',').contains('GitHubAuth') %] - <span id="github_mini_login[% qs_suffix FILTER html %]" class="bz_default_hidden mini_login[% qs_suffix FILTER html %]"> + <span id="github_mini_login[% qs_suffix FILTER html %]" class="mini_login[% qs_suffix FILTER html %]"> <form method="post" action="[% urlbase FILTER html %]github.cgi"> <input type="hidden" name="github_secret" value="[% Bugzilla.github_secret FILTER html %]"> <input type="hidden" name="target_uri" value="[% Bugzilla.cgi.target_uri FILTER html %]"> diff --git a/extensions/MyDashboard/template/en/default/hook/global/common-links-action-links.html.tmpl b/extensions/MyDashboard/template/en/default/hook/global/header-action-links.html.tmpl index 518743ccf..bf25e7a88 100644 --- a/extensions/MyDashboard/template/en/default/hook/global/common-links-action-links.html.tmpl +++ b/extensions/MyDashboard/template/en/default/hook/global/header-action-links.html.tmpl @@ -7,6 +7,10 @@ #%] [% IF user.login %] - <li><span class="separator"> | </span> - <a href="[% urlbase FILTER none %]page.cgi?id=mydashboard.html">My Dashboard</a></li> + <li class="link-dashboard"> + <a href="[% urlbase FILTER none %]page.cgi?id=mydashboard.html" title="Show My Dashboard"> + <span class="icon" aria-hidden="true"></span> + <span class="label">My Dashboard</span> + </a> + </li> [% END %] diff --git a/extensions/Review/template/en/default/hook/global/header-message.html.tmpl b/extensions/Review/template/en/default/hook/global/header-badge.html.tmpl index e4bb1c687..aca61561e 100644 --- a/extensions/Review/template/en/default/hook/global/header-message.html.tmpl +++ b/extensions/Review/template/en/default/hook/global/header-badge.html.tmpl @@ -12,7 +12,7 @@ || user.needinfo_request_count %] -<a id="badge" +<a id="header-flags" class="badge" href="request.cgi?action=queue&requestee=[% user.login FILTER uri %]&group=type" title="Flags requested of you: [%- " review (" _ user.review_request_count _ ")" IF user.review_request_count -%] diff --git a/extensions/Review/web/styles/badge.css b/extensions/Review/web/styles/badge.css index e699b5825..53f539df8 100644 --- a/extensions/Review/web/styles/badge.css +++ b/extensions/Review/web/styles/badge.css @@ -5,12 +5,16 @@ * This Source Code Form is "Incompatible With Secondary Licenses", as * defined by the Mozilla Public License, v. 2.0. */ -#badge { - background-color: #c00; - font-size: small; +#header .badge { + display: flex; + align-items: center; + justify-content: center; + border-radius: 16px; + padding: 4px; + min-width: 16px; + height: 16px; + font-size: 14px; font-weight: bold; - padding: 0 5px; - border-radius: 10px; - margin: 0 5px; - color: #fff !important; + color: #FFF !important; + background-color: #C00; } @@ -27,8 +27,9 @@ my $vars = {}; # Yes, I really want to avoid two calls to the id method. my $user_id = $user->id; -# We only cache unauthenticated requests now, because invalidating is harder for logged in users. -my $can_cache = $user_id == 0; +# Disable content caching by browser because there will be different items on the global navigation +# before and after signed in. +my $can_cache = 0; # And log out the user if requested. We do this first so that nothing # else accidentally relies on the current login. diff --git a/js/comments.js b/js/comments.js index 12bc00d46..88ba49364 100644 --- a/js/comments.js +++ b/js/comments.js @@ -144,7 +144,7 @@ function goto_add_comments( anchor ){ anchor = (anchor || "add_comment"); // we need this line to expand the comment box document.getElementById('comment').focus(); - setTimeout(function(){ + setTimeout(function(){ document.location.hash = anchor; // firefox doesn't seem to keep focus through the anchor change document.getElementById('comment').focus(); @@ -178,3 +178,23 @@ function getText(element) { } return text; } + +/** + * If the URL contains a comment ID like #c10, scroll down the page to show the + * entire comment below the fixed global header. + */ +function scroll_comment_into_view() { + if (location.hash.match(/^#c\d+$/)) { + var $header = document.querySelector('#header'); + var $comment = document.querySelector(location.hash); + + if ($comment) { + window.setTimeout(function() { + window.scrollTo(0, $comment.offsetTop - $header.offsetHeight - 20); + }, 100); + } + } +} + +window.addEventListener('load', scroll_comment_into_view, { once: true }); +window.addEventListener('hashchange', scroll_comment_into_view); diff --git a/extensions/BugModal/web/dropdown.js b/js/dropdown.js index 181be9f73..32ce4696f 100644 --- a/extensions/BugModal/web/dropdown.js +++ b/js/dropdown.js @@ -33,19 +33,19 @@ $(function() { if ($content.is(':visible')) { e.preventDefault(); e.stopPropagation(); - var $li = $content.find('li'); + var $items = $content.find('[role="menuitem"]'); // if none focused select the first or last - var $any_focused = $content.find('a:focus'); + var $any_focused = $items.filter(':focus'); if ($any_focused.length == 0) { - var index = e.keyCode == 40 ? 0 : $li.length - 1; - var $link = $li.eq(index).find('a'); + var index = e.keyCode == 40 ? 0 : $items.length - 1; + var $link = $items.eq(index); $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'); + var move = $items.index($any_focused) + inc; + var $link = $items.eq(move % $items.length); $content.find('a').removeClass('active'); $link.addClass('active').focus(); } @@ -78,6 +78,13 @@ $(function() { }); function toggleDropDown(e, $button, $content, hide_only) { + // hide other expanded dropdown menu if any + var $expanded = $('.dropdown-button[aria-expanded="true"]'); + if ($expanded.length && !$expanded.is($button)) { + $('#' + $expanded.attr('aria-controls')).hide(); + $expanded.attr('aria-expanded', false); + } + // clear all active links $content.find('a').removeClass('active'); if ($content.is(':visible')) { diff --git a/js/global.js b/js/global.js index 102ab05af..b7b517631 100644 --- a/js/global.js +++ b/js/global.js @@ -10,10 +10,10 @@ * * The Original Code is the Bugzilla Bug Tracking System. * -* Contributor(s): +* Contributor(s): * Guy Pyrzak <guy.pyrzak@gmail.com> * Max Kanat-Alexander <mkanat@bugzilla.org> -* +* */ var BUGZILLA = $("#bugzilla-global").data("bugzilla"); @@ -85,30 +85,27 @@ function manage_old_lists() { function show_mini_login_form( suffix ) { - $('#login_link' + suffix).addClass('bz_default_hidden'); - $('#mini_login' + suffix).removeClass('bz_default_hidden'); - $('.mini_login' + suffix).removeClass('bz_default_hidden'); + hide_forgot_form(suffix); + $('#mini_login' + suffix).removeClass('bz_default_hidden').find('input[required]:first').focus(); $('#new_account_container' + suffix).addClass('bz_default_hidden'); return false; } function hide_mini_login_form( suffix ) { - $('#login_link' + suffix).removeClass('bz_default_hidden'); $('#mini_login' + suffix).addClass('bz_default_hidden'); $('#new_account_container' + suffix).removeClass('bz_default_hidden'); return false; } function show_forgot_form( suffix ) { - $('#forgot_link' + suffix).addClass('bz_default_hidden'); - $('#forgot_form' + suffix).removeClass('bz_default_hidden'); + hide_mini_login_form(suffix); + $('#forgot_form' + suffix).removeClass('bz_default_hidden').find('input[required]:first').focus(); $('#login_container' + suffix).addClass('bz_default_hidden'); return false; } function hide_forgot_form( suffix ) { - $('#forgot_link' + suffix).removeClass('bz_default_hidden'); $('#forgot_form' + suffix).addClass('bz_default_hidden'); $('#login_container' + suffix).removeClass('bz_default_hidden'); return false; diff --git a/qa/t/lib/QA/Util.pm b/qa/t/lib/QA/Util.pm index 4999e6f3b..0ef843ce7 100644 --- a/qa/t/lib/QA/Util.pm +++ b/qa/t/lib/QA/Util.pm @@ -203,7 +203,7 @@ sub file_bug_in_product { my $config = get_config(); $classification ||= "Unclassified"; - $sel->click_ok("link=New", undef, "Go create a new bug"); + $sel->click_ok('//*[@class="link-file"]//a', undef, "Go create a new bug"); $sel->wait_for_page_to_load(WAIT_TIME); my $title = $sel->get_title(); if ($sel->is_text_present("Select Classification")) { @@ -328,7 +328,7 @@ sub add_product { sub open_advanced_search_page { my $sel = shift; - $sel->click_ok("link=Search"); + $sel->click_ok('//*[@class="link-search"]//a'); $sel->wait_for_page_to_load(WAIT_TIME); my $title = $sel->get_title(); if ($title eq "Simple Search") { diff --git a/qa/t/test_create_user_accounts.t b/qa/t/test_create_user_accounts.t index 4d66f6862..99792367e 100644 --- a/qa/t/test_create_user_accounts.t +++ b/qa/t/test_create_user_accounts.t @@ -37,7 +37,7 @@ $sel->title_is("Request for new user account '$valid_account' submitted"); $sel->is_text_present_ok("A confirmation email has been sent"); # Try creating the same account again. It's too soon. -$sel->click_ok("link=Home"); +$sel->click_ok('//*[@id="header-title"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bugzilla Main Page"); $sel->is_text_present_ok("Open a New Account"); @@ -123,7 +123,7 @@ logout($sel); # Make sure that links pointing to createaccount.cgi are all deactivated. ok(!$sel->is_text_present("New Account"), "No link named 'New Account'"); -$sel->click_ok("link=Home"); +$sel->click_ok('//*[@id="header-title"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->refresh; $sel->wait_for_page_to_load_ok(WAIT_TIME); diff --git a/qa/t/test_keywords.t b/qa/t/test_keywords.t index 72a4f6049..0edffcc2f 100644 --- a/qa/t/test_keywords.t +++ b/qa/t/test_keywords.t @@ -128,7 +128,7 @@ $sel->wait_for_page_to_load(WAIT_TIME); $sel->title_is("Bug List"); $sel->is_text_present_ok("2 bugs found"); -$sel->click_ok("link=Search"); +$sel->click_ok('//*[@class="link-search"]//a'); $sel->wait_for_page_to_load(WAIT_TIME); $sel->title_is("Search for bugs"); $sel->remove_all_selections("product"); @@ -140,7 +140,7 @@ $sel->wait_for_page_to_load(WAIT_TIME); $sel->title_is("Bug List"); $sel->is_text_present_ok("One bug found"); -$sel->click_ok("link=Search"); +$sel->click_ok('//*[@class="link-search"]//a'); $sel->wait_for_page_to_load(WAIT_TIME); $sel->title_is("Search for bugs"); $sel->remove_all_selections("product"); diff --git a/qa/t/test_long_list_redirection.t b/qa/t/test_long_list_redirection.t index 2ee23f9a2..b2c22e66a 100644 --- a/qa/t/test_long_list_redirection.t +++ b/qa/t/test_long_list_redirection.t @@ -15,6 +15,6 @@ my ($sel, $config) = get_selenium(); $sel->open_ok("/$config->{bugzilla_installation}/long_list.cgi?id=1"); $sel->title_is("Full Text Bug Listing", "Display bug as format for printing"); -my $text = $sel->get_text("//h1"); +my $text = $sel->get_text('//*[@id="bugzilla-body"]//h1'); $text =~ s/[\r\n\t\s]+/ /g; is($text, 'Bug 1', 'Display bug 1 specifically'); diff --git a/qa/t/test_require_login.t b/qa/t/test_require_login.t index 7b39e7329..1cfd5b42f 100644 --- a/qa/t/test_require_login.t +++ b/qa/t/test_require_login.t @@ -76,6 +76,6 @@ set_parameters($sel, { "User Authentication" => {"requirelogin-off" => undef} }) logout($sel); # Make sure we can access random pages again. -$sel->click_ok("link=Search"); +$sel->click_ok('//*[@class="link-search"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_isnt("Log in to Bugzilla"); diff --git a/qa/t/test_show_all_products.t b/qa/t/test_show_all_products.t index 36f61e42c..ecc806980 100644 --- a/qa/t/test_show_all_products.t +++ b/qa/t/test_show_all_products.t @@ -25,7 +25,7 @@ set_parameters($sel, { "Bug Fields" => {"useclassification-on" => undef} }); # The admin is not a member of the "QA‑Selenium‑TEST" group, and so # cannot see the "QA‑Selenium‑TEST" product. -$sel->click_ok("link=New"); +$sel->click_ok('//*[@class="link-file"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Enter Bug"); $sel->click_ok("link=Other Products", undef, "Choose full product list"); @@ -38,7 +38,7 @@ logout($sel); # The "QA‑Selenium‑TEST" product must be visible to him. log_in($sel, $config, 'QA_Selenium_TEST'); -$sel->click_ok("link=New"); +$sel->click_ok('//*[@class="link-file"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Enter A Bug"); if ($sel->is_text_present('None of the above; my bug is in')) { @@ -48,8 +48,8 @@ if ($sel->is_text_present('None of the above; my bug is in')) { } $sel->click_ok('link=Other Products'); $sel->wait_for_page_to_load_ok(WAIT_TIME); -$sel->is_text_present_ok("QA-Selenium-TEST"); # For some unknown reason, Selenium doesn't like hyphens in links. +# $sel->is_text_present_ok("QA-Selenium-TEST"); # $sel->click_ok("link=QA-Selenium-TEST"); $sel->click_ok('//div[@id="choose_product"]//a[contains(@href, "QA-Selenium-TEST")]'); $sel->wait_for_page_to_load_ok(WAIT_TIME); diff --git a/qa/t/test_shutdown.t b/qa/t/test_shutdown.t index 33b9b426b..922307207 100644 --- a/qa/t/test_shutdown.t +++ b/qa/t/test_shutdown.t @@ -69,7 +69,7 @@ $sel->title_is("Parameters Updated"); # Accessing index.cgi should work again now. -$sel->click_ok("link=Home"); +$sel->click_ok('//*[@id="header-title"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Bugzilla Main Page"); logout($sel); diff --git a/qa/t/test_status_whiteboard.t b/qa/t/test_status_whiteboard.t index 94582dd54..2252b2317 100644 --- a/qa/t/test_status_whiteboard.t +++ b/qa/t/test_status_whiteboard.t @@ -71,7 +71,7 @@ $sel->is_text_present_ok("2 bugs found"); set_parameters($sel, {'Bug Fields' => {'usestatuswhiteboard-off' => undef}}); # Show detailed bug information panel on advanced search ok($sel->create_cookie('TUI=information_query=1'), 'Show detailed bug information'); -$sel->click_ok("link=Search"); +$sel->click_ok('//*[@class="link-search"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Search for bugs"); ok(!$sel->is_text_present("Whiteboard:"), "Whiteboard label no longer displayed"); diff --git a/qa/t/test_target_milestones.t b/qa/t/test_target_milestones.t index 6aa211428..7558f0525 100644 --- a/qa/t/test_target_milestones.t +++ b/qa/t/test_target_milestones.t @@ -68,7 +68,7 @@ ok($text =~ /OK, you have a new search named selenium_m0./, "New search named se set_parameters($sel, { "Bug Fields" => {"usetargetmilestone-off" => undef} }); -$sel->click_ok("link=Search"); +$sel->click_ok('//*[@class="link-search"]//a'); $sel->wait_for_page_to_load_ok(WAIT_TIME); $sel->title_is("Search for bugs"); ok(!$sel->is_text_present("Target Milestone:"), "The target milestone field is no longer displayed"); diff --git a/skins/standard/admin.css b/skins/standard/admin.css index fd0ff2808..0b9d3e740 100644 --- a/skins/standard/admin.css +++ b/skins/standard/admin.css @@ -324,6 +324,13 @@ input[disabled] { width: 70%; } +body.mfa-warning #mfa-select button { + outline: none; + border-color: #FF5300; + border-width: 1px; + box-shadow: 2px 2px 15px #FF5300; +} + .flex { display: flex; flex-flow: row; diff --git a/skins/standard/fonts/MaterialIcons-Regular.woff b/skins/standard/fonts/MaterialIcons-Regular.woff Binary files differnew file mode 100644 index 000000000..b648a3eea --- /dev/null +++ b/skins/standard/fonts/MaterialIcons-Regular.woff diff --git a/skins/standard/fonts/MaterialIcons-Regular.woff2 b/skins/standard/fonts/MaterialIcons-Regular.woff2 Binary files differnew file mode 100644 index 000000000..9fa211252 --- /dev/null +++ b/skins/standard/fonts/MaterialIcons-Regular.woff2 diff --git a/skins/standard/global.css b/skins/standard/global.css index 34d5ccc51..3b58c1d63 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -21,8 +21,19 @@ * Svetlana Harisova <light@rathedg.com> * Marc Schumann <wurblzap@gmail.com> * Pascal Held <paheld@gmail.com> + * Kohei Yoshino <kohei.yoshino@gmail.com> */ +/* fonts (begin) */ + @font-face{ + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(fonts/MaterialIcons-Regular.woff2) format('woff2'), + url(fonts/MaterialIcons-Regular.woff) format('woff'); + } +/* fonts (end) */ + /* global (begin) */ body { font-family: sans-serif; @@ -41,106 +52,312 @@ /* header (begin) */ #header { - margin-bottom: 1em; + position: absolute; + top: 0; + left: 0; + z-index: 1000; + width: 100%; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + color: #555; + background-color: #FFF; } - #header form, #header form input, - #footer form, #footer form input - { - font-size: 95%; - display: inline; + @media only screen and (min-device-width: 1024px) { + #header { + position: fixed; /* Make the header fixed on desktop */ + } } - #header .links { - border-left: 1px solid #747E93; - border-right: 1px solid #747E93; - border-bottom: 1px solid #747E93; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - padding: 0.5em; + #header a, + #header a:visited, + #header a:hover { + color: #555; + text-decoration: none; } - #lang_links_container { - float: right; + #header a, + #header button, + #header input { + outline: 0; /* Hide outline on Chrome & Safari */ } - #lang_links_container .links { - border: none; - padding: .5em; + + #header button::-moz-focus-inner { + border: 0; /* Hide outline on Firefox */ } - .lang_current { - font-weight: bold; + #header button * { + pointer-events: none; /* Make sure button is clickable on Chrome & Safari */ } - #message { - border: 1px solid green; - margin: 0.3em 0em; - padding: 0.3em 0.5em; - color: green; + #header .inner { + display: flex; + align-items: center; + position: relative; + margin: 0 auto; + padding: 8px 0; + width: 1024px; + height: 32px; } - form.mini_login input.bz_login { - width: 10em; + #header .inner > * { + flex: none; + margin: 0 8px; } - form.mini_login input.bz_password { - width: 6em; + + #header .icon { + display: inline-block; + width: 24px; + font-size: 20px; + line-height: 1; + font-family: 'Material Icons'; + vertical-align: middle; + color: #777; } - form.mini_login input.bz_remember { - margin: 0; + + #header .title { + margin: 0 !important; + font-size: 20px; + font-weight: normal; } - .bz_mini_login_help { - color: #777; + + #header .title a, + #header .links a { + display: flex; + align-items: center; + border-radius: 4px; + padding: 0 8px; + height: 32px; + } + + #header .title a:hover, + #header .title a:focus, + #header .links a:hover, + #header .links a:focus, + #header-tools-menu-button:hover, + #header-tools-menu-button:focus, + #header .dropdown-content a.active { + background-color: rgba(0, 0, 0, .05) !important; } -/* header (end) */ + #header .title a:active, + #header .links a:active, + #header-tools-menu-button:active, + #header .dropdown-content a:active { + background-color: rgba(0, 0, 0, .1) !important; + } -/* banner (begin) */ - #banner { + #header form.quicksearch { + display: block; } -/* banner (end) */ + #header .searchbox-outer { + position: relative; + width: 240px; + height: 32px; + } -/* titles (begin) */ - #titles { + #header .searchbox-outer button { + position: absolute; + top: 4px; + left: 4px; + border: 0; + padding: 0; + width: 24px; + height: 24px; + background: transparent; + box-shadow: none; + } + + #header .searchbox-outer button .icon::before { + content: '\E8B6'; + } + + #header #quicksearch_top { + box-sizing: border-box; + border-color: rgba(0, 0, 0, .1); + border-radius: 4px; + padding: 0 8px 0 32px; width: 100%; - background-color: #404D6C; - color: #fff; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - font-size: 110%; - margin: 0; - padding: 0.5em; - vertical-align: bottom; + height: 100%; + background-color: rgba(0, 0, 0, .05); + box-shadow: none; + font-size: 14px !important; + line-height: 32px; } - #titles a { - color: #fff; + #header #quicksearch_top:hover { + border-color: rgba(0, 0, 0, .2); + box-shadow: 0 0 2px rgba(0, 0 ,0, .2); } - #titles p { - margin: 0; + #header #quicksearch_top:focus { + border-color: #42a4e0; + background-color: transparent; + box-shadow: 0 0 0 2px rgba(73, 173, 227, .4); + } + + #header nav { + flex: auto !important; + display: flex; + align-items: center; + margin: 0 !important; + } + + #header .links { + flex: none; + display: flex; + font-size: 14px; + } + + #header .link-browse .icon::before { + content: '\E8EF'; + } + + #header .link-search .icon::before { + content: '\E8A0'; + } + + #header .link-file .icon::before { + content: '\E254'; + } + + #header .link-dashboard .icon::before { + content: '\E871'; + } + + #header .dropdown { + flex: none; + } + + #header .dropdown-button { + display: block; padding: 0; + color: inherit; + background: transparent; + box-shadow: none; } - #titles #title { - font-weight: bold; - white-space: nowrap; + #header-tools-menu-button { + width: 32px; + height: 32px; + border-radius: 4px; } - #titles #subtitle { - font-weight: normal; - width: 100%; - text-align: center; + #header-tools-menu-button .icon { + text-indent: -.7em; + letter-spacing: -.7em; } - #titles #information { - font-weight: normal; - text-align: right; - font-size: 90%; + #header-tools-menu-button .icon::before { + content: '\E5CC\E5CC'; + } + + #header-account-menu-button img { + display: block; + border-radius: 50%; + } + + #header-account-menu-button .icon::before { + font-size: 32px; + content: '\E853'; + } + + #header .dropdown-content { + top: calc(100% + 4px); + right: -4px; + border-color: #BBB #999 #777; + border-radius: 4px; + padding: 4px 0; + min-width: 160px; + max-width: 240px; + background-color: #FCFCFC; + box-shadow: 0 2px 8px rgba(0,0,0,.3); + } + + #header .dropdown-content::before, + #header .dropdown-content::after { + content: ''; + display: block; + width: 0; + height: 0; + position: absolute; + right: 10px; + border-width: 8px; + border-color: transparent; + border-style: solid; + } + + #header .dropdown-content::before { + top: -17px; + border-bottom-color: #BBB; + } + + #header .dropdown-content::after { + top: -16px; + border-bottom-color: #FFF; + } + + #header .dropdown-content a, + #header .dropdown-content li > div { + padding: 2px 16px; + line-height: 1.5; + white-space: normal; + background-color: transparent; + } + + #header .account-label * { + overflow: hidden; white-space: nowrap; + text-overflow: ellipsis; } -/* titles (end) */ + #header .account-label .name { + font-size: 16px; + } + + #header .account-label .email { + font-size: 12px; + color: #666; + } + + #header .dropdown-separator { + height: 0; + margin: 4px 0; + border-color: #BBB; + } + + #header-login .mini-popup { + position: absolute; + top: 48px; + right: 0; + display: flex; + align-items: center; + padding: 8px; + background-color: #FFF; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + } + + #header-login .mini-popup form { + display: flex; + align-items: center; + } + + #header-login .mini-popup input { + margin: 0 4px; + } + + #header-login .mini-popup .close-button { + padding: 0; + width: 32px; + justify-content: center; + text-align: center; + } + + #header-login .mini-popup .close-button .icon::before { + content: '\E5CD'; + } +/* header (end) */ /* footer (begin) * See also the "header" section for styles that apply @@ -149,9 +366,9 @@ #footer { display: flex; clear: both; - margin: 2em 0 0; + margin: 15px 0 0; border-top: 1px solid rgba(0, 0, 0, 0.1); - padding: 2em; + padding: 8px; color: #bbb; background-color: #fff; line-height: 1.5; @@ -161,8 +378,13 @@ flex: none; display: flex; align-items: center; - width: 25%; - min-width: 20em; + border-right: 1px solid #DDD; + padding: 16px 24px 16px 16px; + } + + #footer .org-links { + display: flex; + align-items: center; } #footer .org-links h1 { @@ -182,7 +404,7 @@ #footer .org-links ul { display: flex; - margin: .5em 0 0; + margin: 0 0 0 16px; padding: 0; } @@ -191,7 +413,7 @@ } #footer .org-links li:not(:last-child) { - margin-right: 1.5em; + margin-right: 16px; } #footer #useful-links { @@ -199,7 +421,7 @@ display: flex; flex-direction: column; justify-content: center; - margin: 0; + margin: 0 0 0 24px; padding: 0; } @@ -221,20 +443,6 @@ #footer .links { vertical-align: top; } - - #footer .links .quicksearch_form { - display: none; - } - - #footer .form { - display: block; - margin-top: 1em; - } - - #footer .form input { - padding: 1px 2px; - margin-top: 3px; - } /* footer (end) */ /* link lists (begin) */ @@ -879,11 +1087,11 @@ body, td, th, input, select, option, optgroup, button, .text_input { font-family: "Fira Sans", "Open Sans", "Helvetica Neue", Arial, Helvetica, sans-serif; } -a, #header a, #header a:visited, #footer a, #footer a:visited { +a, #footer a, #footer a:visited { color: #0095dd; } -a:hover, #header a:hover, #footer a:hover { +a:hover, #footer a:hover { color: #00539f; } @@ -928,189 +1136,31 @@ hr { display: none; } -#header { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - background: #e5e3dc; - background: -moz-linear-gradient(#e5e3dc, #ecebe5); - background: -webkit-linear-gradient(#e5e3dc, #ecebe5); - background: linear-gradient(#e5e3dc, #ecebe5); - border-radius: 0; - border-bottom: 1px solid rgba(0, 0, 0, 0.2); - border-top: 2px solid rgb(255, 255, 255); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); - margin: -15px -15px 0 -15px; -} - #mfa-warning { - outline: none; - border-color: #FF5300; - border-width: 1px; - box-shadow: 2px 2px 15px #FF5300; - color: black; - padding: 2px 2px 2px 2px; -} - -body.mfa-warning #mfa-select button { - outline: none; - border-color: #FF5300; - border-width: 1px; - box-shadow: 2px 2px 15px #FF5300; -} - - -#header .subheader { - text-align: left; - padding-left: 10px; -} - -#header .wrapper { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - margin: -1px auto 0px; - width: 99%; -} - -#header .wrapper:after { - clear: both; - content: "."; - display: block; - height: 0; - visibility: hidden; -} - -#titles { - width: 100%; - background-color: transparent; - padding: 0 1em 0 1em; -} - -#information { - text-align: left; - padding-left: 2em; -} - -#title { - width: 150px; - font-size: 120%; -} - -#moz_login { - text-align: right; - color: #404040; -} - -#header .links { - background: transparent; - border: none; - border-radius: 0; - color: #404040; - position: relative; - width: 50%; -} - -#header .links { - width: auto; -} - -.login-links ul { -} - -.login-links li { - display: inline; -} - -.links a { - margin: 0 10px 0 10px; -} - -.links .home { - font-weight: bold; -} - -.links .separator { - display: none; -} - -#quicksearch_top, #quicksearch_main { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - background: url(search.png) 5px center no-repeat, #fafafa; - background: url(search.png) 5px center no-repeat, -moz-linear-gradient(#fafafa, #fff); - background: url(search.png) 5px center no-repeat, -webkit-linear-gradient(#fafafa, #fff); - background: url(search.png) 5px center no-repeat, linear-gradient(#fafafa, #fff); - padding: .4em 1em .45em 26px; - width: 200px; -} - -#header .form a { - margin: 0; -} - -.links .dropdown { - background: rgba(0, 0, 0, 0.05); - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: .25em; - display: inline-block; - padding: 4px 8px; - position: relative; - cursor: default; -} - -.links .dropdown .anchor { - background-image: url(../../images/dropdown.png); - background-position: right center; - background-repeat: no-repeat; - display: inline-block; - min-width: 110px; - padding-right: 15px; -} - -.links .dropdown ul { - background: #fafafa; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0 0 .25em .25em; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); - display: none; - padding: 4px; - position: absolute; - right: -1px; - margin-top: 4px; - z-index: 2; - text-align: left; -} - -.links .dropdown:hover ul { - display: block; -} - -.links .dropdown li { - display: block; -} - -.links .dropdown:hover { - border-bottom-right-radius: 0; -} - -.links .dropdown li { - display: block; + margin: 0 -15px; + padding: 10px 15px; + color: #FFF; + background-color: #FF5300; } #bugzilla-body { background: none; border: none; color: #404040; - margin: 10px auto 15px; - padding: 0; - width: 99%; + margin: 15px auto; } #bugzilla-body th { white-space: nowrap; } +#message { + border: 1px solid green; + margin: 0.3em 0em; + padding: 0.3em 0.5em; + color: green; +} + /* Home */ /*#page-index { @@ -1457,10 +1507,6 @@ table.edit_form hr { padding: 2px 2px 2px 1px; } -#links-actions, #links-saved { - margin-left: -10px; -} - button, input[type=submit], input[type=button], #commit, #commit_top, #header .btn, #header input[type=submit] { background-color: #43a6e2; background-image: -moz-linear-gradient(#43a6e2,#277ac1); @@ -1591,7 +1637,7 @@ table.tabs { body { margin: 0; - padding: 15px; + padding: 50px 15px 15px; } #header .btn, #header .txt { @@ -1654,3 +1700,54 @@ a.controller { .vcard a .fn:after, .vcard a .ln:after { content: ' \25BE'; } + +/******************/ +/* Dropdown Menus */ +/******************/ + +/* 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; + right: 0px; +} + +.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/skins/standard/index.css b/skins/standard/index.css index f7533c6c4..9fe9202db 100644 --- a/skins/standard/index.css +++ b/skins/standard/index.css @@ -18,6 +18,7 @@ #page-index { + margin: 50px 0; padding: 0.2em 0.2em 0.15em 0.2em; max-width: none; } diff --git a/t/bmo/passwords.t b/t/bmo/passwords.t index 249cdfb3c..83bea60be 100644 --- a/t/bmo/passwords.t +++ b/t/bmo/passwords.t @@ -198,7 +198,7 @@ sub click_and_type { my ($sel, $name, $text) = @_; eval { - my $el = $sel->find_element(qq{//input[\@name="$name"]}, 'xpath'); + my $el = $sel->find_element(qq{//*[\@id="bugzilla-body"]//input[\@name="$name"]}, 'xpath'); $el->click(); $sel->send_keys_to_active_element($text); pass("found $name and typed $text"); @@ -244,7 +244,7 @@ sub login { $sel->title_is("Log in to Bugzilla"); click_and_type($sel, 'Bugzilla_login', $login); click_and_type($sel, 'Bugzilla_password', $password); - submit($sel, '//input[@name="GoAheadAndLogIn"]'); + submit($sel, '//*[@id="bugzilla-body"]//input[@name="GoAheadAndLogIn"]'); } sub login_ok { diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl index 1f38f18b7..a64384c98 100644 --- a/template/en/default/account/auth/login-small.html.tmpl +++ b/template/en/default/account/auth/login-small.html.tmpl @@ -31,7 +31,6 @@ [% login_target = urlbase _ login_target %] <li id="mini_login_container[% qs_suffix %]"> - <span class="separator">| </span> [% connector = "?" %] [% IF cgi.request_method == "GET" AND cgi.query_string %] [% connector = "&" %] @@ -40,37 +39,38 @@ <a id="login_link[% qs_suffix %]" href="[% script_url FILTER html %]" class='show_mini_login_form' data-qs-suffix="[% qs_suffix FILTER html %]">Log In</a> + <div id="mini_login[% qs_suffix FILTER html %]" class="mini-popup mini_login bz_default_hidden"> [% Hook.process('additional_methods') %] - - <form action="[% login_target FILTER html %]" method="POST" - class="mini_login bz_default_hidden " - id="mini_login[% qs_suffix FILTER html %]" - data-qs-suffix="[% qs_suffix FILTER html %]" - > - - <input id="Bugzilla_login[% qs_suffix FILTER html %]" + + <form action="[% login_target FILTER html %]" method="POST" + data-qs-suffix="[% qs_suffix FILTER html %]"> + + <input id="Bugzilla_login[% qs_suffix FILTER html %]" class="bz_login" name="Bugzilla_login" title="Login" - placeholder="email address" + placeholder="Email" + aria-label="Email" type="email" required > <input class="bz_password" - id="Bugzilla_password[% qs_suffix FILTER html %]" + id="Bugzilla_password[% qs_suffix FILTER html %]" name="Bugzilla_password" type="password" title="Password" + placeholder="Password" + aria-label="Password" required > - <input class="bz_password bz_default_hidden bz_mini_login_help" type="text" + <input class="bz_password bz_default_hidden bz_mini_login_help" type="text" id="Bugzilla_password_dummy[% qs_suffix %]" value="password" title="Password" > [% IF Param('rememberlogin') == 'defaulton' || - Param('rememberlogin') == 'defaultoff' + Param('rememberlogin') == 'defaultoff' %] - <input type="checkbox" id="Bugzilla_remember[% qs_suffix %]" + <input type="checkbox" id="Bugzilla_remember[% qs_suffix %]" name="Bugzilla_remember" value="on" class="bz_remember" [%+ "checked" IF Param('rememberlogin') == "defaulton" %]> <label for="Bugzilla_remember[% qs_suffix %]">Remember</label> @@ -80,23 +80,27 @@ <input type="submit" name="GoAheadAndLogIn" value="Log in" class="check_mini_login_fields" id="log_in[% qs_suffix %]"> - <a href="#" id="hide_mini_login[% qs_suffix FILTER html %]" - class="hide_mini_login_form" data-qs-suffix="[% qs_suffix FILTER html %]">[x]</a> + <a href="#" id="hide_mini_login[% qs_suffix FILTER html %]" aria-label="Close" + class="close-button hide_mini_login_form" data-qs-suffix="[% qs_suffix FILTER html %]"> + <span class="icon" aria-hidden="true"></span> + </a> </form> + </div> </li> <li id="forgot_container[% qs_suffix %]"> - <span class="separator">| </span> <a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot" class='show_forgot_form' data-qs-suffix="[% qs_suffix FILTER html %]">Forgot Password</a> - <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]" - class="mini_forgot bz_default_hidden"> - <label for="login[% qs_suffix FILTER html %]">Login:</label> - <input type="text" name="loginname" size="20" id="login[% qs_suffix FILTER html %]"> - <input id="forgot_button[% qs_suffix %]" value="Reset Password" + <div id="forgot_form[% qs_suffix %]" class="mini-popup mini_forgot bz_default_hidden"> + <form action="token.cgi" method="post"> + <input type="email" name="loginname" size="20" placeholder="Email" aria-label="Email" required> + <input id="forgot_button[% qs_suffix %]" value="Reset Password" type="submit"> <input type="hidden" name="a" value="reqpw"> <input type="hidden" id="token[% qs_suffix FILTER html %]" name="token" value="[% issue_hash_token(['reqpw']) FILTER html %]"> - <a href="#" class="hide_forgot_form" data-qs-suffix="[% qs_suffix FILTER html %]">[x]</a> + <a href="#" class="close-button hide_forgot_form" aria-label="Close" data-qs-suffix="[% qs_suffix FILTER html %]"> + <span class="icon" aria-hidden="true"></span> + </a> </form> + </div> </li> diff --git a/template/en/default/global/common-links.html.tmpl b/template/en/default/global/common-links.html.tmpl deleted file mode 100644 index c2c054b24..000000000 --- a/template/en/default/global/common-links.html.tmpl +++ /dev/null @@ -1,57 +0,0 @@ -[%# 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> - # Svetlana Harisova <light@rathedg.com> - #%] - -[% DEFAULT qs_suffix = "" %] -[% USE Bugzilla %] - -<ul class="links"> - <li><a href="./">Home</a></li> - <li><span class="separator">| </span><a href="enter_bug.cgi">New</a></li> - <li><span class="separator">| </span><a href="describecomponents.cgi">Browse</a></li> - <li><span class="separator">| </span><a href="query.cgi">Search</a></li> - - <li class="form quicksearch_form"> - <span class="separator">| </span> - <form action="buglist.cgi" method="get" - class='quicksearch_check_empty'> - <input class="txt" type="text" id="quicksearch[% qs_suffix FILTER html %]" name="quicksearch" - title="Quick Search" value="[% quicksearch FILTER html %]"> - <input class="btn" type="submit" value="Search" - id="find[% qs_suffix FILTER html %]"> - [%-# Work around FF bug: keep this on one line %]</form> - [<a href="page.cgi?id=quicksearch.html" title="Quicksearch Help">help</a>] - </li> - - <li><span class="separator">| </span><a href="report.cgi">Reports</a></li> - - [% Hook.process('action-links') %] - -</ul> - -[% Hook.process("link-row") %] -[% BLOCK link_to_documentation %] - [% IF doc_section && Param('docs_urlbase') %] - <li> - <span class="separator">| </span> - <a href="[% docs_urlbase _ doc_section FILTER html %]" target="_blank">Help</a> - </li> - [% END %] -[% END %] diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl index 90cdbd4e8..a7aed895e 100644 --- a/template/en/default/global/header.html.tmpl +++ b/template/en/default/global/header.html.tmpl @@ -19,6 +19,7 @@ # Vaskin Kissoyan <vkissoyan@yahoo.com> # Vitaly Harisov <vitaly@rathedg.com> # Svetlana Harisova <light@rathedg.com> + # Kohei Yoshino <kohei.yoshino@gmail.com> #%] [%# INTERFACE: @@ -90,8 +91,7 @@ # value of title anyway. To get around that problem we explicitly # set header's default value here only if it is undefined. %] [% IF !header.defined %][% header = title %][% END %] -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE html> <html lang="en"> <head> [%- js_BUGZILLA = { @@ -124,6 +124,7 @@ END; %] + <meta name="viewport" content="width=1024"> <meta name="generator" content="[% terms.Bugzilla _ " " _ constants.BUGZILLA_VERSION FILTER html %]"> <meta name="bugzilla-global" content="dummy" id="bugzilla-global" data-bugzilla="[% json_encode(js_BUGZILLA) FILTER html %]"> @@ -173,7 +174,7 @@ [% FOREACH jq_name = jquery.unique %] [% starting_js_urls.push("js/jquery/plugins/$jq_name/${jq_name}-min.js") %] [% END %] - [% starting_js_urls.push('js/global.js') %] + [% starting_js_urls.push('js/global.js', 'js/dropdown.js') %] [% FOREACH asset_url = concatenate_js(starting_js_urls) %] [% PROCESS format_js_link %] @@ -244,96 +245,148 @@ # 'bannerhtml' #%] -<div id="header"> - - <div class="wrapper"> - <table border="0" cellspacing="0" cellpadding="0" id="titles"> - <tr> - <td id="title"> - <a href="./" title="Home">[% terms.BugzillaTitle %]</a> - </td> - <td> - [% Hook.process("message") %] - [% IF Bugzilla.request_cache.mfa_warning - AND user.mfa_required_date - AND NOT Bugzilla.request_cache.on_mfa_page %] - <span id="mfa-warning"> - Please <a href="userprefs.cgi?tab=mfa">enable two-factor authentication</a> - [% IF Param('mfa_group_grace_period') %] - before <i>[% user.mfa_required_date FILTER time %]</i>. - [% ELSE %] - now. - [% END %] - </span> - [% END %] - </td> - <td id="moz_login"> +<header id="header" role="banner"> + <div class="inner"> + <h1 id="header-title" class="title"><a href="./" title="Go to home page">[% terms.BugzillaTitle %]</a></h1> + <form role="search" id="header-search" class="quicksearch quicksearch_check_empty" action="buglist.cgi"> + <div class="searchbox-outer"> + <input role="searchbox" id="quicksearch_top" name="quicksearch" + value="[% quicksearch FILTER html %]" placeholder="Search [% terms.Bugs %]" + title="Search [% terms.bugs %] by keywords"> + <button type="submit" id="find_top" aria-label="Submit"> + <span class="icon" aria-hidden="true"></span> + </button> + </div> + </form> + <nav id="header-nav"> + <ul class="links"> + <li class="link-browse"> + <a href="describecomponents.cgi" title="Browse [% terms.bugs %] by component"> + <span class="icon" aria-hidden="true"></span> + <span class="label">Browse</span> + </a> + </li> + <li class="link-search"> + <a href="query.cgi?format=advanced" title="Search [% terms.bugs %] using various criteria"> + <span class="icon" aria-hidden="true"></span> + <span class="label">Advanced Search</span> + </a> + </li> [% IF user.id %] - <ul class="links"> - <li class="dropdown"> - <span class="anchor">[% user.login FILTER html %]</span> - <ul> - [% IF user.showmybugslink %] - [% filtered_username = user.login FILTER uri %] - <li><a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a></li> - [% END %] - <li><a href="page.cgi?id=mydashboard.html">My Dashboard</a></li> - <li><a href="user_profile">My Profile</a></li> - <li><a href="page.cgi?id=user_activity.html&action=run&who=[% user.login FILTER uri %]">My Activity</a></li> - <li><a href="request.cgi?requester=[% user.login FILTER uri %]&requestee=[% user.login FILTER uri %]&do_union=1&group=type&action=queue">My Requests</a></li> - <li><a href="userprefs.cgi">Preferences</a></li> - [% IF user.in_group('tweakparams') || user.in_group('editusers') || user.can_bless - || (Param('useclassification') && user.in_group('editclassifications')) - || user.in_group('editcomponents') || user.in_group('admin') || user.in_group('creategroups') - || user.in_group('editkeywords') || user.in_group('bz_canusewhines') - || user.get_products_by_permission("editcomponents").size %] - <li><a href="admin.cgi">Administration</a></li> - [% END %] - [% IF user.authorizer.can_logout %] - <li><a href="index.cgi?logout=1">Log out</a></li> - [% END %] - [% IF sudoer %] - <li> - <a href="relogin.cgi?action=end-sudo">End sudo session impersonating [% user.login FILTER html %]</a> - </li> - [% END %] - </ul> + <li class="link-file"> + <a href="enter_bug.cgi" title="File a new [% terms.bug %]"> + <span class="icon" aria-hidden="true"></span> + <span class="label">New [% terms.Bug %]</span> + </a> + </li> + [% END %] + [% Hook.process('action-links') %] + </ul> + <div class="dropdown"> + <button type="button" id="header-tools-menu-button" class="dropdown-button minor" title="More tools…" + aria-label="More tools…" aria-expanded="false" aria-haspopup="true" aria-controls="header-tools-menu"> + <span class="icon" aria-hidden="true"></span> + </button> + <ul class="dropdown-content" id="header-tools-menu" role="menu" style="display:none;"> + [% IF user.showmybugslink %] + [% filtered_username = user.login FILTER uri %] + <li role="presentation"> + <a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]" role="menuitem" tabindex="-1">My [% terms.Bugs %]</a> + </li> + [% END %] + [% IF user.id %] + <li role="presentation"> + <a href="request.cgi?requester=[% user.login FILTER uri %]&requestee=[% user.login FILTER uri %]&do_union=1&group=type&action=queue" role="menuitem" tabindex="-1">My Requests</a> + </li> + [% END %] + <li role="presentation"> + <a href="report.cgi" role="menuitem" tabindex="-1">Reports</a> + </li> + [% IF user.in_group('tweakparams') || user.in_group('editusers') || user.can_bless + || (Param('useclassification') && user.in_group('editclassifications')) + || user.in_group('editcomponents') || user.in_group('admin') || user.in_group('creategroups') + || user.in_group('editkeywords') || user.in_group('bz_canusewhines') + || user.get_products_by_permission("editcomponents").size %] + <li role="presentation"> + <a href="admin.cgi" role="menuitem" tabindex="-1">Administration</a> </li> - </ul> - [% ELSE %] - <ul class="login-links"> - [% IF Param('createemailregexp') - && user.authorizer.user_can_create_account %] - <li id="moz_new_account_container_top"><a href="createaccount.cgi">New Account</a> - [% IF use_login_page %] <span class="separator">| </span> [% END %] - </li> - [% END %] - - [% IF use_login_page %] - <li> - <a href="[% urlbase FILTER html %]login">Log In</a> - </li> - [% ELSE %] - [%# Only display one login form when we're on a LOGIN_REQUIRED page. That - # way, we're guaranteed that the user will use the form that has - # hidden_fields in it (the center form) instead of this one. Also, it's - # less confusing to have one form (as opposed to three) when you're - # required to log in. - #%] - [% IF user.authorizer.can_login && !Bugzilla.page_requires_login %] - [% PROCESS "account/auth/login-small.html.tmpl" qs_suffix = "_top" %] - [% END %] - [% END %] - </ul> + [% END %] + [% IF Param('docs_urlbase') %] + <li role="separator" class="dropdown-separator"></li> + <li role="presentation"> + <a href="[% docs_urlbase FILTER html %]" role="menuitem" tabindex="-1">Documentation</a> + </li> + [% END %] + </ul> + </div> + </nav> + [% Hook.process("badge") %] + [% IF user.id %] + <div id="header-account" class="dropdown"> + <button type="button" id="header-account-menu-button" class="dropdown-button minor" title="Account" + aria-label="Account" aria-expanded="false" aria-haspopup="true" aria-controls="header-account-menu"> + [% IF user.gravatar %] + <img src="[% user.gravatar FILTER html %]" width="32" height="32" alt=""> + [% ELSE %] + <span class="icon" aria-hidden="true"></span> + [% END %] + </button> + <ul class="dropdown-content" id="header-account-menu" role="menu" style="display:none;"> + <li role="presentation"> + <div href="user_profile" class="account-label"> + <div class="name">[% user.name FILTER html %]</div> + <div class="email">[% user.login FILTER html %]</div> + </div> + </li> + <li role="separator" class="dropdown-separator"></li> + <li role="presentation"> + <a href="user_profile" role="menuitem" tabindex="-1">My Profile</a> + </li> + <li role="presentation"> + <a href="page.cgi?id=user_activity.html&action=run&who=[% user.login FILTER uri %]" role="menuitem" + tabindex="-1">My Activity</a> + </li> + <li role="presentation"> + <a href="userprefs.cgi" role="menuitem" tabindex="-1">Preferences</a> + </li> + [% IF user.authorizer.can_logout %] + <li role="separator" class="dropdown-separator"></li> + <li role="presentation"> + <a href="index.cgi?logout=1" role="menuitem" tabindex="-1">Log out</a> + </li> + [% END %] + [% IF sudoer %] + <li role="presentation"> + <a href="relogin.cgi?action=end-sudo" role="menuitem" tabindex="-1">End sudo session impersonating [% user.login FILTER html %]</a> + </li> + [% END %] + </ul> + </div> + [% ELSE %] + <ul id="header-login" class="links"> + [% IF Param('createemailregexp') && user.authorizer.user_can_create_account %] + <li id="moz_new_account_container_top"><a href="createaccount.cgi">New Account</a></li> [% END %] - </td> - </tr> - </table> - - [% PROCESS "global/common-links.html.tmpl" qs_suffix = "_top" %] - + [% IF user.authorizer.can_login %] + [% PROCESS "account/auth/login-small.html.tmpl" qs_suffix = "_top" %] + [% END %] + </ul> + [% END %] </div> -</div> [%# header %] +</header> [%# header %] + +[% IF Bugzilla.request_cache.mfa_warning + AND user.mfa_required_date + AND NOT Bugzilla.request_cache.on_mfa_page %] + <aside id="mfa-warning"> + Please <a href="userprefs.cgi?tab=mfa">enable two-factor authentication</a> + [% IF Param('mfa_group_grace_period') %] + before <i>[% user.mfa_required_date FILTER time %]</i>. + [% ELSE %] + now. + [% END %] + </aside> +[% END %] <div id="bugzilla-body"> diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl index 467719028..90a3268cb 100644 --- a/template/en/default/global/useful-links.html.tmpl +++ b/template/en/default/global/useful-links.html.tmpl @@ -26,10 +26,6 @@ [% PROCESS global/variables.none.tmpl %] <ul id="useful-links"> - <li id="links-actions"> - [% PROCESS "global/common-links.html.tmpl" qs_suffix = "_bottom" %] - </li> - [%# Saved searches %] [% IF user.showmybugslink OR user.queries.size |