User:PerfektesChaos/js/clickDivertimento/d.js

/// User:PerfektesChaos/js/clickDivertimento/d.js /// 2019-07-24 PerfektesChaos@de.wikipedia // Divert links into other browser window or tab // ResourceLoader: compatible; //                 dependencies: user, user.options /// Fingerprint: #0#0# /// @license: CC-by-sa/4.0 /// Documentation: w:en:User:PerfektesChaos/js/clickDivertimento /// /* global window: false, MutationObserver: false                      */ /* jshint forin:false, bitwise:true, curly:true, eqeqeq:true, latedef:true, laxbreak:true, nocomma:true, strict:true, undef:true, unused:true          */

( function ( mw, $ ) {  "use strict";   var Version  =  -1.9,       CDV      =  "clickDivertimento",       Config   =  { },       Prego    =  { };   if ( typeof mw.libs[ CDV ]  !==  "object"   ||   ! mw.libs[ CDV ] ) {     mw.libs[ CDV ]  =  { };   }   mw.libs[ CDV ].type  =  CDV;   CDV                  =  mw.libs[ CDV ];   if ( typeof CDV.vsn  !==  "number" ) {      // 2014-02-20      CDV.vsn        =  Version;      CDV.signature  =  "ext.gadget." + CDV.type;      CDV.support    =  "User:PerfektesChaos/js/" + CDV.type;      CDV.doc        =  "" + CDV.support + "";      Config.pages   =  [ "en", "de" ];      Config.texts   =  {         // 2014-02-20 PerfektesChaos@de.wikipedia         "^show":   {"en": "Click-Divertimento",                     "de": "Click-Divertimento"},         "^suffix": {"en": "&#8211; Open links in new browser window",                     "de": "&#8211; Links"                           + " in neuem Browserfenster öffnen"},         "^^large": {"en": "Include more list pages",                     "de": "Weitere Seiten mit Listen einschließen"},         "^^leave": {"en": "All external links shall be opened" + " in new browser window", "de": "Alle externen Links" + " in neuem Browserfenster öffnen"}, "^^mode": {"en": "Create entirely new window", "de": "Völlig neues Fenster öffnen"}, "^^mode0": {"en": "For all diverted targets", "de": "Immer, wenn ein Link beeinflusst wird"}, "^^mode1": {"en": "Shared windows for the same tasks", "de": "Wiederbenutzung für gleiche Aufgaben"}, "^^mode2": {"en": "All in the same different window", "de": "Alle im selben Zweitfenster"} };  // .texts }

/*   * 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 */

function fiat { // Handle particular link element // Uses: //   >  this //   >  Config.source //   >  Config.shift //   >  Config.kind //   >  Config.mode //   >  Config.targets // 2019-07-24 PerfektesChaos@de.wikipedia /* jshint validthis:true                                        */ var $hype = $( this ), src  = $hype.attr( "href" ), k    = src.charCodeAt( 0 ), cond, conds, i, shift; if ( k === 35 ) { $hype = false; } else { i = src.indexOf( "#" ); if ( i > 0  &&              src.substr( 0, i )  ===  Config.source ) { $hype = false; }        if ( $hype   &&              k !== 47   &&              src.indexOf( "//" )  <  0 ) { $hype = false; }     }      if ( $hype ) { shift = Config.shift; if ( Config.kind === 1 ) { if ( $hype.hasClass( "external" ) ) { if ( Config.mode ) { shift = "WikiExtern"; }           } else { shift = false; }        }         if ( typeof Config.targets  ===  "object"  ) { for ( k in Config.targets ) { conds = Config.targets[ k ]; for ( i = 0; i < conds.length;  i++ ) { cond = conds[ i ]; switch ( typeof cond ) { case "string" : if ( src.indexOf( cond ) >=  0 ) { conds = false; }                       break; case "object" : if ( cond.test( src ) ) { conds = false; }                       break; }  // switch typeof if ( ! conds ) { break;  // for i                  } }  // for i               if ( ! conds ) { shift = k;                 break;   // for k               } }  // for k         } if ( shift &&  ! $hype.attr( "target" ) ) { $hype.attr( "target", shift ); }     }   }   // fiat

function fit { // Handle particular form element // Uses: //   >  this //   >  Config.shift // 2019-07-24 PerfektesChaos@de.wikipedia /* jshint validthis:true                                        */ var $hype = $( this ); if ( ! $hype.attr( "target" ) ) { $hype.attr( "target", Config.shift ); }  }   // fit

function flyout { // Handle suggestions elements // Uses: //   (fit) // 2016-04-03 PerfektesChaos@de.wikipedia var suggestion = "a.mw-searchSuggest-link", observer, $div; if ( typeof MutationObserver ===  "function" ) { $div = $( ".suggestions-results" ); if ( $div.length ) { observer = new MutationObserver(                                function( mutations ) {                                    mutations.forEach( function { $( suggestion ).each( fit ); } );                                } );            observer.observe( $div.get( 0 ),                              { childList: true } ); }     }   }   // flyout

function furnish( $area ) { // Divert link targets on document // Precondition: //   document ready //   $area  -- jQuery object of current $content // Uses: //   >  Config.kind //   >  Config.start //   (fiat) //   (fit) //   (flyout) // Remark: May be used as event handler -- 'this' is not accessed // 2016-04-03 PerfektesChaos@de.wikipedia var scope, $hypes; switch ( Config.kind ) { case 1 : $hypes = $area.find( ".external" ); break; case 2 : case 3 : switch ( Config.special ) { case "Contributions" : $hypes = $area.find( "ul,ol" ); break; case "LinkSearch" : $hypes = $area.find( ".special" ); break; case "Whatlinkshere" : $hypes = $area.find( "#mw-whatlinkshere-list" ); break; case "Recentchanges" : case "Watchlist" : $hypes = $area.find( ".mw-changeslist" ); break; default: $hypes = $area; }  // switch wgCanonicalSpecialPageName $hypes = $hypes.find( "a[href*=\"/\"]" ); break; case 4 : $hypes     = $( "a[href*=\"/\"]" ); Config.kind = 3; break; }  // switch kind $hypes.each( fiat ); if ( Config.kind > 1 ) { scope = "#searchform, .searchbox"; if ( Config.kind === 2 &&  Config.start === "history" ) { scope = scope + ", #mw-history-compare"; }        $( scope ).each( fit ); mw.loader.using( [ "mediawiki.searchSuggest" ],                         flyout ); }  }   // furnish

Config.features = function { // Establish user configured appearance // Precondition: //   Prego user.options available // Uses: //   this //   >  .large //   >  .leave //   >  .mode //   >  Prego.supply //   >  .targets //    < Config.large //    < Config.leave //    < Config.mode //    < Prego.lib //    < Config.targets // 2015-10-03 PerfektesChaos@de.wikipedia var pars = [ [ "large", "boolean" ], [ "leave", "boolean" ], [ "mode", "number"  ] ], n   = pars.length, i, s, v, vals; for ( i = 0; i < n;  i++ ) { v = pars[ i ]; s = v[ 0 ]; if ( typeof CDV[ s ] ===  v[ 1 ] ) { this[ s ] = CDV[ s ]; } else { this[ s ] = false; }     }   // for i      Prego.lib = mw.libs[ Prego.supply ]; if ( typeof Prego.lib ===  "object"   &&                  Prego.lib   &&           typeof Prego.lib.fetch  ===  "function" ) { vals = Prego.lib.fetch( CDV.type ); if ( vals  &&   typeof vals  ===  "object" ) { for ( i = 0; i < n;  i++ ) { v = pars[ i ]; s = v[ 0 ]; if ( typeof vals[ s ] ===  v[ 1 ] ) { this[ s ] = vals[ s ]; }           }   // for i         } } else { Prego.lib = false; }     if ( typeof CDV.targets  ===  "object"   &&           CDV.targets   &&           this.mode ) { this.targets = { }; for ( s in CDV.targets ) { v = CDV.targets[ s ]; if ( v ) { switch ( typeof v ) { case "string" : v = [ v ]; break; case "object" : if ( typeof v.length !==  "number" ) { if ( typeof v.ignoreCase ===  "boolean" ) { v = [ v ]; } else { v = false; }                    }                     break; default: v = false; }  // switch typeof v               if ( v ) { this.targets[ s ] = v;              } }        }   // for s in .targets }  };   // Config.features

Config.fire = function { // Start possible actions on current page // Precondition: //   Resources available // Uses: //   >  Config.learn //   >  Prego.lib //   >  Config.special //   >  Config.large //   >  Config.start //   >  Config.leave //   >  window.location.href //   >  Config.mode //    < Config.kind //    < Config.source //    < Config.shift //   Config.features //   Prego.form //   mw.hook //   (furnish) // Remark: May be used as event handler -- 'this' is not accessed // 2019-07-01 PerfektesChaos@de.wikipedia var i;     Config.features; if ( Config.learn ) { Config.kind = 4; if ( Prego.lib ) { Prego.form; }     } else { Config.kind = false; if ( typeof Config.special ===  "string" ) { switch ( Config.special ) { case "Contributions" : case "LinkSearch" : case "Whatlinkshere" : if ( Config.large ) { Config.kind = 2; }                 break; default: Config.kind = 2; }  // switch wgCanonicalSpecialPageName } else { switch ( Config.start ) { case "edit" : case "submit" : Config.kind = 4; $( ".cancelLink" ).hide; break; case "history" : if ( Config.large ) { Config.kind = 2; }                 break; case "view" : if ( Config.leave ) { Config.kind = 1; }                 break; }  // switch wgAction }     }      if ( Config.kind ) { Config.source = window.location.href; i            = Config.source.indexOf( "#" ); if ( i > 0 ) { Config.source = Config.source.substr( 0, i ); }        switch ( Config.mode ) { case 1 : Config.shift = "_blank"; break; case 2 : Config.shift = "clickDiver"; break; default: Config.shift = "_blank"; }  // switch .mode mw.hook( "wikipage.content" ).add( furnish ); }  };   // Config.fire

Prego.fire = function { // Prepare preferencesGadgetOptions availability // Postcondition: //   preferencesGadgetOptions requested, if not yet defined // Uses: //   this //    < Prego.supply //   mw.loader.getState //   mw.loader.state //   mw.loader.load // 2018-08-30 PerfektesChaos@de.wikipedia var rls, signature; this.supply = "preferencesGadgetOptions"; signature  = "ext.gadget." + this.supply; if ( ! mw.loader.getState( signature ) ) { rls = { }; rls[ signature ] = "loading"; mw.loader.state( rls ); mw.loader.load( "https://en.wikipedia.org"                        + "/w/index.php?title="                         + "User:PerfektesChaos/js/" + this.supply                         + "/r.js"                         + "&action=raw&bcache=1&maxage=604809"                         + "&ctype=text/javascript",                         "text/javascript" ); }  };   // Prego.fire

Prego.firing = function { // Intermediate loading process step // Precondition: //   MW ressources are available // Uses: //   >  Prego.supply //   mw.hook //   (Config.fire) // Remark: Used as event handler -- 'this' is not Prego // 2016-04-03 PerfektesChaos@de.wikipedia mw.hook( Prego.supply + ".ready" ).add( Config.fire ); };  // Prego.firing

Prego.form = function { // Equip Special:Blankpage PREGO page with entry and form // Uses: //   this //   >  Config.texts //   >  Config.pages //   >  .support //   >  .type //   >  Config.large //   >  Config.leave //   >  Config.mode //   >  Prego.lib //   mw.libs.preferencesGadgetOptions.form // 2015-01-28 PerfektesChaos@de.wikipedia var pages = { }, poly = [ ], txt  = Config.texts, dialog, i, s;     for ( i = 0;  i < Config.pages.length;  i++ ) { s         = Config.pages[ i ]; pages[ s ] = "//" + s + ".wikipedia.org/wiki/" + CDV.support; }  // for i      for ( i = 0;  i < 3;  i++ ) { poly.push( { val: i,                      show: txt[ "^^mode" + i ] } ); }  // for i      dialog = { script:  CDV.type, show:   txt[ "^show" ], support: pages, suffix: txt[ "^suffix" ], opts:   [ { signature: "large", type:     "checkbox", show:     txt[ "^^large" ], val:      Config.large },                             { signature: "leave", type:     "checkbox", show:     txt[ "^^leave" ], val:      Config.leave },                             { signature: "mode", type:     "radio", show:     txt[ "^^mode" ], val:      Config.mode, poly:     poly } ] }; Prego.lib.form( dialog ); };  // Prego.form

CDV.fire = function { // Start possible actions on current page // Uses: //    < CDV.signature //    < Config.learn //    < Config.special //    < Config.start //   mw.loader.getState //   mw.loader.state //   mw.config.get //   Prego.fire //   (Prego.firing) // Remark: May be used as event handler -- 'this' is not accessed // 2018-08-24 PerfektesChaos@de.wikipedia var env, launch, rls; if ( mw.loader.getState( CDV.signature ) !== "ready" ) { rls = { }; rls[ CDV.signature ] = "ready"; mw.loader.state( rls ); env   = mw.config.get( [ "wgAction",                                     "wgCanonicalSpecialPageName",                                     "wgNamespaceNumber" ] ); launch = true; Config.learn = false; if ( env.wgNamespaceNumber === -1 ) { Config.special = env.wgCanonicalSpecialPageName; switch ( Config.special ) { case "Blankpage" : case "Gadgets" : Config.learn = true; break; case "Contributions" : case "EditWatchlist" : case "LinkSearch" : case "Recentchanges" : case "Watchlist" : case "Whatlinkshere" : break; default: launch = false; }  // switch wgCanonicalSpecialPageName } else { Config.start = env.wgAction; }        if ( launch ) { Prego.fire; mw.loader.using( [ "user",                              "user.options" ],                             Prego.firing ); }     }   };   // .fire

CDV.fire;  // autorun }( window.mediaWiki, window.jQuery ) );

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

/// EOF  clickDivertimento/d.js