User:PerfektesChaos/js/paneMarker/d.js

/// User:PerfektesChaos/js/paneMarker/d.js /// 2022-08-28 PerfektesChaos@de.wikipedia // Mark browser panes (tabbed or window) if particular action taken. // Try to exchange wiki-favicon for a red one if editing a wiki page. // Insert indicating character before document title. // User defined changes of page title and favicon. // ResourceLoader: compatible; //       dependencies: user, user.options, mediawiki.util, jquery.client /// Fingerprint: #0#0# /// License: CC-by-sa/4.0 /// /* global window: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  =  -3.6,       PaneMk   =  "paneMarker";   if ( typeof mw.libs[ PaneMk ]  !==  "object" ||  ! mw.libs[ PaneMk ] ) {      mw.libs[ PaneMk ]  =  {  opt:  { }  };   }   mw.libs[ PaneMk ].vsn   =  Version;   mw.libs[ PaneMk ].type  =  PaneMk;   PaneMk                  =  mw.libs[ PaneMk ];   if ( ! PaneMk.prefs ) {     PaneMk.heads    =  "|commonswiki|dewiki|";      PaneMk.rels     =  [ "icon", "shortcut icon" ];      PaneMk.support  =  "User:PerfektesChaos/js/" + PaneMk.type;      PaneMk.doc      =  "" + PaneMk.support + "";      PaneMk.config   =  { lazy:     false,                           shortcut: true };      PaneMk.prefs    =  { supply: "preferencesGadgetOptions" };   }

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

/*  What links here: Special:GlobalUsage */

PaneMk.prefs.fetch =  function  { // Retrieve preferences and overwrite presets // Uses: //   >  .type //    < .config.* //   mw.libs.preferencesGadgetOptions.fetch // 2014-09-09 PerfektesChaos@de.wikipedia var s, v,         scope  =  " appleIcon faviconICO faviconPNG lazy" + " chars charDiff charHistory charLinks charVitally" + " lowChar" + " favicon leave shortcut ", vals  =  mw.libs[ this.supply ].fetch( PaneMk.type ); for ( s in vals ) { if ( scope.indexOf( " " + s + " " ) >  0 ) { v =  vals[ s ]; if ( v !== "" ) { PaneMk.config[ s ] =  v;            } }     }   // for s in vals };  // .prefs.fetch

PaneMk.prefs.fiat =  function ( access, allow ) { // Convert object component user configuration into // Precondition: //   access  -- option ID      //    allow   -- default if boolean, return boolean; else string // Uses: //   >  .config.* // 2014-09-09 PerfektesChaos@de.wikipedia var r;     if ( typeof allow === "boolean" ) { if ( typeof PaneMk.config[ access ] ===  "boolean" ) { r =  PaneMk.config[ access ]; } else { r =  allow; }     } else { if ( typeof PaneMk.config[ access ] ===  "string" ) { r =  PaneMk.config[ access ]; } else { r =  ""; }     }      return  r;   };   // .prefs.fiat

PaneMk.prefs.fire =  function  { // Prepare preferencesGadgetOptions availability // Postcondition: //   loader.implement requested, if not yet defined //   Returns module ID      // Uses: //   >  .prefs.supply //    < .prefs.suffix //   mw.loader.getState //   mw.loader.state //   mw.loader.load //   mw.hook //   (.prefs.fired) // Remark: May be used as event handler -- 'this' is not .prefs // 2022-08-28 PerfektesChaos@de.wikipedia var signature = "ext.gadget." + PaneMk.prefs.supply, rls; if ( ! mw.loader.getState( signature ) ) { rls = { }; rls[ signature ] = "loading"; mw.loader.state( rls ); }     PaneMk.prefs.suffix  =  "/r.js" + "&bcache=1&maxage=604804" + "&action=raw&ctype=text/javascript"; mw.loader.load( "https://en.wikipedia.org/w/index.php?title="                     + "User:PerfektesChaos/js/"                      + PaneMk.prefs.supply + PaneMk.prefs.suffix,                      "text/javascript" ); mw.hook( PaneMk.prefs.supply + ".ready" ) .add( PaneMk.prefs.fired ); };  // .prefs.fire

PaneMk.prefs.fired =  function  { // Prepare ResourceLoader availability // Postcondition: //   loader.implement requested, if not yet defined //   Returns module ID      // Uses: //   .furnish // Remark: May be used as event handler -- 'this' is not .prefs // 2018-08-24 PerfektesChaos@de.wikipedia PaneMk.furnish; };  // .prefs.fired

PaneMk.prefs.form =  function  { // Trigger dialog form for Special:Gadgets // Postcondition: //   loader.implement requested, if not yet defined // Uses: //   >  .support //   >  .prefs.suffix //   mw.loader.load // 2016-10-21 PerfektesChaos@de.wikipedia mw.loader.load( "https://www.mediawiki.org/w/index.php?title="                     + PaneMk.support + "/dialog"                      + this.suffix ); };  // .prefs.form

PaneMk.facilitate =  function  { // Set document title to relevant page name and site name // Postcondition: //   document.title has been set // Uses: //   >  this //   >  .env //    < document.title // Remark: wgRelevantPageName available since MW 1.20 // 2022-08-25 PerfektesChaos@de.wikipedia var re =  new RegExp( "_", "g" ), s  =  this.env.wgRelevantPageName; if ( ! s ) { s =  this.env.wgPageName; }     window.document.title  =  s.replace( re, " " )  + " * " +  this.env.wgSiteName; };  // .facilitate

PaneMk.favicon =  function ( apply ) { // Try to exchange wiki-favicon // Precondition: //   apply  -- true:   red icon (page used in vulnerable mode) //             false:  show user defined default project icon // Uses: //   >  this //   >  .site //   >  .less //   >  .config.favicon //   >  .config.appleIcon //   >  .config.faviconICO //   >  .config.faviconPNG //   >  .rels //   .file //   .filter // 2022-08-28 PerfektesChaos@de.wikipedia var $apple, $head    =  $( window.document ).find( "head" ), $favicon, apple    =  false, i,         k,          light     =  apply, n        =  0, offer    =  false, png      =  false, s;     if ( $head.length ) { if ( apply ) { png =  [ "wmf", "f7" ]; if ( this.site === "commonswiki" ) { apple =  [ "commons", "70" ]; png   =  [ "commons", "e7" ]; } else if ( this.site === "metawiki" ) { png   =  [ "meta", "96" ]; } else if ( this.site === "testwiki" ) { apple =  [ "wikipedia", "f1" ]; png   =  [ "testwiki", "b6" ]; } else if ( this.site === "mediawikiwiki" ) { apple =  [ "mediawiki", "b6" ]; png   =  [ "mediawiki", "fa" ]; } else if ( this.site.slice( -4 ) ===  "wiki" ) { apple =  [ "wikipedia", "f1" ]; if ( this.less ) { png =  [ "beta-wikipedia", "25" ]; } else { png =  [ "wikipedia", "fb" ]; }           } else if ( this.site.slice( -9 )  ===  "wikibooks" ) { png   =  [ "wikibooks", "7e" ]; } else if ( this.site.slice( -8 ) ===  "wikinews" ) { apple =  [ "wikinews", "a9" ]; png   =  [ "wikinews", "cc" ]; } else if ( this.site.slice( -9 ) ===  "wikiquote" ) { png   =  [ "wikiquote", "cb" ]; } else if ( this.site.slice( -10 ) ===  "wikisource" ) { png   =  [ "wikisource", "f4" ]; } else if ( this.site.slice( -11 ) ===  "wikiversity" ) { png   =  [ "wikiversity", "95" ]; } else if ( this.site.slice( -10 ) ===  "wiktionary" ) { apple =  [ "wiktionary", "f8" ]; png   =  [ "wiktionary", "c0" ]; } else { apple =  [ "wmf", "a9" ]; }        } else { if ( this.less &&                 typeof this.config.faviconPNG === "undefined" ) { this.config.favicon =  this.file( "Favicon-",                                                  "beta-wikipedia",                                                  "14" ); }           light  =  this.config.favicon; }        if ( apply ) { $apple =  $head.find( "link" ).filter( function {                              return ( this.rel === "apple-touch-icon" );                                                               } ); if ( $apple.length === 1 ) { s =  false; switch ( typeof this.config.appleIcon ) { case "string" : s =  this.config.appleIcon; break; case "boolean" : if ( ! this.config.appleIcon ) { break; }  // fall through default: if ( apple ) { s =  this.file( "Apple-touch-icon-red-",                                         apple[0],                                         apple[1] ); }              }   // switch   typeof .config.appleIcon if ( s ) { $apple.detach; $apple.attr( "href", s ); $head.append( $apple ); }           }         }         if ( light ) { $favicon =  $head.find( "link" ).filter( PaneMk.filter ); n =  $favicon.length; }        if ( n ) { if ( apply ) { s =  false; switch ( typeof this.config.faviconPNG ) { case "string" : s =  this.config.faviconPNG; break; case "boolean" : if ( ! this.config.faviconPNG ) { break; }   // fall through default: s =  this.file( "Favicon-red-",                                      png[ 0 ],                                      png[ 1 ] ); }  // switch   typeof .config.faviconPNG offer =  [  [ s, "image/png" ]  ]; s     =  this.config.faviconICO; if ( s ) { if ( typeof s === "string" ) { offer.push( [ s, "image/x-icon" ] ); }              }            } else { s =  this.config.favicon; if ( s ) { if ( typeof s === "string" ) { offer =  [  [ s, null ]  ]; s =  s.slice( -4 ).toLowerCase; switch ( s ) { case ".ico" : offer[ 0 ][ 1 ] =  "image/x-icon"; break; case ".gif" : case ".png" : offer[ 0 ][ 1 ] =  "image/" + s.substr(1); break; }  // switch   s.slice( -4 ).toLowerCase }              }            }            if ( offer ) { for ( i = 0; i < n;  i++ ) { $favicon.eq( i ).detach; }  // for i               if ( n > 1 ) { $favicon =  $favicon.eq( 0 ); }              for ( i = 0;  i < offer.length;  i++ ) { $favicon.attr( "href", offer[ i ][ 0 ] ); $favicon.attr( "type", offer[ i ][ 1 ] ); for ( k = 0; k < PaneMk.rels.length;  k++ ) { $favicon.attr( "rel", PaneMk.rels[ k ] ); $head.append( $favicon ); if ( k + 1 <  PaneMk.rels.length ) { $favicon =  $favicon.clone; }                 }   // for k                  if ( i + 1  <  offer.length ) { $favicon =  $favicon.clone; }              }   // for i            } }  // $favicon.length }  // $head };  // .favicon

PaneMk.file =  function ( album, assign, access ) { // Retrieve PNG file URL at commons // Precondition: //   album   -- apple or favicon prefix //   assign  -- site //   access  -- hashcode octet // Postcondition: //   Returns URL // 2012-06-07 PerfektesChaos@de.wikipedia var r =  "//upload.wikimedia.org/wikipedia/commons/" + access.substr( 0, 1 )  +  "/"  +  access  +  "/" + album  +  assign  +  ".png"; return r;  };   // .file

PaneMk.filter =  function  { // Test for appropriate rel="" // Precondition: //   this  -- // Postcondition: //   Returns true if matching rel // Uses: //   this   (not PaneMk) //   >  .rels // 2022-08-28 PerfektesChaos@de.wikipedia var s = this.rel, i, r;     for ( i = 0;  i < PaneMk.rels.length;  i++ ) { if ( PaneMk.rels[ i ] === s ) { r = true; break;  // for i         } }  // for i      return r;   };   // .filter

PaneMk.fire =  function  { // Startup // Uses: //   this //   >  .type //   >  .vsn //   >  .doc //   mw.loader.getState //   mw.loader.state //   mw.loader.using //   mw.hook //   (.prefs.fire) // 2018-08-24 PerfektesChaos@de.wikipedia var signature = "ext.gadget." + this.type, profile, rls; if ( mw.loader.getState( signature ) !==  "ready" ) { rls = { }; rls[ signature ] = "ready"; mw.loader.state( rls ); mw.loader.using( [ "user",                           "user.options",                            "mediawiki.util",                            "jquery.client" ],                          this.prefs.fire ); profile =  { type: this.type, vsn: this.vsn, doc: this.doc }; mw.hook( this.type ).fire( profile ); }  };   // .fire

PaneMk.flag =  function ( action ) { // Put character together with document title // Precondition: //   action  -- "Diff", "History", "Links", "Vitally", "*" // Uses: //   this //   >  .config.leave //   >  .site //   >  .heads //   >  .config.charDiff //   >  .config.charHistory //   >  .config.charLinks //   >  .config.charVitally //   >  .config.chars //   >  .config.lowChar //   >  .config.lazy //   >  .config.rightleft //   >< document.title //    < .leave //   .facilitate // Requires: JavaScript 1.3  String.fromCharCode // 2013-01-01 PerfektesChaos@de.wikipedia var c      =  true, learn  =  true; if ( this.config.leave ) { this.facilitate; } else if ( this.heads.indexOf( this.site ) <  0 ) { c     =  this.config[ "char" + action ]; learn =  false; }     if ( typeof this.config.chars === "boolean" ) { if ( c === true ) { c =  this.config.chars; }     }      if ( c ) { if ( learn ) { c =  this.config[ "char" + action ]; if ( c === undefined ) { c =  true; } else { learn =  false; }        }         if ( learn ) { switch ( action ) { case "Diff" : c =  ( this.config.lowChar ? "±" :  916 );   // 'Δ' break; case "History" : c =  ( this.config.lowChar ? "^" : 8595 );   // '↓' break; case "Links" : c =  ( this.config.lowChar ? ">" : 8594 );   // '→' break; case "Vitally" : if ( c &&  ! this.config.lazy ) { c =  false; break; }                 c  =  "*"; break; default: c =  false; }  // switch action }        if ( c ) { if ( ! this.config.leave ) { if ( action === "Links" ) { this.facilitate; }           }            if ( typeof c === "number" ) { if ( c > 0 ) { c =  String.fromCharCode( c ); }           }            if ( typeof c === "string" ) { if ( this.config.rightleft ) { window.document.title =  window.document.title + " " + c;              } else { c =  c + " "; if ( window.document.title.indexOf( c ) !==  0 ) { window.document.title =  c + window.document.title; }              }            }         }      }   };   // .flag

PaneMk.flip =  function  { // Abbreviate document title by namespace shortcut, if any // Uses: //   >  this //   >  .nsN //   >  .env //   >< .config.shortcut //    < document.title // 2014-08-30 PerfektesChaos@de.wikipedia var s = false, e,         o,          $shortcut; if ( typeof this.config.shortcut !== "boolean" ) { this.config.shortcut =  true; }     if ( this.config.shortcut ) { $shortcut =  $( ".shortcut" ); if ( $shortcut.length ) { s =  $shortcut.data( "shortcut" ); }     }      if ( ! s  &&  this.nsN > 0 ) { o =  this.env.wgNamespaceIds; for ( e in o ) { if ( e.length < 4 ) {  // file help talk user if ( o[ e ] === this.nsN ) { s =  e.toUpperCase + ":" + this.env.wgTitle; break;  // for e               }   // first match }        }   // for e      } if ( s ) { window.document.title =  s;      } };  // .flip

PaneMk.fresh =  function  { // Run paneMarker in this particular situation // Precondition: //   Page may be under loading, but not necessarily ready. //   .using( [ "user", "mediawiki.util" ] ) // Uses: //   >  .opt.* //   >  .prefs.supply //   >  .jQuery.client //   >  .config.favicon //   >< this.* //    < .config.* //    < .env.* //    < .site //    < .nsN //    < .less //   mw.user.isAnon //   .prefs.fetch //   .flip //   .flag //   mw.config.get //   mw.util.getParamValue //   .favicon //   .prefs.form // 2016-10-08 PerfektesChaos@de.wikipedia var lenient =  true, browser, s;     if ( typeof this.opt === "object"  &&  this.opt ) { for ( s in this.opt ) { this.config[ s ] =  this.opt[ s ]; }  // for s in vals }     if ( ! mw.user.isAnon  &&           mw.libs[ this.prefs.supply ] ) { this.prefs.fetch; }     this.env   =  mw.config.get( [ "wgAction",                                     "wgCanonicalSpecialPageName",                                     "wgDBname",                                     "wgNamespaceIds",                                     "wgNamespaceNumber",                                     "wgPageName",                                     "wgRelevantPageName",                                     "wgServer",                                     "wgSiteName",                                     "wgTitle" ] ); this.site =  this.env.wgDBname; this.nsN  =  this.env.wgNamespaceNumber; this.less =  ( this.env.wgServer.indexOf( ".beta.wmflabs.org" )                      > 0 ); if ( ! this.config.lazy ) { if ( $.client ) { browser =  $.client.profile; if ( browser.name === "msie" ) { this.config.lazy =  ( browser.versionNumber < 10 ); }        }      }      this.flip; switch ( this.env.wgAction ) { case "edit" : case "submit" : if ( ! this.config.lazy ) { this.favicon( true ); lenient =  false; }           this.flag( "Vitally" ); break; case "history" : this.flag( "History" ); break; case "view" : if ( mw.util.getParamValue( "diff" ) !==  null ) { this.flag( "Diff" ); } else if ( this.nsN === -1 ) { switch ( this.env.wgCanonicalSpecialPageName ) { case "Blankpage" : case "Gadgets" : if ( ! mw.user.isAnon &&                          mw.libs[ this.prefs.supply ] ) { this.prefs.form; }                    break; case "Emailuser" : case "Upload" : if ( ! this.config.lazy ) { this.favicon( true ); lenient =  false; }                    this.flag( "Vitally" ); break; case "Whatlinkshere" : this.flag( "Links" ); break; }  // switch wgCanonicalSpecialPageName } else { this.flag( "*" ); }           break; }  // switch wgAction if ( lenient ) { if ( this.less ||              typeof this.config.favicon === "string" ) { this.favicon( false ); }     }   };   // .fresh

PaneMk.furnish =  function  { // Launch paneMarker from event queue // Uses: //   .fresh // Remark: May be used as event handler -- 'this' is not accessed // 2012-06-07 PerfektesChaos@de.wikipedia PaneMk.fresh; };  // .furnish

PaneMk.fire; }( window.mediaWiki, window.jQuery ) );

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

/// EOF  paneMarker/d.js