Merge "Deprecate assertException in MediaWikiTestCase as it adds no value"
[lhc/web/wiklou.git] / resources / mediawiki / mediawiki.feedback.js
index bf9cf60..1afe51e 100644 (file)
-( function( mw, $, undefined ) {
-
+/**
+ * mediawiki.feedback
+ *
+ * @author Ryan Kaldari, 2010
+ * @author Neil Kandalgaonkar, 2010-11
+ * @since 1.19
+ *
+ * This is a way of getting simple feedback from users. It's useful
+ * for testing new features -- users can give you feedback without
+ * the difficulty of opening a whole new talk page. For this reason,
+ * it also tends to collect a wider range of both positive and negative
+ * comments. However you do need to tend to the feedback page. It will
+ * get long relatively quickly, and you often get multiple messages
+ * reporting the same issue.
+ *
+ * It takes the form of thing on your page which, when clicked, opens a small
+ * dialog box. Submitting that dialog box appends its contents to a
+ * wiki page that you specify, as a new section.
+ *
+ * Not compatible with LiquidThreads.
+ *
+ * Minimal example in how to use it:
+ *
+ *    var feedback = new mw.Feedback();
+ *    $( '#myButton' ).click( function () { feedback.launch(); } );
+ *
+ * You can also launch the feedback form with a prefilled subject and body.
+ * See the docs for the launch() method.
+ */
+( function ( mw, $ ) {
        /**
         * Thingy for collecting user feedback on a wiki page
-        * @param {mw.Api}  api properly configured to talk to this wiki
-        * @param {mw.Title} the title of the page where you collect feedback
-        * @param {id} a string identifying this feedback form to separate it from others on the same page
+        * @param {Array} options -- optional, all properties optional.
+        *  api: {mw.Api} if omitted, will just create a standard API
+        *  title: {mw.Title} the title of the page where you collect feedback. Defaults to "Feedback".
+        *  dialogTitleMessageKey: {String} message key for the title of the dialog box
+        *  bugsLink: {mw.Uri|String} url where bugs can be posted
+        *  bugsListLink: {mw.Uri|String} url where bugs can be listed
         */
-       mw.Feedback = function( api, feedbackTitle ) {
-               var _this = this;
-               this.api = api;
-               this.feedbackTitle = feedbackTitle;
+       mw.Feedback = function ( options ) {
+               if ( options === undefined ) {
+                       options = {};
+               }
+
+               if ( options.api === undefined ) {
+                       options.api = new mw.Api();
+               }
+
+               if ( options.title === undefined ) {
+                       options.title = new mw.Title( 'Feedback' );
+               }
+
+               if ( options.dialogTitleMessageKey === undefined ) {
+                       options.dialogTitleMessageKey = 'feedback-submit';
+               }
+
+               if ( options.bugsLink === undefined ) {
+                       options.bugsLink = '//bugzilla.wikimedia.org/enter_bug.cgi';
+               }
+
+               if ( options.bugsListLink === undefined ) {
+                       options.bugsListLink = '//bugzilla.wikimedia.org/query.cgi';
+               }
+
+               $.extend( this, options );
                this.setup();
        };
 
        mw.Feedback.prototype = {
-               setup: function() {
-                       var _this = this;
+               setup: function () {
+                       var $feedbackPageLink,
+                               $bugNoteLink,
+                               $bugsListLink,
+                               fb = this;
 
-                       // Set up buttons for dialog box. We have to do it the hard way since the json keys are localized
-                       _this.buttons = {};
-                       _this.buttons[ mw.msg( 'mwe-upwiz-feedback-cancel' ) ] = function() { _this.cancel(); };
-                       _this.buttons[ mw.msg( 'mwe-upwiz-feedback-submit' ) ] = function() { _this.submit(); };
-                               
-                       var $feedbackPageLink = $j( '<a></a>' ).attr( { 'href': _this.feedbackTitle.getUrl(), 'target': '_blank' } );
-                       this.$dialog = 
-                               $( '<div style="position:relative;"></div>' ).append( 
-                                       $( '<div class="mwe-upwiz-feedback-mode mwe-upwiz-feedback-form"></div>' ).append( 
-                                               $( '<div style="margin-top:0.4em;"></div>' ).append( 
-                                                       $( '<small></small>' ).msg( 'mwe-upwiz-feedback-note', 
-                                                                                   _this.feedbackTitle.getNameText(), 
-                                                                                   $feedbackPageLink ) 
+                       $feedbackPageLink = $( '<a>' )
+                               .attr( {
+                                       href: fb.title.getUrl(),
+                                       target: '_blank'
+                               } )
+                               .css( {
+                                       whiteSpace: 'nowrap'
+                               } );
+
+                       $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>' ).append( 
-                                                       mw.msg( 'mwe-upwiz-feedback-subject' ), 
-                                                       $( '<br/>' ), 
-                                                       $( '<input type="text" class="mwe-upwiz-feedback-subject" name="subject" maxlength="60" style="width:99%;"/>' ) 
+                                               $( '<div style="margin-top: 1em;"></div>' ).append(
+                                                       mw.msg( 'feedback-subject' ),
+                                                       $( '<br>' ),
+                                                       $( '<input type="text" class="feedback-subject" name="subject" maxlength="60" style="width: 99%;"/>' )
                                                ),
-                                               $( '<div style="margin-top:0.4em;"></div>' ).append( 
-                                                       mw.msg( 'mwe-upwiz-feedback-message' ), 
-                                                       $( '<br/>' ), 
-                                                       $( '<textarea name="message" class="mwe-upwiz-feedback-message" style="width:99%;" rows="5" cols="60"></textarea>' ) 
+                                               $( '<div style="margin-top: 0.4em;"></div>' ).append(
+                                                       mw.msg( 'feedback-message' ),
+                                                       $( '<br>' ),
+                                                       $( '<textarea name="message" class="feedback-message" style="width: 99%;" rows="5" cols="60"></textarea>' )
                                                )
                                        ),
-                                       $( '<div class="mwe-upwiz-feedback-mode mwe-upwiz-feedback-submitting" style="text-align:center;margin:3em 0;"></div>' ).append( 
-                                               mw.msg( 'mwe-upwiz-feedback-adding' ), 
-                                               $( '<br/>' ), 
-                                               $( '<img src="http://upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif" />' ) 
+                                       $( '<div class="feedback-mode feedback-bugs"></div>' ).append(
+                                               $( '<p>' ).msg( 'feedback-bugcheck', $bugsListLink )
                                        ),
-                                       $( '<div class="mwe-upwiz-feedback-mode mwe-upwiz-feedback-error" style="position:relative;"></div>' ).append( 
-                                               $( '<div class="mwe-upwiz-feedback-error-msg style="color:#990000;margin-top:0.4em;"></div>' )
-
+                                       $( '<div class="feedback-mode feedback-submitting" style="text-align: center; margin: 3em 0;"></div>' ).append(
+                                               mw.msg( 'feedback-adding' ),
+                                               $( '<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()
+                                       ),
+                                       $( '<div class="feedback-mode feedback-error" style="position: relative;"></div>' ).append(
+                                               $( '<div class="feedback-error-msg style="color: #990000; margin-top: 0.4em;"></div>' )
                                        )
-                               ).dialog({
+                               );
+
+                               // undo some damage from dialog css
+                               this.$dialog.find( 'a' ).css( {
+                                       color: '#0645ad'
+                               } );
+
+                               this.$dialog.dialog({
                                        width: 500,
                                        autoOpen: false,
-                                       title: mw.msg( 'mwe-upwiz-feedback-title' ),
+                                       title: mw.msg( this.dialogTitleMessageKey ),
                                        modal: true,
-                                       buttons: _this.buttons
-                               }); 
+                                       buttons: fb.buttons
+                               });
+
+                       this.subjectInput = this.$dialog.find( 'input.feedback-subject' ).get(0);
+                       this.messageInput = this.$dialog.find( 'textarea.feedback-message' ).get(0);
 
-                       this.subjectInput = this.$dialog.find( 'input.mwe-upwiz-feedback-subject' ).get(0);
-                       this.messageInput = this.$dialog.find( 'textarea.mwe-upwiz-feedback-message' ).get(0);
-                       this.displayForm();             
                },
 
-               display: function( s ) {
+               display: function ( s ) {
                        this.$dialog.dialog( { buttons:{} } ); // hide the buttons
-                       this.$dialog.find( '.mwe-upwiz-feedback-mode' ).hide(); // hide everything
-                       this.$dialog.find( '.mwe-upwiz-feedback-' + s ).show(); // show the desired div 
+                       this.$dialog.find( '.feedback-mode' ).hide(); // hide everything
+                       this.$dialog.find( '.feedback-' + s ).show(); // show the desired div
                },
 
-               displaySubmitting: function() { 
+               displaySubmitting: function () {
                        this.display( 'submitting' );
                },
 
-               displayForm: function( contents ) {
-                       this.subjectInput.value = (contents && contents.subject) ? contents.subject : '';
-                       this.messageInput.value = (contents && contents.message) ? contents.message : '';
-                                               
-                       this.display( 'form' ); 
-                       this.$dialog.dialog( { buttons: this.buttons } ); // put the buttons back
+               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
+                       } );
                },
 
-               displayError: function( message ) {
-                       this.display( 'error' );
-                       this.$dialog.find( '.mwe-upwiz-feedback-error-msg' ).msg( message ); 
+               displayThanks: function () {
+                       var fb = this,
+                               closeButton = {};
+                       this.display( 'thanks' );
+                       closeButton[ mw.msg( 'feedback-close' ) ] = function () {
+                               fb.$dialog.dialog( 'close' );
+                       };
+                       this.$dialog.dialog( {
+                               buttons: closeButton
+                       } );
                },
 
-               cancel: function() { 
-                       this.$dialog.dialog( 'close' );
-               },
+               /**
+                * Display the feedback form
+                * @param {Object} optional prefilled contents for the feedback form. Object with properties:
+                *  subject: {String}
+                *      message: {String}
+                */
+               displayForm: function ( contents ) {
+                       var fb = this,
+                               formButtons = {};
+                       this.subjectInput.value = ( contents && contents.subject ) ? contents.subject : '';
+                       this.messageInput.value = ( contents && contents.message ) ? contents.message : '';
 
-               submit: function() {
-                       var _this = this;
+                       this.display( 'form' );
 
-                       // get the values to submit
-                       var subject = this.subjectInput.value;
+                       // 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
+               },
 
-                       var message = "<small>User agent: " + navigator.userAgent + "</small>\n\n"
-                                + this.messageInput.value;
-                       if ( message.indexOf( '~~~' ) == -1 ) {
-                               message += " ~~~~";
-                       }
+               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 } );
+               },
 
-                       this.displaySubmitting();
+               cancel: function () {
+                       this.$dialog.dialog( 'close' );
+               },
 
-                       var ok = function( result ) {
+               submit: function () {
+                       var subject, message,
+                               fb = this;
+
+                       function ok( result ) {
                                if ( result.edit !== undefined ) {
                                        if ( result.edit.result === 'Success' ) {
-                                               _this.$dialog.dialog( 'close' ); // edit complete, close dialog box
+                                               fb.displayThanks();
                                        } else {
-                                               _this.displayError( 'mwe-upwiz-feedback-error1' ); // unknown API result
+                                               // unknown API result
+                                               fb.displayError( 'feedback-error1' );
                                        }
                                } else {
-                                       displayError( 'mwe-upwiz-feedback-error2' ); // edit failed
+                                       // edit failed
+                                       fb.displayError( 'feedback-error2' );
                                }
-                       };
+                       }
 
-                       var err = function( code, info ) {
-                               displayError( 'mwe-upwiz-feedback-error3' ); // ajax request failed
-                       };
-               
-                       this.api.newSection( this.feedbackTitle, subject, message, ok, err );
+                       function err() {
+                               // ajax request failed
+                               fb.displayError( 'feedback-error3' );
+                       }
 
-               }, // close submit button function
+                       // 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 += ' ~~~~';
+                       }
 
-               launch: function( contents ) {
+                       this.displaySubmitting();
+
+                       this.api.newSection( this.title, subject, message, ok, err );
+               },
+
+               /**
+                * Modify the display form, and then open it, focusing interface on the subject.
+                * @param {Object} optional prefilled contents for the feedback form. Object with properties:
+                *                                              subject: {String}
+                *                                              message: {String}
+                */
+               launch: function ( contents ) {
                        this.displayForm( contents );
                        this.$dialog.dialog( 'open' );
                        this.subjectInput.focus();
-               }       
+               }
 
        };
 
-
-} )( window.mediaWiki, jQuery );
+}( mediaWiki, jQuery ) );