/// User:PerfektesChaos/js/citoidWikitext/core.js
// Execute core functionality for citoid on wikitext source editing
/// 2018-09-03 [email protected]
// ResourceLoader: compatible;
// dependencies: --
/// Fingerprint: #0#0#
/// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA)
/// <nowiki>
/* global window: false, JSON: 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 = -4.3,
Signature = "citoidWikitext",
Sub = "core",
Sites = "|dewiki|",
APIC = { },
BOOK = { },
DESC = { },
EDIT = { codeMirror: false,
wikEd: false },
GUIP = { btn: { },
caret: { },
gadget: { },
input: { },
push: { } },
HELP = { site: "w:en",
support: "user:PerfektesChaos/js/" + Signature },
I18N = { },
PREGO = { maxage: 604812,
signature: "preferencesGadgetOptions",
site: "w:en",
store: "User:PerfektesChaos/js/",
sub: "/r.js" },
REPOS = { maxage: 86400,
site: "w:en",
store: "User:PerfektesChaos/js/" },
PROJ = false,
TASK = { },
UTIL = { },
XPORT = { core: { sites: Sites } },
CITWT;
function facilitated() {
// Mark sub-module as ready
// Uses:
// > Signature
// > Sub
// > Version
// > XPORT
// < CITWT
// < .signature
// < .vsn
// < .type
// mw.loader.getState()
// mw.loader.state()
// mw.hook()
// 2018-08-24 [email protected]
var sign = "ext.gadget." + Signature,
sub = "/" + Sub,
signature = sign + sub,
s = mw.loader.getState( signature ),
e, o, rls;
if ( s !== "loaded" && s !== "ready" ) {
rls = { };
rls[ signature ] = "loaded";
mw.loader.state( rls );
if ( typeof mw.libs[ Signature ] !== "object" ||
! mw.libs[ Signature ] ) {
mw.libs[ Signature ] = { };
}
CITWT = mw.libs[ Signature ];
CITWT.signature = sign;
if ( typeof CITWT.vsn === "string" ) {
CITWT.vsn = CITWT.vsn + " ";
} else {
CITWT.vsn = "";
}
CITWT.vsn = CITWT.vsn + Sub.substr( 0, 1 ) + ":" + Version;
CITWT.type = Signature;
CITWT.suite = ( Version > 1 ? "r" : "d" );
if ( typeof CITWT[ Sub ] !== "object" ||
! CITWT[ Sub ] ) {
CITWT[ Sub ] = { };
}
e = XPORT[ Sub ];
o = CITWT[ Sub ];
for ( s in e ) {
o[ s ] = e[ s ];
} // for s in e
for ( s in XPORT ) {
if ( typeof XPORT[ s ] === "function" ) {
CITWT[ s ] = XPORT[ s ];
}
} // for s in XPORT
rls[ signature ] = "ready";
mw.loader.state( rls );
mw.hook( CITWT.type + sub + ".ready" ).fire();
}
} // facilitated()
//-----------------------------------------------------------------------
APIC.site = "https://citoid.wikimedia.org/api";
APIC.stateless = "/api/rest_v1/data/citation/mediawiki/";
APIC.fault = function ( jqXHR, textStatus, errorThrown ) {
// API failure
// Precondition:
// Common failure call
// Uses:
// > .type
// < APIC.scream
// GUIP.flat()
// console.log()
// console.dir()
// Remark: Used as event handler -- 'this' is not APIC
// 2015-05-01 [email protected]
GUIP.flat( "unanswered" );
APIC.scream = textStatus + " -- Error: " + errorThrown;
if ( typeof window.console === "object" &&
typeof window.console.log === "function" ) {
window.console.log( CITWT.type + " * " + APIC.scream );
if ( textStatus &&
typeof textStatus === "object" &&
typeof window.console.dir === "function" ) {
window.console.dir( textStatus );
}
}
}; // APIC.fault()
APIC.finish = function () {
// All queries have been answered
// Uses:
// > APIC.results
// >< APIC.queries
// TASK.follow()
// 2017-06-10 [email protected]
var n = APIC.queries.length,
i, j, q, r, ufo;
for ( i = 0; i < APIC.results.length; i++ ) {
r = APIC.results[ i ];
if ( r ) {
for ( j = 0; j < n; j++ ) {
q = APIC.queries[ j ];
if ( q === r.url ) {
r.lucky = true;
APIC.queries[ j ] = r;
r = false;
break; // for j
}
} // for j
if ( r ) {
if ( ! ufo ) {
ufo = [ ];
}
r.idResult = i;
ufo.push( r );
}
}
} // for i
if ( ufo ) {
i = 0;
if ( ufo.length === 1 ) {
ufo[ 0 ].idResult = false;
}
for ( j = 0; j < n; j++ ) {
q = APIC.queries[ j ];
if ( typeof q === "string" ) {
ufo[ i ].queryURL = q;
APIC.queries[ j ] = ufo[ i ];
i++;
}
} // for j
}
TASK.follow();
}; // APIC.finish()
APIC.fire = function () {
// Run queries at WMF via API
// Precondition:
// mediawiki.api has been loaded
// Uses:
// > .server
// > APIC.site
// > APIC.stateless
// > APIC.queries
// >< APIC.data
// >< APIC.jq
// >< APIC.legacy
// < APIC.results
// < APIC.missing
// (APIC.found)
// (APIC.fault)
// Remark: Used as event handler -- 'this' is not APIC
// 2017-06-11 [email protected]
var f, i, query, service;
if ( typeof APIC.jq !== "object" ) {
f = function ( jqXHR ) {
jqXHR.setRequestHeader( "Content-Type",
"application/json" );
};
if ( typeof CITWT.server === "string" ) {
service = CITWT.server;
} else {
service = APIC.site;
}
APIC.data = { format: "mediawiki" }; // mediawiki zotero
APIC.jq = { beforeSend: f,
dataType: "json", // No "Intelligent Guess"
url: service };
APIC.legacy = ( service.indexOf( "/url" ) > 0 );
if ( APIC.legacy ) {
APIC.jq.type = "POST";
} else if ( APIC.stateless ) {
APIC.site = window.location.protocol + "//" +
window.location.hostname + APIC.stateless;
} else {
APIC.jq.data = APIC.data;
}
}
APIC.results = [ ];
APIC.missing = APIC.queries.length;
for ( i = 0; i < APIC.missing; i++ ) {
/* citoid.wmflabs appears to handle an Array of URL
and will return an Array of result objects,
but there is nothing promised nor documented
nor a stable implementation in spring 2015.
*/
query = APIC.queries[ i ];
switch ( typeof query ) {
case "string":
if ( APIC.legacy ) {
APIC.data.url = query;
APIC.jq.data = JSON.stringify( APIC.data );
} else if ( APIC.stateless ) {
APIC.jq.url = APIC.site + encodeURIComponent( query );
} else {
APIC.jq.data.search = query;
}
$.ajax( APIC.jq ).done( APIC.found )
.fail( APIC.fault );
break;
case "object":
if ( typeof query.beforeSend === "string"
&& query.beforeSend === "json" ) {
query.jq.beforeSend = f;
}
query.jq.beforeSend = f;
$.ajax( query.jq ).done( query.found )
.fail( query.fault );
break;
} // switch typeof query
} // for i
}; // APIC.fire()
APIC.found = function ( arrived ) {
// Answer arrived
// Precondition:
// arrived -- object, full result
// string, favorite result
// boolean, no favorite result
// Uses:
// >< APIC.missing
// >< APIC.results
// GUIP.flat()
// TASK.follow()
// APIC.finish()
// Remark: Used as event handler -- 'this' is not APIC
// 2018-07-14 [email protected]
var got;
switch ( typeof arrived ) {
case "boolean":
APIC.missing--;
break;
case "string":
APIC.missing = -1;
GUIP.flat();
TASK.follow();
break;
case "object":
if ( arrived && typeof arrived.length === "number" ) {
got = arrived[ 0 ];
if ( got && typeof got === "object" ) {
if ( typeof got.url === "string" && got.url ) {
APIC.results.push( got );
APIC.missing--;
} else if ( typeof got.Error === "string" ) {
// Never reached
// HTTP-OPTIONS call APIC.fault() only
// Plan:
// * Record on console
// shared with APIC.fault()
// * Enrich flat("unanswered") by details
GUIP.flat( "unanswered" );
// GUIP.flat( "unanswered", $span );
}
}
}
break;
} // switch typeof arrived
if ( ! APIC.missing ) {
APIC.finish();
}
}; // APIC.found()
//-----------------------------------------------------------------------
BOOK.fire = function () {
// Initialize ISBN support
// Uses:
// mw.hook()
// (BOOK.first)
// 2016-03-21 [email protected]
mw.hook( "isbnLib.ready" ).add( BOOK.first );
}; // BOOK.fire()
BOOK.first = function ( application ) {
// Uses:
// Precondition:
// application -- isbnLib
// Uses:
// < .isbnLib
// .isbnLib.furnish()
// GUIP.fire()
// 2016-03-25 [email protected]
CITWT.isbnLib = application;
switch ( typeof CITWT.isbn ) {
case "string":
case "object":
CITWT.isbnLib.furnish( CITWT.isbn );
} // switch typeof CITWT.isbn
GUIP.fire();
}; // BOOK.first()
//-----------------------------------------------------------------------
DESC.re = { };
DESC.fire = function ( attempt ) {
// Analyse request description string
// Precondition:
// attempt -- string or false
// Postcondition:
// Returns object, or false
// Uses:
// > GUIP.caret.story
// DESC.fold()
// DESC.*()
// 2015-07-01 [email protected]
var got, i, mode, r, s, start;
if ( attempt ) {
s = attempt.replace( /^\s+/, "" );
i = s.indexOf( "</ref>" );
if ( i >= 0 ) {
s = s.substr( 0, i );
}
if ( s ) {
switch ( s.substr( 0, 1 ) ) {
case "[":
if ( s.substr( 1, 1 ) === "[" ) {
i = s.indexOf( "]]", 2 );
if ( i > 0 ) {
s = s.substr( 0, i );
i = s.indexOf( "|", 1 );
if ( i > 0 ) {
s = s.substr( 0, i );
}
if ( s.indexOf( ":", 2 ) > 0 ) {
mode = 2;
} else {
s = false;
}
} else {
s = false;
}
} else if ( s.indexOf( "//" ) > 0 ) {
mode = 1;
}
if ( mode ) {
s = s.substr( mode );
}
break;
case "{":
if ( s.substr( 1, 1 ) === "{" ) {
s = DESC.fold( s );
if ( s ) {
mode = 3;
}
}
break;
default:
mode = 0;
i = s.indexOf( "\n", 5 );
if ( i > 0 ) {
s = s.substr( 0, i );
}
i = s.indexOf( "]]", 2 );
if ( i > 0 ) {
s = s.substr( 0, i );
}
break;
} // switch s.substr( 0, 1 )
if ( s ) {
if ( mode ) {
s = s.replace( /^\s+/, "" )
.replace( /\s+$/, "" );
if ( mode === 1 && s.substr( 0, 2 ) === "//" ) {
s = window.location.protocol + s;
}
}
got = /^([a-zA-Z]+)\b/.exec( s );
if ( got ) {
start = got[ 1 ].toLowerCase();
if ( typeof DESC[ start ] === "function"
&& start !== "fire" ) {
r = DESC[ start ]( s, mode );
}
}
}
}
}
return r;
}; // DESC.fire()
DESC.fold = function ( attempt ) {
// Analyse presumable template transclusion
// Precondition:
// attempt -- string with query, beginning with "{{"
// Postcondition:
// Returns string with URL or keyword/data, or false
// Uses:
// > PROJ
// mw.config.get()
// 2017-05-17 [email protected]
var r = false,
env, got, i, ns, sign, space, suffix;
got = /^({{\s*([^|}]+)\s*)[|}]/.exec( attempt );
if ( got ) {
suffix = attempt.substr( got[ 1 ].length )
.replace( /\n/g, " " );
sign = got[ 2 ].replace( /\n/g, " " );
i = sign.indexOf( ":" );
if ( i >= 0 ) {
env = mw.config.get( [ "wgNamespaceIds",
"wgFormattedNamespaces" ] );
if ( i ) {
space = sign.substr( 0, i )
.toLowerCase()
.replace( /\s+/g, "_" )
.replace( /__+/g, "_" );
ns = env.wgNamespaceIds[ space ];
if ( ! ns ) {
ns = -9;
}
} else {
ns = 0;
}
if ( ns >= 0 ) {
sign = sign.substr( i + 1 ).replace( /^\s+/, "" );
sign = env.wgFormattedNamespaces[ "" + ns ] + ":"
+ sign.substr( 0, 1 )
+ sign.substr( 1 );
}
}
sign = sign.replace( /\s+/g, "_" )
.replace( /__+/g, "_" )
.replace( /_$/, "" );
switch ( sign.toUpperCase() ) {
case "ARXIV":
case "DNB":
case "DOI":
case "ISBN":
case "LCCN":
case "OCLC":
case "PMC":
case "PMID":
case "RFC":
got = /^\|\s*([^|}]+)\s*[|}]/.exec( suffix );
if ( got ) {
r = sign.toUpperCase() + " " + got[ 1 ];
}
break;
default:
if ( typeof PROJ.templates === "object" &&
typeof PROJ.templates[ sign ] === "function" ) {
r = PROJ.templates[ sign ]( suffix );
}
} // switch sign
}
return r;
}; // DESC.fold()
DESC.arxiv = function ( attempt ) {
// Analyse request string, presumably arXiv
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// 2015-05-10 [email protected]
var got = /^arxiv\s*[:=|]?\s*(\S+)\s*/i.exec( attempt ),
r, s;
if ( got ) {
s = got[ 1 ];
r = { scheme: "arxiv",
arxiv: s,
url: "http://arxiv.org/abs/" + s,
say: "arXiv " + s };
}
return r;
}; // DESC.arxiv()
DESC.dnb = function ( attempt ) {
// Analyse request string, presumably Deutsche Nationalbibliothek
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// 2015-05-10 [email protected]
var got = /^dnb\s*[:=|]?\s*([1-9][0-9]+X?)\b/i.exec( attempt ),
r, s;
if ( got ) {
s = got[ 1 ];
r = { scheme: "dnb",
dnb: s,
url: "http://d-nb.info/" + s,
say: "DNB " + s };
}
return r;
}; // DESC.dnb()
DESC.doi = function ( attempt, achieved ) {
// Analyse request string, presumably DOI
// Precondition:
// attempt -- string with query
// achieved -- number of mode
// Postcondition:
// Returns object, or not
// 2015-06-30 [email protected]
var got, i, r, s;
switch ( achieved ) {
case 0:
got = /^doi\s*[:=]?\s*(\S+)(?:\s.+)?$/i.exec( attempt );
break;
case 2:
got = /^doi:\s*(\S+)$/i.exec( attempt );
break;
case 3:
got = /^doi\s*\|([^|]+)(?:\|.+)?$/i.exec( attempt );
break;
} // switch achieved
if ( got ) {
s = got[ 1 ].replace( /^\s+/, "" )
.replace( /\s+$/, "" );
i = s.indexOf( "}}" );
if ( i > 0 && s.indexOf( "{", i ) < 0 ) {
s = s.substr( 0, i );
}
r = { scheme: "doi",
doi: s,
say: "doi:" + s };
if ( /^10\.[1-9]\d\d\d+\/\S+$/.test( s ) ) {
r.url = "http://dx.doi.org/" + s;
}
}
return r;
}; // DESC.doi()
DESC.ftp = function ( attempt ) {
// Analyse request string, presumably URL
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// Uses:
// this
// DESC.http()
// 2015-05-01 [email protected]
return this.http( attempt );
}; // DESC.ftp()
DESC.http = function ( attempt ) {
// Analyse request string, presumably URL
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// Uses:
// > GUIP.caret.starter
// >< DESC.re.url
// 2015-09-07 [email protected]
var got = /(\S+)\s?/.exec( attempt ),
i, r, re, s, site, suffix;
if ( got ) {
if ( typeof DESC.re.url !== "object" ) {
s = "^((?:f|ht)tps?://"
+ "(?:[^./]+\\.)+\\w+"
+ "(?::[0-9]+)?)"
+ "(/.*)$";
DESC.re.url = new RegExp( s, "i" );
}
s = got[ 1 ];
r = { scheme: "url" };
got = DESC.re.url.exec( s );
if ( got ) {
site = got[ 1 ].toLowerCase();
suffix = got[ 2 ];
i = suffix.indexOf( "]" );
if ( i > 0 ) {
suffix = suffix.substr( 0, i );
}
i = suffix.indexOf( "|" );
if ( i > 0 &&
typeof GUIP.caret.starter === "string" ) {
if ( /[|=]\s*$/.test( GUIP.caret.starter ) ) {
// template parameter
suffix = suffix.substr( 0, i );
}
}
re = /^([^#<]+)([#<])(.*)$/;
got = re.exec( suffix );
if ( got ) {
suffix = got[ 1 ];
if ( got[ 2 ] === "#" ) {
r.subtle = got[ 3 ];
}
}
r.url = site + suffix;
// TODO ///////// redirect URL
r.source = r.url;
got = /[.\/]?([^.\/]+\.\w+)(:[0-9]+)?$/.exec( site );
if ( got ) {
r.say = got[ 1 ];
}
}
}
return r;
}; // DESC.http()
DESC.https = function ( attempt ) {
// Analyse request string, presumably URL
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// Uses:
// this
// DESC.http()
// 2015-05-01 [email protected]
return this.http( attempt );
}; // DESC.https()
DESC.isbn = function ( attempt, achieved ) {
// Analyse request string, presumably ISBN
// Precondition:
// attempt -- string with query
// achieved -- number of mode
// Postcondition:
// Returns object, or not
// Uses:
// .isbnLib.focus()
// .isbnLib.finder()
// 2016-03-29 [email protected]
var got, i, isbnLib, r;
switch ( achieved ) {
case 0:
case 2:
got = /^isbn\s*[:=]?\s*([-0-9]+x?.*)$/i.exec( attempt );
break;
} // switch achieved
if ( got ) {
r = { scheme: "isbn",
isbn: got[ 1 ],
lang: false };
got = /^([-0-9]+x?)(?:[^-0-9x].*)?$/i.exec( r.isbn );
if ( got ) {
isbnLib = CITWT.isbnLib;
r.isbn = got[ 1 ].replace( /-/g, "" );
switch ( r.isbn.length ) {
case 10:
r.isbn = r.isbn.toUpperCase();
if ( /^[0-9]+X?$/.test( r.isbn ) ) {
r.lang = isbnLib.focus( r.isbn );
r.url = true;
}
break;
case 13:
got = /^97([89])[0-9]+$/.exec( r.isbn );
if ( got ) {
if ( got[ 1 ] === "8" ) {
r.lang = isbnLib.focus( r.isbn.substr( 3 ) );
} else {
r.lang = isbnLib.focus( r.isbn );
}
r.url = true;
}
break;
} // switch n
if ( r.url ) {
r.url = isbnLib.finder( r.lang );
r.say = r.isbn;
r.url.push( "/wiki/Special:Booksources/#" );
for ( i = 0; i < r.url.length; i++ ) {
r.url[ i ] = r.url[ i ].replace( /#/, r.isbn );
} // for i
i = r.url.length - 1;
r.url[ i ] = [ r.url[ i ], "ISBN" ];
}
} else {
r.isbn = r.isbn.substr( 0, 30 );
}
}
return r;
}; // DESC.isbn()
DESC.lccn = function ( attempt ) {
// Analyse request string, like Library of Congress Control Number
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// 2015-05-10 [email protected]
var got = /^lccn\s*[:=|]?\s*([-a-z/0-9]+)\b/i.exec( attempt ),
r, s;
if ( got ) {
s = got[ 1 ];
r = { scheme: "lccn",
lccn: s,
url: "http://lccn.loc.gov/" + s,
say: "LCCN " + s };
}
return r;
}; // DESC.lccn()
DESC.oclc = function ( attempt ) {
// Analyse request string, presumably OCLC
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// 2015-05-10 [email protected]
var got = /^oclc\s*[:=|]?\s*([1-9][0-9]+)\b/i.exec( attempt ),
r, s;
if ( got ) {
s = got[ 1 ];
r = { scheme: "oclc",
oclc: s,
url: "http://worldcat.org/oclc/" + s,
say: "OCLC " + s };
}
return r;
}; // DESC.oclc()
DESC.pmc = function ( attempt ) {
// Analyse request string, presumably PMC
// Precondition:
// attempt -- string with query
// Postcondition:
// Returns object, or not
// 2015-05-01 [email protected]
var got = /^pmc\s*[:=|]?\s*([1-9][0-9]+)\b/i.exec( attempt ),
r, s;
if ( got ) {
s = got[ 1 ];
r = { scheme: "pmc",
pmc: s,
url: "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC"
+ s,
say: "PMC " + s };
}
return r;
}; // DESC.pmc()
DESC.pmid = function ( attempt, achieved ) {
// Analyse request string, presumably PMID
// Precondition:
// attempt -- string with query
// achieved -- number of mode
// Postcondition:
// Returns object, or not
// 2015-05-01 [email protected]
var got, r, s;
switch ( achieved ) {
case 0:
case 2:
got = /^pmid\s*[:=]?\s*([1-9][0-9]+)\b/i.exec( attempt );
break;
} // switch achieved
if ( got ) {
s = got[ 1 ];
r = { scheme: "pmid",
pmid: s,
url: "https://www.ncbi.nlm.nih.gov/pubmed/" + s,
say: "PMID " + s };
}
return r;
}; // DESC.pmid()
//-----------------------------------------------------------------------
GUIP.gallery = {
buttonTool: "00/Button_easy_cite_%281%29.png",
throbber: "de/Ajax-loader.gif",
wikiEditor: "67/WikiEditor_Cite.svg",
MISSING: "45/%D0%95%D0%B3%D0%B3%D0%BE%D0%B3.svg"
}; // 2015-05-01 [email protected]
GUIP.$panel = false;
GUIP.factory = function () {
// Equip page GUI with panel
// Uses:
// > .type
// > GUIP.btn.show
// > .vsn
// > GUIP.$textarea
// < GUIP.live
// < GUIP.oneof
// < GUIP.$panel
// < GUIP.$button
// < GUIP.input.$text
// < GUIP.push.$bar
// GUIP.gadget.factory{)
// GUIP.fiat()
// (TASK.fiat)
// 2015-06-16 [email protected]
var collection = [ "empty",
"invalid",
"throbber",
"translated",
"unanswered",
"yippie" ],
i, $editarea;
GUIP.live = false;
GUIP.oneof = { };
GUIP.$panel = $( "<div>" );
GUIP.$panel.attr( { "id": CITWT.type } );
GUIP.$panel.css( { "border": "#808080 2px solid",
"margin-top": "0.5em",
"margin-bottom": "0.5em",
"overflow": "auto",
"padding": "5px" } );
GUIP.$panel.hide();
GUIP.$button = $( "<button>" );
GUIP.$button.attr( { "id": CITWT.type + "-button",
"title": CITWT.vsn } );
GUIP.$button.click( TASK.fiat );
GUIP.$button.css( { "float": "left",
"margin-right": "2em" } );
GUIP.$button.text( GUIP.btn.show );
GUIP.$panel.append( GUIP.$button );
GUIP.gadget.factory();
for ( i = 0; i < collection.length; i++ ) {
GUIP.fiat( collection[ i ] );
} // for i
GUIP.input.$text = false;
GUIP.push.$bar = false;
$editarea = $( "#edithelper-panel"); // user:Schnark
if ( ! $editarea.length ) {
if ( $( "#syntaxhighlight").length ) {
// hack Schnark/js/syntaxhighlight.js
$editarea = GUIP.$textarea.parent();
}
if ( ! $editarea.length ) {
$editarea = GUIP.$textarea;
}
}
$editarea.before( GUIP.$panel );
}; // GUIP.factory()
GUIP.fiat = function ( achieve ) {
// Create element
// Precondition:
// achieve -- keyword
// * empty
// * invalid
// * throbber
// * translated
// * unanswered
// * yippie
// Uses:
// > .type
// > GUIP.oneof
// > GUIP.$panel
// GUIP.file()
// I18N.fair()
// 2015-05-25 [email protected]
var $elem = $( "<span>" ),
colours = { empty: "808080",
invalid: "FF0000",
translated: "208020",
unanswered: "FF0000",
yippie: "40C040" },
$img, $span;
$elem.attr( { id: CITWT.type + "_" + achieve } );
$elem.css( { "vertical-align": "top" } );
if ( achieve === "throbber" ) {
$img = $( "<img />" );
$img.attr( { src: GUIP.file( "throbber" ),
id: CITWT.type + "_throbber_ajax",
height: "32",
alt: "Ajax" } );
$elem.append( $img );
} else {
$span = $( "<span>" );
$span.css( { "color": "#" + colours[ achieve ],
"font-size": "200%",
"font-weight": "bold",
"margin-right": "1em" } );
$span.text( I18N.fair( "msg"
+ achieve.substr( 0, 1 ).toUpperCase()
+ achieve.substr( 1 ),
true ) );
$elem.append( $span );
}
if ( "|invalid|throbber|translated|".indexOf( achieve ) > 0 ) {
$span = $( "<span>" );
$span.attr( { id: CITWT.type + "_" + achieve + "_text" } );
$span.css( { "margin-left": "1em" } );
if ( achieve === "invalid" ) {
$span.css( { "color": "#FF0000",
"font-weight": "bold" } );
}
$elem.append( $span );
} else if ( achieve === "unanswered" ) {
$elem.css( { "letter-spacing": "0.13em" } );
}
$elem.hide();
GUIP.oneof[ "$" + achieve ] = $elem;
GUIP.$panel.append( $elem );
}; // GUIP.fiat()
GUIP.file = function ( access ) {
// Retrieve image URL
// Precondition:
// access -- keyword
// Postcondition:
// Returns any image access string
// Uses:
// > GUIP.gallery
// 2015-05-01 [email protected]
var r = GUIP.gallery[ access ];
if ( ! r ) {
r = GUIP.gallery.MISSING;
}
return "//upload.wikimedia.org/wikipedia/commons/"
+ r.substr(0, 1) + "/" + r;
}; // GUIP.file()
GUIP.fire = function () {
// Start page GUI equipping
// Uses:
// $()
// (GUIP.first)
// Remark: Used as event handler -- 'this' is not GUIP
// 2015-05-12 [email protected]
$( GUIP.first );
}; // GUIP.fire()
GUIP.first = function () {
// Equip page GUI with DOM elements
// Precondition:
// DOM ready
// mediawiki modules and user options/config have been loaded
// Uses:
// > GUIP.$panel
// > .bibRecord
// > .leading (user defined)
// < GUIP.$textarea
// < GUIP.submit
// < GUIP.btn.show
// I18N.fair()
// GUIP.factory()
// GUIP.btn.fire()
// mw.loader.using()
// GUIP.flat()
// mw.loader.load()
// (.fire);
// Remark: Used as event handler -- 'this' is not GUIP
// 2017-02-20 [email protected]
var require;
GUIP.$textarea = $( "#wpTextbox1" );
if ( GUIP.$textarea.length && ! GUIP.$panel ) {
GUIP.submit = false;
GUIP.btn.show = I18N.fair( "Citoid", true );
GUIP.factory();
GUIP.btn.fire();
require = [ "jquery.textSelection",
"mediawiki.api" ];
if ( CITWT.bibRecord && CITWT.bibRecord.launch ) {
mw.loader.using( require, CITWT.fire );
} else {
if ( typeof CITWT.leading === "boolean"
&& CITWT.leading ) {
GUIP.flat( false );
}
mw.loader.load( require );
}
}
}; // GUIP.first()
GUIP.flat = function ( access, $add ) {
// Disable main button, rise cleared panel; show message
// Precondition:
// access -- keyword, if any
// -- false: do not discard text field
// $add -- additional jQuery object (second call only)
// Uses:
// > GUIP.$button
// > GUIP.oneof
// > .vsn
// > GUIP.$panel
// < GUIP.live
// GUIP.input.free()
// GUIP.input.fire()
// 2015-06-16 [email protected]
var leave, s, $child, $elem;
if ( access ) {
if ( access !== true ) {
$elem = GUIP.oneof[ "$" + access ];
$child = $elem.children().eq( 1 );
if ( $child.length ) {
$child.empty();
}
s = "|empty|invalid|unanswered|";
if ( s.indexOf( access ) > 0 ) {
GUIP.input.free();
}
}
} else if ( access !== false ) {
GUIP.input.fire( true );
}
if ( $add ) {
if ( $child ) {
$child.append( $add );
}
} else {
leave = ( access === "throbber" );
GUIP.$button.attr( { "disabled": leave,
"title": CITWT.vsn } );
for ( s in GUIP.oneof ) {
GUIP.oneof[ s ].hide();
} // for $elem in .oneof
GUIP.push.flip( 0 );
GUIP.$panel.show();
GUIP.live = true;
if ( $elem ) {
$elem.show();
}
}
}; // GUIP.flat()
GUIP.$flip = function ( $assembly, add, assign ) {
// Create sequence of external links
// Precondition:
// $assembly -- <span> or nothing
// add -- add Array[2]
// -- [0] URL string
// -- [1] title string
// assign -- serial number
// Postcondition:
// Returns extended $assembly
// Uses:
// < GUIP.$info
// 2015-05-01 [email protected]
var $a = $( "<a>" ),
$r;
if ( $assembly ) {
$r = $assembly;
} else {
$r = $( "<span>" );
GUIP.$info = false;
}
$a.attr( { href: add[ 0 ],
target: "CITWT" + assign } );
$a.css( { "margin-right": "0.75em" } );
$a.text( add[ 1 ] );
$r.append( $a );
return $r;
}; // GUIP.$flip()
GUIP.$flipper = function ( $assembly, add ) {
// Add identifier element to query info
// Precondition:
// $assembly -- <span>
// add -- displayed string
// Uses:
// < GUIP.$info
// 2015-05-01 [email protected]
GUIP.$info = $( "<span>" );
GUIP.$info.css( { "margin-right": "0.75em" } );
GUIP.$info.text( add );
$assembly.append( GUIP.$info );
}; // GUIP.$flipper()
GUIP.flop = function ( about ) {
// Show error message on invalid data format
// Precondition:
// about -- object with details
// -- about.scheme data type
// -- about[about.scheme] data content
// Uses:
// I18N.fair()
// GUIP.flat()
// 2015-05-01 [email protected]
var story = I18N.fair( "invalid" ),
$msg = $( "<span>" ),
$span = $( "<span>" ),
$code;
GUIP.flat( "invalid" );
if ( typeof about.scheme === "string" ) {
story = about.scheme.toUpperCase() + " – " + story;
if ( typeof about[ about.scheme ] === "string" ) {
$code = $( "<code>" );
$code.css( { "margin-left": "1.5em" } );
$code.text( about[ about.scheme ] );
}
}
$span.html( story );
$msg.append( $span );
if ( $code ) {
$msg.append( $code );
}
GUIP.flat( "invalid", $msg );
}; // GUIP.flop()
GUIP.btn.fire = function () {
// Equip page GUI with general button
// Uses:
// this
// > GUIP.opts
// >< GUIP.submit
// mw.loader.using()
// GUIP.btn.wikEd()
// GUIP.btn.toolbar()
// GUIP.btn.portlet()
// (GUIP.btn.wikiEditor)
// 2018-08-24 [email protected]
if ( ! this.wikEd() ) {
if ( GUIP.opts.usebetatoolbar ) {
GUIP.submit = "wikiEditor ... (loading)";
mw.loader.using( [ "ext.wikiEditor" ],
this.wikiEditor );
} else if ( GUIP.opts.showtoolbar ) {
this.toolbar();
}
}
if ( ! GUIP.submit ) {
this.portlet();
}
}; // GUIP.btn.fire()
GUIP.btn.portlet = function () {
// Equip wikiEditor toolbar with button
// Uses:
// > .type
// > GUIP.btn.show
// < GUIP.submit
// mw.util.addPortletLink()
// (.fire)
// 2015-05-12 [email protected]
var portlet = mw.util.addPortletLink( "p-tb",
"#",
GUIP.btn.show,
"t-" + CITWT.type );
$( portlet ).click( CITWT.fire );
GUIP.submit = "portlet-tb";
}; // GUIP.btn.portlet()
GUIP.btn.toolbar = function () {
// Equip classic toolbar with button
// Uses:
// > .type
// > GUIP.btn.show
// < GUIP.submit
// GUIP.file()
// (.fire)
// 2015-05-12 [email protected]
var $toolbar = $( "#toolbar" ),
$img;
if ( $toolbar.length ) {
$img = $( "<img />" );
$img.attr( { "src": GUIP.file( "buttonTool" ),
"id": CITWT.type + "-toolbar",
"height": "22",
"width": "23",
"alt": GUIP.btn.show,
"title": GUIP.btn.show } );
$img.click( CITWT.fire );
$toolbar.prepend( $img );
GUIP.submit = "toolbar";
}
}; // GUIP.btn.toolbar()
GUIP.btn.wikEd = function () {
// Equip wikEd GUI with button
// Postcondition:
// Returns something, if equipped for wikEd
// Uses:
// > wikEd
// > .type
// > GUIP.btn.show
// < GUIP.submit
// < EDIT.wikEd
// mw.user.options.get()
// GUIP.file()
// 2018-07-21 [email protected]
var id = 746,
cnf;
if ( mw.user.options.get( "gadget-wikEd" )
|| ( typeof window.wikEd === "object"
&& window.wikEd ) ) {
if ( typeof window.wikEd !== "object" ) {
window.wikEd = { config: { } };
}
EDIT.wikEd = window.wikEd;
if ( typeof EDIT.wikEd.config !== "object" ) {
EDIT.wikEd.config = { button: { },
buttonBar: { } };
}
cnf = EDIT.wikEd.config;
if ( typeof cnf.button !== "object" ) {
cnf.button = { };
}
cnf.button[ id ] = [ "wikEdCitoid",
"wikEdButton",
GUIP.btn.show,
GUIP.file( "buttonTool" ),
"16", "16",
"DIV",
"window.mediaWiki.libs."
+ CITWT.type
+ ".fire();" ];
if ( typeof cnf.buttonBar !== "object" ) {
cnf.buttonBar = { };
}
if ( typeof cnf.buttonBar.custom1 !== "object" ) {
cnf.buttonBar.custom1 = [ "wikEdButtonBarCustom1",
"wikEdButtonBarCustom1",
"wikEdButtonsCustom1",
"wikEdButtonsCustom1",
44,
GUIP.btn.show,
[ ] ];
}
cnf.buttonBar.custom1[ 6 ].push( id );
if ( typeof EDIT.wikEd.disabled === "boolean" &&
typeof EDIT.wikEd.highlightSyntax === "boolean" &&
typeof EDIT.wikEd.turnedOn === "boolean" &&
typeof EDIT.wikEd.useWikEd === "boolean"
&& EDIT.wikEd.useWikEd ) {
GUIP.submit = "wikEd";
}
}
return GUIP.submit;
}; // GUIP.btn.wikEd()
GUIP.btn.wikiEditor = function () {
// Equip wikiEditor toolbar with button
// Precondition:
// ext.wikiEditor.toolbar has been loaded
// Uses:
// > GUIP.$textarea
// > .type
// > GUIP.btn.show
// < GUIP.submit
// GUIP.file()
// (.fire)
// 2015-05-12 [email protected]
GUIP.$textarea.wikiEditor( "addToToolbar",
{ "section": "main",
"group": "format",
"tools": { citoid:
{ type: "button",
label: GUIP.btn.show,
icon: GUIP.file( "wikiEditor" ),
action: { type: "callback",
execute: CITWT.fire
}
}
}
} );
GUIP.submit = "wikiEditor";
}; // GUIP.btn.wikiEditor()
GUIP.caret.fetch = function ( after ) {
// Get selection
// Precondition:
// after -- callback function
// Postcondition:
// selection assigned
// Uses:
// this
// < GUIP.caret.min
// < GUIP.caret.max
// < GUIP.caret.selection
// < GUIP.caret.starter
// < GUIP.caret.further
// GUIP.caret.wikEd()
// mw.loader.using()
// (GUIP.caret.find)
// 2015-05-19 [email protected]
this.min = -2;
this.max = -3;
this.selection = false;
this.starter = false;
if ( this.wikEd() ) {
after( "wikEd" );
} else {
this.further = after;
mw.loader.using( [ "jquery.textSelection" ],
this.find );
}
}; // GUIP.caret.fetch()
GUIP.caret.fill = function ( apply ) {
// Insert/replace string at selection
// Precondition:
// apply -- string to be added
// Postcondition:
// edited text modified
// Uses:
// this
// < GUIP.caret.shift
// GUIP.caret.fetch()
// (GUIP.caret.filler)
// 2015-05-01 [email protected]
this.shift = apply;
this.fetch( this.filler );
}; // GUIP.caret.fill()
GUIP.caret.filler = function ( alien ) {
// Insert/replace string at selection
// Precondition:
// alien -- string with name of editor, or false
// Postcondition:
// edited text modified
// Uses:
// > GUIP.caret.shift
// > GUIP.caret.story
// > GUIP.caret.min
// > GUIP.caret.max
// > GUIP.$textarea
// > EDIT.codeMirror
// > EDIT.wikEd
// Remark: Used as event handler -- 'this' is not GUIP.caret
// 2018-07-21 [email protected]
var shift, start, story;
if ( GUIP.caret.max >= 0 ) {
shift = GUIP.caret.shift;
story = GUIP.caret.story;
start = story.substr( 0, GUIP.caret.min );
story = story.substr( GUIP.caret.max );
if ( shift.substr( 0, 4 ) === "<ref" ) {
start = start.replace( /\s+$/, "" );
} else if ( shift.substr( 0, 1 ) === "\n" &&
/\n$/.test( start ) ) {
shift = shift.substr( 1 );
}
if ( story.substr( 0, 1 ) === "\n" &&
/\n$/.test( shift ) ) {
story = story.substr( 1 );
}
story = start + shift + story;
GUIP.$textarea.val( story );
if ( EDIT.codeMirror && EDIT.codeMirror.liveCITWT ) {
EDIT.codeMirror.doc.setValue( story );
} else if ( alien === "wikEd" ) {
EDIT.wikEd.UpdateFrame();
}
}
}; // GUIP.caret.filler()
GUIP.caret.find = function () {
// Get selection in regular textarea, but perhaps CodeMirror
// Precondition:
// jquery.textSelection has been loaded
// Postcondition:
// selection assigned
// Uses:
// > CodeMirror
// > GUIP.$textarea
// > GUIP.caret.further
// >< EDIT.codeMirror
// < GUIP.caret.story
// < GUIP.caret.min
// < GUIP.caret.max
// < GUIP.caret.selection
// < GUIP.caret.starter
// Remark: Used as event handler -- 'this' is not GUIP.caret
// 2018-07-21 [email protected]
var rg, uo;
if ( ! EDIT.codeMirror &&
typeof window.CodeMirror === "function" &&
typeof window.CodeMirror.doc === "object"
&& window.CodeMirror.doc ) {
EDIT.codeMirror = window.CodeMirror;
}
if ( EDIT.codeMirror ) {
uo = mw.user.options.get( "usecodemirror" );
EDIT.codeMirror.liveCITWT = ( typeof uo === "number"
&& uo > 0 );
if ( EDIT.codeMirror.liveCITWT ) {
GUIP.$textarea.val( EDIT.codeMirror.doc.getValue() );
}
}
rg = GUIP.$textarea.textSelection( "getCaretPosition",
{ "startAndEnd": true } );
GUIP.caret.story = GUIP.$textarea.val();
if ( rg[0] <= rg[1] ) {
GUIP.caret.min = rg[0];
GUIP.caret.max = rg[1];
GUIP.caret.selection = GUIP.caret.story.substr( rg[0] );
GUIP.caret.starter = GUIP.caret.story.substr( 0, rg[0] );
}
GUIP.caret.further();
}; // GUIP.caret.find()
GUIP.caret.wikEd = function () {
// Get wikEd selection
// Precondition:
// assign -- object
// Postcondition:
// Returns true, if selection assigned
// Uses:
// this
// > EDIT.wikEd
// > GUIP.$textarea
// < GUIP.caret.start
// < GUIP.caret.stop
// < GUIP.caret.min
// < GUIP.caret.max
// < GUIP.caret.story
// < GUIP.caret.selection
// < GUIP.caret.starter
// (GUIP.caret.wikEdEnclose)
// 2018-01-21 [email protected]
var r;
if ( EDIT.wikEd &&
! EDIT.wikEd.disabled &&
EDIT.wikEd.useWikEd &&
EDIT.wikEd.turnedOn &&
EDIT.wikEd.highlightSyntax ) {
this.start = "##\f#citoid_marker_begin##\f#";
this.stop = "##\f#citoid_marker_end##\f#";
EDIT.wikEd.EditButton( null,
null,
null,
this.wikEdEnclose );
EDIT.wikEd.UpdateTextarea();
r = GUIP.$textarea.val();
this.min = r.search( this.start );
r = r.replace( this.start, "" );
this.max = r.search( this.stop ) - 1;
r = r.replace( this.stop, "" );
GUIP.$textarea.val( r );
this.story = r;
this.selection = this.story.substr( this.min );
this.starter = this.story.substr( 0, this.min );
EDIT.wikEd.UpdateFrame();
r = true;
}
return r;
}; // GUIP.caret.wikEd()
GUIP.caret.wikEdEnclose = function ( assign ) {
// Mark wikEd selection region
// Precondition:
// assign -- object
// Postcondition:
// assign got further properties
// Uses:
// > EDIT.wikEd
// > GUIP.caret.start
// > GUIP.caret.stop
// Remark: Used as event handler -- 'this' is not GUIP.caret
// 2018-07-21 [email protected]
EDIT.wikEd.GetText( assign, "selection, cursor" );
if ( assign.selection.plain === "" ) {
assign.sel = EDIT.wikEd.GetSelection();
if ( assign.sel.anchorNode.previousSibling ) {
assign.changed = assign.cursor;
} else {
EDIT.wikEd.GetText( assign, "whole" );
assign.changed = assign.whole;
}
} else {
assign.changed = assign.selection;
}
assign.changed.plain = GUIP.caret.start
+ assign.changed.plain
+ GUIP.caret.stop;
}; // GUIP.caret.wikEdEnclose()
GUIP.gadget.factory = function () {
// Create gadget bar
// Uses:
// this
// > GUIP.$panel
// < GUIP.gadget.$bar
// 2015-05-01 [email protected]
var buttons = [ "hide", "help", "hear", "home" ],
i;
this.$bar = $( "<div>" );
this.$bar.attr( { "id": CITWT.type + "-bar" } );
this.$bar.css( { "float": "right" } );
for ( i = 0; i < 4; i++ ) {
this.$fiat( buttons[ i ] );
} // for i
GUIP.$panel.append( this.$bar );
}; // GUIP.gadget.factory()
GUIP.gadget.$fiat = function ( assign ) {
// Create a single gadget button and add to bar
// Precondition:
// assign -- string as identifier
// Uses:
// this
// > GUIP.gadget.$bar
// 2015-05-12 [email protected]
var colours = { hear: "000000",
help: "208020",
hide: "FF0000",
home: "0000FF" },
suffix = assign.substr( 0, 1 ).toUpperCase()
+ assign.substr( 1 ),
$btn = $( "<button>" ),
$span = $( "<span>" );
$btn.attr( { "id": CITWT.type + "-button-" + assign,
"title": I18N.fair( "tip" + suffix, true ) } );
$btn.click( this[ assign ] );
$btn.css( { "float": "right",
"margin-left": "2px" } );
$span.css( { "color": "#" + colours[ assign ],
"font-weight": "bold" } );
$span.html( I18N.fair( "gadget" + suffix, true ) );
$btn.append( $span );
this.$bar.append( $btn );
}; // GUIP.gadget.$fiat()
GUIP.gadget.hear = function ( event ) {
// Gadget button for input field has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// UTIL.fullstop()
// GUIP.input.fire()
// Remark: Used as event handler -- 'this' is not GUIP.gadget
// 2015-05-12 [email protected]
UTIL.fullstop( event );
GUIP.input.fire( false );
GUIP.input.$text.show();
}; // GUIP.gadget.hear()
GUIP.gadget.help = function ( event ) {
// Gadget button for help page has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// > HELP.support
// UTIL.fullstop()
// I18N.fair()
// mw.util.getUrl()
// Remark: Used as event handler -- 'this' is not GUIP.gadget
// 2018-07-20 [email protected]
var support = "https://" + I18N.fair( "helpSite", true )
+ ".wikipedia.org"
+ mw.util.getUrl( HELP.support );
UTIL.fullstop( event );
window.open( support, "citWThelp" );
}; // GUIP.gadget.help()
GUIP.gadget.hide = function ( event ) {
// Gadget button has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// > GUIP.$panel
// < GUIP.live
// GUIP.gadget.home()
// Remark: Used as event handler -- 'this' is not GUIP.gadget
// 2015-06-16 [email protected]
GUIP.gadget.home( event );
GUIP.$panel.hide();
GUIP.live = false;
}; // GUIP.gadget.hide()
GUIP.gadget.home = function ( event ) {
// Gadget button has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// UTIL.fullstop()
// GUIP.flat()
// Remark: Used as event handler -- 'this' is not GUIP.gadget
// 2015-05-12 [email protected]
UTIL.fullstop( event );
GUIP.flat();
}; // GUIP.gadget.home()
GUIP.input.filler = function ( assign ) {
// Retrieve text input content, disable field with content, or hide
// Precondition:
// assign -- string to be assigned to the invisible field
// Postcondition:
// Returns non-empty input text, or false
// Hide empty field, disable field with content
// Uses:
// this
// > GUIP.input.$text
// > GUIP.input.live
// GUIP.input.fire()
// 2015-05-01 [email protected]
var r;
if ( GUIP.input.$text ) {
r = this.$text.val()
.replace( /^\s+/, "" )
.replace( /\s+$/, "" )
.replace( /\s+ /, " " );
this.$text.val( r );
if ( ! this.live ) {
if ( assign ) {
this.$text.val( assign );
}
r = false;
} else if ( r ) {
this.$text.attr( { "disabled": true } );
} else {
this.fire( true );
r = false;
}
}
return r;
}; // GUIP.input.filler()
GUIP.input.fed = function ( event ) {
// Keypress event on input field
// Precondition:
// event -- jQuery event object
// Uses:
// > GUIP.input.live
// > GUIP.input.$text
// CITWT.fire()
// Remark: Used as event handler -- 'this' is not GUIP.input
// 2015-06-16 [email protected]
if ( ( event.which === 10 || event.which === 13 )
&& GUIP.input.live
&& GUIP.input.$text.is( ":focus" ) ) {
CITWT.fire( event );
}
}; // GUIP.input.fed()
GUIP.input.fire = function ( abort ) {
// Set or toggle input field visibility
// Precondition:
// abort -- true: unconditionally vanishing
// Uses:
// > .type
// > GUIP.$panel
// >< GUIP.input.$text
// >< GUIP.input.live
// GUIP.flat()
// GUIP.input.free()
// GUIP.input.filler()
// (GUIP.input.fed)
// Remark: Used as event handler -- 'this' is not GUIP.input
// 2015-05-25 [email protected]
if ( abort ) {
GUIP.input.live = false;
} else {
GUIP.input.live = ( ! GUIP.input.live );
}
if ( GUIP.input.live ) {
if ( ! GUIP.input.$text ) {
GUIP.input.$text = $( "<input />" );
GUIP.input.$text.addClass( "mw-ui-input NOIME" );
GUIP.input.$text.attr( { id: CITWT.type + "_text_input",
size: 40,
type: "text" } );
GUIP.$panel.append( GUIP.input.$text );
}
GUIP.flat( false );
GUIP.input.free();
GUIP.input.$text.show();
GUIP.input.$text.focus();
GUIP.input.$text.keypress( GUIP.input.fed );
} else if ( GUIP.input.$text ) {
if ( abort === true ) {
GUIP.input.$text.hide();
}
if ( abort !== true ) {
GUIP.input.filler();
}
}
}; // GUIP.input.fire()
GUIP.input.free = function () {
// Enable text input
// Uses:
// this
// > GUIP.input.live
// > GUIP.input.$text
// 2015-05-25 [email protected]
if ( this.live && this.$text ) {
this.$text.attr( { "disabled": false } );
}
}; // GUIP.input.free()
GUIP.push.$fiat = function ( assign ) {
// Create a single result push button and add to bar
// Precondition:
// assign -- string as identifier
// Uses:
// this
// > GUIP.push.$bar
// 2015-05-01 [email protected]
var s = "$" + assign,
$span = $( "<span>" ),
$btn;
this[ s ] = $( "<button />" );
$btn = this[ s ];
$btn.attr( { "id": CITWT.type + "-push-" + assign } );
$btn.click( this[ assign ] );
$btn.css( { "float": "right",
"margin-left": "1em" } );
$span.css( { "white-space": "nowrap" } );
$span.html( I18N.fair( assign, true ) );
$btn.append( $span );
if ( assign === "bibSection" ) {
$btn.hide();
}
this.$bar.append( $btn );
}; // GUIP.push.$fiat()
GUIP.push.fired = function ( event, action ) {
// Insertion button has been clicked
// Precondition:
// event -- jQuery event object
// action -- string as insertion format identifier
// Uses:
// UTIL.fullstop()
// GUIP.push.flip()
// TASK.fruit()
// 2015-05-12 [email protected]
UTIL.fullstop( event );
this.flip( 0 );
TASK.fruit( action );
}; // GUIP.push.fired()
GUIP.push.flip = function ( action ) {
// Create or hide result insertion push bar
// Precondition:
// action -- number: 0, 3, 4
// Uses:
// this
// > GUIP.$panel
// > GUIP.push.$bibSection
// >< GUIP.push.$bar
// GUIP.input.fire()
// GUIP.push.$fiat()
// 2015-05-01 [email protected]
var btns, i;
if ( action ) {
GUIP.input.fire( true );
if ( ! this.$bar ) {
btns = [ "references", "bibSection", "refref", "compact" ];
this.$bar = $( "<span>" );
this.$bar.css( { "white-space": "nowrap" } );
this.$bar.attr( { "id": CITWT.type + "-push" } );
for ( i = 0; i < 4; i++ ) {
this.$fiat( btns[ i ] );
} // for i
this.$references.css( { "margin-right": "3em" } );
GUIP.$panel.append( this.$bar );
}
if ( action === 3 ) {
this.$bibSection.hide();
} else {
this.$bibSection.show();
}
this.$bar.show();
} else if ( this.$bar ) {
this.$bar.hide();
}
}; // GUIP.push.flip()
GUIP.push.bibSection = function ( event ) {
// Button for insertion at bibSection has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// GUIP.push.fired()
// Remark: Used as event handler -- 'this' is not GUIP.push
// 2015-05-01 [email protected]
GUIP.push.fired( event, "bibSection" );
}; // GUIP.push.bibSection()
GUIP.push.compact = function ( event ) {
// Button for insertion at compact has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// GUIP.push.fired()
// Remark: Used as event handler -- 'this' is not GUIP.push
// 2015-05-01 [email protected]
GUIP.push.fired( event, "compact" );
}; // GUIP.push.compact()
GUIP.push.references = function ( event ) {
// Button for insertion at <references> has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// GUIP.push.fired()
// Remark: Used as event handler -- 'this' is not GUIP.push
// 2015-05-01 [email protected]
GUIP.push.fired( event, "references" );
}; // GUIP.push.references()
GUIP.push.refref = function ( event ) {
// Button for insertion at <ref></ref> has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// GUIP.push.fired()
// Remark: Used as event handler -- 'this' is not GUIP.push
// 2015-05-01 [email protected]
GUIP.push.fired( event, "refref" );
}; // GUIP.push.refref()
//-----------------------------------------------------------------------
I18N.texts = {
bibSection: { de: "== Literatur ==" },
Citoid: { en: "Citoid" },
compact: { en: "compact",
de: "kompakt" },
gadgetHear: { en: "_" },
gadgetHelp: { en: "?" },
gadgetHide: { en: "X" },
gadgetHome: { en: "0" },
helpSite: { en: "en",
de: "de" },
invalid: { en: "Invalid data:",
de: "Datenformat nicht erkannt" },
msgEmpty: { en: "???" },
msgInvalid: { en: "!?!?!" },
msgTranslated: { en: "*" },
msgUnanswered: { en: ":-(" },
msgYippie: { en: ":-)" },
myButtons: { en: "My buttons",
de: "Meine Buttons" },
references: { en: "<references>" },
refref: { en: "<ref></ref>" },
tipHear: { en: "input field",
de: "Eingabefeld" },
tipHelp: { en: "help page",
de: "Hilfeseite" },
tipHide: { en: "hide box",
de: "Citoid-Box ausblenden" },
tipHome: { en: "abort requests, clear box",
de: "Anfragen abbrechen, Citoid-Box leeren" }
}; // 2015-05-01 [email protected]
I18N.translate = { // fallback languages
"als" : "de",
"bar" : "de",
"dsb" : "de",
"frr" : "de",
"gsw" : "de",
"hsb" : "de",
"ksh" : "de",
"lb" : "de",
"nds" : "de",
"pdc" : "de",
"pdt" : "de",
"pfl" : "de",
"sli" : "de",
"stq" : "de",
"vmf" : "de" };
I18N.facility = function ( available ) {
// Localize in user language, GUI only
// Precondition:
// available -- translation object
// Postcondition:
// Returns string, or undefined
// Uses:
// > I18N.userLang
// > I18N.translate
// 2015-05-01 [email protected]
var slang = I18N.userLang,
i, r;
if ( typeof available[ slang ] === "string" ) {
r = available[ slang ];
} else {
i = slang.indexOf( "-", 2 );
if ( i > 0 ) {
slang = slang.substr( 0, i );
if ( typeof available[ slang ] === "string" ) {
r = available[ slang ];
}
}
}
if ( ! r ) {
if ( typeof I18N.translate[ slang ] === "string" ) {
slang = I18N.translate[ slang ];
if ( typeof available[ slang ] === "string" ) {
r = available[ slang ];
}
}
if ( ! r ) {
r = available.en;
}
}
return r;
}; // I18N.facility()
I18N.fair = function ( access, adapt, alter ) {
// Localization
// Precondition:
// access -- configuration keyword
// adapt -- false, if project (language) dependant
// else user language dependant
// alter -- default string (en)
// Postcondition:
// Returns value, or keyword 'access'
// Uses:
// > I18N.texts
// > .core.site
// > I18N.contentLang
// I18N.facility()
// 2015-05-01 [email protected]
var el = I18N.texts[ access ],
r = ( alter ? alter : access ),
say;
if ( el ) {
if ( adapt ) {
say = I18N.facility( el );
if ( say ) {
r = say;
} else if ( typeof alter !== "string" ) {
r = "???" + access + "???";
}
} else {
if ( typeof el[ CITWT.core.site ] === "string" ) {
r = el[ CITWT.core.site ];
} else {
if ( typeof el[ I18N.contentLang ] === "string" ) {
r = el[ I18N.contentLang ];
}
}
}
} else if ( adapt ) {
r = "???" + access + "???";
}
return r;
}; // I18N.fair()
I18N.fire = function () {
// Initialize internationalization
// Uses:
// > .l10n
// >< I18N.texts
// < I18N.contentLang
// < I18N.wgUserLanguage
// mw.config.get()
// 2015-05-31 [email protected]
var env = mw.config.get( [ "wgContentLanguage",
"wgUserLanguage" ] );
I18N.contentLang = env.wgContentLanguage;
I18N.userLang = env.wgUserLanguage.toLowerCase();
if ( typeof CITWT.l10n === "object" && CITWT.l10n ) {
$.extend( true, I18N.texts, CITWT.l10n );
}
}; // I18N.fire()
//-----------------------------------------------------------------------
PREGO.feed = function () {
// Provide PREGO
// Uses:
// > PREGO.signature
// > PREGO.site
// > PREGO.store
// > PREGO.sub
// > PREGO.maxage
// mw.loader.getState()
// mw.loader.state()
// REPOS.fire()
// 2018-09-03 [email protected]
var sign = "ext.gadget." + PREGO.signature,
rls;
if ( ! mw.loader.getState( sign ) ) {
rls = { };
rls[ sign ] = "loading";
mw.loader.state( rls );
REPOS.fire( PREGO.site,
PREGO.store + PREGO.signature + PREGO.sub,
false,
{ action: "raw",
ctype: "text/javascript",
bcache: 1,
maxage: PREGO.maxage } );
}
}; // PREGO.feed()
//-----------------------------------------------------------------------
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 [email protected]
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 [email protected]
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()
//-----------------------------------------------------------------------
TASK.fiat = function ( event ) {
// Panel launch button has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// < TASK.template
// GUIP.input.filler()
// UTIL.fullstop()
// GUIP.input.fire()
// TASK.found()
// GUIP.caret.fetch()
// GUIP.flat()
// (TASK.found)
// Remark: Used as event handler -- 'this' is not TASK
// 2015-06-16 [email protected]
var listen = true,
suggest;
if ( event ) {
listen = GUIP.live && GUIP.$button.is( ":focus" );
if ( listen ) {
UTIL.fullstop( event );
}
}
if ( listen ) {
suggest = GUIP.input.filler();
TASK.template = false;
if ( suggest ) {
TASK.found( suggest );
} else {
GUIP.flat( true );
GUIP.caret.fetch( TASK.found );
}
}
}; // TASK.fiat()
TASK.filter = function () {
// Process completed result of queries
// Uses:
// > TASK.query
// > APIC.queries
// > PROJ
// > .bibRecord
// < TASK.template
// .opus.fire()
// .(project).fire()
// GUIP.caret.fill()
// GUIP.flat()
// GUIP.push.flip()
// Remark: Used as event handler -- 'this' is not TASK
// 2017-06-04 [email protected]
var mode, result;
if ( ! APIC.missing ) {
result = CITWT.opus.fire( TASK.query, APIC.queries );
}
TASK.template = PROJ.fire( result );
switch ( typeof TASK.template ) {
case "object":
mode = ( TASK.template[ 0 ][ 2 ] ? 4 : 3 );
break;
case "string":
if ( CITWT.bibRecord && CITWT.bibRecord.launch ) {
GUIP.caret.fill( TASK.template );
TASK.template = false;
GUIP.flat( "translated", TASK.query.$links );
} else {
mode = 3;
}
break;
default:
TASK.template = false;
} // switch typeof array
if ( mode ) {
GUIP.push.flip( mode );
}
}; // TASK.filter()
TASK.fire = function () {
// Initialize page
// Precondition:
// mediawiki modules and user options/config have been loaded
// Uses:
// > .core.site
// > mw.user.options
// < PROJ
// < GUIP.opts
// I18N.fire()
// mw.user.options.get()
// mw.loader.using()
// BOOK.fire()
// (BOOK.fire)
// 2016-03-21 [email protected]
if ( typeof CITWT[ CITWT.core.site ] === "object" ) {
PROJ = CITWT[ CITWT.core.site ];
if ( PROJ ) {
I18N.fire();
GUIP.opts = mw.user.options.get( [ "showtoolbar",
"usebetatoolbar" ] );
if ( GUIP.opts.usebetatoolbar ) {
// race condition
mw.loader.using( [ "ext.wikiEditor" ],
BOOK.fire );
} else {
BOOK.fire();
}
}
}
}; // TASK.fire()
TASK.follow = function () {
// Proceed after completion of query results
// Uses:
// > .signature
// > TASK.query.$links
// GUIP.flat()
// mw.loader.using()
// (TASK.filter)
// 2016-02-21 [email protected]
GUIP.flat( "translated" );
mw.loader.using( [ CITWT.signature + "/opus",
"user:PerfektesChaos/WikiSyntaxTextMod/U" ],
TASK.filter );
GUIP.flat( "translated", TASK.query.$links );
}; // TASK.follow()
TASK.found = function ( ask ) {
// Source text selection is ready or input is known
// Precondition:
// ask -- search string, if known
// Uses:
// > GUIP.caret.selection
// > .bibRecord
// > APIC.stateless
// > APIC.found
// < TASK.query
// < APIC.queries
// DESC.fire()
// GUIP.flat()
// APIC.worldCat.fire()
// .(project).favorite()
// GUIP.$flip()
// GUIP.$flipper()
// mw.loader.using()
// GUIP.flop()
// GUIP.input.filler()
// (APIC.fire)
// 2017-06-11 [email protected]
var search = ( ask ? ask : GUIP.caret.selection ),
stateless = "|isbn|", // |oclc
i, k, m, project, q, suggest, url;
if ( ! search && CITWT.bibRecord ) {
search = CITWT.bibRecord.sign + " " + CITWT.bibRecord.subject;
}
if ( search ) {
TASK.query = DESC.fire( search );
if ( TASK.query ) {
q = TASK.query;
switch ( typeof q.url ) {
case "string":
q.url = [ q.url ];
break;
case "object":
break;
default:
q.url = false;
} // switch typeof q.url
if ( q.url ) {
GUIP.flat( "throbber" );
APIC.queries = [ ];
q.$links = false;
for ( i = 0; i < q.url.length; i++ ) {
url = q.url[ i ];
for ( m = 0; m < i; m++ ) {
if ( url === q.url[ m ] ) {
url = false;
break;
}
} // for m
if ( typeof url === "string" ) {
k = i + 1;
APIC.queries.push( url );
url = [ url, "[" + k + "]" ];
q.url[ i ] = url;
}
if ( url ) {
q.$links = GUIP.$flip( q.$links, url, k );
}
} // for i
if ( typeof q.say === "string" ) {
GUIP.$flipper( q.$links, q.say );
suggest = q.say;
}
GUIP.flat( "throbber", q.$links );
if ( typeof APIC.stateless === "string" &&
typeof q.scheme === "string" &&
stateless.indexOf( "|" + q.scheme + "|" ) >= 0 ) {
stateless = q[ q.scheme ];
if ( typeof stateless === "string" ) {
stateless = q.scheme.toUpperCase()
+ " " + stateless;
APIC.queries.push( stateless );
}
}
if ( typeof PROJ.favorite === "function" ) {
project = PROJ.favorite( q, APIC.found );
if ( project ) {
project.local = true;
APIC.queries.push( project );
}
}
mw.loader.using( [ "mediawiki.api" ],
APIC.fire );
if ( typeof q.source === "string" ) {
suggest = q.source;
}
GUIP.input.filler( suggest );
} else {
GUIP.flop( q );
}
} else {
GUIP.flat( "empty" );
}
} else {
TASK.query = false;
}
}; // TASK.found()
TASK.fruit = function ( action ) {
// Insert template
// Precondition:
// action -- string as insertion format identifier
// Uses:
// >< TASK.template
// .opus.fruit()
// GUIP.caret.fill()
// 2015-05-25 [email protected]
var indent, seed, start, suffix;
switch ( action ) {
case "compact":
indent = -1;
break;
case "refref":
indent = -1;
start = "<ref>";
suffix = "</ref>";
break;
case "bibSection":
indent = 3;
start = "\n* ";
suffix = "\n";
break;
case "references":
indent = 1;
start = "\n<ref name=\"\">\n";
suffix = "\n</ref>\n";
break;
} // switch action
seed = CITWT.opus.fruit( TASK.template, indent );
TASK.template = false;
if ( seed ) {
seed = ( start ? start : "" ) +
seed +
( suffix ? suffix : "" );
GUIP.caret.fill( seed );
}
}; // TASK.fruit()
//-----------------------------------------------------------------------
UTIL.feed = function ( assigned, access, address ) {
// Load and run script
// Precondition:
// assigned -- signature
// access -- script
// address -- URL to be used, else created from access
// Uses:
// > .suite
// > REPOS.maxage
// mw.loader.getState()
// mw.loader.state()
// mw.loader.load()
// REPOS.fire()
// 2018-09-03 [email protected]
var p, rls;
if ( ! mw.loader.getState( assigned ) ) {
rls = { };
rls[ assigned ] = "loading";
mw.loader.state( rls );
if ( address ) {
mw.loader.load( address );
} else {
p = { bcache: 1 };
p.maxage = ( CITWT.suite === "r" ? REPOS.maxage : 100 );
REPOS.fire( REPOS.site,
REPOS.store + access + ".js",
false,
p );
}
}
}; // UTIL.feed()
UTIL.fetch = function ( access ) {
// Run subscripts
// Precondition:
// access -- subscript
// Uses:
// > .signature
// > .type
// > .suite
// UTIL.feed()
// 2018-07-28 [email protected]
var sub = "/" + access;
UTIL.feed( CITWT.signature + sub,
CITWT.type + sub + "/" + CITWT.suite );
}; // UTIL.fetch()
UTIL.friend = function () {
// Load current project plug-in, if appropriate
// Postcondition:
// Returns something, if plug-in should become available
// Uses:
// > .signature
// > .core.site
// > .core.sites
// UTIL.feed()
// mw.loader.getState()
// UTIL.fetch()
// console.log()
// 2018-07-14 [email protected]
var signature = CITWT.signature + "/" + CITWT.core.site,
r, s;
switch ( typeof CITWT[ CITWT.core.site ] ) {
case "string":
// load from URL
r = CITWT[ CITWT.core.site ];
if ( r ) {
UTIL.feed( signature, false, r );
}
break;
case "object":
// already provided
if ( mw.loader.getState( signature ) ) {
r = CITWT[ CITWT.core.site ];
}
break;
default:
// load from code base, if registered
s = "|" + CITWT.core.site + "|";
if ( CITWT.core.sites.indexOf( s ) >= 0 ) {
UTIL.fetch( CITWT.core.site );
r = true;
}
} // switch typeof CITWT[ CITWT.core.site ]
if ( ! r &&
typeof window.console === "object" &&
typeof window.console.log === "function" ) {
window.console.log( CITWT.type + " * Local project unknown: "
+ CITWT.core.site );
}
return r;
}; // UTIL.friend()
UTIL.fullstop = function ( activity ) {
// Stop immediately event propagation
// Precondition:
// activity -- event
// 2015-05-12 [email protected]
if ( typeof activity === "object" && activity ) {
if ( typeof activity.preventDefault === "function" ) {
activity.preventDefault();
}
if ( typeof activity.stopPropagation === "function" ) {
activity.stopPropagation();
}
}
}; // UTIL.fullstop()
//-----------------------------------------------------------------------
XPORT.core.fold = function ( analyse ) {
// Derive simple template parameters; not nested
// Precondition:
// analyse -- string, with parameter list
// Postcondition:
// Returns object, with components identified by strings
// 2015-05-12 [email protected]
var i = 0,
m = 0,
r = { },
s = analyse,
t = [ ],
j, k, sign;
while ( s ) {
j = s.indexOf( "|", i );
k = s.indexOf( "}}", i );
if ( j >= 0 && j < k ) {
if ( i ) {
t.push( s.substring( i, j ) );
}
i = j + 1;
} else if ( k >= 0 ) {
if ( k ) {
t.push( s.substring( i, k ) );
}
s = false;
} else {
s = false;
}
} // while s
for ( i = 0; i < t.length; i++ ) {
s = t[ i ].replace( /^\s+/, "" )
.replace( /\s+$/, "" );
j = s.indexOf( "=", i );
if ( j > 0 ) {
sign = s.substr( 0, j )
.replace( /\s+$/, "" );
s = s.substr( j + 1 )
.replace( /^\s+/, "" );
} else {
m++;
sign = "" + m;
}
r[ sign ] = s;
} // for i
return r;
}; // XPORT.core.fold()
//-----------------------------------------------------------------------
XPORT.fire = function ( event ) {
// Tool button has been clicked
// Precondition:
// event -- jQuery event object
// Uses:
// > GUIP.$panel
// UTIL.fullstop()
// GUIP.flat()
// GUIP.factory()
// TASK.fiat()
// Remark: Used as event handler -- 'this' is not XPORT
// 2015-05-23 [email protected]
UTIL.fullstop( event );
if ( GUIP.$panel ) {
GUIP.flat( false );
} else {
GUIP.factory();
}
TASK.fiat();
}; // XPORT.fire()
//-----------------------------------------------------------------------
function fire() {
// Start regular workflow in edit mode, if appropriate
// Uses:
// > CITWT
// > HELP.site
// > HELP.support
// > Version
// > .signature
// >< .bibRecord
// < .support
// < .core.site
// facilitated()
// mw.config.get()
// PREGO.feed()
// UTIL.fetch()
// UTIL.feed()
// UTIL.friend()
// mw.loader.using()
// (TASK.fire)
// 2018-07-28 [email protected]
var env, sub, suitable;
facilitated();
if ( CITWT ) {
env = mw.config.get( [ "wgAction",
"wgDBname",
"wgIsProbablyEditable",
"wgPageContentModel" ] );
CITWT.support = "[[" + HELP.site + ":" + HELP.support + "]]";
CITWT.core.site = env.wgDBname;
suitable = "|edit|submit|";
if ( suitable.indexOf( env.wgAction ) > 0 &&
env.wgIsProbablyEditable &&
env.wgPageContentModel === "wikitext" &&
UTIL.friend() ) {
PREGO.feed();
UTIL.fetch( "opus" );
sub = ( Version > 1 ? "r" : "d" );
UTIL.feed( "user:PerfektesChaos/WikiSyntaxTextMod/S",
"WikiSyntaxTextMod/" + sub + "S" );
UTIL.feed( "user:PerfektesChaos/WikiSyntaxTextMod/U",
"WikiSyntaxTextMod/" + sub + "U" );
UTIL.feed( "ext.gadget.isbnLib",
"isbnLib/" + sub );
if ( typeof CITWT.bibRecord !== "object" ) {
CITWT.bibRecord = false;
}
mw.loader.using( [ "mediawiki.user",
"mediawiki.util",
"user",
"user.options",
CITWT.signature + "/" + env.wgDBname ],
TASK.fire );
}
}
} // fire()
fire();
}( window.mediaWiki, window.jQuery ) );
/// EOF </nowiki> citoidWikitext/core/d.js