User:PerfektesChaos/js/resultListSort/d.js

/// mw:User:PerfektesChaos/js/resultListSort/d.js /// 2012-10-29 PerfektesChaos@de.wikipedia // Sort result lists of "Whatlinkshere", "Search" or other special pages. // ResourceLoader: compatible; dependencies: user, mediawiki.util /// Fingerprint: #0#0# /// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA) /// /* jshint curly:true, eqeqeq:true, undef:true, white:false            */ /* global window:false, document:false, jQuery:false, mediaWiki:false */ /*jslint forin: true, plusplus: true, vars: true, white: true         */ /*globals document, jQuery, mediaWiki, window                         */

( function ( mw, $ ) {  "use strict";   var RLS;   if ( typeof mw.libs.resultListSort !== "object"  || ! mw.libs.resultListSort ) {     mw.libs.resultListSort  =  { };   }   RLS             =  mw.libs.resultListSort;   RLS.vsn         =  -1.11;   RLS.type        =  "resultListSort";   RLS.canonicals  =  [ // General Purpose                        "Contributions",                        "LinkSearch",                        "Newpages",                        "Recentchanges",                        "Search",                        "Watchlist",                        "Whatlinkshere",                        // transform table into list                        "Allpages",                        "Prefixindex",                        // Maintenance                        "BrokenRedirects",                        "Deadendpages",                        "Fewestrevisions",                        "DoubleRedirects",                        "Lonelypages",                        "Longpages",                        "Protectedpages", "Protectedtitles", "Shortpages", "Uncategorizedcategories", "Uncategorizedimages", "Uncategorizedpages", "Uncategorizedtemplates", "Unusedcategories", "Unusedimages", "Unusedtemplates", "Wantedcategories", "Wantedfiles", "Wantedpages", "Wantedtemplates" ]; RLS.script     =  "javascript"; RLS.modeDirect =   0;  // direct child RLS.modeContr  =   1;  // Contributions RLS.modeLink2  =   2;  // LinkSearch RLS.modeSRH    =   3;  // .mw-search-result-heading RLS.modeSize   =  21;  // Newpages size RLS.modeSumm   =  22;  // Newpages summary RLS.modeURL    =  23;  // LinkSearch URL RLS.modeUser   =  24;  // Newpages user RLS.modeColumn =  -1;  // transform table into list RLS.unsorted   =  [ "Search", "LinkSearch", "Whatlinkshere" ]; if ( typeof RLS.debugging !== "object" ) { RLS.debugging =  { loud: true, say: "RLS" }; } //mw.log({loud:true},".",0);

// User options: // .auto // .casing // .group // .portlet

/*   * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as   * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. *   * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *   * You should have received a copy of the GNU General Public License * along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html */

// Requires: JavaScript 1.3 //          ECMA        262-3 § 11.8.5  (string comparison operators) //          MediaWiki   1.18 (mw.libs, jQuery core)

RLS.texts =  { // 2012-10-29 PerfektesChaos@de.wikipedia "byName":   {"en": "Sort results", "de": "Sortiere Ergebnisseiten"}, "bySize":   {"en": "Sort by size", "de": "Sortiere nach Größe"}, "bySummary": {"en": "Sort by summary", "de": "Sortiere nach BK"}, "byURL":    {"en": "URL Sort", "de": "Sortiere nach URL"}, "byUser":   {"en": "Sort by user", "de": "Sortiere nach Benutzer"}, "OL":       {"en": "As list", "de": "Als Liste"} };  // .texts

RLS.factory =  function ( access, action ) { // Insert portlet link // Precondition: //   access  -- text distinguisher ("by") //   action  -- mode code // Uses: //   this //   >  .slang //   >  .texts //   >  .script //   >  .vsn //   >< .controls //   mw.util.addPortletLink //   (.flip) // 2012-10-29 PerfektesChaos@de.wikipedia var dom; var s      =  ( action < 0  ?  access  :  "by" + access ); var script =  this.script + ":mw.libs.resultListSort.flip(" + action + ");" + "void(0);"; var show   =  this.texts[ s ][ this.slang ]; var signal =  show + " * resultListSort " + this.vsn; var slot   =  ( action < 0  ?  "ca-format-" + access                                   :  "ca-sort-by" + access ); if ( ! show ) { show =  this.texts[ s ].en; }     dom  =  mw.util.addPortletLink( "p-cactions",                                      script,                                      show,                                      slot,                                      signal,                                      null,                                      null ); if ( ! this.controls ) { this.controls =  {}; }     if ( ! this.controls[ action ] ) { this.controls[ action ] =  { lazy: false, dom: dom, text: show }; } else { this.controls[ action ].lazy =  false; }  };   // .factory

RLS.fair =  function ( $access ) { // Make sortable element from jQuery list item // Precondition: //   $access  -- jQuery list item // Postcondition: //   Returns   [ $access, ns, title, talkmod, oldid ] // Uses: //   this //   >  .mode //   >  .modeURL //   >  .reNS //   >  .space2num //   >  .group //   >  .casing //   >  .modeContr //   .fetch // 2012-07-29 PerfektesChaos@de.wikipedia var g;     var k   =  0; var m  =  0; var n  =  0; var p;     var s   =  this.fetch( $access ); if ( s ) { if ( RLS.mode !== RLS.modeURL ) { g =  this.reNS.exec( s ); if ( g ) { p =  g[ 1 ].toLowerCase; n =  this.space2num[ p ]; s =  s.substr( p.length + 1 );   // decodeURI if ( RLS.group ) { m =  n % 2; n =  ( n - m )  /  2; }           }            if ( RLS.casing ) { s =  s.toLowerCase; }           if ( RLS.mode === RLS.modeContr ) { p =  $access.children( "a" ).attr( "href" ); p =  /[&?]oldid=([0-9]+)(?:&.*)?$/.exec( p ); if (p) { k =  parseInt( p[1], 10 ); }           }         }      } else { s =  ""; }     return  [ $access, n, s, m, k ]; };  // .fair

RLS.favorite =  function  { // Guess user language // Uses: //   this //   >< .slang //   mw.config.get // 2012-10-29 PerfektesChaos@de.wikipedia if ( ! this.slang ) { this.slang =  mw.config.get( "wgUserLanguage" ).toLowerCase; switch ( this.slang ) { case "de" : case "de-at" : case "de-ch" : case "de-formal" : case "als" : case "nds" : this.slang =  "de"; break; default: this.slang =  "en"; }  // switch wgUserLanguage }  };   // .favorite

RLS.fetch =  function ( $access ) { // Retrieve distinguisher from jQuery list item // Precondition: //   $access  -- jQuery list item // Postcondition: //   Returns namespace:title string // Uses: //   this //   >  .mode //   >  .modeDirect //   >  .modeContr //   >  .modeLink2 //   >  .modeSize //   >  .modeSRH //   >  .modeSumm //   >  .modeURL //   >  .modeUser // 2012-10-29 PerfektesChaos@de.wikipedia var j   =  0; var r   =  false; var sub =  "a"; var $s  =  false; switch ( this.mode ) { case this.modeContr : case this.modeDirect : $s =  $access; break; case this.modeLink2 : $s =  $access; j  =  1; break; case this.modeSize : r =  $access.children( ".mw-newpages-length" ).text; if ( r ) { r =  r.replace( /\[?([.0-9]+)[^0-9].*/, "$1" ); r =  "            ".substr( 0, 13 - r.length )  +  r; /*                    123456789012 r =  r.replace( /\./g, "" );   parseint(,10); }           break; case this.modeSRH : $s =  $access.children( ".mw-search-result-heading" ); break; case this.modeSumm : r =  $access.children( ".comment" ).text; break; case this.modeURL : r =  $access.children( "a" ).attr( "href" ); break; case this.modeUser : $s  =  $access.children( ".mw-userlink" ); sub =  false; break; }  // switch .mode if ( $s ) { if ( $s.length ) { if ( sub ) { $s =  $s.children( sub ); if ( j ) { $s =  $s.eq( j ); }           }            r  =  $s.attr( "title" ); }     }      return  r;   };   // .fetch

RLS.fiat =  function  { // Ensure namespace RegExp and list objects // Postcondition: //   configuration has been set // Uses: //   this //   >< .reNS //   >< .space2num //   mw.config.get // Requires: JavaScript 1.3  charCodeAt // 2012-10-29 PerfektesChaos@de.wikipedia var k, o, re, s;     if ( ! this.reNS ) { o              =  mw.config.get( "wgNamespaceIds" ); re             =  ""; this.space2num =  { }; for ( s in o ) { k =  o[ s ]; if ( k ) {  // not main s                   =  s.replace( /_/, " " ); this.space2num[ s ] =  k;               re                   =  re  +  ( re ? "|" : "" )  +  s;            } }  // for s in .space2num this.reNS =  new RegExp( "^(" + re + "):",  "i" ); }  };   // .fiat */

RLS.find =  function ( album, allow ) { // Is element matching? // Precondition: //   album  -- collection or single item //   allow  -- default for album===true // Postcondition: //   Returns false iff not matching // Uses: //   this //   >  .specialPage // 2012-07-27 PerfektesChaos@de.wikipedia var i;     var o  =  album; var r =  false; switch ( typeof o ) { case "number" : case "string" : r =  ( o === this.specialPage ); break; case "boolean" : if ( ! o ) { break; }           o  =  allow; // fall through case "object" : // if ( o ) { if ( typeof o.length ===  "number" ) {   // Array for ( i = 0; i < o.length;  i++ ) { r =  ( o[i] === this.specialPage ); if ( r ) { break;  // for i                     } }  // for i               } else { r =  o[ this.specialPage ]; }           }            break; }  // switch typeof album return r;   };   // .find

RLS.fire =  function  { // Start possible actions on current page // Precondition: //   Current page is special page // Uses: //   >  .auto //   >  .unsorted //   >  .portlet //   >  .canonicals //   .find //   .fresh //   .furnish // Remark: May be used as event handler -- 'this' is not accessed // 2012-07-27 PerfektesChaos@de.wikipedia if ( RLS.find( RLS.auto, RLS.unsorted ) ) { RLS.fresh; }     if ( RLS.find( ( RLS.portlet === undefined  ?  RLS.canonicals                                                  :  RLS.portlet ), RLS.canonicals ) ) { RLS.furnish; }  };   // .fire

RLS.first =  function ( arg1, arg2 ) { // Compare two list elements //   element:  [ *, ns, title, talkmod, oldid, ... ]     // Precondition: //   arg1  -- first element //   arg2  -- second element // Postcondition: //   Returns number  -1 :  arg2 -> arg1 //                    0 :  arg1 == arg2 //                    1 :  arg1 -> arg2 // 2012-07-23 PerfektesChaos@de.wikipedia var r =  arg1[ 1 ]  -  arg2[ 1 ]; if ( ! r ) { if ( arg1[ 2 ] ===  arg2[ 2 ] ) { if ( arg1[ 3] ===  arg2[ 3 ] ) { r =  arg1[ 4 ]  -  arg2[ 4 ]; } else { r =  arg1[ 3 ]  -  arg2[ 3 ]; }        } else if ( arg1[ 2 ]  <  arg2[ 2 ] ) { r =  -1; } else { r =  1; }     }      return  r;   };   // .first

RLS.flat =  function  { // Transform 3-column table into list // Uses: //   >  mw.util.$content //   jQuery.find //   jQuery.children //   jQuery // 2012-10-29 PerfektesChaos@de.wikipedia var i, k, n, $div, $item, $li, $ol, $rows, $table, $tr; switch ( this.specialPage ) { case "Allpages" : k =  ".mw-allpages-table-chunk"; break; case "Prefixindex" : k =  "#mw-prefixindex-list-table"; break; }  // switch this.specialPage $div   =  mw.util.$content.find( "#mw-content-text" ); $table =  $div.find( k ); $rows  =  $table.find( "tbody" ).children( "tr" ); n =  $rows.length; if ( n ) { $ol =  $( " " ); for ( i = 0; i < n;  i++ ) { $tr =  $rows.eq( i ).children; for ( k = 0; k < $tr.length;  k++ ) { $li   =  $( " " ); $item =  $tr.eq( k ).children; $item.detach; $li.append( $item ); $ol.append( $li ); }  // for k         }   // for i         $div.append( $ol ); $table.remove; }  };   // .flat

RLS.flip =  function ( action ) { // Perform interactive user action // Precondition: //   action  -- distinguisher // Uses: //   this //   >  .controls //   jQuery //   jQuery.find //   mw.config.get //   .flat //   .fresh // 2012-10-29 PerfektesChaos@de.wikipedia var control, key; if ( this.controls ) { for ( key in this.controls ) { control =  this.controls[ key ]; if ( control ) { if ( control.lazy ) { control.lazy =  false; control.$greyed.detach; control.$control.append( control.$a ); break; }           }         }   // for key in .controls } else { this.controls =  { }; }     control  =  this.controls[ action ]; if ( control ) { control.lazy =  true; if ( ! control.$control ) { control.$control =  $( control.dom ); }        if ( action < 0 ) { control.$control.detach; } else { if ( ! control.$a ) { control.$a       =  control.$control.find( "a" ); control.$greyed  =  $( ""                                       +  control.text                                       +  " " ); }           if ( mw.config.get( "skin" ) ===  "vector" ) { control.$greyed.css( "font-size", "0.8em" ); }           control.$control.empty; control.$control.append( control.$greyed ); }     }      if ( action < 0 ) { this.flat; } else { this.fresh( action ); }  };   // .flip

RLS.fresh =  function ( alter ) { // Launch sorting process on current page // Precondition: //   alter  -- optional distinguisher // Uses: //   >  .specialPage //   >  .modeContr //   >  .modeURL //   >  .modeLink2 //   >  .modeDirect //   >  .modeSRH //   >  mw.util.$content //   >< .lean //    < .mode //   jQuery.find //   jQuery.children //   .fiat //   .fair //   (.first) // Remark: May be used as event handler -- 'this' is not accessed // 2012-10-29 PerfektesChaos@de.wikipedia var g, i, n, $lis; var select =  false; var $l     =  false; switch ( RLS.specialPage ) { case "Contributions" : RLS.mode =  RLS.modeContr; select   =  "#mw-content-text ul"; break; case "LinkSearch" : RLS.mode =  ( alter ? RLS.modeURL : RLS.modeLink2 ); select   =  "ol.special"; break; case "Newpages" : RLS.mode =  ( alter ? alter : RLS.modeDirect ); select   =  "#mw-content-text ul"; break; case "Recentchanges" : case "Watchlist" : RLS.mode =  ( alter ? alter : RLS.modeDirect ); select   =  ".special"; if ( ! RLS.lean ) { $l =  mw.util.$content.find( "#mw-content-text" ); $l.find( "h4" ).remove; $l.find( ".mw-changeslist-date" ).remove; RLS.lean =  true; }           break; case "Recentchangeslinked" : RLS.mode =  RLS.modeDirect; select   =  ".special"; break; case "Search" : RLS.mode =  RLS.modeSRH; select   =  ".mw-search-results"; break; case "Whatlinkshere" : RLS.mode =  RLS.modeDirect; select   =  "#mw-whatlinkshere-list"; break; }  // switch .specialPage if ( select ) { $l =  mw.util.$content.find( select ); if ( $l.length ) { // "Recentchangeslinked" --  $l.length > 1; loop $lis =  $l.children( "li" ); n    =  $lis.length; if ( n > 1 ) { g =  new Array( n ); RLS.fiat; for ( i = 0; i < n;  i++ ) { g[ i ] =  RLS.fair( $lis.eq( i ) ); }  // for i               g.sort( RLS.first ); $lis.detach; for ( i = 0; i < n;  i++ ) { $l.append( g[ i ][ 0 ] ); }  // for i            } }     }   };   // .fresh

RLS.furnish =  function  { // Equip current page with portlet links // Uses: //   this //   >  .specialPage //   >  .modeColumn //   >  .modeDirect //   >  .modeURL //   >  .modeUser //   >  .modeSize //   >  .modeSumm //   .favorite //   .factory // 2012-10-29 PerfektesChaos@de.wikipedia this.favorite; if ( this.specialPage === "Prefixindex" ||           this.specialPage === "Allpages" ) { this.factory( "OL", this.modeColumn ); } else { this.factory( "Name", this.modeDirect ); }     switch ( this.specialPage ) { case "LinkSearch" : this.factory( "URL", this.modeURL ); break; case "Newpages" : this.factory( "User", this.modeUser ); this.factory( "Size", this.modeSize ); this.factory( "Summary", this.modeSumm ); break; case "Recentchanges" : case "Watchlist" : this.factory( "User", this.modeUser ); this.factory( "Summary", this.modeSumm ); break; }  // switch .specialPage };  // .furnish

if ( ! RLS.loaded ) { RLS.loaded =  true; if ( mw.config.get( "wgNamespaceNumber" ) ===  -1 ) { $( document ).ready( function {               RLS.specialPage  =                           mw.config.get( "wgCanonicalSpecialPageName" );               mw.loader.using( [ "user", "mediawiki.util" ], RLS.fire );                                         } );   // .ready }  }   mw.loader.state( "ext.gadget.resultListSort", "ready" ); }( mediaWiki, jQuery ) );

// Emacs // Local Variables: // encoding: utf-8-dos // coding: utf-8-dos // fill-column: 80 // End:

/// EOF  resultListSort/d.js