/// PerfektesChaos/js/versionControl/d.js
/// 2018-09-10 [email protected]
// Managing version identificaction by wiki revision identifier
/// Fingerprint: #0#0#
/// <nowiki>
// ResourceLoader: compatible; dependencies: mediawiki.api
// mediawiki.RegExp
// mediawiki.user
// mediawiki.util
/* global window:false */
/* jshint bitwise:true, curly:true, eqeqeq:true, latedef:true,
laxbreak:true,
nocomma:true, strict:true, undef:true, unused:true */
( function ( mw ) {
"use strict";
var Signature = "versionControl",
Version = -5.1,
VC = { doc: "[[w:en:User:PerfektesChaos/js/" + Signature
+ "]]",
sign: "user:PerfektesChaos/" + Signature,
type: Signature,
vsn: Version };
// Requires:
// MediaWiki 1.26wmf11
// mw.libs
// mw.loader.getState()
// mw.loader.state()
// mw.loader.using()
// mw.util.wikiUrlencode()
// mw.Api
function fed( arrived, at, after ) {
// Fetched JSON source after query
// Precondition:
// arrived -- result of ajax query for JSON source
// at -- location of JSON source
// .site domain
// .space wide area
// .store particular task
// after -- callback function
// Remark: May be used as event handler -- 'this' is not accessed
// 2018-09-10 [email protected]
var page, parsed, rev, store;
if ( typeof arrived === "object" &&
typeof arrived.query === "object" ) {
store = arrived.query.pageids[ 0 ];
page = arrived.query.pages[ store ];
rev = page.revisions[ 0 ];
if ( typeof rev === "object" &&
typeof rev.slots === "object" &&
typeof rev.slots.main === "object" ) {
try {
parsed = JSON.parse( rev.slots.main[ "*" ] );
if ( typeof parsed === "object"
&& parsed ) {
parsed.site = at.site;
parsed.space = at.space;
parsed.store = at.store;
after( parsed );
}
} catch (e) {
}
}
}
} // fed()
function feed( at, after ) {
// Retrieve JSON source from page
// Precondition:
// at -- object, with location of JSON source
// .site domain
// .space wide area
// .store particular task
// after -- callback function
// Uses:
// >< .api
// >< .script
// mw.Api
// (.fed)
// 2018-09-10 [email protected]
if ( typeof at === "object"
&& at &&
typeof at.site === "string"
&& at.site &&
typeof at.space === "string"
&& at.space &&
typeof at.store === "string"
&& at.store &&
typeof after === "function" ) {
if ( typeof VC.api !== "object" ) {
VC.api = new mw.Api();
}
VC.api.get( { action: "query",
"continue": "",
indexpageids: true,
origin: "https://" +
window.document.location.hostname,
prop: "revisions",
rvprop: "content",
rvslots: "main",
titles: at.space + "/" + at.store + ".json",
maxage: 0
},
{ url: "https://" + at.site + "/w/api.php",
dataType: "json" } )
.done( function ( arrived ) { fed( arrived, at, after );
} );
}
} // feed()
function filed () {
// Called upon termination
// Remark: May be used as event handler -- 'this' is not accessed
// 2018-09-10 [email protected]
} // .filed()
function fill( assign, action ) {
// Dump JSON source on page
// Precondition:
// assign -- object, with model
// .site domain
// .space wide area
// .store particular task
// .revisions Array, or not
// action -- boolean, if do anything
// Uses:
// > .vsn
// >< .reEscape
// >< .api
// >< .token
// mw.Api
// mw.user.tokens()
// (.filed)
// 2018-09-10 [email protected]
var d, e, i, n, s;
if ( action ) {
d = new Date();
if ( typeof VC.reEscape !== "object" ) {
VC.reEscape = new RegExp( "[\"\\|\n]+", "g" );
}
s = '{ "stamp": "' + d.toISOString() + '",\n'
+ ' "site": "'
+ assign.site.replace( VC.reEscape, "" ) + '",\n'
+ ' "space": "'
+ assign.space.replace( VC.reEscape, "" ) + '",\n'
+ ' "store": "'
+ assign.store.replace( VC.reEscape, "" ) + '"';
if ( typeof assign.revisions === "object" ) {
s = s + ',\n "revisions": [\n';
n = assign.revisions.length;
for ( i = 0; i < n; i++ ) {
if ( i ) {
s = s + ',\n';
}
e = assign.revisions[ i ];
if ( typeof e.id !== "number" ) {
e.id = 0;
}
if ( typeof e.stamp !== "string" ) {
e.stamp = "-";
}
s = s + ' { "src": "'
+ e.src.replace( VC.reEscape, "" ) + '",\n'
+ ' "id": ' + e.id + ',\n'
+ ' "stamp": "'
+ e.stamp.replace( VC.reEscape, "" ) + '" }';
} // for i
s = s + '\n ]';
}
s = s + '\n}';
if ( typeof VC.api !== "object" ) {
VC.api = new mw.Api();
}
if ( typeof VC.token !== "string" ) {
VC.token = mw.user.tokens.get( "csrfToken" );
}
VC.api.post( { action: "edit",
token: VC.token,
title: assign.space + "/"
+ assign.store + ".json",
text: s,
summary: "VersionControl " + VC.vsn,
nocreate: true },
{ url: "https://" + assign.site + "/w/api.php" } )
.done( filed );
}
} // fill()
function forward( arrived, assembly, after ) {
// Page revision data arrived
// Precondition:
// arrived -- result of ajax query for
// assembly -- object, with entire old information
// after -- callback function
// Uses:
// fill()
// 2018-09-10 [email protected]
var e, i, j, k, l, n, p, query, s, v;
if ( typeof arrived === "object" ) {
query = arrived.query;
}
if ( query ) {
n = query.pageids.length;
if ( n ) {
k = assembly.start.length;
v = assembly.revisions;
for ( i = 0; i < n; i++ ) {
s = query.pageids[ i ];
if ( s.charCodeAt( 0 ) !== 45 ) { // '-'
p = query.pages[ s ];
j = assembly.order[ p.title.substr( k ) ];
if ( typeof j === "number" ) {
e = v[ j ];
if ( typeof e.id !== "number" ||
typeof e.stamp !== "string" ||
e.id !== p.lastrevid ||
e.stamp !== p.touched ) {
e.id = p.lastrevid;
e.stamp = p.touched;
l = true;
}
}
}
} // for i
after( assembly, l );
}
}
} // forward()
function found( assembly, after ) {
// Retrieve single pages revision data
// Precondition:
// assembly -- object, with entire (old) information
// after -- callback function
// Uses:
// >< .api
// mw.util.wikiUrlencode()
// mw.Api
// (forward)
// Remark: May be used as event handler -- 'this' is not accessed
// 2018-09-10 [email protected]
var e, i, n, p, q, s, v;
if ( typeof assembly.revisions === "object"
&& assembly.revisions &&
typeof assembly.revisions.length === "number" ) {
v = assembly.revisions;
n = v.length;
if ( n > 1 ) {
s = mw.util.wikiUrlencode( assembly.space ) + "/";
assembly.start = s;
assembly.order = { };
for ( i = 0; i < n; i++ ) {
e = v[ i ];
if ( typeof e.src === "string"
&& e.src ) {
if ( q ) {
q = q + "|";
} else {
q = "";
}
p = mw.util.wikiUrlencode( e.src );
q = q + s + p;
assembly.order[ p ] = i;
}
} // for i
if ( q ) {
if ( typeof VC.api !== "object" ) {
VC.api = new mw.Api();
}
VC.api.get( { prop: "info",
// inprop: "lastrevid|touched",
titles: q,
indexpageids: true },
{ url: "https://" + assembly.site
+ "/w/api.php" } )
.done( function( arrived ) {
forward( arrived, assembly, after );
} );
}
} // entries
}
} // found()
function fresh( at ) {
// Update page
// Precondition:
// at -- object, with location of JSON source
// .site domain
// .space wide area
// .store particular task
// Uses:
// (found)
// (fill)
// Remark: May be used as event handler -- 'this' is not accessed
// 2018-09-10 [email protected]
feed( at,
function( assembly ) { found( assembly, fill ); } );
} // fresh()
function full() {
// Complete initialization
// Precondition:
// Modules ready
// Uses:
// > .sign
// > .doc
// > .type
// > .vsn
// mw.loader.state()
// mw.hook()
// (feed)
// (found)
// (fresh)
// Remark: May be used as event handler -- 'this' is not accessed
// 2018-09-10 [email protected]
var rls = { };
rls[ VC.sign ] = "ready";
mw.loader.state( rls );
mw.hook( VC.sign + ".ready" ).fire( { doc: VC.doc,
sign: VC.sign,
type: VC.type,
vsn: VC.vsn } );
mw.hook( VC.sign + ".retrieve" ).add( feed );
mw.hook( VC.sign + ".revisions" ).add( found );
mw.hook( VC.sign + ".update" ).add( fresh );
} // full()
function furnish() {
// Autorun on script load
// Precondition:
// Current project is project of queries
// Postcondition:
// Started analysis
// Uses:
// > .sign
// mw.loader.getState()
// mw.loader.state()
// mw.loader.using()
// (full)
// 2018-09-10 [email protected]
var state = mw.loader.getState( VC.sign ),
rls;
if ( state !== "ready" && state !== "loaded" ) {
rls = { };
rls[ VC.sign ] = "loaded";
mw.loader.state( rls );
mw.loader.using( [ "mediawiki.api",
"mediawiki.user",
"mediawiki.util" ],
full );
}
} // furnish()
furnish();
}( window.mediaWiki ) );
/// EOF </nowiki> versionControl/d.js