/// 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
/// <nowiki>
/* 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 = $( "<div>" );
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 <img>
// Uses:
// > PTH.ltr
// > PTH.re.spc
// > Signature
// 2020-12-27 PerfektesChaos@de.wikipedia
var $r = $( "<img>" ),
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 = $( "<div>" ),
img, trigger, $img, $rel;
if ( ! this.$widget ) {
mw.loader.load( "mediawiki.ui.button" );
// w:de:Template:MediaWiki-Button/styles.css
this.$widget = $( "<div>" );
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 </nowiki> pageTeaserHint/d.js