User:PerfektesChaos/js/pageTeaserHint/d.js

/// User:PerfektesChaos/js/pageTeaserHint/d.js /// 2020-12-27 PerfektesChaos@de.wikipedia // Enrich links to pages with short description, intro preview and image // Part 1: Check wiki page for page links, equip with button etc. //  ResourceLoader:  compatible; //   dependencies: mediawiki.api, //                 mediawiki.storage, //                 mediawiki.ui.button, //                 mediawiki.util /// 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   = -1.5,       Signature = "pageTeaserHint",       Store     = "User:PerfektesChaos/js/" + Signature,       PTH       = { core:      { maxage: 86400,                                  site:   "w:en",                                  store:  Store,                                  sub:    "core" },                     doc:       { site:   "w:en",                                  store:  Store },                     got:       false,                     lazy:      true,                     limited:   true,                     paged:     { "allpages":                                    { suite:  ".mw-allpages-nav",                                      search: ".mw-allpages-body"                                    },                                  "category":                                    { suite:  "#mw-pages",                                      search: "#mw-pages" },                                 "contributions": { suite: ".mw-contributions-list", search: "#mw-content-text" },                                 "info": { suite: "#mw-pageinfo-" + "header-restrictions", search: false },                                 "prefixindex": { suite: ".mw-prefixindex-body", search: ".mw-prefixindex-body" },                                 "search": { suite: ".mw-search-results", search: ".mw-search-results" },                                 "whatlinkshere": { suite: "#mw-whatlinkshere-list", search: "#mw-content-text" }                               },                     pages:     { "*":      { button: { large: true },                                             list:   true }, "info":  { button: { large: false },                                             list:   true }, "search": { button: { large: true },                                             list:   false }, "user":  { button: { large: false },                                             list:   true } },                      re:      false, result: false, rooms:  false, scope:  false, trigger: { src: "OOjs UI icon " + "window-invert.svg", sub: "ec" },                      $widget: false },      REPOS     = { }; PTH.REPOS = REPOS;

function face { // Page orientation // Precondition: //   DOM ready // Uses: //   >< PTH.$body //    < PTH.ltr // 2020-12-27 PerfektesChaos@de.wikipedia if ( ! PTH.$body ) { PTH.$body = $( "body" ); PTH.ltr  = ( $( "html" ).attr( "dir" )  !==  "rtl" ); }  }   // face

function factory ( area, at, $a ) { // Check for matching link and register if appropriate // Precondition: //   area  -- number, of namespace //   at    -- string, with decoded link title //   $a    -- object of link to page, or not // Postcondition: //   Returns pretty link title, or not // Uses: //   >  PTH.limited //   >  PTH.re.usc //   >< PTH.got // 2020-12-27 PerfektesChaos@de.wikipedia var r = at; if ( area  &&           ( area < 0    // How comes? || PTH.limited || area % 2 ) ) { r = false; }     if ( r   &&   ( area ===  2  || area === 6  || area === 8  || area === 14 ) ) { r = false; }     if ( r  &&  area  &&  PTH.limited ) { r = false; }     if ( r ) { r = r.replace( PTH.re.usc, " " ); PTH.got = PTH.got ||  { }; if ( typeof PTH.got[ r ] !==  "object" ) { PTH.got[ r ] = { ns:     area, show:   r,                             ul:      [ ] };        }         if ( $a ) { PTH.got[ r ].ul.push( $a ); }     }      return r;   }   // factory

function feed { // All preconditions met, run core script // Uses: //   >  Signature //   >  PTH //   mw.hook // 2020-12-27 PerfektesChaos@de.wikipedia mw.hook( Signature + ".init" ).fire( PTH ); }  // feeder

function feeder { // Retrieve core script // Uses: //   >< PTH.core //   REPOS.fire //   mw.loader.using //   (feed) // 2020-12-27 PerfektesChaos@de.wikipedia if ( PTH.core ) { PTH.core.suite = ( Version > 1 ?  "r"  :  "d" ); if ( PTH.core.suite !== "r" ) { PTH.core.maxage = 100; }        REPOS.fire( PTH.core.site,                     PTH.core.store,                     "/" + PTH.core.sub                     + "/" + PTH.core.suite + ".js",                     { maxage: PTH.core.maxage } ); PTH.core = false; mw.loader.using( [ "mediawiki.api",                           "mediawiki.storage",                            "mediawiki.util" ],                          feed ); }  }   // feeder

function fetch { // Button has been pressed // Uses: //   >  PTH.selector //   >  PTH.$widget //   >  PTH.got //   >  PTH.page //   feeder //   mw.hook // 2020-12-27 PerfektesChaos@de.wikipedia var $ajax = $( " " ); PTH.$widget.empty; $ajax.addClass( "mw-ajax-loader",                     PTH.selector + "ajax" ) .css( { "margin-bottom": "0.2em",                  "margin-left":   "1em",                   "margin-right":  "1em",                   "margin-top":    "0.2em" } ) .text( String.fromCharCode( 160 ) ); PTH.$widget.append( $ajax ); feeder; mw.hook( Signature + ".result" ).fire( PTH.got, PTH.page ); }  // fetch

function fiat ( at, assigned ) { // Matching link // Precondition: //   at        -- number of link to page, ignored //   assigned  -- DOM object of link to page // Uses: //   >  PTH.re.abs //   >  PTH.re.sns //   >  PTH.rooms //    < PTH.page.learnt //    < PTH.lazy //   factory // 2020-12-27 PerfektesChaos@de.wikipedia var $a = $( assigned ), s = $a.attr( "href" ), got, i, ns, space; if ( s.substr( 0, 6 ) === "/wiki/" ) { s = s.substr( 6 ); } else { got = PTH.re.abs.exec( s ); if ( got ) { s = got[ 1 ]; } else { s = false; }     }      if ( s ) { i = s.indexOf( "#" ); if ( i > 0 ) { s = s.substr( 0, i ); }        try { s = decodeURIComponent( s ); } catch ( e ) { }        got = PTH.re.sns.exec( s ); if ( got ) { space = got[ 1 ].toLowerCase; if ( typeof PTH.rooms[ space ] ===  "number" ) { ns = PTH.rooms[ space ]; }        }         if ( s ) { ns = ns || 0; if ( factory( ns, s, $a ) ) { PTH.page.learnt = true; if ( ! ns ) { PTH.lazy = false; }           }         }      }   }   // fiat

function finesse { // Process info page // Uses: //   >  PTH.nsn //   >  PTH.page.button //    < PTH.page.learnt //    < PTH.lazy //   mw.config.get // 2020-12-27 PerfektesChaos@de.wikipedia var cnf = mw.config.get( [ "wgPageContentModel",                                "wgTitle" ] ); if ( cnf.wgPageContentModel === "wikitext" &&           factory( PTH.nsn, cnf.wgTitle ) ) { if ( ! PTH.nsn ) { PTH.lazy = false; }        PTH.page.learnt = true; }  }   // finesse

function fire { // Document ready // Uses: //   >  PTH.scope //   >  PTH.pages //   >  Signature //   >  Version //   >  PTH.got //   >< PTH.page //    < PTH.$container //    < PTH.result //   mw.loader.load //   PTH.furnish //   feeder //   (fetch) //   (fiat) // 2020-12-27 PerfektesChaos@de.wikipedia var button, seek, $got; switch ( PTH.scope ) { case "allpages": case "contributions": case "prefixindex": case "whatlinkshere": case "category": PTH.page = PTH.pages[ "*" ]; break; default: PTH.page = PTH.pages[ PTH.scope ]; }  // switch PTH.scope PTH.page.learnt = false; button         = PTH.page.button; button.fiat    = fetch; button.sel     = PTH.paged[ PTH.scope ].suite; button.support = Signature + " " + Version; PTH.page.search = PTH.paged[ PTH.scope ].search; if ( PTH.page.search ) { PTH.page.$container = $( PTH.page.search ); seek = "a[href*=\"/wiki/\"]:not(a[href*=\"#\"])"; $got = PTH.page.$container.find( seek ); if ( PTH.scope !== "user" ) { $got.not( ".mw-parser-output a" ); }        $got.each( fiat ); } else { finesse; }     if ( PTH.page.learnt ) { PTH.furnish( PTH.page.button ); }     delete PTH.page.learnt; }  // fire

function firing ( apply ) { // Check request conditions // Precondition: //   apply  -- config object, or not // Uses: //   >  Signature //   >< PTH.scope //    < PTH.limited //    < PTH.rooms //    < PTH.nsn //    < PTH.selector //    < PTH.paged.user //    < PTH.re      //    mw.hook //   mw.config.get //   (fire) // 2020-12-27 PerfektesChaos@de.wikipedia var cnf, listen, s;     mw.hook( Signature + ".config" ).remove( firing ); if ( PTH.scope === false ) { PTH.scope = null; cnf      = mw.config.get( [ "wgAction",                                      "wgPageContentModel",                                      "wgNamespaceIds",                                      "wgNamespaceNumber" ] ); PTH.rooms   = cnf.wgNamespaceIds; PTH.nsn     = cnf.wgNamespaceNumber; PTH.selector = Signature.toLowerCase + "-"; if ( typeof apply ===  "object"   &&              apply ) { if ( typeof apply.limited ===  "boolean" ) { PTH.limited = apply.limited; }           if ( typeof apply.listen  ===  "boolean" ) { listen = apply.listen; PTH.paged.user = { suite: "." + PTH.selector + "private", search: "." + PTH.selector + "private" };           }         }         switch ( cnf.wgAction ) { case "view": if ( PTH.nsn === -1 ) { s = mw.config.get( "wgCanonicalSpecialPageName" ); switch ( s ) { case "Allpages": case "Contributions": case "Prefixindex": case "Search": case "Whatlinkshere": PTH.scope = s.toLowerCase; break; }  // switch wgCanonicalSpecialPageName } else if ( cnf.wgPageContentModel === "wikitext"                          && PTH.nsn ) { if ( PTH.nsn === 14 ) { PTH.scope = "category"; } else if ( listen ) { PTH.scope = "user"; }              }               break; case "edit": case "submit": if ( listen  &&                    cnf.wgPageContentModel === "wikitext"   &&                    PTH.nsn ) { PTH.scope = "user"; }              break; case "info": if ( ! ( PTH.nsn && apply.limited )  &&                    PTH.nsn !== 14 ) { PTH.scope = "info"; }              break; }  // switch wgAction if ( PTH.scope ) { PTH.re = { abs: new RegExp( "^(?:[htps]*:)?//[^/]+/wiki/"                                         + "(.+)$" ), sns: new RegExp( "^([^:]+):" ), spc: new RegExp( " ", "g" ), usc: new RegExp( "_", "g" ), wsp: new RegExp( "^\\s*$" ) };           $( fire ); }     }   }   // firing

function first { // Autorun on loading // Uses: //   >  Signature //   >  PTH.doc //   >  Version //    < PTH.signature //    < PTH.pub //   mw.loader.getState //   mw.loader.state //   mw.config.get //   mw.hook //   (firing) // 2020-12-27 PerfektesChaos@de.wikipedia var rls, s;     PTH.signature = "ext.gadget." + Signature; if ( mw.loader.getState( PTH.signature ) !==  "ready" ) { rls = { }; rls[ PTH.signature ] = "ready"; mw.loader.state( rls ); s = "" + PTH.doc.site + "/" + PTH.doc.store + ""; PTH.pub = { doc:      s,                     signature: PTH.signature, type:     Signature, vsn:      Version }; mw.hook( Signature + ".ready" ).fire( PTH.pub ); mw.hook( Signature + ".config" ).add( firing ); mw.hook( Signature + ".config" ).fire; }  }   // first

PTH.$file = function ( access, appear ) { // Create image // Precondition: //   access  -- media ID      //               .ltr   -- version LTR //              .rtl   -- version RTL //              .src   -- page title //              .sub   -- 2-char-code of subdir //              .site  -- default: commons //   appear  -- number, of pixels // Postcondition: //   Returns jQuery // Uses: //   >  PTH.ltr //   >  PTH.re.spc //   >  Signature // 2020-12-27 PerfektesChaos@de.wikipedia var $r = $( " " ), obj, src; if ( typeof access ===  "object"           &&     access  &&           typeof appear  ===  "number"           &&     appear > 0 ) { if ( typeof access.ltr ===  "object"              &&     access.ltr   &&              typeof access.rtl  ===  "object"              &&     access.rtl ) { obj = access[ ( this.ltr ? "ltr" : "rtl" ) ]; } else { obj = access; }        if ( typeof obj.src  ===  "string"              &&     obj.src   &&              typeof obj.sub  ===  "string"              &&     obj.sub.length === 2 ) { src = obj.src.replace( PTH.re.spc, "_" );  // + encode $r.attr( { "src": "https://upload."                             + "wikimedia.org/wikipedia/commons"                              + "/thumb/"                              + obj.sub.substr( 0, 1 ) + "/"                              + obj.sub + "/"                              + src + "/"                              + appear + "px-" + src + ".png"                     } ) .css( { "display": "inline" } ); } else { window.console.log( Signature + ".$file s", access ); }     } else { window.console.log( Signature + ".$file *",                            access,                             appear ); }     return $r; };  // PTH.$file

PTH.furnish = function ( apply ) { // Insert button // Precondition: //   apply  -- descriptive object //             .fiat     -- action //             .large    -- large or line-size? //             .sel      -- selector ahead of which to insert //             .support  -- query tooltip // Uses: //   >  PTH.ltr //   >  PTH.selector //   >< PTH.$widget //   mw.loader.load //   face //   PTH.$file // 2020-12-27 PerfektesChaos@de.wikipedia var css  = { "background-color": "#3366CC", "border":          "1px solid #3366CC", "border-radius":   "2px", "color":           "#FFFFFF", "cursor":          "pointer", "display":         "table", "padding":         "0.546875em 1em", "text-align":      "center", "vertical-align":  "middle" },         $btn = $( " " ), img, trigger, $img, $rel; if ( ! this.$widget ) { mw.loader.load( "mediawiki.ui.button" ); // w:de:Template:MediaWiki-Button/styles.css this.$widget = $( " " ); this.$widget.addClass( this.selector + "widget" ); face; this.$widget.css( { "float":                                    ( this.ltr ? "right" : "left" ) } ); $rel = $( apply.sel ); $rel.eq( 0 ).before( this.$widget ); }     trigger = this.trigger; if ( typeof trigger.ltr ===  "object" ) { trigger = trigger[ ( this.ltr ? "ltr" : "rtl" ) ]; }     img  = ( apply.large ? 30 : 18 ); $img = this.$file( trigger, img ); $btn.addClass( [ "mw-ui-button",                      "mw-ui-progressive",                       this.selector + "-button" ] ) .append( $img ) .attr( { "role": "button",                   "title": apply.support } ) .click( apply.fiat ) .css( css ); this.$widget.append( $btn ); };  // PTH.furnish

REPOS.fire = function ( at, access, append, alter ) { // Load from external URL // Precondition: //   at      -- Wikimedia Foundation site code, or not //   access  -- string with basic page name //   append  -- string with subpage, or not //   alter   -- parameter object, or MIME string, or not // Uses: //   >< REPOS.requests //   REPOS.foundation //   mw.loader.load // 2018-03-21 PerfektesChaos@de.wikipedia var source, syntax; if ( typeof REPOS.requests !==  "object" ) { REPOS.requests = { }; }     if ( typeof REPOS.requests[ access ]  !==  "boolean" ) { REPOS.requests[ access ] = true; if ( append ) { source = access + append; } else { source = access; }        if ( at ) { source = REPOS.foundation( at, source, alter ); if ( typeof alter ===  "object"                 &&     alter   &&                 typeof alter.ctype  ===  "string" ) { syntax = alter.ctype; }        } else { syntax = alter; }        mw.loader.load( source, syntax ); }  };   // REPOS.fire

REPOS.foundation = function ( at, access, alter ) { // Create URL within Wikimedia Foundation // Precondition: //   at      -- site code, or not //   access  -- string with page name //   alter   -- parameter object, or not // Postcondition: //   Returns full URL // 2018-03-21 PerfektesChaos@de.wikipedia var s = access, r = encodeURI( s ); if ( typeof alter ===  "object"           &&     alter ) { r = "/w/index.php?title=" + r;        if ( access.substr( -3 ) === ".js" ) { alter.ctype = "text/javascript"; } else if ( access.substr( -4 ) === ".css" ) { alter.ctype = "text/css"; }        alter.action = "raw"; for ( s in alter ) { r = r + "&" + s + "=" + encodeURI( alter[ s ] ); }  // for s in alter } else { r = "/wiki/" + r;     } if ( typeof at ===  "string"           &&     at ) { switch ( at ) { case "meta": r = "meta.wikimedia.org" + r;              break; case "mw": r = "www.mediawiki.org" + r;              break; case "w:en": r = "en.wikipedia.org" + r;              break; default: r = window.location.host + r;        }   // switch at         r = "https://" + r;      } return r;  };   // REPOS.foundation

first; }( window.mediaWiki, window.jQuery ) );

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

/// EOF  pageTeaserHint/d.js