/* 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. */ var REVIEW = { widget: false, target: false, fields: [], use_error_for: false, ispatch_override: false, description_override: false, ignore_patch_event: true, init_review_flag: function(fid, flag_name) { var idx = this.fields.push({ 'fid': fid, 'flag_name': flag_name, 'component': '' }) - 1; this.flag_change({ data: idx }); $('#' + fid).on('change', null, idx, this.flag_change); }, init_mandatory: function() { var form = this.find_form(); if (!form) return; $(form).on('submit', this.check_mandatory); for (var i = 0; i < this.fields.length; i++) { var field = this.fields[i]; // existing reviews that have empty requestee shouldn't force a // reviewer to be selected field.old_empty_review = $('#' + field.fid).val() == '?' && $('#' + field.flag_name).val() == ''; if (!field.old_empty_review) $('#' + field.flag_name).addClass('required'); } }, init_enter_bug: function() { $('#component').on('change', REVIEW.component_change); BUGZILLA.string['reviewer_required'] = 'A reviewer is required.'; this.use_error_for = true; this.init_create_attachment(); }, init_create_attachment: function() { $('#data').on('change', REVIEW.attachment_change); $('#description').on('change', REVIEW.description_change); $('#ispatch').on('change', REVIEW.ispatch_change); }, component_change: function() { for (var i = 0; i < REVIEW.fields.length; i++) { REVIEW.flag_change({ data: i }); } }, attachment_change: function() { var filename = $('#data').val().split('/').pop().split('\\').pop(); var description = $('#description').first(); if (description.val() == '' || !REVIEW.description_override) { description.val(filename); } if (!REVIEW.ispatch_override) { $('#ispatch').prop('checked', REVIEW.endsWith(filename, '.diff') || REVIEW.endsWith(filename, '.patch')); } setContentTypeDisabledState(this.form); description.select(); description.focus(); }, description_change: function() { REVIEW.description_override = true; }, ispatch_change: function() { // the attachment template triggers this change event onload // as we only want to set ispatch_override when the user clicks on the // checkbox, we ignore this first event if (REVIEW.ignore_patch_event) { REVIEW.ignore_patch_event = false; return; } REVIEW.ispatch_override = true; }, flag_change: function(e) { var field = REVIEW.fields[e.data]; var suggestions_span = $('#' + field.fid + '_suggestions'); // for requests only if ($('#' + field.fid).val() != '?') { suggestions_span.hide(); return; } // find selected component var component = static_component || $('#component').val(); if (!component) { suggestions_span.hide(); return; } // add the menu if (field.component != component) { var items = []; for (var i = 0, il = review_suggestions._mentors.length; i < il; i++) { REVIEW.add_menu_item(items, review_suggestions._mentors[i], true); } if (review_suggestions[component] && review_suggestions[component].length) { REVIEW.add_menu_items(items, review_suggestions[component]); } else if (review_suggestions._product) { REVIEW.add_menu_items(items, review_suggestions._product); } if (items.length) { suggestions_span.show(); $.contextMenu('destroy', '#' + field.fid + '_suggestions'); $.contextMenu({ selector: '#' + field.fid + '_suggestions', trigger: 'left', events: { show: function() { REVIEW.target = $('#' + field.flag_name); } }, items: items }); } else { suggestions_span.hide(); } } }, add_menu_item: function(items, user, is_mentor) { for (var i = 0, il = items.length; i < il; i++) { if (items[i].login == user.login) return; } var queue = ''; if (user.review_count == 0) { queue = 'empty queue'; } else { queue = user.review_count + ' review' + (user.review_count == 1 ? '' : 's') + ' in queue'; } items.push({ name: user.identity + ' (' + queue + ')', login: user.login, className: (is_mentor ? 'mentor' : ''), callback: function() { REVIEW.target.val(user.login); } }); }, add_menu_items: function(field_idx, users) { for (var i = 0; i < users.length; i++) { if (!review_suggestions._mentor || users[i].login != review_suggestions._mentor.login) { REVIEW.add_menu_item(field_idx, users[i]); } } }, check_mandatory: function(e) { if ($('#data').length && !$('#data').val() && $('#attach_text').length && !$('#attach_text').val()) { return; } for (var i = 0; i < REVIEW.fields.length; i++) { var field = REVIEW.fields[i]; if (!field.old_empty_review && $('#' + field.fid).val() == '?' && $('#' + field.flag_name).val() == '') { if (REVIEW.use_error_for) { _errorFor($('#' + REVIEW.fields[i].flag_name)[0], 'reviewer'); } else { alert('You must provide a reviewer for review requests.'); } e.preventDefault(); } } }, find_form: function() { for (var i = 0; i < document.forms.length; i++) { var action = document.forms[i].getAttribute('action'); if (action == 'attachment.cgi' || action == 'post_bug.cgi') return document.forms[i]; } return false; }, endsWith: function(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; } };