Make the templates/category lists on edit page collapsible
authorMatmaRex <matma.rex@gmail.com>
Sat, 23 Mar 2013 15:36:14 +0000 (16:36 +0100)
committerTim Starling <tstarling@wikimedia.org>
Fri, 26 Jul 2013 05:20:32 +0000 (05:20 +0000)
This is a total rewrite of Vector extension's functionality, to fix
various accessibility and internationalization issues with the
original one. Both the JavaScript and the CSS have been redone from
scratch.

Still, the look&feel is almost the same as in the original version,
save for the mentioned messaging changes and minor UI differences (the
toggles are no longer <a> elements). The same cookie names have been
used to avoid any issues when migrating.

Used standard arrow icons from the mediawiki.icon module.

Bug: 43689
Change-Id: I91a3704cb09b9e17dd8baa516ab6f8ee441b7467

RELEASE-NOTES-1.22
includes/EditPage.php
resources/Resources.php
resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css [new file with mode: 0644]
resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js [new file with mode: 0644]

index 318f592..f996204 100644 (file)
@@ -114,6 +114,9 @@ production.
 * LinkCache singleton can now be altered or cleared, letting one to specify
   another instance that does not rely on a database backend.
 * MediaWiki's PHPUnit tests can now use PHPUnit installed using composer --dev.
+* (bug 43689) The lists of templates used on the page and hidden categories it
+  is a member of, shown below the edit form, are now collapsible (and collapsed
+  by default).
 * New user rights have been added to increase granularity in rights management
   for extensions such as OAuth:
 ** editmyusercss controls whether a user may edit their own CSS subpages.
index c41d9a1..36ec741 100644 (file)
@@ -521,6 +521,8 @@ class EditPage {
                $wgOut->addHTML( Html::rawElement( 'div', array( 'class' => 'templatesUsed' ),
                        Linker::formatTemplates( $this->getTemplates() ) ) );
 
+               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+
                if ( $this->mTitle->exists() ) {
                        $wgOut->returnToMain( null, $this->mTitle );
                }
@@ -2270,6 +2272,8 @@ class EditPage {
                $wgOut->addHTML( Html::rawElement( 'div', array( 'class' => 'hiddencats' ),
                        Linker::formatHiddenCategories( $this->mArticle->getHiddenCategories() ) ) );
 
+               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+
                if ( $this->isConflict ) {
                        try {
                                $this->showConflict();
index 02cde52..6352843 100644 (file)
@@ -725,6 +725,14 @@ return array(
                ),
                'position' => 'top',
        ),
+       'mediawiki.action.edit.collapsibleFooter' => array(
+               'scripts' => 'resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js',
+               'styles' => 'resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css',
+               'dependencies' => array(
+                       'jquery.makeCollapsible',
+                       'mediawiki.icon',
+               ),
+       ),
        'mediawiki.action.edit.preview' => array(
                'scripts' => 'resources/mediawiki.action/mediawiki.action.edit.preview.js',
                'dependencies' => array(
diff --git a/resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css b/resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css
new file mode 100644 (file)
index 0000000..89f54c4
--- /dev/null
@@ -0,0 +1,11 @@
+/* Styles for collapsible lists of templates used and hidden categories */
+.mw-editfooter-toggler {
+       cursor: pointer;
+       background-position: left center;
+       padding-left: 16px;
+}
+
+.mw-editfooter-list {
+       margin-bottom: 1em;
+       margin-left: 2.5em;
+}
diff --git a/resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js b/resources/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js
new file mode 100644 (file)
index 0000000..0fb5912
--- /dev/null
@@ -0,0 +1,49 @@
+jQuery( document ).ready( function ( $ ) {
+       var collapsibleLists, i, handleOne;
+
+       // Collapsible lists of categories and templates
+       collapsibleLists = [
+               {
+                       $list: $( '.templatesUsed ul' ),
+                       $toggler: $( '.mw-templatesUsedExplanation' ),
+                       cookieName: 'templates-used-list'
+               },
+               {
+                       $list: $( '.hiddencats ul' ),
+                       $toggler: $( '.mw-hiddenCategoriesExplanation' ),
+                       cookieName: 'hidden-categories-list'
+               }
+       ];
+
+       handleOne = function ( $list, $toggler, cookieName ) {
+               var isCollapsed = $.cookie( cookieName ) !== 'expanded';
+
+               // Style the toggler with an arrow icon and add a tabIndex and a role for accessibility
+               $toggler.addClass( 'mw-editfooter-toggler' ).prop( 'tabIndex', 0 ).attr( 'role', 'button' );
+               $list.addClass( 'mw-editfooter-list' );
+
+               $list.makeCollapsible( {
+                       $customTogglers: $toggler,
+                       linksPassthru: true,
+                       plainMode: true,
+                       collapsed: isCollapsed
+               } );
+
+               $toggler.addClass( isCollapsed ? 'mw-icon-arrow-collapsed' : 'mw-icon-arrow-expanded' );
+
+               $list.on( 'beforeExpand.mw-collapsible', function () {
+                       $toggler.removeClass( 'mw-icon-arrow-collapsed' ).addClass( 'mw-icon-arrow-expanded' );
+                       $.cookie( cookieName, 'expanded' );
+               } );
+
+               $list.on( 'beforeCollapse.mw-collapsible', function () {
+                       $toggler.removeClass( 'mw-icon-arrow-expanded' ).addClass( 'mw-icon-arrow-collapsed' );
+                       $.cookie( cookieName, 'collapsed' );
+               } );
+       };
+
+       for ( i = 0; i < collapsibleLists.length; i++ ) {
+               // Pass to a function for iteration-local variables
+               handleOne( collapsibleLists[i].$list, collapsibleLists[i].$toggler, collapsibleLists[i].cookieName );
+       }
+} );