/* 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. */ /** * Reference or define the Bugzilla app namespace. * @namespace */ var Bugzilla = Bugzilla || {}; /** * Reference or define the Review namespace. * @namespace */ Bugzilla.Review = Bugzilla.Review || {}; /** * Provide the Badge functionality that shows the current review summary in the dropdown. */ Bugzilla.Review.Badge = class Badge { /** * Get a new Badge instance. * @returns {Badge} New Badge instance. */ constructor() { this.initialized = false; this.$button = document.querySelector('#header-requests-menu-button'); this.$panel = document.querySelector('#header-requests .dropdown-panel'); this.$loading = document.querySelector('#header-requests .dropdown-panel .loading'); if (this.$loading) { this.$button.addEventListener('mouseover', () => this.init(), { once: true }); this.$button.addEventListener('focus', () => this.init(), { once: true }); } } /** * Initialize the Reviews dropdown menu. */ async init() { if (this.initialized) { return; } this.initialized = true; const url = this.$panel.querySelector('footer a').href.replace(/type$/, 'requestee') + '&ctype=json'; const response = await fetch(url, { credentials: 'same-origin' }); const _requests = response.ok ? await response.json() : []; if (!response.ok) { this.$loading.innerHTML = 'Couldn’t load requests for you.
Please try again later.'; return; } if (!_requests.length) { this.$loading.className = 'empty'; this.$loading.innerHTML = 'You’re all caught up!'; return; } const requests = []; const $ul = this.$panel.querySelector('ul'); const $fragment = document.createDocumentFragment(); // Sort requests from new to old, then group reviews/feedbacks asked by the same person in the same bug _requests.reverse().forEach(_req => { const dup_index = requests.findIndex(req => req.requester === _req.requester && req.type === _req.type && req.bug_id === _req.bug_id && req.attach_mimetype === _req.attach_mimetype); if (dup_index > -1) { requests[dup_index].dup_count++; } else { _req.dup_count = 1; requests.push(_req); } }); // Show up to 20 newest requests requests.slice(0, 20).forEach(req => { const $li = document.createElement('li'); const [, name, email] = req.requester.match(/^(?:(.*)\s<)?(.+?)>?$/); const pretty_name = name ? name.replace(/([\[\(<‹].*?[›>\)\]]|\:[\w\-]+|\s+\-\s+.*)/g, '').trim() : email; const [link, attach_label] = this.get_link(req); $li.setAttribute('role', 'none'); $li.innerHTML = `` + `` + `` + ``; $fragment.appendChild($li); }); this.$loading.remove(); $ul.appendChild($fragment); $ul.hidden = false; } /** * Get the link to a request as well as the label of any attachment. It could be the direct link to the attachment * unless multiple requests are grouped. * @param {Object} req - A request object. * @returns {Array} The result including the link and attachment label. */ get_link(req) { const dup = req.dup_count > 1; const splinter_base = BUGZILLA.param.splinter_base; const x_types = ['github-pull-request', 'review-board-request', 'phabricator-request', 'google-doc']; const is_patch = req.attach_ispatch; const [is_ghpr, is_rbr, is_phr, is_gdoc] = x_types.map(type => req.attach_mimetype === `text/x-${type}`); const is_redirect = is_ghpr || is_rbr || is_phr || is_gdoc; const is_file = req.attach_id && !is_patch && !is_redirect; const link = (is_patch && !dup && splinter_base) ? `${splinter_base}&bug=${req.bug_id}&attachment=${req.attach_id}` : (is_redirect && !dup) ? `attachment.cgi?id=${req.attach_id}` // external redirect : ((is_patch || is_file) && !dup) ? `attachment.cgi?id=${req.attach_id}&action=edit` : `show_bug.cgi?id=${req.bug_id}`; const attach_label = (is_patch || is_rbr || is_phr) ? (dup ? `${req.dup_count} patches` : 'a patch') : is_ghpr ? (dup ? `${req.dup_count} pull requests` : 'a pull request') : is_gdoc ? (dup ? `${req.dup_count} Google Docs` : 'a Google Doc') : is_file ? (dup ? `${req.dup_count} files` : 'a file') : undefined; return [link, attach_label]; } } window.addEventListener('DOMContentLoaded', () => new Bugzilla.Review.Badge(), { once: true });