/// User:PerfektesChaos/js/listPageOptions/d.js
/// 2019-02-04 PerfektesChaos@de.wikipedia
// Add specific functionality on watchlists and 'recent changes'
// ResourceLoader: compatible;
// dependencies: user, user.options,
// mediawiki.api, mediawiki.api.watch,
// mediawiki.user, mediawiki.util
// namespaces: -1
/// Documentation: [[w:en:User:PerfektesChaos/js/listPageOptions]]
/// Fingerprint: #0#0#
/// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA)
/// <nowiki>
/* global window:false, unescape: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 = -6.2,
POpt = "listPageOptions";
if ( typeof mw.libs[ POpt ] !== "object" ||
! mw.libs[ POpt ] ) {
mw.libs[ POpt ] = { };
}
mw.libs[ POpt ].type = POpt;
POpt = mw.libs[ POpt ];
// Requires: JavaScript 1.3
// MediaWiki 1.23 (mw .libs .hook, jQuery core)
if ( typeof POpt.loaded !== "boolean" ) {
// 2018-08-24
POpt.loaded = true;
POpt.config = { "wikidata.bgc": "AFEEEE" };
POpt.disguise = { };
POpt.edit = { };
POpt.group = { "sign": POpt.type + "_groupPg",
"show": "groupie",
"soft": "enhanced" };
POpt.increm = { more: 30 };
POpt.multi = { "sign": POpt.type + "_multiPg",
"show": "multiple",
"soft": "extended" };
POpt.notice = { };
POpt.picked = { "sign": POpt.type + "_visitedPg",
"show": "visited",
"soft": "visited" };
POpt.reduce = { };
POpt.storage = { };
POpt.unwatch = { };
POpt.values = { };
POpt.config.texts = {
// 2015-10-11
"edit": {"en": "edit",
"de": "Bearbeiten"},
"groupie": {"en": "Group by pages",
"de": "Seitenbezogene\xA0Gruppierung"},
"hide": {"en": "Hide",
"de": "ausblenden"},
"multiple": {"en": "Multiple entries",
"de": "Mehrere\xA0Einträge"},
"notice": {"en": "+\xA0Visited",
"de": "+\xA0Gesehen"},
"notice?": {"en": "Add link for [visited] to every entry",
"de": "Link zu 'Gesehen'"
+ " bei jedem Eintrag"},
"notice!": {"en": "Mark as visited",
"de": "Markiere als 'Gesehen'"},
/*
"ignore": {"en": "Ignore",
"de": "Ignorieren"},
"ignored": {"en": "Unwatched",
"de": "Unbeobachtet"},
*/
"options": {"en": "Options and notices",
"de": "Anzeigeoptionen"},
"show": {"en": "Show",
"de": "einblenden"},
"toggleOff": {"en": "off",
"de": "aus"}, // abschalten
"toggleOn": {"en": "on",
"de": "ein"}, // einschalten
"update": {"en": "meanwhile",
"de": "Zwischenzeitlich"},
"unwatch": {"en": "+\xA0[Unwatch]",
"de": "+\xA0Nicht-Beobachten"},
"unwatch?": {"en": "Add link for [unwatch] to every entry",
"de": "Link zu 'Nicht beobachten'"
+ " bei jedem Eintrag"},
"visited": {"en": "Visited\xA0Pages",
"de": "Besuchte\xA0Seiten:"},
"watchPgRE": {"en": "^\\s*([1-9][0-9,]*[^.\n]+[.\n])(.|\n)*$",
"de": "^\\s*([1-9][0-9.]*[^.\n]+[.\n])(.|\n)*$"},
"wlnoteRE": {"en": "as of(.+,.+)\\.",
"de": "Stand:(.+,.+)Uhr\\."},
"^show": {"en": "List-Page-Options",
"de": "List-Page-Options"},
"^suffix": {"en": "–"
+ " equip watchlist and recent changes"
+ " with Options",
"de": "–"
+ " Beobachtungsliste und Letzte Änderungen"
+ " mit Optionen ausstatten"},
"^support": {"en": "/wiki/"
+ "User:PerfektesChaos/js/listPageOptions",
"de": "/wiki/"
+ "User:PerfektesChaos/js/listPageOptions"},
"^^lean-show":
{"en": "Compress option block" ,
"de": "Komprimierter Optionsblock"},
"^^learnt-show":
{"en": "Enable hiding of visited changes"
+ " on watchlist",
"de": "Möglichkeit zum Verbergen"
+ " besuchter Änderungen"
+ " auf der Beobachtungsliste"},
"^^learnt-null":
{"en": "not enabled",
"de": "keine Möglichkeit"},
"^^learnt-false":
{"en": "additional button; preset: show all",
"de": "Zusatz-Button; Vorgabe: alle anzeigen"},
"^^learnt-true":
{"en": "additional button; preset: hide visited",
"de": "Zusatz-Button;"
+ " Vorgabe: besuchte ausblenden"},
"^^leyo-show":
{"en": "Enable hiding of "
+ " last-edit-your-own on watchlist",
"de": "Möglichkeit zum Verbergen"
+ " eigener letzter Beiträge"
+ " auf der Beobachtungsliste"},
"^^link-show":
{"en": "Button to access this option page",
"de": "Schaltknopf,"
+ " um auf diese Optionsseite zu kommen"},
"^^looked-show":
{"en": "Enable entries to be marked as 'visited'"
+ " on watchlist",
"de": "Möglichkeit zum Markieren"
+ " einzelner Änderungen als 'Gesehen'"
+ " auf der Beobachtungsliste"},
"^^looked-null":
{"en": "not enabled",
"de": "keine Möglichkeit"},
"^^looked-false":
{"en": "on demand",
"de": "auf Anforderung"},
"^^looked-true":
{"en": "always",
"de": "immer"},
"^^lower-show":
{"en": "Additional buttons:"
+ " hide and show option block",
"de": "Zusätzliche Knöpfe:"
+ " Ein- und Ausblenden"
+ " des Optionsblocks"},
"^^lower-null":
{"en": "no additional button",
"de": "kein zusätzlicher Knopf"},
"^^lower-false":
{"en": "button for hiding",
"de": "Knopf zum Ausblenden"},
"^^lower-true":
{"en": "hide: button for showing",
"de": "Ausblenden; Knopf zum Einblenden"},
"^^luxury-show":
{"en": "Additional checkboxes for hide and show",
"de": "Zusätzliche Checkboxen"
+ " zum Ein- und Ausblenden"},
"^^more-show":
{"en": "Overlap seconds for incremental watchlist",
"de": "Zeitüberschneidung"
+ " für inkrementelle Beobachtungsliste"
+ " in Sekunden"},
"^^self": {"en": "Mark own edit",
"de": "Eigene Bearbeitung markieren"}
}; // POpt.texts
POpt.spooling = "https://upload.wikimedia.org/wikipedia/commons"
+ "/d/de/Ajax-loader.gif"; // throbber URL
} // ! .loaded
function fullstop( activity ) {
// Stop immediately event propagation
// Precondition:
// activity -- event
// 2015-05-12 PerfektesChaos@de.wikipedia
if ( typeof activity === "object" && activity ) {
if ( typeof activity.preventDefault === "function" ) {
activity.preventDefault();
}
if ( typeof activity.stopPropagation === "function" ) {
activity.stopPropagation();
}
}
} // fullstop()
POpt.config.feature = function ( apply ) {
// Wrap message text access for user or project language
// Precondition:
// apply -- text keyword
// Postcondition:
// Return text closest to user language
// Uses:
// this
// > .config.supply
// > .config.texts
// >< .config.language
// >< .prego
// mw.libs.preferencesGadgetOptions.translation()
// Remark: To be replaced
// if one day ResourceLoader3 gives access to
// gadget@translatewiki
// 2015-01-11 PerfektesChaos@de.wikipedia
var e, r;
if ( typeof this.language !== "boolean" ) {
if ( typeof POpt.prego !== "object" ) {
if ( typeof mw.libs[ this.supply ] === "object" ) {
POpt.prego = mw.libs[ this.supply ];
}
}
if ( typeof POpt.prego === "object" ) {
if ( typeof POpt.prego.translation === "function" ) {
this.language =
( typeof POpt.prego.translation === "function" );
}
} else {
this.language = false;
}
}
e = this.texts[ apply ];
if ( e ) {
if ( this.language ) {
r = POpt.prego.translation( e );
} else {
r = e.en;
}
} else {
r = "***" + apply + "***";
}
return r;
}; // .config.feature()
POpt.config.fetch = function () {
// Retrieve preferences and overwrite presets
// Uses:
// > .prego
// > .type
// < .lean
// < .learn
// < .leyo
// < .lower
// < .luxury
// < .more
// < .self
// mw.libs.preferencesGadgetOptions.fetch()
// 2016-05-07 PerfektesChaos@de.wikipedia
var scope = " lean learnt leyo link looked lower luxury"
+ " more self ",
vals = POpt.prego.fetch( POpt.type ),
s;
for ( s in vals ) {
if ( scope.indexOf( " " + s + " " ) > 0 ) {
POpt[ s ] = vals[ s ];
}
} // for s in vals
}; // .config.fetch()
POpt.config.fire = function () {
// Prepare ResourceLoader availability
// Postcondition:
// preferencesGadgetOptions requested, if not yet defined
// Uses:
// this
// < .config.supply
// mw.loader.getState()
// mw.loader.state()
// mw.loader.load()
// 2018-08-24 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=604802"
+ "&ctype=text/javascript",
"text/javascript" );
}
}; // .config.fire()
POpt.config.$flow = function () {
// Create throbber
// Postcondition:
// Return jQuery throbber image
// Uses:
// > .spooling
// jQuery()
// 2015-10-11 PerfektesChaos@de.wikipedia
var $r = $( "<img />" );
$r.attr( { src: POpt.spooling,
height: "16",
alt: "Ajax" } );
return $r;
}; // .config.$flow()
POpt.config.form = function () {
// Equip Special:Gadgets page with entry and form
// Uses:
// > .config.texts
// > .type
// > .increm.more
// > .prego
// mw.libs.preferencesGadgetOptions.form()
// 2016-05-07 PerfektesChaos@de.wikipedia
var txt = this.texts,
dialog =
{ script: POpt.type,
show: txt[ "^show" ],
support: txt[ "^support" ],
suffix: txt[ "^suffix" ],
opts: [ { signature: "lean",
type: "checkbox",
show: txt[ "^^lean-show" ],
val: false
},
{ signature: "learnt",
type: "radio",
show: txt[ "^^learnt-show" ],
poly: [ { val: null,
show: txt[ "^^learnt-null" ] },
{ val: false,
show: txt[ "^^learnt-false" ] },
{ val: true,
show: txt[ "^^learnt-true" ] }
] },
{ signature: "looked",
type: "radio",
show: txt[ "^^looked-show" ],
poly: [ { val: null,
show: txt[ "^^looked-null" ] },
{ val: false,
show: txt[ "^^looked-false" ] },
{ val: true,
show: txt[ "^^looked-true" ] }
] },
{ signature: "leyo",
type: "checkbox",
show: txt[ "^^leyo-show" ],
val: false
},
{ signature: "lower",
type: "radio",
show: txt[ "^^lower-show" ],
val: null,
poly: [ { val: null,
show: txt[ "^^lower-null" ] },
{ val: false,
show: txt[ "^^lower-false" ] },
{ val: true,
show: txt[ "^^lower-true" ] }
] },
{ signature: "luxury",
type: "checkbox",
show: txt[ "^^luxury-show" ],
val: false
},
{ signature: "self",
type: "text",
show: txt[ "^^self" ],
val: false
},
{ signature: "more",
type: "text",
show: txt[ "^^more-show" ],
minimum: 4,
maxlength: 4,
val: POpt.increm.more
},
{ signature: "link",
type: "checkbox",
show: txt[ "^^link-show" ],
val: false
}
] };
POpt.prego.form( dialog );
}; // .config.form()
POpt.disguise.fetch = function () {
// Initialize Array with leading item links
// Postcondition:
// Hidden if matched
// Return true for continuation
// Uses:
// this
// > mw.util.$content
// > .picked.learn
// > .letal
// > .self
// > .reLeyo
// < .picked.leap
// < .disguise.got
// Array of Arrays
// [0] $li jQuery entry, or $table
// [1] page URL
// [2] user URL
// [3] true: Minor
// [4] true: unseen
// [5] comment
// < .disguise.list
// jQuery.find()
// jQuery.eq()
// jQuery.children()
// jQuery.attr()
// jQuery().css()
// 2015-01-23 PerfektesChaos@de.wikipedia
var leap = false,
learn = false,
$list = mw.util.$content.find( "table.mw-enhanced-rc" ),
n = $list.length,
seen = "mw-changeslist-line-not-watched", // visited
e, i, low, staff, story, stuff, $e, $li, $trs, $user;
POpt.picked.leap = false;
this.got = [ ];
this.list = ( n === 0 );
if ( this.list ) { // standard
$e = mw.util.$content.find( "#resultListSort" );
if ( $e.length ) {
$e = $e.find( "ol" );
} else {
$e = mw.util.$content.find( "UL.special" );
}
if ( $e.length ) {
$list = $e.children( "li" );
n = $list.length;
for ( i = 0; i < n; i++ ) {
$li = $list.eq( i );
if ( POpt.picked.learn ) {
learn = $li.hasClass( seen );
if ( learn ) {
POpt.picked.leap = true;
} else {
leap = true;
}
}
$e = $li.children( "a" ).eq( 0 );
stuff = $e.attr( "href" );
stuff = $li.find( "A.mw-changeslist-title" )
.attr( "href" );
$user = $li.find( "A.mw-userlink" );
if ( $user.length ) {
staff = $user.attr( "href" );
} else {
staff = false;
}
low = ( $li.children( ".minoredit" ).length > 0 );
if ( POpt.letal ) {
story = false;
}
this.got.push( [ $li, stuff, staff, low, learn, story ] );
} // for i
if ( POpt.mode === 1 && POpt.self ) {
story = ".mw-changeslist-separator";
$e = $( "<span>" );
$e.css( { "font-weight": "bold" } );
$e.text( POpt.self );
for ( i = 0; i < n; i++ ) {
e = this.got[ i ];
staff = e[ 2 ];
if ( staff ) {
if ( this.reLeyo.test( staff ) ) {
e[ 0 ].find( story ).after( $e.clone() );
}
}
} // for i
}
}
} else { // enhanced (grouped)
staff = false;
for ( i = 0; i < n; i++ ) {
$li = $list.eq( i );
if ( POpt.picked.learn ) {
learn = $li.hasClass( seen );
if ( learn ) {
POpt.picked.leap = true;
} else {
leap = true;
}
}
$trs = $li.children( "tbody" ).children( "tr" );
stuff = $trs.find( "SPAN.mw-title" ).children( "a" )
.attr( "href" );
$e = $trs.find( "A.mw-userlink" );
staff = false;
switch ( $e.length ) {
case 0 :
break;
case 1 :
staff = $e.attr( "href" );
break;
default :
$e = $trs.find( ".changedby" )
.children( "A.mw-userlink" );
if ( $e.length === 1 ) {
staff = $e.attr( "href" );
} else if ( this.reLeyo ) {
$e = $trs.eq( 1 ).find( "A.mw-userlink" );
staff = $e.attr( "href" );
}
} // switch $e.length
if ( this.reLeyo && staff ) {
if ( this.reLeyo.test( staff ) ) {
$li.hide();
}
}
if ( $li ) {
low = ( $trs.children( ".minoredit" ).length > 0 );
// if ( POpt.letal && $trs.length == 2 ) {
// }
this.got.push( [ $li, stuff, staff, low, learn, story ] );
}
} // for i
}
POpt.picked.leap = ( POpt.picked.leap && leap );
}; // .disguise.fetch()
POpt.disguise.fiat = function ( array, abolish ) {
// Hiding or show entries
// Precondition:
// array -- filter condition
// abolish -- true: hide; false: show again
// Uses:
// this
// > .mode
// .disguise.filter()
// jQuery.isArray()
// 2015-11-01 PerfektesChaos@de.wikipedia
var i, k, m, n, q, q3, q4;
if ( $.isArray( array ) ) {
n = array.length;
for ( i = 0; i < n; i++ ) {
q = array[ i ];
if ( $.isArray( q ) ) {
m = q.length;
if ( m > 1 ) {
k = q[ 2 ];
if ( m < 4 ) {
q4 = false;
if ( m < 3 ) {
q3 = false;
} else {
q3 = q[ 3 ];
}
} else {
q3 = q[ 3 ];
q4 = q[ 4 ];
}
if ( ! k || k === POpt.mode ) {
if ( this.filter( q[ 0 ],
q[ 1 ],
q3,
q4,
abolish ) ) {
break; // for i
}
}
}
}
} // for i
}
}; // .disguise.fiat()
POpt.disguise.filter = function ( alter, abandon, account, ant, abolish ) {
// Hide or show for one entry pattern rule
// Precondition:
// alter -- special page
// abandon -- namespace page pattern, special page name pattern
// account -- user pattern
// ant -- limit to minor edit
// abolish -- true: hide; false: show again
// Postcondition:
// Returns true if to be aborted, no elements any more
// Elements hidden if matched
// Uses:
// this
// > .picked.learn
// > .picked.leap
// > .disguise.list
// >< .disguise.got
// >< .disguise.special
// .format()
// .disguise.format()
// mw.config.get()
// jQuery.remove()
// 2015-01-26 PerfektesChaos@de.wikipedia
var r = false,
i, l, n, q, rep, reu, s;
if ( alter || abandon || account
|| ( POpt.picked.learn && POpt.picked.leap ) ) {
n = this.got.length;
if ( n ) {
if ( alter || ! this.list ) {
rep = "/wiki/";
if ( alter ) {
if ( ! this.special ) {
q = mw.config.get( "wgFormattedNamespaces" );
if ( q ) {
rep = q[ -1 ];
}
this.special = rep + ":";
}
rep = this.special;
}
} else {
rep = "/w(iki/|/index\\.php\\?title=)";
}
if ( abandon ) {
s = POpt.format( abandon );
} else {
s = "";
}
rep = new RegExp( rep + s );
reu = this.format( account );
r = true;
for ( i = 0; i < n; i++ ) {
q = this.got[ i ];
if ( q ) {
l = false;
if ( rep.test( q[ 1 ] ) ) {
l = alter;
if ( reu ) {
l = reu.test( q[ 2 ] );
}
if ( l && ant ) {
l = q[ 3 ];
}
}
if ( l ) {
if ( abolish ) {
q[ 0 ].hide();
} else {
q[ 0 ].show();
}
this.got[ i ] = false;
} else {
r = false;
}
}
} // for i
}
}
return r;
}; // .disguise.filter()
POpt.disguise.fire = function () {
// Start hiding entries
// Uses:
// this
// > .leyo
// > .self
// > .picked.learn
// > .disguise.hide
// > .disguise.show
// > .hide
// > .show
// .disguise.fresh()
// .disguise.fetch()
// .disguise.fiat()
// 2015-01-26 PerfektesChaos@de.wikipedia
if ( POpt.leyo || POpt.self ) {
this.fresh();
} else if ( POpt.picked.learn || this.hide || this.show ) {
this.fetch();
}
if ( this.hide ) {
this.fiat( POpt.hide, true );
}
if ( this.show ) {
this.fiat( POpt.show, false );
}
}; // .disguise.fire()
POpt.disguise.format = function ( account ) {
// Retrieve RegExp for User
// Precondition:
// account -- user pattern, or false
// Postcondition:
// Returns RegExp, or false
// Uses:
// .format()
// 2013-04-18 PerfektesChaos@de.wikipedia
var r;
if ( account ) {
r = new RegExp( "/w(iki/|/index.php?title=)[^:]+:"
+ POpt.format( account ) );
} else {
r = false;
}
return r;
}; // .disguise.format()
POpt.disguise.fresh = function () {
// Prepare "last edit your own" mode
// Uses:
// this
// < .reLeyo
// .disguise.format()
// .disguise.fetch()
// mw.config.get()
// 2013-04-18 PerfektesChaos@de.wikipedia
this.reLeyo = this.format( mw.config.get( "wgUserName" ) );
this.fetch();
}; // .disguise.fresh()
POpt.edit.fire = function () {
// Equip page with link for editing pages
// Precondition:
// document ready
// Remark: Used as event handler -- 'this' is not POpt
// 2018-05-13 PerfektesChaos@de.wikipedia
var $entries = $( ".mw-htmlform-flatlist-item," // OBSOLETING
+ ".oo-ui-fieldLayout-header" );
$entries.each( POpt.edit.furnish );
}; // .edit.fire()
POpt.edit.furnish = function ( address, achieve ) {
// Add page edit link to watchlist edit page entry
// Precondition:
// address -- number in superset
// achieve -- DOM element of list entry
// Uses:
// jQuery().find()
// jQuery().eq()
// jQuery().attr()
// jQuery().last()
// jQuery().insertAfter()append
// .config.feature()
// Remark: Used as $.each() result -- 'this' is not POpt
// 2015-03-21 PerfektesChaos@de.wikipedia
var $entry = $( achieve ),
$links = $entry.find( "a" ),
$a = $links.eq( 2 ),
swift = $a.attr( "href" ),
$end, $span;
$links.attr( { target: "_blank" } );
if ( swift ) {
$end = $links.last();
swift = swift.replace( /&action=history/, "&action=edit" );
$a = $( "<a>" );
$a.attr( { href: swift,
target: "_blank" } );
$a.text( POpt.config.feature( "edit" ) );
$end.after( $a );
$span = $( "<span>" );
$span.text( " | " );
$end.after( $span );
}
}; // .edit.furnish()
POpt.group.find = function ( assigned ) {
// Analyze URL and page by grabbing; less items than all?
// Precondition:
// assigned -- found URL parameter value "0", "1", null
// Postcondition:
// Initial state of page grouping has been explored
// Uses:
// this
// > mw.util.$content
// > .group.sign
// > .group.leaves
// >< .values.ctl2url
// jQuery().find()
// mw.user.options.get()
// 2013-02-27 PerfektesChaos@de.wikipedia
var less = false,
$grab;
if ( assigned ) {
less = ( assigned === "1" );
} else {
$grab = mw.util.$content.find( ".mw-enhanced-rc" );
if ( $grab.length ) {
less = true;
} else if ( ! this.leaves ) {
if ( mw.user.options.get( "usenewrc" ) ) {
less = true;
}
}
}
POpt.values.ctl2url[ this.sign ].val = ( less ? "1" : "0" );
}; // .group.find()
POpt.increm.fire = function () {
// Incremental page refresh
// Uses:
// > .increm.retrieved
// > .increm.more
// > .values.script
// > .special
// >< .more
// >< location
// < .values.ctl2url.days
// mw.config.get()
// .values.factory()
// Remark: Used as event handler -- 'this' is not POpt.increm
// 2016-05-09 PerfektesChaos@de.wikipedia
var date = new Date(),
incr = ( date - POpt.increm.retrieved ) / 1000,
more = POpt.increm.more,
site = mw.config.get( "wgServer" );
if ( typeof POpt.more === "string" && POpt.more ) {
POpt.more = parseInt( POpt.more, 10 );
}
if ( typeof POpt.more === "number" && POpt.more > more ) {
more = POpt.more;
}
incr += more;
POpt.values.ctl2url.days = false;
if ( site.indexOf( "://" ) < 0 ) {
site = window.location.protocol + site;
}
window.location = site + POpt.values.script
+ "?title=Special:" + POpt.special
+ POpt.values.factory()
+ "&days=" + ( incr / 86400 );
}; // .increm.fire()
POpt.increm.furnish = function ( $around ) {
// Precondition:
// $around -- options block, or false
// Postcondition:
// Return jQuery 'update' button, or false
// Uses:
// this
// > mw.util.$content
// > .type
// < .increm.retrieved
// jQuery()
// jQuery().find()
// jQuery().attr()
// jQuery().click()
// jQuery().css()
// .config.feature()
// jQuery().text()
// jQuery().before()
// (.increm.fire)
// 2015-01-26 PerfektesChaos@de.wikipedia
var $r = false,
$box, $e;
if ( $around ) {
$box = $around;
} else {
$box = mw.util.$content.find( "#mw-watchlist-options" );
}
if ( $box.length ) {
POpt.increm.retrieved = new Date();
$e = $box.find( "br" ).eq( 0 );
if ( $e.length ) {
$r = $( "<button />" );
$r.attr( { id: POpt.type + "_incrNormal",
type: "button" } )
.click( this.fire )
.css( { "margin-left": "1em",
"margin-right": "1em" } )
.text( POpt.config.feature( "update" ) );
$e.before( $r );
}
}
return $r;
}; // .increm.furnish()
POpt.multi.find = function ( assigned ) {
// Analyze URL; less items than all?
// Precondition:
// assigned -- found URL parameter value "0", "1", null
// Postcondition:
// Initial state of page has been explored
// Uses:
// this
// > .multi.sign
// >< .values.ctl2url
// jQuery().find()
// mw.user.options.get()
// 2013-02-27 PerfektesChaos@de.wikipedia
var less = false;
if ( assigned ) {
less = ( assigned === "1" );
} else {
if ( mw.user.options.get( "extendwatchlist" ) ) {
less = true;
}
}
POpt.values.ctl2url[ this.sign ].val = ( less ? "1" : "0" );
}; // .multi.find()
POpt.notice.factory = function () {
// Equip one entry with a [visited] link
// Postcondition:
// Return true -- continue $.each()
// Uses:
// > .unwatch.less
// jQuery()
// jQuery().parent()
// jQuery().attr()
// jQuery().find()
// jQuery().each()
// (.notice.feed)
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2015-10-11 PerfektesChaos@de.wikipedia
var $e = $( this ),
s;
if ( POpt.unwatch.less ) { // enhanced
$e = $e.parent();
} else { // standard
s = $e.attr( "class" );
if ( s ) {
if ( s.indexOf( "mw-changeslist-line-" ) < 0 ) {
$e = false;
}
} else {
$e = false;
}
}
if ( $e ) {
$e.find( "a" ).each( POpt.notice.feed );
}
return true;
}; // .notice.factory()
POpt.notice.feed = function () {
// Insert [unwatch] link after history link
// Postcondition:
// Return true or false -- continue or break $.each()
// Uses:
// jQuery()
// jQuery().attr()
// jQuery().text()
// jQuery().click()
// jQuery().css()
// jQuery().data()
// jQuery().append()
// jQuery().after()
// (POpt.notice.fire)
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2015-10-11 PerfektesChaos@de.wikipedia
var loop = true,
$e = $( this ),
s = $e.attr( "href" ),
g, id, $btn, $span;
if ( s && s.indexOf( "&action=history" ) > 0 ) {
g = /[?&]title=([^&]+)(&.+)*&curid=([0-9]+)(&.+)?$/.exec( s );
if ( g ) {
s = g[ 1 ];
id = g[ 3 ];
$btn = $( "<button />" );
$btn.attr( { type: "button",
title: POpt.config.feature( "notice!" ) } )
.click( POpt.notice.fire )
.css( { "color": "#006000",
"font-size": "85%",
"font-weight": "bold",
"padding-left": "0",
"padding-right": "0" } )
.data( { curid: id,
title: s } )
.text( "+" );
$span = $( "<span>" );
$span.attr( { "class": "curid" + id } )
.text( " | " )
.append( $btn );
$e.after( $span );
loop = false;
}
}
return loop;
}; // .notice.feed()
POpt.notice.fiat = function () {
// Provide link(s) for visited page
// Precondition:
// Watchlist
// Uses:
// this
// < .notice.$portlet
// .config.feature()
// mw.util.addPortletLink()
// (.notice.furnish)
// 2015-10-11 PerfektesChaos@de.wikipedia
this.$portlet =
$( mw.util.addPortletLink( "p-tb",
"#",
POpt.config.feature( "notice" ),
"t-mark-visited",
POpt.config.feature( "notice?" ),
"v",
null ) );
this.$portlet.click( this.furnish );
}; // .notice.fiat()
POpt.notice.fine = function ( arrived, $apply ) {
// Normalize entry after successful [visited]
// Precondition:
// arrived -- JSON info of ajax query
// $apply -- current set of throbber element containers
// Uses:
// jQuery().children()
// jQuery().each()
// (.notice.fix)
// Remark: Used as jQuery handler -- 'this' is not POpt.notice
// 2015-10-11 PerfektesChaos@de.wikipedia
if ( typeof arrived === "object" &&
typeof arrived.invalid === "undefined" ) {
$apply.children( "img" ).remove();
$apply.each( POpt.notice.fix );
} else {
POpt.fault( "notice", arrived, $apply );
}
}; // .notice.fine()
POpt.notice.fire = function () {
// Perform visited action
// Uses:
// this
// > mw.util.$content
// >< .notice.api
// jQuery().find()
// jQuery().children()
// jQuery().hide()
// .config.$flow()
// jQuery().append()
// mw.Api()
// mw.Api().postWithToken()
// (.notice.fine)
// (.fault)
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2015-10-11 PerfektesChaos@de.wikipedia
var $g = $( this ),
id = $g.data( "curid" ),
$e = mw.util.$content.find( ".curid" + id ),
defaults, promise, s;
if ( $e.length ) {
$e.children( "button" ).hide();
$e.append( POpt.config.$flow() );
if ( typeof POpt.notice.api !== "object" ) {
defaults = { parameters:
{ action: "setnotificationtimestamp" }
};
POpt.notice.api = new mw.Api( defaults );
}
s = unescape( decodeURI( $g.data( "title" ) ) );
promise = POpt.notice.api.postWithToken( "edit",
{ titles: s } );
promise.done( function ( arrived ) {
POpt.notice.fine( arrived, $e );
} )
.fail( function ( arrived ) {
POpt.fault( "notice", arrived, $e );
} );
}
}; // .notice.fire()
POpt.notice.first = function () {
// Provide link(s) for visited page
// Precondition:
// Watchlist
// Uses:
// this
// > .looked
// < .notice.$unvisiteds
// < .notice.$portlet
// .notice.furnish()
// .notice.fiat()
// 2015-10-11 PerfektesChaos@de.wikipedia
if ( typeof POpt.looked === "boolean" ) {
this.$unvisiteds = $( ".mw-changeslist-line-watched" );
if ( this.$unvisiteds.length ) {
if ( POpt.looked ) {
this.$portlet = false;
this.furnish();
} else {
this.fiat();
}
}
}
}; // .notice.first()
POpt.notice.fix = function () {
// Turn one entry into visited and remove throbber
// Postcondition:
// Return true -- continue $.each()
// Uses:
// jQuery().attr()
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2015-10-11 PerfektesChaos@de.wikipedia
var $g = $( this ).parent(),
state = $g.attr( "class" )
.replace( /\bmw-changeslist-line-watched\b/,
"mw-changeslist-line-not-watched" );
$g.attr( "class", state );
}; // .notice.fix()
POpt.notice.furnish = function ( activity ) {
// Equip all entries with an [unwatch] link
// Precondition:
// activity -- event
// Current page is watchlist
// Uses:
// > .$unvisiteds
// > .$portlet
// fullstop()
// jQuery().each()
// jQuery().remove()
// (.notice.factory)
// Remark: Used as event handler -- 'this' is not POpt.notice
// 2016-11-11 PerfektesChaos@de.wikipedia
fullstop( activity );
POpt.notice.$unvisiteds.each( POpt.notice.factory );
if ( POpt.notice.$portlet ) {
POpt.notice.$portlet.remove();
}
}; // .notice.furnish()
POpt.picked.$factory = function () {
// Create toggle for visited
// Postcondition:
// Return toggle text
// Uses:
// this
// > .picked.leap
// > .type
// > .values.$POpt
// > .picked.learning
// >< .picked.$toggle
// jQuery()
// jQuery().attr()
// jQuery().click()
// jQuery().css()
// jQuery().append()
// .config.feature()
// jQuery().text()
// (.picked.fire)
// 2015-01-11 PerfektesChaos@de.wikipedia
var s;
if ( this.leap ) {
if ( typeof this.$toggle !== "object" ) {
this.$toggle = $( "<button />" );
this.$toggle.attr( { id: POpt.type + "_visited",
type: "button" } );
this.$toggle.click( this.fire );
this.$toggle.css( { "margin-left": "0.5em",
"margin-right": "0.5em" } );
POpt.values.$POpt.append( this.$toggle );
}
s = ( this.learning ? "hide" : "show" );
this.$toggle.text( POpt.config.feature( s ) );
}
}; // .picked.$factory()
POpt.picked.fire = function () {
// Execute visited toggling
// Uses:
// this
// > .picked.leap
// >< .picked.learning
// >< .disguise.got
// jQuery().hide()
// jQuery().show()
// .storage.flush()
// .picked.$factory()
// Remark: Used as event handler -- 'this' is not POpt.reduce
// 2015-01-26 PerfektesChaos@de.wikipedia
var less = ( POpt.picked.learning && POpt.picked.leap ),
n, i, q;
n = POpt.disguise.got.length;
for ( i = 0; i < n; i++ ) {
q = POpt.disguise.got[ i ];
if ( q[ 4 ] ) {
if ( less ) {
q[ 0 ].hide();
} else {
q[ 0 ].show();
}
}
} // for i
POpt.storage.flush( "learnt", POpt.picked.learning );
POpt.picked.learning = ! POpt.picked.learning;
POpt.picked.$factory();
}; // .picked.fire()
POpt.picked.furnish = function () {
// Equip page with link for visited pages
// Uses:
// this
// > .values.$form
// > .learnt
// > .picked.show
// > .picked.leap
// > .lean
// > .values.$POpt
// < .picked.learning
// < .picked.$toggle
// .storage.find()
// .storage.flush()
// jQuery()
// jQuery().text()
// jQuery().append()
// .config.feature()
// jQuery().css()
// .picked.fire()
// 2015-01-11 PerfektesChaos@de.wikipedia
var s, $span;
if ( POpt.values.$form ) {
s = POpt.storage.find( "learnt" );
if ( s ) {
this.learning = ( s === "true" );
} else {
this.learning = POpt.learnt;
POpt.storage.flush( "learnt", this.learning );
}
$span = $( "<span>" );
$span.text( "\xA0| " );
POpt.values.$POpt.append( $span );
$span = $( "<span>" );
$span.text( POpt.config.feature( this.show ) );
POpt.values.$POpt.append( $span );
if ( ! this.leap ) {
$span = $( "<span>" );
$span.css( { "color": "#B0B0B0" } );
$span.text( " ./." );
POpt.values.$POpt.append( $span );
if ( POpt.mode === 2 ) { // should be excluded anyway
this.learning = false;
}
}
if ( POpt.mode === 2 && ! POpt.lean ) {
POpt.values.$POpt.append( $( "<hr />" ) );
}
this.fire();
}
}; // .picked.furnish()
POpt.reduce.facility = function () {
// Make options and notices visible
// Uses:
// > .reduce.$box
// > .reduce.$resuscitate
// < .reduce.lower
// jQuery().show()
// jQuery().hide()
// .storage.flush()
// Remark: Used as event handler -- 'this' is not POpt.reduce
// 2015-01-11 PerfektesChaos@de.wikipedia
POpt.reduce.$box.show();
POpt.reduce.$resuscitate.hide();
POpt.reduce.lower = false;
POpt.storage.flush( "lower", POpt.reduce.lower );
}; // .picked.facility()
POpt.reduce.fade = function () {
// Hide options and notices
// Uses:
// > .reduce.$resuscitate
// > .reduce.$box
// < .reduce.lower
// jQuery().css()
// jQuery().show()
// jQuery().hide()
// Remark: Used as event handler -- 'this' is not POpt.reduce
// 2015-01-11 PerfektesChaos@de.wikipedia
POpt.reduce.$resuscitate.css( { "margin-top": "10px" } );
POpt.reduce.$resuscitate.show();
POpt.reduce.$box.hide();
POpt.reduce.lower = true;
POpt.storage.flush( "lower", POpt.reduce.lower );
}; // .picked.fade()
POpt.reduce.furnish = function () {
// Equip options area with collapsible handle and prego button
// Uses:
// this
// > .type
// > .lower
// > mw.util.$content
// > .mode
// > .prego
// > .link
// >< .$options
// < .reduce.lower
// < .reduce.$box
// < .reduce.stamp
// < .reduce.$resuscitate
// < .reduce.$vanish
// .storage.find()
// .storage.flush()
// jQuery().find()
// .config.feature()
// jQuery()
// jQuery().attr()
// jQuery().css()
// jQuery().text()
// jQuery().append()
// .increm.furnish
// jQuery().clone()
// jQuery().click()
// jQuery().after()
// jQuery().before()
// .reduce.fade()
// .reduce.facility()
// .prego.$button()
// (.increm.fire)
// (.reduce.facility)
// (.reduce.fade)
// 2015-10-11 PerfektesChaos@de.wikipedia
var s = POpt.storage.find( "lower" ),
btnR, got, re, $btn, $div, $span;
if ( s ) {
this.lower = ( s === "true" );
} else {
this.lower = POpt.lower;
POpt.storage.flush( "lower", this.lower );
}
s = ( POpt.mode === 1 ? "#mw-watchlist-options"
: ".rcoptions" );
this.$box = mw.util.$content.find( s );
if ( this.$box.length ) {
btnR = { "float": ( POpt.ltr ? "right" : "left " ) };
btnR[ ( POpt.ltr ? "margin-left" : "margin-right" ) ] = "8px";
btnR[ ( POpt.ltr ? "margin-right" : "margin-left" ) ] = "0";
this.$resuscitate = $( "<div>" );
this.$resuscitate.attr( { id: POpt.type + "_resuscitate" } );
this.$resuscitate.css( { "margin-top": "10px" } );
if ( POpt.mode === 1 ) {
s = this.$box.text();
if ( s ) {
re = new RegExp( POpt.config.feature( "wlnoteRE" ) );
got = re.exec( s );
if ( got ) {
$span = $( "<span>" );
$span.text( got[ 1 ] );
this.$resuscitate.append( $span );
$btn = POpt.increm.furnish( this.$box );
if ( $btn ) {
$btn = $btn.clone();
$btn.attr( { id: POpt.type + "_incrShrinked" } );
$btn.click( POpt.increm.fire );
this.$resuscitate.append( $btn );
}
}
}
}
if ( ! POpt.$options ) {
POpt.$options = this.$box.find( "legend" );
}
if ( POpt.link && POpt.prego ) {
$btn = POpt.prego.$button( POpt.type );
$btn.attr( { id: POpt.type + "_optPage" } );
$btn.css( btnR );
$btn.css( { "margin-top": "20px" } );
POpt.$options.after( $btn );
$div = $( "<div>" );
$div.css( { "clear": "right" } );
POpt.$options.after( $div );
}
$btn = $( "<button />" );
$btn.attr( { id: POpt.type + "_optShow",
type: "button" } );
$btn.click( POpt.reduce.facility );
$btn.css( ( POpt.ltr ? "margin-left" : "margin-right" ),
"10px" );
$btn.text( POpt.config.feature( "options" ) );
this.$resuscitate.append( $btn );
this.$box.before( this.$resuscitate );
$btn = $( "<button />" );
$btn.attr( { id: POpt.type + "_optHide",
type: "button" } );
$btn.click( POpt.reduce.fade );
$btn.css( btnR );
$span = $( "<span>" );
$span.css( { "color": "#FF0000",
"font-weight": "bold" } );
$span.text( "X" );
$btn.append( $span );
POpt.$options.after( $btn );
if ( this.lower ) {
this.fade();
} else {
this.facility();
}
}
}; // .reduce.furnish()
POpt.storage.find = function ( access ) {
// Retrieve volatile configuration from session storage
// Precondition:
// access -- key
// Postcondition:
// Return value string, or false
// Uses:
// this
// sessionStorage
// > .type
// >< .stored
// 2013-09-06 PerfektesChaos@de.wikipedia
var r = false,
s = "~" + access + "_",
i, j;
if ( ! this.stored ) {
if ( window.sessionStorage ) {
this.stored = window.sessionStorage.getItem( POpt.type );
}
if ( ! this.stored ) {
this.stored = "~";
}
}
i = this.stored.indexOf( s );
if ( i >= 0 ) {
j = this.stored.indexOf( "~", i + 2 );
if ( j > 0 ) {
r = this.stored.substring( i + s.length, j );
}
}
return r;
}; // .storage.find()
POpt.storage.flush = function ( access, assign ) {
// Remember volatile configuration in session storage
// Precondition:
// access -- key
// assign -- value
// Uses:
// this
// > .type
// >< .stored
// 2013-09-06 PerfektesChaos@de.wikipedia
var s = "~" + access + "_",
i, j;
if ( ! this.stored ) {
this.stored = "~";
}
i = this.stored.indexOf( s );
s = s + assign;
if ( i < 0 ) {
this.stored = s + this.stored;
} else {
j = this.stored.indexOf( "~", i + 2 );
if ( j < 0 ) {
this.stored = s + "~";
} else {
this.stored = this.stored.substr( 0, i )
+ s
+ this.stored.substr( j );
}
}
if ( window.sessionStorage ) {
window.sessionStorage.setItem( POpt.type, this.stored );
}
}; // .storage.flush()
POpt.unwatch.factory = function () {
// Equip one entry with an [unwatch] link, if appropriate
// Postcondition:
// Return true -- continue $.each()
// Uses:
// > .unwatch.less
// jQuery()
// jQuery().parent()
// jQuery().attr()
// jQuery().find()
// jQuery().each()
// (.unwatch.feed)
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2013-02-08 PerfektesChaos@de.wikipedia
var $e = $( this ),
s;
if ( POpt.unwatch.less ) { // enhanced
$e = $e.parent();
} else { // standard
s = $e.attr( "class" );
if ( s ) {
if ( s.indexOf( "mw-changeslist-line-" ) < 0 ) {
$e = false;
}
} else {
$e = false;
}
}
if ( $e ) {
$e.find( "a" ).each( POpt.unwatch.feed );
}
return true;
}; // .unwatch.factory()
POpt.unwatch.feed = function () {
// Insert [unwatch] link after history link
// Postcondition:
// Return true or false -- continue or break $.each()
// Uses:
// jQuery()
// jQuery().attr()
// jQuery().text()
// jQuery().click()
// jQuery().css()
// jQuery().data()
// .unwatch.flag()
// jQuery().append()
// jQuery().after()
// (POpt.unwatch.fire)
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2015-01-11 PerfektesChaos@de.wikipedia
var loop = true,
$e = $( this ),
s = $e.attr( "href" ),
g, id, $btn, $span;
if ( s && s.indexOf( "&action=history" ) > 0 ) {
g = /[?&]title=([^&]+)(&.+)*&curid=([0-9]+)(&.+)?$/.exec( s );
if ( g ) {
s = g[ 1 ];
id = g[ 3 ];
$btn = $( "<button />" );
$btn.attr( { type: "button" } )
.click( POpt.unwatch.fire )
.css( { "padding-left": "0",
"padding-right": "0" } )
.data( { curid: id,
leave: true,
title: s } )
.text( POpt.unwatch.flag( false ) );
$span = $( "<span>" );
$span.attr( { "class": "curid" + id } )
.text( " | " )
.append( $btn );
$e.after( $span );
loop = false;
}
}
return loop;
}; // .unwatch.feed()
POpt.unwatch.fiat = function () {
// Equip watchlist toolbox with link to [unwatch]
// Precondition:
// watchlist has been loaded
// Uses:
// this
// < .unwatch.$portlet
// .config.feature()
// mw.util.addPortletLink()
// (POpt.unwatch.furnish)
// 2015-10-11 PerfektesChaos@de.wikipedia
this.$portlet =
$( mw.util.addPortletLink( "p-tb",
"#",
POpt.config.feature( "unwatch" ),
"t-unwatch",
POpt.config.feature( "unwatch?" ),
"w",
null ) );
this.$portlet.click( POpt.unwatch.furnish );
}; // .unwatch.fiat()
POpt.unwatch.fine = function ( arrived, $apply ) {
// Insert [watch again] link after successful unwatch
// Precondition:
// arrived -- JSON info of ajax query
// $apply -- current set of throbber element containers
// Uses:
// jQuery().children()
// jQuery().remove()
// jQuery().each()
// .fault()
// (.unwatch.fix)
// Remark: Used as event handler -- 'this' is not POpt.unwatch
// 2015-10-11 PerfektesChaos@de.wikipedia
if ( typeof arrived === "object" &&
typeof arrived.invalid === "undefined" ) {
$apply.children( "img" ).remove();
$apply.each( POpt.unwatch.fix );
} else {
POpt.fault( "unwatch", arrived, $apply );
}
}; // .unwatch.fine()
POpt.unwatch.fire = function () {
// Perform unwatch action, or undo this
// Uses:
// this
// > mw.util.$content
// >< .unwatch.api
// jQuery().find()
// .config.$flow()
// mw.Api()
// mw.Api().unwatch()
// mw.Api().watch()
// jQuery().children()
// jQuery().hide()
// jQuery().append()
// (.unwatch.fine)
// (.fault)
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2016-11-11 PerfektesChaos@de.wikipedia
var $g = $( this ),
id = $g.data( "curid" ),
$e = mw.util.$content.find( ".curid" + id ),
promise, subject, submit;
if ( $e.length ) {
$e.children( "button" ).hide();
$e.append( POpt.config.$flow() );
subject = unescape( decodeURI( $g.data( "title" ) ) );
submit = ( $g.data( "leave" ) ? "unwatch" : "watch" );
if ( typeof this.api !== "object" ) {
this.api = new mw.Api();
}
promise = this.api[ submit ]( subject );
promise.done( function ( arrived ) {
POpt.unwatch.fine( arrived, $e );
} )
.fail( function ( arrived ) {
POpt.fault( "unwatch", arrived, $e );
} );
}
}; // .unwatch.fire()
POpt.unwatch.fix = function () {
// Turn [unwatch] link into [watch again]
// Uses:
// jQuery()
// jQuery().children()
// jQuery().text()
// jQuery().data()
// .unwatch.flag()
// jQuery().show()
// Remark: Used as event handler -- 'this' is DOM element
// 2015-01-11 PerfektesChaos@de.wikipedia
var $e = $( this ),
$btn = $e.children( "button" ),
leave;
if ( $btn.length ) {
leave = $btn.data( "leave" );
$btn.css( { "background-color": ( leave ? "#FFB0B0"
: "#B0B0FF" ),
"padding-left": "5px",
"padding-right": "5px" } );
$btn.data( { leave: ! leave } );
$btn.text( POpt.unwatch.flag( leave ) );
$btn.show();
}
}; // .unwatch.fix()
POpt.unwatch.flag = function ( again ) {
// Retrieve [unwatch] link title, or [watch again]
// Precondition:
// again -- true iff [watch]
// Postcondition:
// Return string with [unwatch] link title
// 2015-01-11 PerfektesChaos@de.wikipedia
return ( again ? "/////" : String.fromCharCode( 8212 ) );
}; // .unwatch.flag()
POpt.unwatch.furnish = function () {
// Equip all entries with an [unwatch] link
// Precondition:
// Current page is watchlist
// Uses:
// > mw.util.$content
// > .group.sign
// > .values.ctl2url
// > .unwatch.$portlet
// < .unwatch.less
// jQuery().find()
// jQuery().each()
// jQuery().remove()
// (.unwatch.factory)
// Remark: Used as event handler -- 'this' is not POpt.unwatch
// 2015-10-11 PerfektesChaos@de.wikipedia
var $list = mw.util.$content.find( "#mw-content-text" ),
ctl, seek;
if ( $list.length ) {
ctl = POpt.values.ctl2url[ POpt.group.sign ];
POpt.unwatch.less = ctl.val;
if ( POpt.unwatch.less === "0" ) {
POpt.unwatch.less = false;
}
seek = ( POpt.unwatch.less ? ".mw-title" : "li" );
$list.find( seek ).each( POpt.unwatch.factory );
}
POpt.unwatch.$portlet.remove();
}; // .unwatch.furnish()
POpt.values.factory = function () {
// Make URL from .ctl2url
// Postcondition:
// Return query part of URL
// Uses:
// this
// > .values.ctl2url
// .values.fiat()
// 2013-02-08 PerfektesChaos@de.wikipedia
var r = "",
s;
for ( s in this.ctl2url ) {
r = r + this.fiat( s );
} // for s in .ctl2url
return r;
}; // .values.factory()
POpt.values.fiat = function ( access ) {
// Make URL parameter assignment from '&' until value
// Precondition:
// access -- identifier in .ctl2url
// Postcondition:
// Return assignment
// Uses:
// this
// > .values.ctl2url
// 2013-02-06 PerfektesChaos@de.wikipedia
var par = this.ctl2url[ access ],
r = "",
s = access;
if ( par ) {
if ( par.val !== undefined ) {
if ( par.url ) {
s = par.url;
}
if ( par.type === "checkbox" ) {
if ( typeof par.val !== "string" ) {
par.val = ( par.val ? "1" : "0" );
}
}
r = "&" + s + "=" + par.val;
}
}
return r;
}; // .values.fiat()
POpt.values.find = function ( around, adapt ) {
// Initialize form and .values fields with hidden input
// Precondition:
// around -- identification of wrapping element
// adapt -- identification of form
// Uses:
// this
// > mw.util.$content
// > .lean
// > .type
// < .values.$wrap
// < .values.$form
// < .values.$POpt
// .values.first()
// jQuery().find()
// jQuery().each()
// jQuery().append()
// jQuery().attr()
// (.values.found)
// 2015-01-11 PerfektesChaos@de.wikipedia
var $input, $sep;
this.first();
this.$wrap = mw.util.$content.find( around );
if ( this.$wrap.length ) {
this.$form = mw.util.$content.find( adapt );
if ( this.$form.length ) {
$input = this.$form.find( "input" );
$input.each( this.found );
}
if ( POpt.lean ) {
$sep = $( "<span>" );
$sep.text( "\xA0| " );
this.$wrap.append( $sep );
this.$POpt = $( "<span>" );
} else {
this.$POpt = $( "<div>" );
}
this.$POpt.attr( { id: POpt.type + "_extra" } );
this.$wrap.append( this.$POpt );
} else {
this.$form = false;
this.$wrap = false;
this.$POpt = false;
}
}; // .values.find()
POpt.values.first = function () {
// Initialize .values component for this application
// Uses:
// this
// > .group.soft
// > .group.sign
// > .multi.soft
// > .multi.sign
// > .mode
// >< .values.ctl2url
// 2013-03-12 PerfektesChaos@de.wikipedia
if ( ! this.ctl2url ) {
this.ctl2url = { "associated": { type: "checkbox" },
"days": { name: "days",
type: false },
// enhanced... Bugzilla:51901, Gerrit:75579
"hideAnons": { type: "checkbox" },
"hideBots": { type: "checkbox" },
"hideLiu": { type: "checkbox" },
"hideMinor": { type: "checkbox" },
"hideOwn": { type: "checkbox" },
"hideReviewed": { type: "checkbox" },
"hideWikibase": { type: "checkbox" },
// #wb-toggle
"nsinvert": { type: "checkbox",
url: "invert" },
"namespace": { type: "select" }
};
this.ctl2url[ POpt.group.sign ] = { type: "checkbox",
url: POpt.group.soft };
this.ctl2url[ POpt.multi.sign ] = { type: "checkbox",
url: POpt.multi.soft };
if ( POpt.mode === 2 ) {
this.ctl2url.from = { type: false };
this.ctl2url.limit = { type: false };
this.ctl2url.tagfilter = { type: "text" };
}
}
}; // .values.first()
POpt.values.fix = function ( access ) {
// Adapt URLs of option links to current state
// Precondition:
// access -- identifier in .ctl2url
// Uses:
// this
// > .values.$wrap
// >< .values.$hrefs
// >< .values.ctl2url
// < .values.current
// jQuery().find()
// jQuery().each()
// (.values.fixing)
// 2019-02-04 PerfektesChaos@de.wikipedia
if ( ! this.$hrefs ) {
if ( this.$wrap ) {
this.$hrefs = this.$wrap.find( "a" );
} else {
this.$hrefs = true;
}
}
if ( typeof this.$hrefs !== "boolean" ) {
this.current = this.ctl2url[ access ];
if ( ! this.current.url ) {
this.current.url = access;
}
this.$hrefs.each( this.fixing );
}
}; // .values.fix()
POpt.values.fixing = function ( at, access ) {
// Adapt URL to current state of a control
// Precondition:
// at -- index of element in $.each() collection
// access -- DOM element
// Postcondition:
// Return true -- continue $.each()
// Uses:
// > .values.current
// > .values.ctl2url
// >< .values.script
// >< .values.reURL
// mw.config.get()
// jQuery().attr()
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2016-10-16 PerfektesChaos@de.wikipedia
var got, par, swap, $e;
if ( at < 0 ) {
$e = access;
} else {
$e = $( access );
}
swap = $e.attr( "href" );
if ( swap ) {
if ( ! POpt.values.script ) {
POpt.values.script = mw.config.get( "wgScript" );
}
if ( swap.indexOf( POpt.values.script ) < 0 ) {
swap = false;
}
if ( swap ) {
par = POpt.values.current;
if ( par.val !== undefined ) {
if ( ! par.reURL ) {
par.reURL = "([?&]" + par.url + "=)"
+ "(?:[^&]*)"
+ "(&?.+)?$";
par.reURL = new RegExp( par.reURL );
}
if ( par.type === "checkbox" ) {
if ( typeof par.val !== "string" ) {
par.val = ( par.val ? "1" : "0" );
}
}
got = par.reURL.exec( swap );
if ( got ) {
swap = swap.replace( par.reURL,
"$1" + par.val + "$2" );
} else {
swap = swap + "&" + par.url + "=" + par.val;
}
$e.attr( { href: swap } );
}
}
}
return true;
}; // .values.fixing()
POpt.values.flat = function () {
// Compress options by removing line breaks and lines
// Uses:
// this
// > .values.$wrap
// jQuery().find()
// jQuery().before()
// jQuery().text()
// jQuery().remove()
// jQuery().show()
// 2015-01-11 PerfektesChaos@de.wikipedia
var $e = this.$wrap.find( "br, hr" ),
$sep = $( "<span>" );
$sep.text( " | " );
$e.before( $sep.clone() );
$e.remove();
this.$wrap.find( "p, form, ul" ).show();
}; // .values.flat()
POpt.values.flip = function ( access ) {
// Value of a checkbox changed
// Precondition:
// access -- identifier in .ctl2url
// Uses:
// this
// > .values.$form
// > .mode
// > .group.sign
// > .multi.sign
// >< .values.ctl2url
// jQuery().find()
// jQuery().attr()
// jQuery().prop()
// jQuery().val()
// jQuery().removeAttr()
// .flip()
// .values.fix()
// Remark: Used as event handler -- 'this' is not POpt.group
// 2013-02-28 PerfektesChaos@de.wikipedia
var par = this.ctl2url[ access ],
s, $e;
if ( par ) {
if ( ! par.$ctl ) {
par.$ctl = this.$form.find( "#" + access );
}
if ( par.$ctl && par.$ctl.length ) {
if ( par.type === "checkbox" ) {
s = par.$ctl.attr( "value" );
if ( s ) {
s = ( s === "0" ? "1" : "0" );
} else {
s = ( par.$ctl.prop( "checked" ) ? "1" : "0" );
}
par.$ctl.val( s );
if ( s === "0" ) {
par.$ctl.removeAttr( "checked" );
}
if ( POpt.mode === 1 ) { // watchlist only
switch ( access ) {
case POpt.group.sign :
POpt.flip( s, "1", POpt.multi );
break;
case POpt.multi.sign :
POpt.flip( s, "0", POpt.group );
break;
} // switch access
}
} else {
s = par.$ctl.val();
}
par.val = s;
$e = this.$form.find( "#hidden_" + access );
if ( $e.length ) {
$e.val( s );
}
this.fix( access );
}
}
}; // .values.flip()
POpt.values.found = function () {
// Initialize .values field with hidden input
// Precondition:
// this is an input field
// Postcondition:
// Return true -- continue $.each()
// Uses:
// > .values.ctl2url
// jQuery().attr()
// jQuery().val()
// Remark: Used as jQuery handler -- 'this' is DOM element
// 2013-02-06 PerfektesChaos@de.wikipedia
var $input = $( this ),
par, sign;
if ( $input.attr( "type" ) === "hidden" ) {
sign = $input.attr( "name" );
par = POpt.values.ctl2url[ sign ];
if ( par ) {
par.val = $input.val();
}
}
return true;
}; // .values.found()
POpt.values.furnish = function ( access ) {
// Equip visible control with onChange
// Precondition:
// access -- identifier in .ctl2url and of control
// Uses:
// this
// > .values.ctl2url
// > .values.$form
// > .slip
// jQuery().find()
// jQuery().val()
// jQuery().attr()
// 2015-01-11 PerfektesChaos@de.wikipedia
var par = this.ctl2url[ access ],
s;
if ( par ) {
if ( ! par.$ctl ) {
if ( this.$form ) { // catch SQL failure
par.$ctl = this.$form.find( "#" + access );
}
}
if ( par.$ctl ) {
if ( par.type === "checkbox" ) {
s = ( par.$ctl.prop( "checked" ) ? "1" : "0" );
} else {
s = par.$ctl.val();
}
par.val = s;
s = POpt.slip + ".values.flip('" + access + "');";
par.$ctl.attr( { onchange: s } );
}
}
}; // .values.furnish()
POpt.facilitate = function () {
// Equip options with checkbox for every plain link
// Uses:
// this
// > .mode
// > .slip
// > .values.$wrap
// > .values.ctl2url
// > .values.$form
// jQuery().find()
// jQuery()
// jQuery().eq()
// jQuery().attr()
// jQuery().before()
// jQuery().append()
// 2015-01-11 PerfektesChaos@de.wikipedia
var bools = [ "hideMinor",
"hideBots",
"hideAnons",
"hideLiu",
"hideOwn",
"hideReviewed"
// "hidePatrolled"
],
j = ( this.mode === 1 ? 8 : 9 ),
n = j + bools.length,
k = 0,
$set = POpt.values.$wrap.find( "a" ),
i, par, sign, $e;
for ( i = j; i < n; i++ ) {
sign = bools[ k ];
par = POpt.values.ctl2url[ sign ];
par.$ctl = $( "<input />" );
par.$ctl.attr( { id: sign,
onchange: POpt.slip
+ ".values.flip(\"" + sign,
type: "checkbox" } );
if ( par.val ) {
par.$ctl.attr( { checked: "true" } );
}
par.$ctl.val( ( par.val ? "1" : "0" ) );
$e = $set.eq( i );
$e.attr( { id: "link_" + sign } );
$e.before( par.$ctl );
$e = $( "<input />" );
$e.attr( { id: "hidden_" + sign,
name: sign,
type: "hidden",
value: ( par.val ? "1'" : "0'" ) } );
$e.val( ( par.val ? "1" : "0" ) );
POpt.values.$form.append( $e );
k++;
} // for i
}; // .facilitate()
POpt.factory = function ( assign, ahead ) {
// Equip page with 'extended'/'enhanced' toggle checkbox and label
// Precondition:
// assign -- object ( .group. or .multi. )
// > .sign
// > .show
// > .soft
// ahead -- true iff leading
// Uses:
// this
// > .values.$form
// > .values.ctl2url
// > .special
// > .lean
// > .slip
// > .values.$POpt
// >< .values.script
// mw.config.get()
// .config.feature()
// .values.factory()
// jQuery()
// jQuery().prepend()
// (.values.flip)
// 2015-01-11 PerfektesChaos@de.wikipedia
var less, shift, sub, $a, $input, $label, $sep, $span;
if ( this.values.$form ) {
if ( ! this.values.script ) {
this.values.script = mw.config.get( "wgScript" );
}
less = this.values.ctl2url[ assign.sign ].val;
if ( less === "0" ) {
less = false;
}
shift = this.values.script + "?title=Special:" + this.special
+ this.values.factory();
sub = "&" + assign.soft + "=";
shift = shift.replace( new RegExp( sub + "?[01]" ),
sub + ( less ? "0" : "1" )
);
if ( this.mode === 1 ) {
if ( shift.indexOf( "&extended=0" ) > 0 ) {
shift = shift.replace( /&enhanced=1/,
"&enhanced=0" );
}
if ( shift.indexOf( "&enhanced=1" ) > 0 ) {
if ( shift.indexOf( "&extended=" ) > 0 ) {
shift = shift.replace( /&extended=0/,
"&extended=1" );
} else {
shift = shift + "&extended=1";
}
}
}
$label = $( "<label />" );
$span = $( "<span>" );
$span.text( this.config.feature( assign.show ) + " (" );
$label.append( $span );
$a = $( "<a>" );
$a.attr( { href: shift } );
$a.text( this.config.feature( ( less ? "toggleOff"
: "toggleOn" ) ) );
$label.append( $a );
$span = $( "<span>" );
$span.text( ")" );
$label.append( $span );
this.values.$POpt.prepend( $label );
$input = $( "<input />" );
$input.attr( { id: assign.sign,
name: assign.soft,
onchange: this.slip
+ ".values.flip('" + assign.sign
+ "')",
type: "checkbox",
value: ( less ? "1" : "0" ) } );
if ( less ) {
$input.attr( { checked: true } );
}
this.values.$POpt.prepend( $input );
if ( this.mode === 1 ) {
if ( ! this.lean && ahead ) {
$sep = $( "<hr />" );
} else if ( ! ahead ) {
$sep = $( "<span>" );
$sep.text( "\xA0| " );
}
this.values.$POpt.prepend( $sep );
}
}
}; // .factory()
POpt.fault = function ( action, arrived, $apply ) {
// Show API failure on any action
// Precondition:
// action -- keyword of request
// arrived -- JSON info of ajax query
// $apply -- current set of throbber element containers
// Uses:
// > mw.util.$content
// > .type
// jQuery()()
// jQuery().css()
// jQuery().text()
// jQuery().empty()
// jQuery().append()
// mw.log()
// Remark: Used as jQuery handler -- 'this' is not POpt.notice
// 2015-10-11 PerfektesChaos@de.wikipedia
var $e = $( "<strong>" );
$e.css( { "border": "#FF0000 2px solid",
"color": "#FF0000",
"margin": "5px" } );
$e.text( "ERROR" );
$apply.empty();
$apply.append( $e );
mw.log( {loud:true},
"." + POpt.type + "." + action + ".fault()",
2,
arrived );
}; // .fault()
POpt.fiat = function () {
// Equip changes page with controls, analyze by grabbing
// Precondition:
// document has been loaded
// Uses:
// > .mode
// > mw.util.$content
// > .store
// > .luxury
// > .learnt
// > .lower
// > .lean
// > .hide
// > .letal
// > .leyo
// > .self
// >< .$options
// < .ltr
// < .group.leaves
// < .disguise.hide
// < .disguise.show
// < .picked.learn
// jQuery().find()
// mw.util.addCSS()
// jQuery().hide()
// .unwatch.fiat()
// .flat()
// .values.find()
// .facilitate()
// .values.furnish()
// .disguise.fire()
// .picked.furnish()
// .reduce.furnish()
// .increm.furnish()
// .values.flat()
// .furnish()
// .notice.first()
// Remark: Used as event handler -- 'this' is not POpt
// 2016-05-07 PerfektesChaos@de.wikipedia
var sep, store, story, style, suite, $grab, $wd;
mw.util.$content.find( ".mw-changeslist-legend" ).hide();
POpt.ltr = ( $( window.document ).find( "html" ).attr( "dir" )
!== "rtl" );
switch ( POpt.mode ) {
case 1 : // watchlist
sep = ".mw-changeslist-separator";
$grab = mw.util.$content.find( sep );
POpt.group.leaves = ( $grab.length > 0 );
if ( POpt.group.leaves ) {
POpt.unwatch.fiat();
}
story = "#mw-watchlist-options";
suite = "#mw-watchlist-form";
POpt.flat();
store = ".wikibase-edit";
$wd = mw.util.$content.find( store );
if ( $wd.length ) {
switch ( typeof POpt.store ) {
case "boolean":
style = POpt.store;
break;
case "string":
if ( /[0-9A-F]{6}/.test( POpt.store ) ) {
style = POpt.store;
break;
} // fall through
default:
style = true;
} // switch typeof POpt.store
if ( style === true ) {
style = POpt.config[ "wikidata.bgc" ];
}
if ( style ) {
style = "{background-color:#" + style + "}";
mw.util.addCSS( store + style );
}
}
break;
case 2 : // rc
POpt.group.leaves = true;
story = ".rcoptions";
suite = "form";
break;
} // switch .mode
POpt.values.find( story, suite );
if ( POpt.luxury ) {
POpt.facilitate();
}
POpt.values.furnish( "associated" );
POpt.values.furnish( "nsinvert" );
POpt.values.furnish( "namespace" );
POpt.disguise.hide = ( typeof POpt.hide === "object"
&& POpt.hide );
POpt.disguise.show = ( typeof POpt.show === "object"
&& POpt.show );
POpt.picked.learn = ( typeof POpt.learnt === "boolean" );
if ( POpt.disguise.hide ||
POpt.disguise.show ||
POpt.picked.learn ||
POpt.letal ||
POpt.leyo ||
POpt.self ) {
POpt.disguise.fire();
}
if ( POpt.picked.learn && POpt.mode === 1 ) {
POpt.picked.furnish(); // watchlist & visited
}
if ( typeof POpt.lower === "boolean" ) {
POpt.reduce.furnish();
} else if ( POpt.mode === 1 ) { // watchlist
POpt.increm.furnish();
}
if ( POpt.lean ) {
POpt.values.flat();
}
POpt.furnish( POpt.group, false );
if ( POpt.mode === 1 ) { // watchlist
POpt.furnish( POpt.multi, true );
if ( POpt.values.$wrap && POpt.values.$score ) {
if ( ! POpt.$options ) {
POpt.$options = POpt.values.$wrap.find( "legend" );
}
POpt.$options.after( POpt.values.$score );
}
POpt.notice.first();
}
}; // .fiat()
POpt.fire = function () {
// Start processing, if appropriate
// Precondition:
// Special page
// Uses:
// this
// > Version
// < .signature
// < .vsn
// < .doc
// < .special
// < .mode
// < .rLoading
// mw.loader.getState()
// mw.loader.state()
// mw.config.get()
// .config.fire()
// mw.loader.using()
// (.firing)
// 2018-08-24 PerfektesChaos@de.wikipedia
var env, pages, require, rls;
POpt.signature = "ext.gadget." + POpt.type;
POpt.vsn = Version;
if ( ! mw.loader.getState( POpt.signature ) ) {
env = mw.config.get( [ "wgCanonicalSpecialPageName",
"wgNamespaceNumber" ] );
pages = { "Blankpage": -1,
"Gadgets": -1,
"Watchlist": 1,
"Recentchanges": 2,
"EditWatchlist": 3 };
rls = { };
POpt.doc = "[[w:en:User:PerfektesChaos/js/" + POpt.type
+ "]]";
if ( env.wgNamespaceNumber === -1 ) {
this.special = env.wgCanonicalSpecialPageName;
this.mode = pages[ this.special ];
if ( this.mode ) {
rls[ this.signature ] = "loading";
mw.loader.state( rls );
rls[ this.signature ] = "ready";
this.rLoading = rls;
rls = false;
this.config.fire();
require = [ "user",
"user.options",
"mediawiki.user",
"mediawiki.util" ];
if ( this.mode === 1 ) {
require = require.concat( [ "mediawiki.api" ] );
}
mw.loader.using( require, this.firing );
}
}
if ( rls ) {
rls[ this.signature ] = "ready";
mw.loader.state( rls );
}
}
}; // .fire()
POpt.firing = function () {
// Intermediate loading process step
// Precondition:
// MW ressources are available
// Uses:
// > .config.supply
// mw.hook()
// (.first)
// Remark: Used as event handler -- 'this' is not POpt
// 2015-09-12 PerfektesChaos@de.wikipedia
mw.hook( POpt.config.supply + ".ready" ).add( POpt.first );
}; // .firing()
POpt.first = function ( attributes ) {
// Start processing
// Precondition:
// attributes -- preferencesGadgetOptions application object
// All ressources are available
// Uses:
// > .type
// > .mode
// > .rLoading
// < .prego
// < .slip
// .config.fetch()
// jQuery().ready()
// .config.form()
// mw.loader.state()
// mw.hook()
// (.fiat)
// (.edit.fire)
// Remark: Used as event handler -- 'this' is not POpt
// 2018-08-26 PerfektesChaos@de.wikipedia
POpt.prego = attributes;
POpt.slip = "mw.libs." + POpt.type;
if ( POpt.mode > 0 ) {
if ( POpt.prego ) {
POpt.config.fetch();
}
if ( POpt.mode < 3 ) {
$( POpt.fiat );
} else {
$( POpt.edit.fire );
}
} else if ( POpt.prego ) {
POpt.config.form();
}
mw.loader.state( POpt.rLoading );
mw.hook( POpt.type + ".ready" ).fire( POpt );
}; // .first()
POpt.flat = function () {
// Remove watchlist information
// Uses:
// > mw.util.$content
// < .values.$score
// jQuery().find()
// jQuery().children()
// .config.feature()
// jQuery().text()
// jQuery().remove()
// 2015-01-11 PerfektesChaos@de.wikipedia
var $e = mw.util.$content.find( "#mw-content-text" ),
re, s;
if ( $e.length ) {
$e = $e.children( "p" );
if ( $e.length ) {
re = new RegExp( POpt.config.feature( "watchPgRE",
false ) );
s = $e.text().replace( re, "$1" );
if ( s ) {
$e.remove();
POpt.values.$score = $( "<span>" );
POpt.values.$score.text( s + "\xA0| " );
// update
}
}
}
}; // .flat()
POpt.flip = function ( alter, allow, assign ) {
// Coordinate multiple and grouped watchlist entries
// Precondition:
// alter -- just set parameter value, "0" or "1"
// allow -- required parameter value, "0" or "1"
// assign -- corresponding object to be updated
// Uses:
// this
// > .values.$form
// >< .values.ctl2url
// jQuery().find()
// jQuery().click()
// 2013-02-28 PerfektesChaos@de.wikipedia
var co, s;
if ( alter === allow ) {
s = assign.sign;
co = this.values.ctl2url[ s ];
if ( co ) {
if ( co.val !== allow ) {
if ( ! co.$ctl ) {
if ( this.values.$form ) {
co.$ctl = this.values.$form.find( "#" + s );
}
}
if ( co.$ctl ) {
co.$ctl.click();
}
}
}
}
}; // .flip()
POpt.format = function ( access ) {
// Encode URL part string regexp conditionally for Wiki
// Precondition:
// access -- string, part of URL
// Postcondition:
// Return string, ready for URL
// Uses:
// this
// >< .sp2_
// 2013-03-08 PerfektesChaos@de.wikipedia
var r = access,
i, k, n, s;
if ( r ) {
if ( access.indexOf( "%" ) < 0 ) {
n = access.length;
r = "";
for ( i = n - 1; i >= 0; i-- ) {
k = access.charCodeAt( i );
s = String.fromCharCode( k );
if ( k > 127 ) {
s = encodeURI( s );
}
r = s + r;
} // for i--
s = mw.util.wikiUrlencode( r );
} else {
if ( ! this.sp2_ ) {
this.sp2_ = new RegExp( " ", "g" );
}
r = r.replace( this.sp2_, "_" );
}
}
return r;
}; // .format()
POpt.furnish = function ( assign, ahead ) {
// Equip page with additional labeled control
// Precondition:
// assign -- object ( .group. or .multi. )
// > .soft
// > .sign
// .find()
// ahead -- true iff leading
// document has been loaded
// Uses:
// this
// mw.util.getParamValue()
// .values.fix()
// .factory()
// 2013-02-27 PerfektesChaos@de.wikipedia
var set = mw.util.getParamValue( assign.soft );
assign.find( set );
POpt.values.fix( assign.sign );
this.factory( assign, ahead );
}; // .furnish()
POpt.fire();
}( window.mediaWiki, window.jQuery ) );
// Emacs
// Local Variables:
// coding: utf-8-dos
// fill-column: 80
// End:
/// EOF </nowiki> listPageOptions/d.js