summaryrefslogtreecommitdiff
path: root/resources/src/mediawiki/mediawiki.feedback.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/src/mediawiki/mediawiki.feedback.js')
-rw-r--r--resources/src/mediawiki/mediawiki.feedback.js699
1 files changed, 441 insertions, 258 deletions
diff --git a/resources/src/mediawiki/mediawiki.feedback.js b/resources/src/mediawiki/mediawiki.feedback.js
index 1c0d8332..d9401001 100644
--- a/resources/src/mediawiki/mediawiki.feedback.js
+++ b/resources/src/mediawiki/mediawiki.feedback.js
@@ -3,8 +3,11 @@
*
* @author Ryan Kaldari, 2010
* @author Neil Kandalgaonkar, 2010-11
+ * @author Moriel Schottlender, 2015
* @since 1.19
*/
+/*jshint es3:false */
+/*global OO*/
( function ( mw, $ ) {
/**
* This is a way of getting simple feedback from users. It's useful
@@ -32,289 +35,469 @@
*
* @class
* @constructor
- * @param {Object} [options]
- * @param {mw.Api} [options.api] if omitted, will just create a standard API
- * @param {mw.Title} [options.title="Feedback"] The title of the page where you collect
- * feedback.
- * @param {string} [options.dialogTitleMessageKey="feedback-submit"] Message key for the
- * title of the dialog box
- * @param {string} [options.bugsLink="//bugzilla.wikimedia.org/enter_bug.cgi"] URL where
- * bugs can be posted
- * @param {mw.Uri|string} [options.bugsListLink="//bugzilla.wikimedia.org/query.cgi"]
- * URL where bugs can be listed
+ * @param {Object} [config] Configuration object
+ * @cfg {mw.Title} [title="Feedback"] The title of the page where you collect
+ * feedback.
+ * @cfg {string} [dialogTitleMessageKey="feedback-dialog-title"] Message key for the
+ * title of the dialog box
+ * @cfg {mw.Uri|string} [bugsLink="//phabricator.wikimedia.org/maniphest/task/create/"] URL where
+ * bugs can be posted
+ * @cfg {mw.Uri|string} [bugsListLink="//phabricator.wikimedia.org/maniphest/query/advanced"] URL
+ * where bugs can be listed
+ * @cfg {boolean} [showUseragentCheckbox=false] Show a Useragent agreement checkbox as part of the form.
+ * @cfg {boolean} [useragentCheckboxMandatory=false] Make the Useragent checkbox mandatory.
+ * @cfg {string|jQuery} [useragentCheckboxMessage] Supply a custom message for the useragent checkbox.
+ * defaults to the message 'feedback-terms'.
*/
- mw.Feedback = function ( options ) {
- if ( options === undefined ) {
- options = {};
- }
+ mw.Feedback = function MwFeedback( config ) {
+ config = config || {};
- if ( options.api === undefined ) {
- options.api = new mw.Api();
- }
+ this.dialogTitleMessageKey = config.dialogTitleMessageKey || 'feedback-dialog-title';
- if ( options.title === undefined ) {
- options.title = new mw.Title( 'Feedback' );
- }
+ // Feedback page title
+ this.feedbackPageTitle = config.title || new mw.Title( 'Feedback' );
- if ( options.dialogTitleMessageKey === undefined ) {
- options.dialogTitleMessageKey = 'feedback-submit';
- }
+ this.messagePosterPromise = mw.messagePoster.factory.create( this.feedbackPageTitle );
- if ( options.bugsLink === undefined ) {
- options.bugsLink = '//bugzilla.wikimedia.org/enter_bug.cgi';
- }
+ // Links
+ this.bugsTaskSubmissionLink = config.bugsLink || '//phabricator.wikimedia.org/maniphest/task/create/';
+ this.bugsTaskListLink = config.bugsListLink || '//phabricator.wikimedia.org/maniphest/query/advanced';
- if ( options.bugsListLink === undefined ) {
- options.bugsListLink = '//bugzilla.wikimedia.org/query.cgi';
- }
+ // Terms of use
+ this.useragentCheckboxShow = !!config.showUseragentCheckbox;
+ this.useragentCheckboxMandatory = !!config.useragentCheckboxMandatory;
+ this.useragentCheckboxMessage = config.useragentCheckboxMessage ||
+ $( '<p>' ).append( mw.msg( 'feedback-terms' ) );
- $.extend( this, options );
- this.setup();
+ // Message dialog
+ this.thankYouDialog = new OO.ui.MessageDialog();
};
- mw.Feedback.prototype = {
- /**
- * Sets up interface
- */
- setup: function () {
- var $feedbackPageLink,
- $bugNoteLink,
- $bugsListLink,
- fb = this;
-
- $feedbackPageLink = $( '<a>' )
- .attr( {
- href: fb.title.getUrl(),
- target: '_blank'
- } )
- .css( {
- whiteSpace: 'nowrap'
- } );
+ /* Initialize */
+ OO.initClass( mw.Feedback );
- $bugNoteLink = $( '<a>' ).attr( { href: '#' } ).click( function () {
- fb.displayBugs();
- } );
-
- $bugsListLink = $( '<a>' ).attr( {
- href: fb.bugsListLink,
- target: '_blank'
- } );
-
- // TODO: Use a stylesheet instead of these inline styles
- this.$dialog =
- $( '<div style="position: relative;"></div>' ).append(
- $( '<div class="feedback-mode feedback-form"></div>' ).append(
- $( '<small>' ).append(
- $( '<p>' ).msg(
- 'feedback-bugornote',
- $bugNoteLink,
- fb.title.getNameText(),
- $feedbackPageLink.clone()
- )
- ),
- $( '<div style="margin-top: 1em;"></div>' )
- .msg( 'feedback-subject' )
- .append(
- $( '<br>' ),
- $( '<input type="text" class="feedback-subject" name="subject" maxlength="60" style="width: 100%; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;"/>' )
- ),
- $( '<div style="margin-top: 0.4em;"></div>' )
- .msg( 'feedback-message' )
- .append(
- $( '<br>' ),
- $( '<textarea name="message" class="feedback-message" rows="5" cols="60"></textarea>' )
- )
- ),
- $( '<div class="feedback-mode feedback-bugs"></div>' ).append(
- $( '<p>' ).msg( 'feedback-bugcheck', $bugsListLink )
- ),
- $( '<div class="feedback-mode feedback-submitting" style="text-align: center; margin: 3em 0;"></div>' )
- .msg( 'feedback-adding' )
- .append(
- $( '<br>' ),
- $( '<span class="feedback-spinner"></span>' )
- ),
- $( '<div class="feedback-mode feedback-thanks" style="text-align: center; margin:1em"></div>' ).msg(
- 'feedback-thanks', fb.title.getNameText(), $feedbackPageLink.clone()
+ /* Static Properties */
+ mw.Feedback.static.windowManager = null;
+ mw.Feedback.static.dialog = null;
+
+ /* Methods */
+
+ /**
+ * Respond to dialog submit event. If the information was
+ * submitted, either successfully or with an error, open
+ * a MessageDialog to thank the user.
+ * @param {string} [status] A status of the end of operation
+ * of the main feedback dialog. Empty if the dialog was
+ * dismissed with no action or the user followed the button
+ * to the external task reporting site.
+ */
+ mw.Feedback.prototype.onDialogSubmit = function ( status ) {
+ var dialogConfig = {};
+ switch ( status ) {
+ case 'submitted':
+ dialogConfig = {
+ title: mw.msg( 'feedback-thanks-title' ),
+ message: $( '<span>' ).append(
+ mw.message(
+ 'feedback-thanks',
+ this.feedbackPageTitle.getNameText(),
+ $( '<a>' )
+ .attr( {
+ target: '_blank',
+ href: this.feedbackPageTitle.getUrl()
+ } )
+ ).parse()
),
- $( '<div class="feedback-mode feedback-error" style="position: relative;"></div>' ).append(
- $( '<div class="feedback-error-msg style="color: #990000; margin-top: 0.4em;"></div>' )
- )
- );
+ actions: [
+ {
+ action: 'accept',
+ label: mw.msg( 'feedback-close' ),
+ flags: 'primary'
+ }
+ ]
+ };
+ break;
+ case 'error1':
+ case 'error2':
+ case 'error3':
+ case 'error4':
+ dialogConfig = {
+ title: mw.msg( 'feedback-error-title' ),
+ message: mw.msg( 'feedback-' + status ),
+ actions: [
+ {
+ action: 'accept',
+ label: mw.msg( 'feedback-close' ),
+ flags: 'primary'
+ }
+ ]
+ };
+ break;
+ }
- this.$dialog.dialog( {
- width: 500,
- autoOpen: false,
- title: mw.message( this.dialogTitleMessageKey ).escaped(),
- modal: true,
- buttons: fb.buttons
- } );
+ // Show the message dialog
+ if ( !$.isEmptyObject( dialogConfig ) ) {
+ this.constructor.static.windowManager.openWindow(
+ this.thankYouDialog,
+ dialogConfig
+ );
+ }
+ };
- this.subjectInput = this.$dialog.find( 'input.feedback-subject' ).get( 0 );
- this.messageInput = this.$dialog.find( 'textarea.feedback-message' ).get( 0 );
- },
+ /**
+ * Modify the display form, and then open it, focusing interface on the subject.
+ *
+ * @param {Object} [contents] Prefilled contents for the feedback form.
+ * @param {string} [contents.subject] The subject of the feedback, as plaintext
+ * @param {string} [contents.message] The content of the feedback, as wikitext
+ */
+ mw.Feedback.prototype.launch = function ( contents ) {
+ // Dialog
+ if ( !this.constructor.static.dialog ) {
+ this.constructor.static.dialog = new mw.Feedback.Dialog();
+ this.constructor.static.dialog.connect( this, { submit: 'onDialogSubmit' } );
+ }
+ if ( !this.constructor.static.windowManager ) {
+ this.constructor.static.windowManager = new OO.ui.WindowManager();
+ this.constructor.static.windowManager.addWindows( [
+ this.constructor.static.dialog,
+ this.thankYouDialog
+ ] );
+ $( 'body' )
+ .append( this.constructor.static.windowManager.$element );
+ }
+ // Open the dialog
+ this.constructor.static.windowManager.openWindow(
+ this.constructor.static.dialog,
+ {
+ title: mw.msg( this.dialogTitleMessageKey ),
+ settings: {
+ messagePosterPromise: this.messagePosterPromise,
+ title: this.feedbackPageTitle,
+ dialogTitleMessageKey: this.dialogTitleMessageKey,
+ bugsTaskSubmissionLink: this.bugsTaskSubmissionLink,
+ bugsTaskListLink: this.bugsTaskListLink,
+ useragentCheckbox: {
+ show: this.useragentCheckboxShow,
+ mandatory: this.useragentCheckboxMandatory,
+ message: this.useragentCheckboxMessage
+ }
+ },
+ contents: contents
+ }
+ );
+ };
- /**
- * Displays a section of the dialog.
- *
- * @param {"form"|"bugs"|"submitting"|"thanks"|"error"} s
- * The section of the dialog to show.
- */
- display: function ( s ) {
- // Hide the buttons
- this.$dialog.dialog( { buttons: {} } );
- // Hide everything
- this.$dialog.find( '.feedback-mode' ).hide();
- // Show the desired div
- this.$dialog.find( '.feedback-' + s ).show();
- },
+ /**
+ * mw.Feedback Dialog
+ *
+ * @class
+ * @extends OO.ui.ProcessDialog
+ *
+ * @constructor
+ * @param {Object} config Configuration object
+ */
+ mw.Feedback.Dialog = function mwFeedbackDialog( config ) {
+ // Parent constructor
+ mw.Feedback.Dialog.super.call( this, config );
+
+ this.status = '';
+ this.feedbackPageTitle = null;
+ // Initialize
+ this.$element.addClass( 'mwFeedback-Dialog' );
+ };
- /**
- * Display the submitting section.
- */
- displaySubmitting: function () {
- this.display( 'submitting' );
+ OO.inheritClass( mw.Feedback.Dialog, OO.ui.ProcessDialog );
+
+ /* Static properties */
+ mw.Feedback.Dialog.static.name = 'mwFeedbackDialog';
+ mw.Feedback.Dialog.static.title = mw.msg( 'feedback-dialog-title' );
+ mw.Feedback.Dialog.static.size = 'medium';
+ mw.Feedback.Dialog.static.actions = [
+ {
+ action: 'submit',
+ label: mw.msg( 'feedback-submit' ),
+ flags: [ 'primary', 'constructive' ]
},
-
- /**
- * Display the bugs section.
- */
- displayBugs: function () {
- var fb = this,
- bugsButtons = {};
-
- this.display( 'bugs' );
- bugsButtons[ mw.msg( 'feedback-bugnew' ) ] = function () {
- window.open( fb.bugsLink, '_blank' );
- };
- bugsButtons[ mw.msg( 'feedback-cancel' ) ] = function () {
- fb.cancel();
- };
- this.$dialog.dialog( {
- buttons: bugsButtons
- } );
+ {
+ action: 'external',
+ label: mw.msg( 'feedback-external-bug-report-button' ),
+ flags: 'constructive'
},
+ {
+ action: 'cancel',
+ label: mw.msg( 'feedback-cancel' ),
+ flags: 'safe'
+ }
+ ];
- /**
- * Display the thanks section.
- */
- displayThanks: function () {
- var fb = this,
- closeButton = {};
-
- this.display( 'thanks' );
- closeButton[ mw.msg( 'feedback-close' ) ] = function () {
- fb.$dialog.dialog( 'close' );
- };
- this.$dialog.dialog( {
- buttons: closeButton
- } );
- },
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.initialize = function () {
+ var feedbackSubjectFieldLayout, feedbackMessageFieldLayout,
+ feedbackFieldsetLayout, termsOfUseLabel;
+
+ // Parent method
+ mw.Feedback.Dialog.super.prototype.initialize.call( this );
+
+ this.feedbackPanel = new OO.ui.PanelLayout( {
+ scrollable: false,
+ expanded: false,
+ padded: true
+ } );
+
+ this.$spinner = $( '<div>' )
+ .addClass( 'feedback-spinner' );
+
+ // Feedback form
+ this.feedbackMessageLabel = new OO.ui.LabelWidget( {
+ classes: [ 'mw-feedbackDialog-welcome-message' ]
+ } );
+ this.feedbackSubjectInput = new OO.ui.TextInputWidget( {
+ multiline: false
+ } );
+ this.feedbackMessageInput = new OO.ui.TextInputWidget( {
+ autosize: true,
+ multiline: true
+ } );
+ feedbackSubjectFieldLayout = new OO.ui.FieldLayout( this.feedbackSubjectInput, {
+ label: mw.msg( 'feedback-subject' )
+ } );
+ feedbackMessageFieldLayout = new OO.ui.FieldLayout( this.feedbackMessageInput, {
+ label: mw.msg( 'feedback-message' )
+ } );
+ feedbackFieldsetLayout = new OO.ui.FieldsetLayout( {
+ items: [ feedbackSubjectFieldLayout, feedbackMessageFieldLayout ],
+ classes: [ 'mw-feedbackDialog-feedback-form' ]
+ } );
+
+ // Useragent terms of use
+ this.useragentCheckbox = new OO.ui.CheckboxInputWidget();
+ this.useragentFieldLayout = new OO.ui.FieldLayout( this.useragentCheckbox, {
+ classes: [ 'mw-feedbackDialog-feedback-terms' ],
+ align: 'inline'
+ } );
+
+ termsOfUseLabel = new OO.ui.LabelWidget( {
+ classes: [ 'mw-feedbackDialog-feedback-termsofuse' ],
+ label: $( '<p>' ).append( mw.msg( 'feedback-termsofuse' ) )
+ } );
+
+ this.feedbackPanel.$element.append(
+ this.feedbackMessageLabel.$element,
+ feedbackFieldsetLayout.$element,
+ this.useragentFieldLayout.$element,
+ termsOfUseLabel.$element
+ );
+
+ // Events
+ this.feedbackSubjectInput.connect( this, { change: 'validateFeedbackForm' } );
+ this.feedbackMessageInput.connect( this, { change: 'validateFeedbackForm' } );
+ this.feedbackMessageInput.connect( this, { change: 'updateSize' } );
+ this.useragentCheckbox.connect( this, { change: 'validateFeedbackForm' } );
+
+ this.$body.append( this.feedbackPanel.$element );
+ };
- /**
- * Display the feedback form
- * @param {Object} [contents] Prefilled contents for the feedback form.
- * @param {string} [contents.subject] The subject of the feedback
- * @param {string} [contents.message] The content of the feedback
- */
- displayForm: function ( contents ) {
- var fb = this,
- formButtons = {};
-
- this.subjectInput.value = ( contents && contents.subject ) ? contents.subject : '';
- this.messageInput.value = ( contents && contents.message ) ? contents.message : '';
-
- this.display( 'form' );
-
- // Set up buttons for dialog box. We have to do it the hard way since the json keys are localized
- formButtons[ mw.msg( 'feedback-submit' ) ] = function () {
- fb.submit();
- };
- formButtons[ mw.msg( 'feedback-cancel' ) ] = function () {
- fb.cancel();
- };
- this.$dialog.dialog( { buttons: formButtons } ); // put the buttons back
- },
+ /**
+ * Validate the feedback form
+ */
+ mw.Feedback.Dialog.prototype.validateFeedbackForm = function () {
+ var isValid = (
+ (
+ !this.useragentMandatory ||
+ this.useragentCheckbox.isSelected()
+ ) &&
+ (
+ !!this.feedbackMessageInput.getValue() ||
+ !!this.feedbackSubjectInput.getValue()
+ )
+ );
+
+ this.actions.setAbilities( { submit: isValid } );
+ };
- /**
- * Display an error on the form.
- *
- * @param {string} message Should be a valid message key.
- */
- displayError: function ( message ) {
- var fb = this,
- closeButton = {};
-
- this.display( 'error' );
- this.$dialog.find( '.feedback-error-msg' ).msg( message );
- closeButton[ mw.msg( 'feedback-close' ) ] = function () {
- fb.$dialog.dialog( 'close' );
- };
- this.$dialog.dialog( { buttons: closeButton } );
- },
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.getBodyHeight = function () {
+ return this.feedbackPanel.$element.outerHeight( true );
+ };
- /**
- * Close the feedback form.
- */
- cancel: function () {
- this.$dialog.dialog( 'close' );
- },
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.getSetupProcess = function ( data ) {
+ return mw.Feedback.Dialog.super.prototype.getSetupProcess.call( this, data )
+ .next( function () {
+ var plainMsg, parsedMsg,
+ settings = data.settings;
+ data.contents = data.contents || {};
+
+ // Prefill subject/message
+ this.feedbackSubjectInput.setValue( data.contents.subject );
+ this.feedbackMessageInput.setValue( data.contents.message );
+
+ this.status = '';
+ this.messagePosterPromise = settings.messagePosterPromise;
+ this.setBugReportLink( settings.bugsTaskSubmissionLink );
+ this.feedbackPageTitle = settings.title;
+ this.feedbackPageName = settings.title.getNameText();
+ this.feedbackPageUrl = settings.title.getUrl();
+
+ // Useragent checkbox
+ if ( settings.useragentCheckbox.show ) {
+ this.useragentFieldLayout.setLabel( settings.useragentCheckbox.message );
+ }
- /**
- * Submit the feedback form.
- */
- submit: function () {
- var subject, message,
- fb = this;
-
- // Get the values to submit.
- subject = this.subjectInput.value;
-
- // We used to include "mw.html.escape( navigator.userAgent )" but there are legal issues
- // with posting this without their explicit consent
- message = this.messageInput.value;
- if ( message.indexOf( '~~~' ) === -1 ) {
- message += ' ~~~~';
- }
+ this.useragentMandatory = settings.useragentCheckbox.mandatory;
+ this.useragentFieldLayout.toggle( settings.useragentCheckbox.show );
+
+ // HACK: Setting a link in the messages doesn't work. There is already a report
+ // about this, and the bug report offers a somewhat hacky work around that
+ // includes setting a separate message to be parsed.
+ // We want to make sure the user can configure both the title of the page and
+ // a separate url, so this must be allowed to parse correctly.
+ // See https://phabricator.wikimedia.org/T49395#490610
+ mw.messages.set( {
+ 'feedback-dialog-temporary-message':
+ '<a href="' + this.feedbackPageUrl + '" target="_blank">' + this.feedbackPageName + '</a>'
+ } );
+ plainMsg = mw.message( 'feedback-dialog-temporary-message' ).plain();
+ mw.messages.set( { 'feedback-dialog-temporary-message-parsed': plainMsg } );
+ parsedMsg = mw.message( 'feedback-dialog-temporary-message-parsed' );
+ this.feedbackMessageLabel.setLabel(
+ // Double-parse
+ $( '<span>' )
+ .append( mw.message( 'feedback-dialog-intro', parsedMsg ).parse() )
+ );
- this.displaySubmitting();
-
- // Post the message, resolving redirects
- this.api.newSection(
- this.title,
- subject,
- message,
- { redirect: true }
- )
- .done( function ( result ) {
- if ( result.edit !== undefined ) {
- if ( result.edit.result === 'Success' ) {
- fb.displayThanks();
- } else {
- // unknown API result
- fb.displayError( 'feedback-error1' );
- }
- } else {
- // edit failed
- fb.displayError( 'feedback-error2' );
+ this.validateFeedbackForm();
+ }, this );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.getReadyProcess = function ( data ) {
+ return mw.Feedback.Dialog.super.prototype.getReadyProcess.call( this, data )
+ .next( function () {
+ this.feedbackSubjectInput.focus();
+ }, this );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.getActionProcess = function ( action ) {
+ if ( action === 'cancel' ) {
+ return new OO.ui.Process( function () {
+ this.close( { action: action } );
+ }, this );
+ } else if ( action === 'external' ) {
+ return new OO.ui.Process( function () {
+ // Open in a new window
+ window.open( this.getBugReportLink(), '_blank' );
+ // Close the dialog
+ this.close();
+ }, this );
+ } else if ( action === 'submit' ) {
+ return new OO.ui.Process( function () {
+ var fb = this,
+ userAgentMessage = ':' +
+ '<small>' +
+ mw.msg( 'feedback-useragent' ) +
+ ' ' +
+ mw.html.escape( navigator.userAgent ) +
+ '</small>\n\n',
+ subject = this.feedbackSubjectInput.getValue(),
+ message = this.feedbackMessageInput.getValue();
+
+ // Add user agent if checkbox is selected
+ if ( this.useragentCheckbox.isSelected() ) {
+ message = userAgentMessage + message;
}
- } )
- .fail( function () {
- // ajax request failed
- fb.displayError( 'feedback-error3' );
- } );
- },
- /**
- * Modify the display form, and then open it, focusing interface on the subject.
- * @param {Object} [contents] Prefilled contents for the feedback form.
- * @param {string} [contents.subject] The subject of the feedback
- * @param {string} [contents.message] The content of the feedback
- */
- launch: function ( contents ) {
- this.displayForm( contents );
- this.$dialog.dialog( 'open' );
- this.subjectInput.focus();
+ // Post the message
+ return this.messagePosterPromise.then( function ( poster ) {
+ return fb.postMessage( poster, subject, message );
+ }, function () {
+ fb.status = 'error4';
+ mw.log.warn( 'Feedback report failed because MessagePoster could not be fetched' );
+ } ).always( function () {
+ fb.close();
+ } );
+ }, this );
}
+ // Fallback to parent handler
+ return mw.Feedback.Dialog.super.prototype.getActionProcess.call( this, action );
};
+
+ /**
+ * Posts the message
+ *
+ * @private
+ *
+ * @param {mw.messagePoster.MessagePoster} poster Poster implementation used to leave feedback
+ * @param {string} subject Subject of message
+ * @param {string} message Body of message
+ * @return {jQuery.Promise} Promise representing success of message posting action
+ */
+ mw.Feedback.Dialog.prototype.postMessage = function ( poster, subject, message ) {
+ var fb = this;
+
+ return poster.post(
+ subject,
+ message
+ ).then( function () {
+ fb.status = 'submitted';
+ }, function ( mainCode, secondaryCode, details ) {
+ if ( mainCode === 'api-fail' ) {
+ if ( secondaryCode === 'http' ) {
+ fb.status = 'error3';
+ // ajax request failed
+ mw.log.warn( 'Feedback report failed with HTTP error: ' + details.textStatus );
+ } else {
+ fb.status = 'error2';
+ mw.log.warn( 'Feedback report failed with API error: ' + secondaryCode );
+ }
+ } else {
+ fb.status = 'error1';
+ }
+ } );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.getTeardownProcess = function ( data ) {
+ return mw.Feedback.Dialog.super.prototype.getTeardownProcess.call( this, data )
+ .first( function () {
+ this.emit( 'submit', this.status, this.feedbackPageName, this.feedbackPageUrl );
+ // Cleanup
+ this.status = '';
+ this.feedbackPageTitle = null;
+ this.feedbackSubjectInput.setValue( '' );
+ this.feedbackMessageInput.setValue( '' );
+ this.useragentCheckbox.setSelected( false );
+ }, this );
+ };
+
+ /**
+ * Set the bug report link
+ * @param {string} link Link to the external bug report form
+ */
+ mw.Feedback.Dialog.prototype.setBugReportLink = function ( link ) {
+ this.bugReportLink = link;
+ };
+
+ /**
+ * Get the bug report link
+ * @returns {string} Link to the external bug report form
+ */
+ mw.Feedback.Dialog.prototype.getBugReportLink = function () {
+ return this.bugReportLink;
+ };
+
}( mediaWiki, jQuery ) );