User:PerfektesChaos/js/pageLinkHelper/d.js

This is an old revision of this page, as edited by PerfektesChaos (talk | contribs) at 19:25, 14 December 2014 (-1.5). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/// Gadget-pageLinkHelper.js
//  Some minor link helpers
// ResourceLoader:  compatible;  dependencies: user, mediawiki.util
/// 2014-12-14 PerfektesChaos@de.wikipedia
/// Fingerprint: #0#0#
/// <nowiki>
/*jshint bitwise:true, curly:true, eqeqeq:true, latedef:true,
         laxbreak:true, strict:true, trailing:true, undef:true,
         unused:true, white:false                                      */
/*global window:false                                                  */
( function ( mw, $ ) {
   "use strict";
   var Version   = -1.5,
       Sign      = "pageLinkHelper",
       Signature = "ext.gadget." + Sign,
       Env, PLH;



   function $factory( access ) {
      // Create <div> for upper right corner
      // Precondition:
      //    access  -- distinguishing selector ID
      // Uses:
      //    >  Sign
      // 2014-12-11 PerfektesChaos@de.wikipedia
      var space = "4px",
          style = "#808080 1px solid",
          $r    = $( "<div>" );
      $r.attr( { "class": Sign,
                 "id":    access } );
      style = "#808080 1px solid";
      $r.css( { "border-bottom":  style,
                "border-left":    style,
                "float":          "right",
                "font-family":    "monospace",
                "margin-bottom":  "1em",
                "margin-left":    "1em",
                "margin-top":     space,
                "padding-bottom": space,
                "padding-left":   space } );
      return $r;
   }   // $factory()



   function $float( $apply ) {
      // Insert upper right corner element
      // Precondition:
      //    $apply  -- jQuery element to insert
      //               false to vheck availability
      // Postcondition:
      //    Returns true, if insertion possible
      // Uses:
      //    >  Sign
      //    >< Env
      // 2014-12-11 PerfektesChaos@de.wikipedia
      var r,      // = undefined
          $div;
      if ( typeof Env.$anchor  ===  "undefined" ) {
         Env.$anchor = $( "#firstHeading" );
      }
      if ( Env.$anchor.length ) {
         r = true;
         if ( $apply ) {
            $div = $( "." + Sign );
            $div.remove();
            $div = $( "<div>" );
            $div.css( { "clear": "left" } );
            Env.$anchor.after( $div );
            Env.$anchor.after( $apply );
         }
      }
      return r;
   }   // $float()



   function fiat( apply, at ) {
      // Equip diffpage revision with wikilink for permalink c&p
      // Precondition:
      //    apply  -- revision ID
      //    at     -- revision column; "n" or "o"
      //    DOM.ready
      //    Diffpage
      // Uses:
      //    >  Sign
      //    >  Env.spcNS
      //    mw.util.getParamValue()
      // 2014-12-14 PerfektesChaos@de.wikipedia
      var $div  = $( "#mw-diff-" + at + "title1" ),
          id, s, $a, $span;
      if ( $div.length ) {
         if ( apply ) {
            id = apply;
         } else {
            $a = $div.find( "a" ).eq( 0 );
            s  = $a.attr( "href" );
            id = mw.util.getParamValue( "oldid", s );
         }
         if ( id ) {
            s     = "[[" + Env.spcNS + ":PermanentLink/" + id + "]]";
            $span = $( "<span>" );
            $span.attr( { "class":  Sign + " " + Sign + "DiffRev" } );
            $span.css( { "font-family": "monospace",
                         "margin-left": "1em" } );
            $span.text( s );
            $div.append( $span );
         }
      }
   }   // fiat()



   function feature( applied ) {
      // Check for user option
      // Precondition:
      //    applied  -- option keyword
      //    module 'user' loaded
      // Postcondition:
      //    Returns value, or undefined
      // Uses:
      //    >  mw.libs
      //    >  Sign
      //    >  Version
      //    >< PLH
      // 2014-12-11 PerfektesChaos@de.wikipedia
      var r;   // = undefined
      if ( typeof mw.libs[ Sign ] === "object" ) {
         PLH = mw.libs[ Sign ];
         if ( PLH ) {
            PLH.vsn = Version;
            if ( typeof PLH[ applied ]  !==  "undefined" ) {
               r = PLH[ applied ];
            }
         }
      }
      return r;
   }   // feature()



   function flip() {
      // Equip diffpage with wikilink for c&p
      // Precondition:
      //    DOM.ready
      //    mediawiki.util loaded
      // Uses:
      //    >  Sign
      //    >  ___location
      //    >< Env
      //    mw.config.get()
      //    $float()
      //    $factory()
      //    fiat()
      //    freezer()
      // 2014-12-14 PerfektesChaos@de.wikipedia
      var sign = Sign + "Difflink",
          $div = $( "#" + sign ),
          got, i, id1, id2, j, re, show, $span;
      if ( ! $div.length  &&  $float() ) {
         if ( Env.wgCanonicalSpecialPageName ) {
            // 2014 redirected to &diff=
            re  = /\/wiki\/[^:]+:[^\/]+\/(\d+)(?:\/(\.+))?$/;
            got = re.exec( window.___location.pathname );
            if ( got ) {
               id1 = got[ 1 ];
               id2 = got[ 2 ];
            }
         } else {
            id1 = Env.diff;
            id2 = Env.oldid;
         }
         if ( id1 ) {
            i = parseInt( id1, 10 );
            if ( id2 ) {
               j = parseInt( id2, 10 );
               if ( isNaN( i ) ) {
                  if ( isNaN( j ) ) {
                     id2 = false;
                  } else {
                     id2 = id1;
                     id1 = j;
                  }
               } else {
                  id1 = i;
                  if ( ! isNaN( j )  &&  i > j ) {
                     id2 = i;
                     id1 = j;
                  }
               }
               if ( id2 === "prev" ) {
                  id2 = false;
               }
            } else if ( isNaN( i ) ) {
               id1 = false;
            } else {
               id1 = i;
            }
         }
         if ( id1 ) {
            Env.spcNS = mw.config.get( "wgFormattedNamespaces" )[ "-1" ];
            show      = "[[" + Env.spcNS + ":Diff/" + id1
                        + ( id2  ?  "/" + id2  :  "" )
                        + "]]";
            $span     = $( "<span>" );
            $span.text( show );
            $div = $factory( sign );
            $div.append( $span );
            $float( $div );
            if ( id2 ) {
               fiat( id1, "o" );
               fiat( id2, "n" );
            } else {
               fiat( false, "o" );
               fiat( false, "n" );
            }
         }
      }
      freezer( true );
   }   // flip()



   function freeze() {
      // Equip page with wikilink to perma for c&p
      // Precondition:
      //    DOM.ready
      //    mediawiki.util loaded
      // Uses:
      //    >  Sign
      //    >< Env
      //    mw.config.get()
      //    $float()
      //    $factory()
      //    mw.util.wikiUrlencode()
      //    mw.util.getUrl()
      //    freezer()
      // 2014-12-14 PerfektesChaos@de.wikipedia
      var sign = Sign + "Permalink",
          $div = $( "#" + sign ),
          show, special, swift, $a, $br, $spanBeg, $spanEnd;
      if ( ! $div.length  &&  $float() ) {
         Env.wgPageName = mw.config.get( "wgPageName" );
         if ( Env.curid ) {
            Env.curid = parseInt( Env.curid, 10 );
         } else {
            Env.curid = mw.config.get( "wgArticleId" );
         }
         if ( Env.oldid ) {
            Env.oldid = parseInt( Env.oldid, 10 );
         } else {
            Env.oldid = mw.config.get( "wgCurRevisionId" );
         }
         $div     = $factory( sign );
         special  = mw.config.get( "wgFormattedNamespaces" )[ "-1" ]
                    + ":";
         swift    = "?title="
                    + mw.util.wikiUrlencode( Env.wgPageName );
         $spanBeg = $( "<span>" );
         $spanBeg.text( "[[" );
         $spanEnd = $( "<span>" );
         $spanEnd.text( "]]" );
         $a = $( "<a>" );
         if ( Env.oldid ) {
            $div.append( $spanBeg.clone() );
            show = special + "PermanentLink/" + Env.oldid;
            $a.attr( { "href":  mw.util.getUrl( show ) + swift } );
            $a.text( show );
            $div.append( $a );
            $div.append( $spanEnd.clone() );
            $br = $( "<br />" );
            $div.append( $br );
            $a = $( "<a>" );
         }
         $div.append( $spanBeg );
         show = special + "Redirect/page/" + Env.curid;
         $a.attr( { "href":  mw.util.getUrl( show ) + swift } );
         $a.text( show );
         $div.append( $a );
         $div.append( $spanEnd );
         $float( $div );
         freezer( false );
      }
   }   // freeze()



   function freezer( assign ) {
      // Change portlet for permalink
      // Precondition:
      //    assign  -- true if link to be diverted, false to gray out
      //    DOM.ready
      // Uses:
      //    >  Sign
      //    >  Version
      //    (freeze)
      // 2014-12-11 PerfektesChaos@de.wikipedia
      var $portlet = $( "#t-permalink" ),
          show, support, $a, $span;
      if ( $portlet.length ) {
         support = Sign + " " + Version;
         if ( assign ) {
            $a = $( "<a>" );
            $a.attr( { "title": support } );
            $a.click( freeze );
            $a.text( "PermaLink" );
            $portlet.empty();
            $portlet.append( $a );
         } else {
            $a   = $portlet.find( "a" );
            show = $a.text();
            if ( show ) {
               $span = $( "<span>" );
               $span.css( { "color": "#808080" } );
               $span.text( show );
               $span.attr( { "title": support } );
               $portlet.empty();
               $portlet.append( $span );
            }
         }
      }
   }   // freezer()



   function fresh() {
      // Provide purge link
      // Precondition:
      //    DOM.ready
      //    mediawiki.util loaded
      //    user resources loaded
      // Uses:
      //    >< Env
      //    feature()
      //    mw.config.get()
      //    mw.util.getUrl()
      //    mw.util.addPortletLink()
      // 2014-12-07 PerfektesChaos@de.wikipedia
      var opt   = feature( "purge" ),
          say   = "PURGE this page from server cache",
          seed  = null,
          slot  = "p-cactions",
          show  = "Purge cache",
          start = "ca",
          got, re, swap;
      switch ( typeof opt ) {
         case "boolean" :
            if ( opt ) {
               seed = false;
            } else {
               slot = false;
            }
            break;
         case "string" :
            seed = opt;
            re   = /^([a-z]+)-(.+)$/;
            got  = re.exec( seed );
            if ( got ) {
               switch ( got[ 1 ] ) {
                  case "p" :
                     slot = seed;
                     seed = false;
                     switch ( got[ 2 ] ) {
                        case "navigation" :
                           start = "n";
                           break;
                        case "tb" :
                           start = "t";
                           break;
                     }   // switch got.2
                     break;
                  case "ca" :
                     break;
                  case "n" :
                     slot = "p-navigation";
                     break;
                  case "t" :
                     slot = "p-tb";
                     break;
               }   // switch got.1
            }
            break;
      }   // switch typeof opt
      if ( slot  &&  seed === null ) {
         Env.skin = mw.config.get( "skin" );
         if ( Env.skin !== "vector" ) {
            slot = false;
         }
      }
      if ( slot ) {
         Env.wgPageName = mw.config.get( "wgPageName" );
         swap = mw.util.getUrl( Env.wgPageName,
                                { action: "purge" } );
         if ( seed ) {
            seed = "#" + seed;
         }
         mw.util.addPortletLink( slot,
                                 swap,
                                 show,
                                 start + "-purge",
                                 say,
                                 null,
                                 seed );
      }
   }   // fresh()



   function from() {
      // Redirected from somewhere
      // Precondition:
      //    mediawiki.util loaded
      // Uses:
      //    >  history
      //    >  ___location
      //    >  document
      //    >  Sign
      //    >< Env
      //    mw.util.getUrl()
      //    feature()
      //    history.___pushState()
      //    history.___replaceState()
      // 2014-12-07 PerfektesChaos@de.wikipedia
      var caused, opts, show, last, legacy, showed, state, swap;
      if ( typeof window.history.___pushState === "function"  &&
           typeof window.history.___replaceState === "function" ) {
         swap = mw.util.getUrl( Env.wgRedirectedFrom,
                                { redirect: "no" } );
         if ( window.history.previous ) {
            // should actually not cause wgRedirectedFrom, but avoid
            last = ( window.history.previous.indexOf( swap )  >=  0 );
         }
         if ( ! last ) {
            opts = feature( "redirect" );
            if ( opts   &&
                 typeof opts  ===  "object"   &&
                 typeof opts.legacy  ===  "boolean" ) {
               legacy = opts.legacy;
            }
            showed = window.document.title;
            caused = { caused: Sign };
            if ( legacy ) {
               state = mw.util.getUrl( Env.wgRedirectedFrom );
            } else {
               state = window.___location.href;
            }
            show = "#REDIRECT " + Env.wgRedirectedFrom;
            window.history.___replaceState( caused, show, swap );
            window.history.___pushState( caused, showed, state );
         }
      }
   }   // from()



   function further( amount ) {
      // Convert links on page into Special: format
      // Precondition:
      //    amount  -- number of links per item to inspect
      //    DOM.ready
      //    mediawiki.util loaded
      // Uses:
      //    mw.util.getParamValue()
      // 2014-12-14 PerfektesChaos@de.wikipedia
      var $results = $( "#mw-content-text li" ),
          n        = $results.length,
          i, j, shift, special, start, strip, $a, $li;
      if ( n ) {
         special  = "/wiki/"
                    + mw.config.get( "wgFormattedNamespaces" )[ "-1" ]
                    + ":";
         for ( i = 0;  i < n;  i++ ) {
            $li = $results.eq( i ).find( "a" );
            for ( j = 0;  j < amount;  j++ ) {
               $a    = $li.eq( j );
               strip = $a.attr( "href" );
               start = mw.util.getParamValue( "oldid", strip );
               if ( start ) {
                  strip = strip.replace( /&oldid=\d+\b/, "" )
                               .replace( /&curid=\d+\b/, "" );
                  shift = mw.util.getParamValue( "diff", strip );
                  if ( shift ) {
                     strip = strip.replace( /&diff=\d+\b/, "" );
                     shift = "Diff/" + start + "/" + shift;
                  } else {
                     shift = "PermanentLink/" + start;
                  }
                  shift = special + shift + "$1";
                  strip = strip.replace( /^.+(\?title=.+)$/,
                                         shift );
                  $a.attr( "href", strip );
               }
            }   // for j
         }   // for i
      }
   }   // further()



   function fire() {
      // Autorun on load
      // Precondition:
      //    mediawiki.util loaded
      // Uses:
      //     < Env
      //    mw.config.get()
      //    mw.util.getParamValue()
      //    flip()
      //    further()
      //    freeze()
      //    freezer()
      //    fresh()
      //    from()
      // 2014-12-14 PerfektesChaos@de.wikipedia
      Env = { wgCanonicalSpecialPageName:
                         mw.config.get( "wgCanonicalSpecialPageName" ) };
      if ( Env.wgCanonicalSpecialPageName ) {
         switch ( Env.wgCanonicalSpecialPageName ) {
            case "Diff" :
               flip();
               break;
            case "Contributions" :
               further( 2 );
               break;
            case "Watchlist" :
               further( 1 );
               break;
         }   // switch wgCanonicalSpecialPageName
      } else {
         Env.diff  = mw.util.getParamValue( "diff" );
         Env.oldid = mw.util.getParamValue( "oldid" );
         if ( Env.diff ) {
            flip();
         } else {
            Env.wgAction = mw.config.get( "wgAction" );
            switch ( Env.wgAction ) {
               case "history" :
                  further( 3 );
                  break;
               case "view" :
                  Env.curid = mw.util.getParamValue( "curid" );
                  if ( Env.curid || Env.oldid ) {
                     freeze( true );
                  } else {
                     freezer( true );
                  }
                  fresh();
                  Env.wgRedirectedFrom
                                   = mw.config.get( "wgRedirectedFrom" );
                  if ( Env.wgRedirectedFrom ) {
                     from();
                  }
                  break;
               default:
                  freezer( true );
            }   // switch wgAction
         }
      }
   }   // fire()



   if ( mw.loader.getState( Signature )  !==  "ready" ) {
      mw.loader.state( Signature, "ready" );
      mw.loader.using( [ "mediawiki.util",
                         "user" ],
                       function () {
                          $( fire );   // don't hurry
                       } );
   }
}( window.mediaWiki, window.jQuery ) );
/// EOF </nowiki>   pageLinkHelper.js