User:PerfektesChaos/js/paneMarker/d.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/// 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
/// <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 = -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 = "[[mw:" + 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]]
</nowiki>
[[File:Apple-touch-icon-red-commons.png]]
[[File:Apple-touch-icon-red-mediawiki.png]]
[[File:Apple-touch-icon-red-wikinews.png]]
[[File:Apple-touch-icon-red-wikipedia.png]]
[[File:Apple-touch-icon-red-wiktionary.png]]
[[File:Apple-touch-icon-red-wmf.png]]
[[File:Favicon-red-commons.png]]
[[File:Favicon-red-mediawiki.png]]
[[File:Favicon-red-meta.png]]
[[File:Favicon-red-testwiki.png]]
[[File:Favicon-red-wikibooks.png]]
[[File:Favicon-red-wikinews.png]]
[[File:Favicon-red-wikipedia.png]]
[[File:Favicon-red-wikiquote.png]]
[[File:Favicon-red-wikisource.png]]
[[File:Favicon-red-wikiversity.png]]
[[File:Favicon-red-wmf.png]]
<nowiki>
*/
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 <link> for appropriate rel=""
// Precondition:
// this -- <link>
// 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 </nowiki> paneMarker/d.js