jenkins-bot has submitted this change and it was merged.
Change subject: Refactoring mw.Feedback to work with OOUI elements
......................................................................
Refactoring mw.Feedback to work with OOUI elements
Transform mw.Feedback into an ooui dialog.
* Added a configurable checkbox for useragent and terms
of servvice options. The checkbox can be configured
to be visible or not, and to be mandatory or optional.
(useragent addition based largely on the unmerged
fix I37b1a271af115)
* Transformed the 'feedback-bugornote' message to a
configurable intro message with a link to the feedback
page.
* Added a 'thank you' or 'error' dialog at the end of the
operation indicating whether the feedback was sent or
if there was some error.
Bug: T89878
Bug: T43291
Bug: T35365
Bug: T54588
Bug: T65290
Change-Id: Id1967a83a502f689c40f1af71398c3be99e30640
---
M languages/i18n/en.json
M languages/i18n/qqq.json
M maintenance/jsduck/categories.json
M resources/Resources.php
M resources/src/mediawiki/mediawiki.feedback.css
M resources/src/mediawiki/mediawiki.feedback.js
D resources/src/mediawiki/templates/dialog.html
7 files changed, 504 insertions(+), 299 deletions(-)
Approvals:
Jforrester: Looks good to me, approved
jenkins-bot: Verified
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index 31c766f..7ff3b25 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -3519,19 +3519,28 @@
"newuserlog-autocreate-entry": "Account created automatically",
"rightslogentry": "changed group membership for $1 from $2 to $3",
"rightslogentry-autopromote": "was automatically promoted from $2 to
$3",
- "feedback-bugornote": "If you are ready to describe a technical problem
in detail please [$1 report a bug].\nOtherwise, you can use the easy form
below. Your comment will be added to the page \"[$3 $2]\", along with your
username.",
- "feedback-subject": "Subject:",
- "feedback-message": "Message:",
- "feedback-cancel": "Cancel",
- "feedback-submit": "Submit Feedback",
"feedback-adding": "Adding feedback to page...",
+ "feedback-back": "Back",
+ "feedback-bugcheck": "Great! Just check that it is not already one of
the [$1 known bugs].",
+ "feedback-bugnew": "I checked. Report a new bug",
+ "feedback-bugornote": "If you are ready to describe a technical problem
in detail please [$1 report a bug].\nOtherwise, you can use the easy form
below. Your comment will be added to the page \"[$3 $2]\", along with your
username.",
+ "feedback-cancel": "Cancel",
+ "feedback-close": "Done",
+ "feedback-external-bug-report-button": "File a technical task",
+ "feedback-dialog-title": "Submit feedback",
+ "feedback-dialog-intro": "You can use the easy form below to submit
your feedback. Your comment will be added to the page \"$1\", along with your
username.",
+ "feedback-error-title": "Error",
"feedback-error1": "Error: Unrecognized result from API",
"feedback-error2": "Error: Edit failed",
"feedback-error3": "Error: No response from API",
+ "feedback-message": "Message:",
+ "feedback-subject": "Subject:",
+ "feedback-submit": "Submit",
+ "feedback-terms": "I understand that my user agent information includes
information about my exact browser and operating system version and will be
shared publicly alongside my feedback.",
+ "feedback-termsofuse": "I agree to provide feedback in accordance with
the Terms of Use.",
"feedback-thanks": "Thanks! Your feedback has been posted to the page
\"[$2 $1]\".",
- "feedback-close": "Done",
- "feedback-bugcheck": "Great! Just check that it is not already one of
the [$1 known bugs].",
- "feedback-bugnew": "I checked. Report a new bug",
+ "feedback-thanks-title": "Thank you!",
+ "feedback-useragent": "User agent:",
"searchsuggest-search": "Search",
"searchsuggest-containing": "containing...",
"api-error-badaccess-groups": "You are not permitted to upload files to
this wiki.",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index 6253fc9..3fab943 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -3683,19 +3683,28 @@
"newuserlog-autocreate-entry": "This message is used in the
[[:mw:Extension:Newuserlog|new user log]] to mark an account that was created
by MediaWiki as part of a [[:mw:Extension:CentralAuth|CentralAuth]] global
account.",
"rightslogentry": "This message is displayed in the
[[Special:Log/rights|User Rights Log]] when a bureaucrat changes the user
groups for a user.\n\nParameters:\n* $1 - the username\n* $2 - list of user
groups or {{msg-mw|Rightsnone}}\n* $3 - list of user groups or
{{msg-mw|Rightsnone}}\n\nThe name of the bureaucrat who did this task appears
before this message.\n\nSimilar to {{msg-mw|Gur-rightslog-entry}}",
"rightslogentry-autopromote": "This message is displayed in the
[[Special:Log/rights|User Rights Log]] when a user is automatically promoted to
a user group.\n\nParameters:\n* $1 - (Unused)\n* $2 - a comma separated list of
old user groups or {{msg-mw|Rightsnone}}\n* $3 - a comma separated list of new
user groups",
- "feedback-bugornote": "When feedback dialog box is opened, this
introductory message in small print explains the options to report a bug or add
simple feedback.\n\nWe expect that people in a hurry will not read
this.\n\nParameters:\n* $1 - Bug note URL\n* $2 - \"Feedback\"\n* $3 - Feedback
page URL",
- "feedback-subject": "Label for a text input\n{{Identical|Subject}}",
- "feedback-message": "Label for a textarea; signature referrs to a
Wikitext signature.\n{{Identical|Message}}",
- "feedback-cancel": "Button label\n{{Identical|Cancel}}",
- "feedback-submit": "Button label\n{{Identical|Submit}}",
"feedback-adding": "Progress notice",
+ "feedback-back": "Button to go back to the previous action in the
feedback dialog.",
+ "feedback-bugcheck": "Message that appears before the user submits a
bug, reminding them to check for known bugs.\n\nParameters:\n* $1 - bug list
page URL",
+ "feedback-bugnew": "Button label - asserts that the user has checked
for existing bugs. When clicked will launch an external form to add a new bug
in a new tab or window",
+ "feedback-bugornote": "When feedback dialog box is opened, this
introductory message in small print explains the options to report a bug or add
simple feedback.\n\nWe expect that people in a hurry will not read
this.\n\nParameters:\n* $1 - Bug note URL\n* $2 - \"Feedback\"\n* $3 - Feedback
page URL",
+ "feedback-external-bug-report-button": "A button for submitting an
external technical bug report.",
+ "feedback-cancel": "Button label\n{{Identical|Cancel}}",
+ "feedback-close": "Button label\n{{Identical|Done}}",
+ "feedback-dialog-title": "Title of the feedback dialog",
"feedback-error1": "Error message, appears when an unknown error occurs
submitting feedback",
"feedback-error2": "Error message, appears when we could not add
feedback",
"feedback-error3": "Error message, appears when we lose our connection
to the wiki",
+ "feedback-dialog-intro": "An introduction at the top of the feedback
dialog. $1 - Feedback page link",
+ "feedback-message": "Label for a textarea; signature refers to a
Wikitext signature.\n{{Identical|Message}}",
+ "feedback-subject": "Label for a text input\n{{Identical|Subject}}",
+ "feedback-submit": "Button label\n{{Identical|Submit}}",
+ "feedback-terms": "Label for a checkbox asking for permissions to
submit browser information.",
+ "feedback-termsofuse": "Label with an agreement about the terms of
use.",
"feedback-thanks": "Thanks message, appears if feedback was successful.
Parameters:\n* $1 - \"Feedback\"\n* $2 - Feedback page URL",
- "feedback-close": "Button label\n{{Identical|Done}}",
- "feedback-bugcheck": "Message that appears before the user submits a
bug, reminding them to check for known bugs.\n\nParameters:\n* $1 - bug list
page URL",
- "feedback-bugnew": "Button label - asserts that the user has checked
for existing bugs. When clicked will launch a bugzilla form to add a new bug in
a new tab or window",
+ "feedback-thanks-title": "The title of the message dialog at the end of
the submission process that shows error in submitting the feedback.",
+ "feedback-thanks-title": "The title of the thank you dialog at the end
of the submission process.",
+ "feedback-useragent": "A label denoting the user agent in the feedback
that is posted to the feedback page.",
"searchsuggest-search": "Greyed out default text in the simple search
box in the Vector skin. (It disappears and lets the user enter the requested
search terms when the search box receives focus.)\n\n{{Identical|Search}}",
"searchsuggest-containing": "Label used in the special item of the
search suggestions list which gives the user an option to perform a full text
search for the term.",
"api-error-badaccess-groups": "API error message that can be used for
client side localisation of API errors.",
diff --git a/maintenance/jsduck/categories.json
b/maintenance/jsduck/categories.json
index 145905f..c0d0499 100644
--- a/maintenance/jsduck/categories.json
+++ b/maintenance/jsduck/categories.json
@@ -55,7 +55,8 @@
{
"name": "Interfaces",
"classes": [
- "mw.Feedback"
+ "mw.Feedback",
+ "mw.Feedback.Dialog"
]
},
{
diff --git a/resources/Resources.php b/resources/Resources.php
index 965c783..a9f383c 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -856,31 +856,36 @@
'position' => 'bottom',
),
'mediawiki.feedback' => array(
- 'templates' => array(
- 'dialog.html' =>
'resources/src/mediawiki/templates/dialog.html',
- ),
'scripts' => 'resources/src/mediawiki/mediawiki.feedback.js',
'styles' => 'resources/src/mediawiki/mediawiki.feedback.css',
'dependencies' => array(
'mediawiki.api.edit',
'mediawiki.Title',
- 'mediawiki.jqueryMsg',
- 'jquery.ui.dialog',
+ 'oojs-ui',
),
'messages' => array(
- 'feedback-bugornote',
- 'feedback-subject',
- 'feedback-message',
- 'feedback-cancel',
- 'feedback-submit',
'feedback-adding',
+ 'feedback-back',
+ 'feedback-bugcheck',
+ 'feedback-dialog-intro',
+ 'feedback-external-bug-report-button',
+ 'feedback-bugnew',
+ 'feedback-bugornote',
+ 'feedback-cancel',
+ 'feedback-close',
+ 'feedback-dialog-title',
+ 'feedback-error-title',
'feedback-error1',
'feedback-error2',
'feedback-error3',
+ 'feedback-message',
+ 'feedback-subject',
+ 'feedback-submit',
+ 'feedback-terms',
+ 'feedback-termsofuse',
'feedback-thanks',
- 'feedback-close',
- 'feedback-bugcheck',
- 'feedback-bugnew',
+ 'feedback-thanks-title',
+ 'feedback-useragent'
),
),
'mediawiki.hidpi' => array(
diff --git a/resources/src/mediawiki/mediawiki.feedback.css
b/resources/src/mediawiki/mediawiki.feedback.css
index 6bd47bb..f2859db 100644
--- a/resources/src/mediawiki/mediawiki.feedback.css
+++ b/resources/src/mediawiki/mediawiki.feedback.css
@@ -7,3 +7,16 @@
width: 18px;
height: 18px;
}
+
+.mw-feedbackDialog-welcome-message,
+.mw-feedbackDialog-feedback-terms {
+ line-height: 1.2em;
+}
+
+.mw-feedbackDialog-feedback-form {
+ margin-top: 1em;
+}
+
+.mw-feedbackDialog-feedback-termsofuse {
+ margin-left: 2.5em;
+}
diff --git a/resources/src/mediawiki/mediawiki.feedback.js
b/resources/src/mediawiki/mediawiki.feedback.js
index 867134c..da17222 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,263 +35,453 @@
*
* @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.Api} [api] if omitted, will just create a standard API
+ * @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 a combination of 'feedback-terms' and
'feedback-termsofuse' which includes a link to the
+ * wiki's Term of Use page.
*/
- 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.api = config.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';
- }
+ // Links
+ this.bugsTaskSubmissionLink = config.bugsLink ||
'//phabricator.wikimedia.org/maniphest/task/create/';
+ this.bugsTaskListLink = config.bugsListLink ||
'//phabricator.wikimedia.org/maniphest/query/advanced';
- if ( options.bugsLink === undefined ) {
- options.bugsLink =
'//bugzilla.wikimedia.org/enter_bug.cgi';
- }
+ // Terms of use
+ this.useragentCheckboxShow = !!config.showUseragentCheckbox;
+ this.useragentCheckboxMandatory =
!!config.useragentCheckboxMandatory;
+ this.useragentCheckboxMessage = config.useragentCheckboxMessage
||
+ $( '<p>' )
+ .append( mw.msg( 'feedback-terms' ) )
+ .add( $( '<p>' ).append( mw.message(
'feedback-termsofuse' ).parse() ) );
- if ( options.bugsListLink === undefined ) {
- options.bugsListLink =
'//bugzilla.wikimedia.org/query.cgi';
- }
-
- $.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;
+ /* Initialize */
+ OO.initClass( mw.Feedback );
- $feedbackPageLink = $( '<a>' )
- .attr( {
- href: fb.title.getUrl(),
- target: '_blank'
- } )
- .css( {
- whiteSpace: 'nowrap'
- } );
+ /* Static Properties */
+ mw.Feedback.static.windowManager = null;
+ mw.Feedback.static.dialog = null;
- $bugNoteLink = $( '<a>' ).attr( { href: '#' } ).click(
function () {
- fb.displayBugs();
- } );
+ /* Methods */
- $bugsListLink = $( '<a>' ).attr( {
- href: fb.bugsListLink,
- target: '_blank'
- } );
+ /**
+ * 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()
+ ),
+ actions: [
+ {
+ action: 'accept',
+ label: mw.msg(
'feedback-close' ),
+ flags: 'primary'
+ }
+ ]
+ };
+ break;
+ case 'error1':
+ case 'error2':
+ case 'error3':
+ dialogConfig = {
+ title: mw.msg( 'feedback-error-title' ),
+ message: mw.msg( 'feedback-' + status ),
+ actions: [
+ {
+ action: 'accept',
+ label: mw.msg(
'feedback-close' ),
+ flags: 'primary'
+ }
+ ]
+ };
+ break;
+ }
- // TODO: Use a stylesheet instead of these inline
styles in the template
- this.$dialog = mw.template.get( 'mediawiki.feedback',
'dialog.html' ).render();
- this.$dialog.find( '.feedback-mode small p' ).msg(
- 'feedback-bugornote',
- $bugNoteLink,
- fb.title.getNameText(),
- $feedbackPageLink.clone()
+ // Show the message dialog
+ if ( !$.isEmptyObject( dialogConfig ) ) {
+ this.constructor.static.windowManager.openWindow(
+ this.thankYouDialog,
+ dialogConfig
);
- this.$dialog.find( '.feedback-form .subject span'
).msg( 'feedback-subject' );
- this.$dialog.find( '.feedback-form .message span'
).msg( 'feedback-message' );
- this.$dialog.find( '.feedback-bugs p' ).msg(
'feedback-bugcheck', $bugsListLink );
- this.$dialog.find( '.feedback-submitting span' ).msg(
'feedback-adding' );
- this.$dialog.find( '.feedback-thanks' ).msg(
'feedback-thanks', fb.title.getNameText(),
- $feedbackPageLink.clone() );
-
- this.$dialog.dialog( {
- width: 500,
- autoOpen: false,
- title: mw.message( this.dialogTitleMessageKey
).escaped(),
- modal: true,
- buttons: fb.buttons
- } );
-
- this.subjectInput = this.$dialog.find(
'input.feedback-subject' ).get( 0 );
- this.messageInput = this.$dialog.find(
'textarea.feedback-message' ).get( 0 );
- },
-
- /**
- * 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();
- },
-
- /**
- * Display the submitting section.
- */
- displaySubmitting: function () {
- this.display( 'submitting' );
- },
-
- /**
- * 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
- } );
- },
-
- /**
- * 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
- } );
- },
-
- /**
- * 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
- },
-
- /**
- * 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 } );
- },
-
- /**
- * Close the feedback form.
- */
- cancel: function () {
- this.$dialog.dialog( 'close' );
- },
-
- /**
- * Submit the feedback form.
- */
- submit: function () {
- var subject, message,
- fb = this;
-
- // Get the values to submit.
- subject = $.trim( 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 = $.trim( this.messageInput.value );
- if ( message.indexOf( '~~~' ) === -1 ) {
- message += ' ~~~~';
- }
-
- this.displaySubmitting();
-
- // Post the message, resolving redirects
- this.api.newSection(
- this.title,
- subject,
- message,
- { redirect: true }
- )
- .done( function ( result ) {
- if ( result.edit.result === 'Success' ) {
- fb.displayThanks();
- } else {
- // unknown API result
- fb.displayError( 'feedback-error1' );
- }
- } )
- .fail( function ( code, result ) {
- if ( code === 'http' ) {
- // ajax request failed
- fb.displayError( 'feedback-error3' );
- mw.log.warn( 'Feedback report failed
with HTTP error: ' + result.textStatus );
- } else {
- fb.displayError( 'feedback-error2' );
- mw.log.warn( 'Feedback report failed
with API error: ' + code );
- }
- } );
- },
-
- /**
- * 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();
}
};
+
+ /**
+ * 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
+ */
+ 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: {
+ api: this.api,
+ title: this.feedbackPageTitle,
+ dialogTitleMessageKey:
this.dialogTitleMessageKey,
+ bugsTaskSubmissionLink:
this.bugsTaskSubmissionLink,
+ bugsTaskListLink: this.bugsTaskListLink,
+ useragentCheckbox: {
+ show:
this.useragentCheckboxShow,
+ mandatory:
this.useragentCheckboxMandatory,
+ message:
this.useragentCheckboxMessage
+ }
+ },
+ contents: contents
+ }
+ );
+ };
+
+ /**
+ * 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' );
+ };
+
+ 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' ]
+ },
+ {
+ action: 'external',
+ label: mw.msg( 'feedback-external-bug-report-button' ),
+ flags: 'constructive'
+ },
+ {
+ action: 'cancel',
+ label: mw.msg( 'feedback-cancel' ),
+ flags: 'safe'
+ }
+ ];
+
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.initialize = function () {
+ var feedbackSubjectFieldLayout, feedbackMessageFieldLayout,
+ feedbackFieldsetLayout;
+
+ // 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( {
+ 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'
+ } );
+
+ this.feedbackPanel.$element.append(
+ this.feedbackMessageLabel.$element,
+ feedbackFieldsetLayout.$element,
+ this.useragentFieldLayout.$element
+ );
+
+ // Events
+ this.feedbackSubjectInput.connect( this, { change:
'validateFeedbackForm' } );
+ this.feedbackMessageInput.connect( this, { change:
'validateFeedbackForm' } );
+ this.useragentCheckbox.connect( this, { change:
'validateFeedbackForm' } );
+
+ this.$body.append( this.feedbackPanel.$element );
+ };
+
+ /**
+ * 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 } );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ mw.Feedback.Dialog.prototype.getBodyHeight = function () {
+ return this.feedbackPanel.$element.outerHeight( true );
+ };
+
+ /**
+ * @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.api = settings.api;
+ 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 );
+ }
+ 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.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;
+ }
+
+ // Add signature if needed
+ if ( message.indexOf( '~~~' ) === -1 ) {
+ message += '\n\n~~~~';
+ }
+
+ // Post the message, resolving redirects
+ this.pushPending();
+ this.api.newSection(
+ this.feedbackPageTitle,
+ subject,
+ message,
+ { redirect: true }
+ )
+ .done( function ( result ) {
+ if ( result.edit.result === 'Success' )
{
+ fb.status = 'submitted';
+ } else {
+ fb.status = 'error1';
+ }
+ fb.popPending();
+ fb.close();
+ } )
+ .fail( function ( code, result ) {
+ if ( code === 'http' ) {
+ fb.status = 'error3';
+ // ajax request failed
+ mw.log.warn( 'Feedback report
failed with HTTP error: ' + result.textStatus );
+ } else {
+ fb.status = 'error2';
+ mw.log.warn( 'Feedback report
failed with API error: ' + code );
+ }
+ fb.popPending();
+ fb.close();
+ } );
+ }, this );
+ }
+ // Fallback to parent handler
+ return
mw.Feedback.Dialog.super.prototype.getActionProcess.call( this, action );
+ };
+
+ /**
+ * @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 ) );
diff --git a/resources/src/mediawiki/templates/dialog.html
b/resources/src/mediawiki/templates/dialog.html
deleted file mode 100644
index e116f3e..0000000
--- a/resources/src/mediawiki/templates/dialog.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<div style="position: relative; display: block;" class="ui-dialog-content
ui-widget-content">
- <div class="feedback-mode feedback-form">
- <small><p></p></small>
- <div class="subject" style="margin-top: 1em;">
- <span></span><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>
- <div class="message" style="margin-top: 0.4em;">
- <span></span><br>
- <textarea name="message" class="feedback-message"
rows="5" cols="60"></textarea>
- </div>
- </div>
- <div class="feedback-mode feedback-bugs">
- <p></p>
- </div>
- <div class="feedback-mode feedback-submitting" style="text-align:
center; margin: 3em 0;">
- <span></span><br>
- <span class="feedback-spinner"></span>
- </div>
- <div class="feedback-mode feedback-thanks" style="text-align: center;
margin:1em"></div>
- <div class="feedback-mode feedback-error" style="position: relative;">
- <div class="feedback-error-msg" style=" color:#990000;
margin-top:0.4em;"></div>
- </div>
-</div>
--
To view, visit https://gerrit.wikimedia.org/r/192749
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id1967a83a502f689c40f1af71398c3be99e30640
Gerrit-PatchSet: 13
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <[email protected]>
Gerrit-Reviewer: Alex Monk <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Jack Phoenix <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Mooeypoo <[email protected]>
Gerrit-Reviewer: Ricordisamoa <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits