Improve HTMLForm (and Special:ChangeCredentials) cancel button
authorGergő Tisza <gtisza@wikimedia.org>
Thu, 2 Jun 2016 14:17:13 +0000 (14:17 +0000)
committerGergő Tisza <gtisza@wikimedia.org>
Thu, 2 Jun 2016 19:42:44 +0000 (19:42 +0000)
Add two new HTMLForm methods:
* showCancel( [bool] ) to display a cancel button
* setCancelTarget( Title|string ) to set where it should take
  the user.

The cancel button is a simple link formatted as a button.
This is faster than a real button (skips an unnecessary
submit and redirect) and avoids some UX problems:
* when clicking on a real button, HTML5 or JS  validators
  might prevent submission, which does not make sense for cancel
* form field values might get saved by the brower, which again
  does not make sense for cancelling

Use the cancel button for Special:ChangeCredentials.

Bug: T136809
Change-Id: Ieb80e2ff36751abc6f00e2a02926fe9800666a8b

includes/htmlform/HTMLForm.php
includes/htmlform/OOUIHTMLForm.php
includes/htmlform/VFormHTMLForm.php
includes/specials/SpecialChangeCredentials.php
languages/i18n/en.json
languages/i18n/qqq.json

index de3e0ae..f073717 100644 (file)
@@ -169,6 +169,8 @@ class HTMLForm extends ContextSource {
        protected $mShowReset = false;
        protected $mShowSubmit = true;
        protected $mSubmitFlags = [ 'constructive', 'primary' ];
+       protected $mShowCancel = false;
+       protected $mCancelTarget;
 
        protected $mSubmitCallback;
        protected $mValidationErrorMessage;
@@ -1108,6 +1110,22 @@ class HTMLForm extends ContextSource {
                        ) . "\n";
                }
 
+               if ( $this->mShowCancel ) {
+                       $target = $this->mCancelTarget ?: Title::newMainPage();
+                       if ( $target instanceof Title ) {
+                               $target = $target->getLocalURL();
+                       }
+                       $buttons .= Html::element(
+                                       'a',
+                                       [
+                                               'type' => 'reset',
+                                               'class' => $useMediaWikiUIEverywhere ? 'mw-ui-button' : null,
+                                               'href' => $target,
+                                       ],
+                                       $this->msg( 'cancel' )->text()
+                               ) . "\n";
+               }
+
                // IE<8 has bugs with <button>, so we'll need to avoid them.
                $isBadIE = preg_match( '/MSIE [1-7]\./i', $this->getRequest()->getHeader( 'User-Agent' ) );
 
@@ -1326,6 +1344,28 @@ class HTMLForm extends ContextSource {
                return $this;
        }
 
+       /**
+        * Show a cancel button (or prevent it). The button is not shown by default.
+        * @param bool $show
+        * @return HTMLForm $this for chaining calls
+        * @since 1.27
+        */
+       public function showCancel( $show = true ) {
+               $this->mShowCancel = $show;
+               return $this;
+       }
+
+       /**
+        * Sets the target where the user is redirected to after clicking cancel.
+        * @param Title|string $target Target as a Title object or an URL
+        * @return HTMLForm $this for chaining calls
+        * @since 1.27
+        */
+       public function setCancelTarget( $target ) {
+               $this->mCancelTarget = $target;
+               return $this;
+       }
+
        /**
         * Set the id of the \<table\> or outermost \<div\> element.
         *
index e5e2d7c..0b22727 100644 (file)
@@ -86,6 +86,17 @@ class OOUIHTMLForm extends HTMLForm {
                        ] );
                }
 
+               if ( $this->mShowCancel ) {
+                       $target = $this->mCancelTarget ?: Title::newMainPage();
+                       if ( $target instanceof Title ) {
+                               $target = $target->getLocalURL();
+                       }
+                       $buttons .= new OOUI\ButtonWidget( [
+                               'label' => $this->msg( 'cancel' )->text(),
+                               'href' => $target,
+                       ] );
+               }
+
                foreach ( $this->mButtons as $button ) {
                        $attrs = [];
 
index f3cba48..3adab70 100644 (file)
@@ -116,6 +116,22 @@ class VFormHTMLForm extends HTMLForm {
                        ) . "\n";
                }
 
+               if ( $this->mShowCancel ) {
+                       $target = $this->mCancelTarget ?: Title::newMainPage();
+                       if ( $target instanceof Title ) {
+                               $target = $target->getLocalURL();
+                       }
+                       $buttons .= Html::element(
+                                       'a',
+                                       [
+                                               'type' => 'reset',
+                                               'class' => 'mw-ui-button mw-ui-big mw-ui-block',
+                                               'href' => $target,
+                                       ],
+                                       $this->msg( 'cancel' )->text()
+                               ) . "\n";
+               }
+
                foreach ( $this->mButtons as $button ) {
                        $attrs = [
                                'type' => 'submit',
index 382dac7..4da8049 100644 (file)
@@ -81,12 +81,6 @@ class SpecialChangeCredentials extends AuthManagerSpecialPage {
                        return;
                }
 
-               if ( $this->getRequest()->getCheck( 'wpCancel' ) ) {
-                       $returnUrl = $this->getReturnUrl() ?: Title::newMainPage()->getFullURL();
-                       $this->getOutput()->redirect( $returnUrl );
-                       return;
-               }
-
                if ( !$this->authRequests ) {
                        // messages used: changecredentials-invalidsubpage, removecredentials-invalidsubpage
                        $this->showSubpageList( $this->msg( static::$messagePrefix . '-invalidsubpage', $subPage ) );
@@ -149,12 +143,8 @@ class SpecialChangeCredentials extends AuthManagerSpecialPage {
                );
 
                // messages used: changecredentials-submit removecredentials-submit
-               // changecredentials-submit-cancel removecredentials-submit-cancel
                $form->setSubmitTextMsg( static::$messagePrefix . '-submit' );
-               $form->addButton( [
-                       'name' => 'wpCancel',
-                       'value' => $this->msg( static::$messagePrefix . '-submit-cancel' )->text()
-               ] );
+               $form->showCancel()->setCancelTarget( $this->getReturnUrl() ?: Title::newMainPage() );
 
                return $form;
        }
index f135f40..e6a8141 100644 (file)
        "cannotauth-not-allowed": "You are not allowed to use this page",
        "changecredentials" : "Change credentials",
        "changecredentials-submit": "Change credentials",
-       "changecredentials-submit-cancel": "Cancel",
        "changecredentials-invalidsubpage": "$1 is not a valid credential type.",
        "changecredentials-success": "Your credentials have been changed.",
        "removecredentials" : "Remove credentials",
        "removecredentials-submit": "Remove credentials",
-       "removecredentials-submit-cancel": "Cancel",
        "removecredentials-invalidsubpage": "$1 is not a valid credential type.",
        "removecredentials-success": "Your credentials have been removed.",
        "credentialsform-provider": "Credentials type:",
index e2a4f8b..ad9a372 100644 (file)
        "cannotauth-not-allowed": "Text of the error page shown when the user tries t use an authentication-related page they should not have access to.",
        "changecredentials": "Title of the special page [[Special:ChangeCredentials]] which allows changing authentication credentials (such as the password).",
        "changecredentials-submit": "Used on [[Special:ChangeCredentials]].",
-       "changecredentials-submit-cancel": "Used on [[Special:ChangeCredentials]].\n{{Identical|Cancel}}",
        "changecredentials-invalidsubpage": "Error message shown when using [[Special:ChangeCredentials]] with an invalid type.\n\nParameters:\n* $1 - subpage name.",
        "changecredentials-success": "Success message after using [[Special:ChangeCredentials]].",
        "removecredentials": "Title of the special page [[Special:RemoveCredentials]] which allows removing authentication credentials (such as a two-factor token).",
        "removecredentials-submit": "Used on [[Special:RemoveCredentials]].",
-       "removecredentials-submit-cancel": "Used on [[Special:RemoveCredentials]].\n{{Identical|Cancel}}",
        "removecredentials-invalidsubpage": "Error message shown when using [[Special:RemoveCredentials]] with an invalid type.\n\nParameters:\n* $1 - subpage name.",
        "removecredentials-success": "Success message after using [[Special:RemoveCredentials]].",
        "credentialsform-provider": "Shown on [[Special:ChangeCredentials]]/[[Special:RemoveCredentials]] as the label for the authentication type (e.g. \"password\", \"English Wikipedia via OAuth\")",