/// tableXpander.js
/// 2023-04-19 PerfektesChaos@de.wikipedia
/// Documentation: [[w:en:User:PerfektesChaos/js/tableXpander]]
/// Fingerprint: #0#0#
/// @license: CC-by-sa/4.0 GPLv3
/// <nowiki>
/* global window:false */
/* jshint forin:false,
bitwise:true, curly:true, eqeqeq:true, latedef:true,
laxbreak:true,
nocomma:true, strict:true, undef:true, unused:true */
( function ( mw, $ ) {
"use strict";
var Version = -2.2,
Signature = "tableXpander",
API = { Api: false },
PAGE = { show: Signature + "@PerfektesChaos",
sign: "|}===={|",
support: "https://en.wikipedia.org/wiki/"
+ "Special:MyLanguage/"
+ "User:PerfektesChaos/js/"
+ Signature,
$textarea: false },
CSS = { background: "FFF8DC",
color: "006400" },
NUM = { structure: "dot;comma" },
TABLE = { },
REPO = { };
CSS.design = { "background": "#" + CSS.background,
"color": "#" + CSS.color };
CSS.def = { "active":
{ "background-color": CSS.design.background
+ "!important" },
"box": { "background-color": CSS.design.background,
"border-color": CSS.design.color,
"border-radius": "6px",
"border-style": "solid",
"border-width": "3px",
"clear": "both",
"margin-bottom": "2em",
"margin-left": "1%",
"margin-right": "1%",
"margin-top": "1em",
"padding": "0.5em",
"width": "95%" },
"caption":
{ },
"cell": { "display": "table-cell",
"vertical-align": "middle" },
"chosen":
{ "background-color": CSS.design.color,
"color": CSS.design.background,
"font-weight": "bold",
"padding": "0.1em" },
"clickable":
{ "color": CSS.design.color,
"text-decoration": "none" },
"clickable::link":
{ "color": CSS.design.color },
"doclink":
{ "font-size": "120%",
"font-weight": "bolder" },
"grouping":
{ "background-color": CSS.design.color,
"color": CSS.design.background,
"font-weight": "bold",
"padding": "0.3em" },
"handle":
{ "background-color": CSS.design.background,
"border-color": CSS.design.color,
"border-radius": "3px",
"border-style": "solid",
"border-width": "2px",
"color": CSS.design.color,
"font-size": "100%",
"font-style": "normal",
"font-weight": "normal",
"padding": "0.2em" },
"icon": { "border-radius": "0.4em",
"border-style": "solid",
"border-width": "0.15em",
"display": "inline-block",
"font-size": "150%",
"font-weight": "bolder",
"margin": "0.5em",
"padding": "0.3em" },
"include":
{ "background-color": CSS.design.background },
"info": { "border-color": CSS.design.color,
"border-radius": "3px",
"border-style": "solid",
"border-width": "1px",
"font-family": "monospace",
"font-size": "100%",
"font-style": "normal",
"font-weight": "normal",
"padding-left": "0.1em",
"padding-right": "0.1em"
},
"quit": { "color": "#FF0000",
"font-size": "150%",
"font-weight": "700",
"text-align": "center",
"vertical-align": "middle"},
"td": { "background-color": CSS.design.background,
"color": CSS.design.color,
"font-size": "100%",
"font-style": "normal",
"font-weight": "normal",
"text-align": "center" },
"textarea":
{ "background-color": CSS.design.background,
"margin-bottom": "2em",
"margin-top": "1em",
"width": "95%" },
"toggle":
{ "display": "inline-block",
"font-size": "80%",
"font-style": "normal",
"font-weight": "normal",
"margin": "0.2em" },
"ul": { "list-style-image": "none",
"list-style-position": "outside",
"list-style-type": "none",
"margin-bottom": "0.2em",
"margin-left": "0",
"margin-right": "0",
"margin-top": "0.2em",
"padding": "0" },
"ul > li":
{ "display": "inline",
"margin-right": "0.7em",
"padding": "0" },
"ul > li::after":
{ "content": " \n" },
"ul > li:last-child":
{ "margin-right": "0" },
"version":
{ "font-size": "80%" },
"widget":
{ "margin-left": "0.8em",
"margin-right": "0.8em" }
};
NUM.call = { "#": "forward",
"+": "full",
"~": "fair",
"%": "fraction",
"?": "fruits" };
NUM.codes = { apos: 0x27,
comma: 0x2C,
dot: 0x2E,
nbsp: 0xA0,
nnbsp: 0x202F };
NUM.entities = { apos: 0x27,
nbsp: 0xA0,
lrm: false,
rlm: false,
zwj: false };
NUM.min = 0.0001;
NUM.offer = [ "dot;comma",
"comma;dot",
"comma;apos",
"comma;nbsp",
"dot;nbsp",
"comma;nnbsp",
"dot;nnbsp" ];
NUM.patterns = { "dot;comma": "0,000.00",
"dot;nbsp": "0▯000.00",
"dot;nnbsp": "0□000.00",
"comma;apos": "0'000,00",
"comma;dot": "0.000,00",
"comma;nbsp": "0▯000,00",
"comma;nnbsp": "0□000,00" };
NUM.translate = { 0x2D: 45, // -
0x2212: 45, // typographic -
0x2B: 43, // +
0xFF0B: 43,
0xFF0D: 45 };
NUM.seek = NUM.structure;
NUM.sep = ".";
NUM.spaces = [ 0xA0,
0x1680,
0x2000,
0x2001,
0x2002,
0x2003,
0x2004,
0x2005,
0x2006,
0x2007,
0x2008,
0x2009,
0x200A,
0x200B,
0x200C,
0x200D,
0x200E,
0x200F,
0x202F,
0x205F,
0x3000,
0x303F ];
NUM.starts = "#+~%?";
NUM.variants = { apos: [ 0x2019,
0xFF07 ],
comma: [ 0xFF0C ],
dot: [ 0xFF0E ] };
NUM.zero = [ 0x30,
0x0660,
0x06F0,
0x07C0,
0x0966,
0x09E6,
0x0A66,
0x0AE6,
0x0B66,
0x0BE6,
0x0C66,
0x0CE6,
0x0D66,
0x0DE6,
0x0E50,
0x0ED0,
0x0F20,
0x102E,
0x1040,
0x1369,
0x17E0,
0x1810,
0x1946,
0x19D0,
0x1A80,
0x1A90,
0x1B50,
0x1BB0,
0x1C40,
0x1C50,
0xA620,
0xA8D0,
0xA900,
0xA9D0,
0xA9F0,
0xAA50,
0xABF0,
0xFF10,
0x1104A,
0x110D3,
0x110E6,
0x11106,
0x1110F,
0x11113,
0x1111D,
0x1112F,
0x11145,
0x1114D,
0x11165,
0x1116C,
0x11173,
0x1118E,
0x111C5,
0x111D5,
0x111DA,
0x116A6,
0x116B5,
0x116E8,
0x11E14,
0x11E2F,
0x11E8C,
0x11E95,
0x1D7F6,
0xE0030 ];
TABLE.title = { "#": "#",
"+": String.fromCharCode( 0x03A3 ), // Sigma
"~": String.fromCharCode( 0x00F8 ), // Oslash
"%": "%",
"?": "^",
"h": String.fromCharCode( 0x2194 ), // <-->
"v": String.fromCharCode( 0x2195 ), // ^
"X": "X"
};
//-----------------------------------------------------------------------
function fire() {
// Start processing
// Uses:
// > $
// (PAGE.fire)
// 2017-11-30 PerfektesChaos@de.wikipedia
if ( $ ) {
if ( typeof $ === "function" ) {
$( PAGE.fire );
}
}
} // fire()
API.fail = function ( arrived, add ) {
// API purging failed
// Precondition:
// arrived -- string with basic message
// add -- object with additional information
// Uses:
// window.console
// 2016-08-30 PerfektesChaos@de.wikipedia
if ( typeof window.console === "object" &&
typeof arrived === "string" ) {
if ( typeof window.console.log === "function" ) {
window.console.log( arrived );
}
if ( typeof add === "object" && add &&
typeof window.console.dir === "function" ) {
window.console.dir( add );
}
}
}; // API.fail()
API.formatnum = function () {
// Launch API query for number formatting
// Uses:
// >< API.Api
// (API.formattednum)
// (API.fail)
// 2017-05-31 PerfektesChaos@de.wikipedia
var o = { action: "expandtemplates",
prop: "wikitext",
text: "{{formatnum:1234567.89}}" };
if ( typeof API.Api !== "object" ) {
API.Api = new mw.Api();
}
API.Api.get( o ).done( API.formattednum )
.fail( API.fail );
}; // API.formatnum()
API.formattednum = function ( arrived ) {
// API success on parsed number formatting
// Precondition:
// arrived -- JSON result of ajax query
// Uses:
// NUM.formatting()
// 2017-05-31 PerfektesChaos@de.wikipedia
if ( typeof arrived === "object"
&& arrived &&
typeof arrived.expandtemplates === "object" &&
typeof arrived.expandtemplates.wikitext === "string" ) {
NUM.formatting( arrived.expandtemplates.wikitext );
}
}; // API.formattednum()
NUM.faculty = function ( attempt, array ) {
// Precondition:
// attempt -- character code to be checked
// access -- Array to be checked against, or not
// Postcondition:
// Returns true if character might be ignored
// 2017-11-30 PerfektesChaos@de.wikipedia
var i, r;
if ( array ) {
for ( i = 0; i < array.length; i++ ) {
if ( array[ i ] === attempt ) {
r = true;
break; // for i
}
} // for i
}
return r;
}; // NUM.faculty()
NUM.fair = function ( $all, $actives, $about ) {
// Average of all figures
// Precondition:
// $all -- <table>
// $actives -- active cells
// $about -- <code> for result
// Uses:
// > Signature
// NUM.full()
// 2020-08-17 PerfektesChaos@de.wikipedia
var n = $actives.length,
g;
if ( n ) {
g = NUM.full( $all, $actives, $about );
if ( g[ 0 ] && g[ 1 ] ) {
n = g[ 0 ] / g[ 1 ];
} else {
n = 0;
}
}
$about.text( n );
}; // NUM.fair()
NUM.fetch = function ( $at ) {
// Retrieve number
// Precondition:
// $at -- <td> / <th>
// Uses:
// > Signature
// > NUM.reInteger
// NUM.fill()
// 2020-08-25 PerfektesChaos@de.wikipedia
var s = $at.data( Signature + "-parsed" ),
skipped = ":hidden,[style*='visibility']",
r, store, $dup;
if ( s ) {
if ( s !== "!" ) {
r = parseInt( s, 10 );
s = false;
}
} else {
s = $at.data( Signature + "-raw" );
if ( ! s ) {
s = $at.data( "sort-value" );
if ( s ) {
$at.attr( { title: s } );
} else {
if ( $at.find( skipped ).length > 1 ) {
$dup = $at.clone();
$dup.find( ":hidden" ).remove();
s = $dup.text();
} else {
s = $at.text();
}
}
if ( s ) {
s = NUM.fill( s );
if ( s ) {
if ( NUM.reInteger.test( s ) ) {
store = "-parsed";
} else {
store = "-raw";
}
$at.data( Signature + store, s );
}
}
}
if ( s ) {
s = NUM.filter( s );
if ( s ) {
r = parseFloat( s );
if ( isNaN( r) ) {
r = false;
}
}
} else {
$at.data( Signature + "-parsed", "!" );
}
}
return r;
}; // NUM.fetch()
NUM.figure = function ( analyze ) {
// Identify digit in scripting systems
// Precondition:
// analyze -- character code
// Postcondition:
// Returns code of zero, or not
// Uses:
// > NUM.zero
// 2017-11-30 PerfektesChaos@de.wikipedia
var i, j, r;
for ( i = 0; i < NUM.zero.length; i++ ) {
j = NUM.zero[ i ];
if ( analyze < j ) {
break; // for i
} else {
if ( analyze <= j + 9 ) {
r = j;
break; // for i
}
}
} // for i
return r;
}; // NUM.figure()
NUM.fill = function ( analyze ) {
// Normalize number string
// Precondition:
// analyze -- string, with number to be parsed
// Postcondition:
// Returns normalized string
// Uses:
// > Signature
// > NUM.reInteger
// > NUM.translate
// NUM.flat()
// PAGE.flat()
// NUM.foreign()
// 2020-08-17 PerfektesChaos@de.wikipedia
var i = analyze.indexOf( "[-]" ),
s = analyze,
j, k, less, r;
if ( i >= 0 ) {
s = s.substr( 0, i );
}
s = PAGE.flat( s );
s = NUM.flat( s );
k = NUM.translate[ s.charCodeAt( 0 ) ];
if ( k === 45 || k === 43 ) {
less = ( k === 45 );
s = NUM.flat( s.substr( 1 ) );
}
j = NUM.figure( s.charCodeAt( 0 ) );
if ( ! j ) {
j = NUM.figure( s.charCodeAt( 1 ) );
}
if ( j ) {
if ( j === 0x30 ) {
r = s;
} else {
r = NUM.foreign( s, j );
}
for ( i = 1; i < r.length; i++ ) {
if ( r.charCodeAt( i ) <= 32 ) {
r = r.substr( 0, i );
break; // for i
}
} // for i
if ( less ) {
r = "-" + r;
}
}
return r;
}; // NUM.fill()
NUM.filter = function ( attempt ) {
// Parse number according to current formatting
// Precondition:
// attempt -- string
// Uses:
// > NUM.seek
// > NUM.codes
// > NUM.variants
// >< NUM.dec
// < NUM.omit
// NUM.faculty()
// 2020-07-25 PerfektesChaos@de.wikipedia
var fill, i, k, large, left, less, m, r, seg, sep;
if ( ! NUM.dec &&
typeof NUM.seek === "string" ) {
i = NUM.seek.indexOf( ";" );
if ( i > 0 ) {
sep = NUM.seek.substr( 0, i );
seg = NUM.seek.substr( i + 1 );
} else {
sep = NUM.seek;
seg = false;
}
NUM.omit = false;
if ( sep &&
typeof NUM.codes[ sep ] === "number" ) {
fill = function ( array, assigned ) {
var i, v;
NUM[ array ] = [ NUM.codes[ assigned ] ];
if ( typeof NUM.variants[ assigned ] === "object" ) {
v = NUM.variants[ assigned ];
for ( i = 0; i < v.length; i++ ) {
NUM[ array ].push( v[ i ] );
} // for i
}
}; // fill()
fill( "dec", sep );
if ( seg &&
typeof NUM.codes[ seg ] === "number" ) {
fill( "omit", seg );
}
}
}
if ( NUM.dec ) {
i = 0;
if ( attempt.charCodeAt( 0 ) === 0x2D ) {
less = true;
i = 1;
}
do { // while k
k = attempt.charCodeAt( i );
if ( k >= 0x30 && k <= 0x39 ) {
r = ( r || "" ) + String.fromCharCode( k );
} else if ( NUM.faculty( k, NUM.omit ) ) {
k = attempt.charCodeAt( i + 1 );
if ( ! r || k < 0x30 || k > 0x39 ) {
break; // do
}
} else if ( NUM.faculty( k, NUM.dec ) ) {
if ( left ) {
break; // do
} else {
if ( r ) {
r = r + ".";
} else {
k = attempt.charCodeAt( i + 1 );
if ( k === 0x45 || k === 0x65 ) {
r = "0.";
} else {
break; // do
}
}
left = true;
}
} else if ( k === 0x45 || k === 0x65 ) {
if ( large ) {
break; // do
} else {
k = attempt.charCodeAt( i + 1 );
if ( k >= 0x30 && k <= 0x39 ) {
large = true;
r = r + "e";
} else if ( k === 0x2B ||
k === 0x2D ||
k === 0x2E ||
k === NUM.dec[ 0 ] ) {
m = k;
k = attempt.charCodeAt( i + 2 );
if ( k >= 0x30 && k <= 0x39 ) {
large = true;
switch ( m ) {
case 0x2D:
r = r + "e-";
break;
case 0x2E:
r = r + "e0.";
break;
default:
r = r + "e";
} // switch m
i++;
}
}
if ( large ) {
left = false;
} else {
break; // do
}
}
} else {
break; // do
}
i++;
} while ( k );
if ( r && less ) {
r = "-" + r;
}
}
return r;
}; // NUM.filter()
NUM.find = function ( assign ) {
// Retrieve character name for formatting character
// Precondition:
// assign -- string with formatting character
// Postcondition:
// Returns name of character
// Uses:
// > NUM.codes
// 2017-11-30 PerfektesChaos@de.wikipedia
var k, r, s;
if ( assign.length === 1 ) {
k = assign.charCodeAt( 0 );
for ( s in NUM.codes ) {
if ( NUM.codes[ s ] === k ) {
r = s;
break; // for s in NUM.codes
}
} // for s in NUM.codes
}
return r;
}; // NUM.find()
NUM.fire = function ( $all ) {
// Requery
// Precondition:
// $all -- <table>
// Uses:
// > Signature
// NUM.first()
// 2020-08-21 PerfektesChaos@de.wikipedia
var $div = $all.find( "." + Signature + "-result" ),
s = $div.data( "query" );
NUM.first( $all, s, $div );
}; // NUM.fire()
NUM.first = function ( $all, activity, $at ) {
// Perform activity processing
// Precondition:
// $all -- <table>
// activity -- code of task, # + ~ % ?
// $at -- <div>
// Uses:
// > Signature
// > NUM.call
// NUM.fore()
// 2020-08-21 PerfektesChaos@de.wikipedia
var s = NUM.call[ activity ],
$code = $at.find( "code" ),
$active;
$code.empty();
if ( activity === "?" ) {
$code.hide();
} else {
$code.text( "0" ).show();
}
NUM.fore( $all );
if ( s ) {
$active = $all.find( "tbody" )
.find( "." + Signature + "-active" )
.not( "." + Signature + "-td" );
if ( $active.length ) {
NUM[ s ]( $all, $active, $code );
}
}
}; // NUM.first()
NUM.flat = function ( adjust ) {
// Trim left
// Precondition:
// adjust -- string
// Postcondition:
// Returns trimmed string
// Uses:
// > NUM.spaces
// 2020-08-17 PerfektesChaos@de.wikipedia
var i = 0,
j, k;
do { // while k <= 32 && i < adjust.length
k = adjust.charCodeAt( i );
if ( k > 32 ) {
for ( j = 0; j < NUM.spaces.length; j++ ) {
if ( NUM.spaces[ j ] === k ) {
k = 32;
break; // for j
}
} // for j
}
i++;
} while ( k <= 32 && i < adjust.length );
return ( i > 1 ? adjust.substr( i - 1 ) : adjust );
}; // NUM.flat()
NUM.flip = function ( action, $at ) {
// Number format selection
// Precondition:
// action -- event data object, or string with identifier
// .data
// [0] -- identifier of pattern
// [1] -- <li> or not
// Uses:
// > NUM.$group
// > Signature
// < NUM.seek
// < NUM.dec
// 2017-11-30 PerfektesChaos@de.wikipedia
var sign = Signature + "-grouping",
i, seek, $li, $ul;
NUM.$group.find( "." + sign ).removeClass( sign );
if ( typeof action === "object"
&& action &&
typeof action.data === "object"
&& action.data ) {
seek = action.data[ 0 ];
if ( typeof action.data[ 1 ] === "object" ) {
$li = action.data[ 1 ];
}
} else if ( typeof action === "string" ) {
seek = action;
$li = $at;
}
if ( seek ) {
NUM.seek = seek;
NUM.dec = false;
if ( ! $li ) {
$ul = NUM.$group.children( "li" );
for ( i = NUM.offer.length - 1; i >= 0; i-- ) {
$li = $ul.eq( i );
if ( NUM.offer[ i ] === NUM.seek ) {
break; // for i--
}
} // for i--
}
$li.addClass( Signature + "-grouping" );
}
}; // NUM.flip()
NUM.fore = function ( $all, $active, assign ) {
// Equip cell(s) with indicating box and display value, or clear
// Precondition:
// $all -- <table> or active cells / clear them all
// $active -- active cell
// assign -- text shown in active cell, or nil
// Postcondition:
// Returns $active content, if not assign
// Uses:
// > Signature
// 2020-08-27 PerfektesChaos@de.wikipedia
var sign = Signature + "-info",
r, $e;
if ( $active ) {
$e = $active.find( "." + sign );
if ( $e.length ) {
$e.show();
} else {
$e = $( "<div>" );
$e.addClass( sign );
$active.prepend( $e );
}
if ( assign ) {
$e.empty()
.text( assign );
} else {
r = $e.text();
}
} else {
$all.find( "." + sign ).hide().empty();
}
return r;
}; // NUM.fore()
NUM.foreign = function ( adjust, align ) {
// Translate non-ASCII digits etc.
// Precondition:
// adjust -- string with non-ASCII digits
// align -- local zero character code
// Postcondition:
// Returns name of character
// 2017-11-30 PerfektesChaos@de.wikipedia
var r = "",
m = align - 0x30,
n = align + 9,
i, k;
for ( i = 0; i < adjust.length; i++ ) {
k = adjust.charCodeAt( i );
if ( k >= align && k <= n ) {
k -= m;
} else if ( align === 0xFF10 &&
( k === 0xFF0E || k === 0xFF0C ) ) {
k -= 0xFEE0;
}
r = r + String.fromCharCode( k );
} // for i
return r;
}; // NUM.foreign()
NUM.formatting = function ( analyze ) {
// Guess project formatting from project query
// Precondition:
// analyze -- string with project number formatting 1234567.89
// Uses:
// >< NUM.reSeparator
// >< NUM.reSegment
// < NUM.sep
// NUM.find()
// NUM.flip()
// REPO.feed()
// 2020-08-21 PerfektesChaos@de.wikipedia
var got, s, start, struct;
if ( typeof NUM.reSeparator !== "object" ) {
NUM.reSeparator = new RegExp( "^(.+)67(.+)89$" );
}
got = NUM.reSeparator.exec( analyze );
if ( got ) {
start = got[ 1 ];
struct = NUM.find( got[ 2 ] );
if ( struct ) {
if ( typeof NUM.codes[ struct ] === "number" ) {
NUM.sep = String.fromCharCode( NUM.codes[ struct ] );
}
if ( typeof NUM.reSegment !== "object" ) {
NUM.reSegment = new RegExp( "[1-4]([^2-4&]+)[2-5]" );
}
got = NUM.reSegment.exec( start );
if ( got ) {
s = NUM.find( got[ 1 ] );
if ( s ) {
struct = struct + ";" + s;
}
}
NUM.flip( struct );
REPO.feed( "seek", struct );
}
}
}; // NUM.formatting()
NUM.forward = function ( $all, $actives, $about ) {
// Renumber cells
// Precondition:
// $all -- <table>
// $actives -- active cells
// $about -- <code> for result
// Uses:
// NUM.fore()
// TABLE.factory()
// 2020-08-27 PerfektesChaos@de.wikipedia
var n = $actives.length,
s = $about.parent().parent().data( "row" ),
i, m, row, table, $t;
$about.text( n );
if ( s ) {
table = TABLE.factory( $all );
row = table[ parseInt( s, 10 ) ];
m = 0;
for ( i = 0; i < row.length; i++ ) {
$t = row[ i ];
if ( $t && $t.is( $actives ) ) {
s = NUM.fore( false, $t );
if ( ! s ) {
m++;
NUM.fore( false, $t, m );
}
}
} // for i
} else {
for ( i = 0; i < n; i++ ) {
NUM.fore( false, $actives.eq( i ), i + 1 );
} // for i
}
}; // NUM.forward()
NUM.fraction = function ( $all, $actives, $about ) {
// Percentage of all figures
// Precondition:
// $all -- <table>
// $actives -- active cells
// $about -- <code> for result
// Uses:
// > Signature
// > NUM.min
// > NUM.sep
// NUM.full()
// NUM.fore()
// 2020-08-25 PerfektesChaos@de.wikipedia
var n = $actives.length,
i, k, less, lesser, m, q, total, $td;
if ( n ) {
total = NUM.full( $all, $actives, $about );
n = total[ 1 ];
}
if ( n ) {
total = total[ 0 ];
lesser = ( total < NUM.min);
if ( lesser ) {
if ( total > -1 * NUM.min ) {
total = false;
} else {
total = -1 * total;
}
}
if ( total ) {
q = 1 / total;
for ( i = 0; i < $actives.length; i++ ) {
$td = $actives.eq( i );
k = NUM.fetch( $td );
if ( typeof k === "number" ) {
less = ( k < 0 );
if ( less ) {
k = -1 * k;
}
k = Math.round( 10000 * k * q );
if ( k ) {
m = k % 100;
k = Math.floor( k * 0.01 );
if ( less !== lesser ) {
k = -1 * k;
}
if ( m ) {
k = k + NUM.sep;
if ( m < 10 ) {
k = k + "0";
}
k = k + m;
}
}
NUM.fore( false, $td, k + "%" );
}
} // for i
}
}
}; // NUM.fraction()
NUM.fruits = function ( $all, $actives, $about ) {
// Renumber cells
// Precondition:
// $all -- <table>
// $actives -- active cells
// $about -- <code> for result
// Uses:
// > Signature
// >< NUM.reWhite
// >< NUM.reSpaces
// NUM.fore()
// PAGE.fruit()
// 2020-08-21 PerfektesChaos@de.wikipedia
var send = "",
i, k, s, $t;
$about.empty();
if ( typeof NUM.reWhite !== "object" ) {
NUM.reWhite = new RegExp( "[\t\n\r]", "g" );
NUM.reSpaces = new RegExp( " +", "g" );
}
for ( i = 0; i < $actives.length; i++ ) {
$t = $actives.eq( i );
NUM.fore( $t );
s = $t.text();
k = s.indexOf( "[-][+]" );
if ( k >= 0 &&
k === s.length - 6 ) {
s = s.substr( 0, k );
}
s = s.replace( NUM.reWhite, " " )
.replace( NUM.reSpaces, " " );
if ( s === " " ) {
s = "";
}
if ( s.substr( 0, 1 ) === " " ) {
s = s.substr( 1 );
}
if ( s.substr( s.length - 1 ) === " " ) {
s = s.substr( 0, s.length - 1 );
}
send = send + ( send ? "\n" : "" ) + s;
} // for i
if ( send ) {
PAGE.fruit( send );
}
}; // NUM.fruits()
NUM.full = function ( $all, $actives, $about ) {
// Sum of all figures
// Precondition:
// $all -- <table>
// $actives -- active cells
// $about -- <code> for result
// Postcondition:
// Returns Array: [ 0 ] -- sum
// [ 1 ] -- number of summands
// Uses:
// >< NUM.reInteger
// NUM.fetch()
// 2020-08-27 PerfektesChaos@de.wikipedia
var n = $actives.length,
m = n,
v = 0,
got, i, k, $t;
if ( typeof NUM.reEntitiy !== "object" ) {
NUM.reInteger = new RegExp( "^-?[0-9]+$" );
NUM.re0000000 = new RegExp( "^(.*\\..*)00000000[1-9]$" );
NUM.re9999999 = new RegExp( "\\.(.*99999999)([1-9])$" );
}
for ( i = 0; i < n; i++ ) {
$t = $actives.eq( i );
k = NUM.fetch( $t );
if ( typeof k === "number" ) {
v += k;
} else {
TABLE.flipper( { data: [ $all, $t, false ] }, true );
m--;
}
} // for i
if ( v !== Math.floor( v ) ) {
k = "" + v;
got = NUM.re0000000.exec( k );
if ( got ) {
v = parseFloat( got[ 1 ] );
} else {
got = NUM.re9999999.exec( k );
if ( got ) {
k = "0.";
n = got[ 1 ].length;
for ( i = 0; i < n; i++ ) {
k = k + "0";
} // for i
k = k + ( 12 - parseInt( got[ 2 ], 10 ) );
v = v + parseFloat( k );
got = NUM.re0000000.exec( "" + v );
if ( got ) {
v = parseFloat( got[ 1 ] );
}
}
}
}
$about.text( v );
return [ v, m ];
}; // NUM.full()
NUM.furnish = function () {
// Initialize number formatting scheme
// Postcondition:
// Selection has been set on project default
// Uses:
// > NUM.codes
// < NUM.sep
// REPO.fetch()
// NUM.flip()
// API.formatnum ()
// 2020-08-21 PerfektesChaos@de.wikipedia
var s = REPO.fetch( "seek" ),
i;
if ( s ) {
NUM.flip( s );
i = s.indexOf( ";" );
if ( i > 0 ) {
s = s.substr( 0, i );
}
if ( typeof NUM.codes[ s ] === "number" ) {
NUM.sep = String.fromCharCode( NUM.codes[ s ] );
}
} else if ( mw ) {
API.formatnum();
}
}; // NUM.furnish()
PAGE.fire = function () {
// Start real processing, if not yet done
// Precondition:
// DOM ready
// Uses:
// > Signature
// > PAGE.support
// >< mw
// < PAGE.$box
// PAGE.first()
// 2020-08-07 PerfektesChaos@de.wikipedia
var $content;
if ( ! $( "#" + Signature ).length ) {
PAGE.$box = $( "<div>" );
PAGE.$box.attr( { id: Signature } );
$content = $( "#content" );
if ( ! $content.length ) {
$content = $( "body" );
}
$content.prepend( PAGE.$box );
if ( ! mw || typeof mw !== "object" ) {
mw = false;
}
PAGE.first();
if ( mw && typeof mw.hook === "function" ) {
mw.hook( Signature + ".ready" ).fire( PAGE.support );
}
}
}; // PAGE.fire()
PAGE.first = function () {
// Start processing by inserting box at top of page
// Uses:
// > mw
// > Signature
// > PAGE.support
// > PAGE.sign
// > PAGE.show
// > CSS.def
// > PAGE.$box
// > Version
// < PAGE.dir
// < PAGE.ltr
// < NUM.$group
// < PAGE.id
// < PAGE.details
// NUM.furnish()
// (REPO.format)
// (NUM.flip)
// 2020-08-22 PerfektesChaos@de.wikipedia
var def, i, s, side, sided, single, style,
$a, $icon, $li, $style, $survey, $tables, $text, $version;
if ( mw && mw.loader ) {
mw.loader.using( [ "mediawiki.storage" ],
REPO.format );
}
PAGE.dir = $( "html" ).attr( "dir" ) || "ltr";
PAGE.ltr = ( PAGE.dir === "ltr" );
side = ( PAGE.ltr ? "left" : "right" );
sided = ( PAGE.ltr ? "right" : "left" );
CSS.def.caption["text-align"] = side;
CSS.def.handle["float"] = side;
CSS.def.icon["margin-"+sided] = "1em";
CSS.def.info["float"] = side;
CSS.def.info["margin-"+sided] = "1em";
CSS.def.toggle["float"] = sided;
CSS.def.toggle["margin-"+side] = "1em";
CSS.def.version["margin-"+side] = "4em";
$style = $( "<style>" );
style = "";
for ( s in CSS.def ) {
def = CSS.def[ s ];
style = style + "." + Signature + "-" + s + "{\n";
for ( single in def ) {
style = style + single + ":" + def[ single ] + ";\n";
} // for single in def
style = style + "}\n";
} // for s in CSS.def
$( "head" ).after( $style.text( style ) );
$a = $( "<a>" );
$a.addClass( Signature + "-icon " + Signature + "-clickable" )
.attr( { href: PAGE.support,
target: "_blank" } )
.text( PAGE.sign );
$icon = $( "<div>" );
$icon.append( $a )
.addClass( Signature + "-cell" )
.attr( { "aria-hidden": "true" } );
PAGE.$box.addClass( Signature + "-box" );
PAGE.$box.append( $icon );
$text = $( "<div>" );
$a = $( "<a>" );
$a.addClass( Signature + "-doclink " + Signature + "-clickable" )
.attr( { href: PAGE.support,
target: "_blank" } )
.text( PAGE.show );
$text.append( $a );
$version = $( "<span>" );
$version.addClass( Signature + "-version" )
.text( Version );
$text.append( $version );
$tables = $( "table" ).not( ":hidden" );
if ( $tables.length ) {
PAGE.$details = $( "<ul>" );
PAGE.id = 0;
$tables.each( PAGE.furnish );
if ( PAGE.id ) {
PAGE.$details.addClass( Signature + "-ul" );
$survey = $( "<div>" );
$survey.addClass( Signature + "-cell" );
$survey.append( $text );
NUM.$group = $( "<ul>" );
NUM.$group.addClass( Signature + "-ul" );
for ( i = 0; i < NUM.offer.length; i++ ) {
s = NUM.offer[ i ];
$li = $( "<li>" );
$li.addClass( Signature + "-ul" )
.on( "click", [ s, $li ], NUM.flip )
.text( PAGE.flat( NUM.patterns[ s ] ) );
if ( i ) {
$li.prepend( $( "<wbr>" ) );
}
NUM.$group.append( $li );
if ( ! i ) {
NUM.flip( s, $li );
}
} // for i
NUM.furnish();
$survey.append( NUM.$group );
$survey.append( PAGE.$details );
PAGE.$box.append( $survey );
} else {
$text.addClass( Signature + "-cell" );
PAGE.$box.append( $text );
}
} else {
$text.addClass( Signature + "-cell" );
PAGE.$box.append( $text );
}
}; // PAGE.first()
PAGE.flat = function ( adjust ) {
// Replace entities by characters
// Precondition:
// adjust -- string expected
// Uses:
// > NUM.entities
// >< PAGE.reEntitiy
// < PAGE.reEntitiyX
// 2017-11-30 PerfektesChaos@de.wikipedia
var r = ( adjust || "ERROR" ),
fun10, fun16, s, seek, sign, shift;
if ( r.indexOf( "&#" ) >= 0 ) {
fun10 = function ( all, adapt ) {
return String.fromCharCode( parseInt( adapt, 10 ) );
};
fun16 = function ( all, adapt ) {
return String.fromCharCode( parseInt( adapt, 16 ) );
};
if ( typeof PAGE.reEntitiy !== "object" ) {
PAGE.reEntitiy = new RegExp( "&#([0-9]+);", "g" );
PAGE.reEntitiyX = new RegExp( "&#x([0-9A-F]+);", "gi" );
}
r = r.replace( PAGE.reEntitiy, fun10 );
if ( r.indexOf( "&#x" ) >= 0 ) {
r = r.replace( PAGE.reEntitiyX, fun16 );
}
}
if ( r.indexOf( "&" ) >= 0 ) {
for ( s in NUM.entities ) {
seek = "&" + s + ";";
if ( r.indexOf( seek ) >= 0 ) {
shift = NUM.entities[ s ];
sign = "re_" + s;
if ( typeof PAGE[ sign ] !== "object" ) {
PAGE[ sign ] = new RegExp( seek, "g" );
}
if ( shift ) {
shift = String.fromCharCode( shift );
} else {
shift = "";
}
r = r.replace( PAGE[ sign ], shift );
break; // for s in NUM.entities
}
} // for s in NUM.entities
}
return r;
}; // PAGE.flat()
PAGE.fruit = function ( assign ) {
// Make selected data available for copy&paste
// Precondition:
// assign -- string, to be copied to clipboard textarea
// Uses:
// > Signature
// > PAGE.$box
// >< PAGE.$textarea
// 2020-07-25 PerfektesChaos@de.wikipedia
if ( ! PAGE.$textarea ) {
PAGE.$textarea = $( "<textarea>" );
PAGE.$textarea.addClass( Signature + "-textarea" )
.attr( { id: Signature + "-copy",
readonly: "readonly",
rows: "5" } );
PAGE.$box.after( PAGE.$textarea );
}
PAGE.$textarea.val( assign );
}; // PAGE.fruit()
PAGE.furnish = function ( i, e ) {
// Initialize data table
// Precondition:
// i -- index number
// e -- DOM element
// Uses:
// > Signature
// > PAGE.sign
// > PAGE.details
// >< PAGE.id
// TABLE.fiat()
// (TABLE.furnish)
// 2020-08-21 PerfektesChaos@de.wikipedia
var $table = $( e ).eq( 0 ),
s, $a, $caption, $handle, $li;
if ( $table.find( "thead" ).length ||
$table.find( "th" ).length ) {
$a = $( "<a>" );
$li = $( "<li>" );
if ( PAGE.id ) {
$li.append( $( "<wbr>" ) );
}
++PAGE.id;
s = Signature + "-" + PAGE.id;
$a.attr( { href: "#" + s } )
.text( PAGE.id );
$li.append( $a );
PAGE.$details.append( $li );
TABLE.fiat( $table, PAGE.id );
$caption = $table.find( "caption" ).eq( 0 );
$handle = $( "<div>" );
if ( ! $caption.length ) {
$caption = $( "<caption>" );
$table.prepend( $caption );
}
$handle.addClass( Signature + "-handle" )
.attr( { id: s,
title: Signature } )
.text( PAGE.sign )
.on( "click", $table, TABLE.furnish );
$caption.addClass( Signature + "-caption" );
$caption.append( $handle );
}
return true;
}; // PAGE.furnish()
REPO.feed = function ( sign, val ) {
// Store value at sign
// Precondition:
// sign -- string, with group ID
// val -- any value
// Uses:
// >< REPO.o
// REPO.fetch()
// 2020-08-21 PerfektesChaos@de.wikipedia
var webSs;
if ( typeof REPO.o !== "object" ) {
REPO.fetch( "" );
}
REPO.o[ sign ] = val;
if ( typeof window.localStorage === "object" ) {
webSs = window.localStorage;
if ( webSs && typeof webSs.setItem === "function" ) {
try {
webSs.setItem( REPO.full(),
JSON.stringify( REPO.o ) );
} catch (e) {
}
}
}
}; // REPO.feed()
REPO.fetch = function ( sign ) {
// Retrieve value at sign
// Precondition:
// sign -- string, with group ID
// Uses:
// < REPO.o
// REPO.full()
// 2020-08-21 PerfektesChaos@de.wikipedia
var got, r, webSs;
if ( typeof REPO.o !== "object" &&
typeof window.localStorage === "object" ) {
webSs = window.localStorage;
if ( webSs && typeof webSs.getItem === "function" ) {
try {
got = JSON.parse( webSs.getItem( REPO.full() ) );
if ( typeof got === "object"
&& got ) {
REPO.o = got;
}
} catch (e) {
}
}
}
if ( typeof REPO.o !== "object" ) {
REPO.o = { };
}
if ( typeof REPO.o[ sign ] !== "undefined" ) {
r = REPO.o[ sign ];
}
return r;
}; // REPO.fetch()
REPO.first = function () {
// Initialize memory
// Uses:
// > Signature
// > JSON
// < BACKUP.repo
// mw.storage.get()
// 2020-01-05 PerfektesChaos@de.wikipedia
var stored;
if ( typeof REPO.repo === "undefined" &&
typeof mw === "object"
&& mw &&
typeof mw.storage === "object"
&& mw.storage &&
typeof mw.storage.get === "function" ) {
REPO.repo = false;
stored = mw.storage.get( Signature );
if ( stored ) {
try {
REPO.repo = JSON.parse( stored );
if ( typeof REPO.repo !== "object"
|| ! REPO.repo ) {
REPO.repo = false;
}
} catch( ex ) {
}
}
}
}; // REPO.first()
REPO.full = function () {
// Provide project selector
// Uses:
// > Signature
// >< REPO.sign
// mw.config.get()
// 2017-10-01 PerfektesChaos@de.wikipedia
if ( typeof REPO.sign !== "string" ) {
REPO.sign = Signature + "." + mw.config.get( "wgDBname" );
}
return REPO.sign;
}; // REPO.full()
TABLE.facilitate = function ( $all, $at ) {
// Cell equipping, if not yet done
// Precondition:
// $all -- <table>
// $at -- <td> / <th>
// Uses:
// > Signature
// (TABLE.flipper)
// 2017-11-30 PerfektesChaos@de.wikipedia
var s = "." + Signature,
$w = $at.find( s + "-exclude" );
if ( $w.length ) {
$w.show();
$at.find( s + "-include" ).hide();
} else {
$w = $( "<div>" );
$w.addClass( Signature + "-exclude " + Signature + "-toggle" )
.on( "click",
[ $all, $at, false ],
TABLE.flipper )
.text( "[-]" );
$at.append( $w );
$w = $( "<div>" );
$w.addClass( Signature + "-include " + Signature + "-toggle" )
.hide()
.on( "click",
[ $all, $at, true ],
TABLE.flipper )
.text( "[+]" );
$at.append( $w );
}
}; // TABLE.facilitate()
TABLE.factory = function ( $all ) {
// Retrieve completed regular mirror table
// Precondition:
// $all -- <table>
// assigned mirror table has been prepared
// .nC
// .nR
// .$rows
// .d
// Postcondition:
// Returns complete assigned mirror table
// Uses:
// >< TABLE.reInteger
// TABLE.fiat()
// 2020-08-25 PerfektesChaos@de.wikipedia
var r = TABLE.fiat( $all ),
e, i, j, k, m, n, s, tmp, ts, $row, $rows, $t;
if ( ! r.d ) {
if ( typeof TABLE.reInteger !== "object" ) {
TABLE.reInteger = new RegExp( "^[0-9]+$" );
}
$rows = r[ "$rows" ];
for ( i = 0; i < r.nR; i++ ) {
n = $rows.eq( i ).children().length - 1;
if ( n > r.nC ) {
r.nC = n;
}
} // for i
r.d = [ ];
tmp = [ ];
for ( i = 0; i < r.nR; i++ ) {
ts = [ ];
r.d.push( new Array( r.nC ) );
$row = $rows.eq( i ).children();
for ( k = 1; k < $row.length; k++ ) {
ts.push( $row.eq( k ) );
} // for k
tmp.push( ts );
} // for i
delete r[ "$rows" ];
do { // while $t
i = 0;
$t = false;
do { // while i < r.nR
ts = tmp[ i ];
if ( ts ) {
$t = ts[ 0 ];
if ( ts.length <= 1 ) {
tmp[ i ] = false;
} else {
tmp[ i ].splice( 0, 1 );
}
s = $t.attr( "colspan" );
if ( s && TABLE.reInteger.test( s ) ) {
j = ( parseInt( s, 10 ) || 1 );
} else {
j = 1;
}
s = $t.attr( "rowspan" );
if ( s && TABLE.reInteger.test( s ) ) {
n = ( parseInt( s, 10 ) || 1 );
} else {
n = 1;
}
n = Math.min( i + n, r.nR );
for ( ; i < n; i++ ) {
e = r.d[ i ];
m = 0;
do { // while m < r.nC
if ( ! e[ m ] ) {
k = Math.min( m + j, r.nC );
for ( ; m < k; m++ ) {
r.d[ i ][ m ] = $t;
} // for m
break; // while m < r.nC
}
m++;
} while ( m < r.nC );
} // for i
} else {
i++;
}
} while ( i < r.nR );
} while ( $t );
TABLE.fiat( $all, false, r );
}
return r.d;
}; // TABLE.factory()
TABLE.fiat = function ( $all, assign, apply ) {
// Create or assign regular mirror table
// Precondition:
// $all -- <table>
// assign -- number, with ID, to be assigned to $all
// apply -- regular mirror table to be stored
// Postcondition:
// Returns any assigned mirror table, if not assigning
// Uses:
// > Signature
// 2020-08-21 PerfektesChaos@de.wikipedia
var r;
if ( typeof assign === "number" ) {
$all.data( Signature, "" + assign );
} else {
r = $all.data( Signature );
if ( apply ) {
TABLE.t[ r ] = apply;
r = apply;
} else {
if ( typeof TABLE.t !== "object" ) {
TABLE.t = { };
}
if ( typeof TABLE.t[ r ] !== "object" ) {
TABLE.t[ r ] = { d: false };
}
r = TABLE.t[ r ];
}
}
return r;
}; // TABLE.fiat()
TABLE.flat = function ( $assembly ) {
// Normalize single row against colspan etc.
// Precondition:
// $assembly -- <tr>
// Postcondition:
// $assembly is split into single cells.
// Returns number of columns or rows
// Uses:
// > Signature
// >< TABLE.reInteger
// 2017-11-30 PerfektesChaos@de.wikipedia
var $row = $assembly.children(),
r = $row.length,
fine = function () {
if ( typeof TABLE.reInteger !== "object" ) {
TABLE.reInteger = new RegExp( "^[0-9]+$" );
}
},
i, m, s, $t;
for ( i = r - 1; i >= 0; i-- ) {
$t = $row.eq( i );
s = $t.attr( "rowspan" );
if ( s ) {
fine();
if ( TABLE.reInteger.test( s ) ) {
m = parseInt( s, 10 );
} else {
m = 0;
}
if ( m < 2 ) {
$t.attr( { rowspan: null } );
}
}
s = $t.attr( "colspan" );
if ( s ) {
fine();
if ( TABLE.reInteger.test( s ) ) {
m = parseInt( s, 10 );
if ( m > 1 ) {
r = r + m - 1;
}
} else {
m = 0;
}
if ( m < 2 ) {
$t.attr( { colspan: null } );
}
}
} // for i--
return r;
}; // TABLE.flat()
TABLE.flatten = function ( $all ) {
// Remove sortability etc.
// Precondition:
// $all -- <table>
// Postcondition:
// Sortability removed
// 2020-08-28 PerfektesChaos@de.wikipedia
var $clickable;
if ( $all.hasClass( "sortable" ) ) {
$all.removeClass( "sortable jquery-tablesorter" );
$clickable = $all.children( "thead" ).find( "th" );
$clickable.off( "click" )
.off( "keypress" )
.off( "mousedown" );
}
$all.removeClass( "mw-datatable" );
}; // TABLE.flatten()
TABLE.flip = function ( action ) {
// Widget usage
// Precondition:
// action -- event data
// .data
// [0] -- <table>
// [1] -- true: horizontal, false: column
// [2] -- number of row or column
// [3] -- activity code
// Postcondition:
// Performed.
// Uses:
// > Signature
// > NUM.call
// NUM.fore()
// TABLE.focus()
// NUM.first()
// 2020-08-27 PerfektesChaos@de.wikipedia
var k, line, query, s, s1, s2,
$active, $table, $tbody, $td, $thead, $tr;
if ( typeof action === "object"
&& action &&
typeof action.data === "object"
&& action.data ) {
s = "." + Signature;
$table = action.data[ 0 ];
line = action.data[ 1 ];
k = action.data[ 2 ];
query = action.data[ 3 ];
$tbody = $table.find( "tbody" );
if ( line ) {
$tr = $tbody.children( "tr" ).eq( k );
$tr = $tr.children();
$td = $tr.eq( 0 );
} else {
$thead = $table.find( "thead" );
$tr = $thead.children( "tr" ).eq( 0 );
$td = $tr.children( "td" ).eq( k );
}
$table.find( s + "-result" ).remove();
NUM.fore( $tbody );
s1 = Signature + "-chosen";
$table.find( "." + s1 ).removeClass( s1 );
if ( typeof query === "boolean" ) {
s1 = Signature + "-active";
$active = $tbody.find( "." + s1 );
$active.removeClass( s1 );
$tbody.find( s + "-exclude" ).hide();
$tbody.find( s + "-include" ).hide();
s1 = s + "-menu";
s2 = s + "-widget";
$table.find( s1 ).hide();
$table.find( s2 ).css( { visibility: "visible" } );
$active = $table.find( s + "-quit" ).children();
if ( query ) {
$td.find( s2 ).css( { visibility: "hidden" } );
$td.find( s1 ).show();
TABLE.focus( $table, $tbody, line, k );
$active.show();
} else {
$active.hide();
}
} else {
$td.find( "." + Signature + "-" + NUM.call[ query ] )
.addClass( s1 );
$active = $( "<div>" );
$active.addClass( Signature + "-result" )
.data( "query", query )
.append( $( "<code>" ) );
$td.append( $active );
NUM.first( $table, query, $active );
}
}
}; // TABLE.flip()
TABLE.flipper = function ( action, abort ) {
// Cell toggle
// Precondition:
// action -- event data
// .data
// [0] -- <table>
// [1] -- <td> / <th>
// [2] -- true: +, false: -
// abort -- true: no propagation to result
// Postcondition:
// Toggled.
// Uses:
// > Signature
// NUM.fore()
// NUM.fire()
// 2020-08-21 PerfektesChaos@de.wikipedia
var less, s, sub, $ex, $in, $t, $table;
if ( typeof action === "object"
&& action &&
typeof action.data === "object"
&& action.data ) {
$table = action.data[ 0 ];
$t = action.data[ 1 ];
less = action.data[ 2 ];
s = "." + Signature;
sub = Signature + "-active";
$ex = $t.find( s + "-exclude" );
$in = $t.find( s + "-include" );
if ( less ) {
$t.addClass( sub );
$in.hide();
$ex.show();
} else {
$t.removeClass( sub );
$ex.hide();
$in.show();
NUM.fore( $t );
}
if ( ! abort ) {
NUM.fire( $table );
}
}
}; // TABLE.flipper()
TABLE.focus = function ( $all, $area, align, at ) {
// Prepare single table for expansion
// Precondition:
// $all -- <table>
// $area -- <tbody>
// align -- true: horizontal, false: column
// at -- number of row or column
// Postcondition:
// Uses:
// > Signature
// TABLE.factory()
// TABLE.facilitate()
// 2020-08-27 PerfektesChaos@de.wikipedia
var s = Signature + "-active",
table = TABLE.factory( $all ),
i, k, row, $cells, $t;
if ( align ) {
row = table[ at ];
for ( i = 0; i < row.length; i++ ) {
$t = row[ i ];
if ( $t ) {
$t.addClass( s );
}
} // for k
} else {
k = at - 1;
for ( i = 0; i < table.length; i++ ) {
$t = table[ i ][ k ];
if ( $t ) {
$t.addClass( s );
}
} // for i
}
$cells = $area.find( "." + s );
for ( k = 0; k < $cells.length; k++ ) {
TABLE.facilitate( $all, $cells.eq( k ) );
} // for k
}; // TABLE.focus()
TABLE.$fold = function ( $all, align, at ) {
// Create control header cell
// Precondition:
// $all -- <table>
// align -- true: horizontal, false: column
// at -- number of row or column
// Postcondition:
// Returns <td>
// Uses:
// > Signature
// > NUM.starts
// > NUM.call
// > PAGE.sign
// (TABLE.flip)
// 2020-08-27 PerfektesChaos@de.wikipedia
var $r = $( "<td>" ),
$widget = $( "<div>" ),
$menu = $( "<div>" ),
$space = $( "<span>" ).text( " " ),
i, s, $e;
$menu.addClass( Signature + "-menu" )
.hide();
for ( i = 0; i < NUM.starts.length; i++ ) {
s = NUM.starts.substr( i, 1 );
$e = $( "<span>" );
$e.addClass( Signature + "-" + NUM.call[ s ] )
.on( "click",
[ $all, align, at, s ],
TABLE.flip );
if ( s === "?" ) {
s = ( align ? "h" : "v" );
}
$e.text( TABLE.title[ s ] );
$menu.append( $e )
.append( $space.clone() );
} // for i
if ( align ) {
$r.data( "row", "" + at );
}
$widget.addClass( Signature + "-widget" )
.on( "click",
[ $all, align, at, true ],
TABLE.flip )
.text( PAGE.sign );
$r.append( $widget )
.append( $menu )
.addClass( Signature + "-td" );
return $r;
}; // TABLE.$fold()
TABLE.furnish = function ( action ) {
// Prepare single table for expansion
// Precondition:
// action -- event data
// .target
// Uses:
// > Signature
// > PAGE.$details
// TABLE.flatten()
// TABLE.fiat()
// TABLE.$fold()
// 2023-04-19 PerfektesChaos@de.wikipedia
var e, i, k, n, sign, table, $caption, $handle,
$rows, $table, $tbody, $td, $tfoot, $thead, $tr, $x;
if ( typeof action === "object"
&& action &&
typeof action.target === "object"
&& action.target ) {
$handle = $( action.target );
sign = $handle.attr( "id" );
$caption = $handle.parent();
$table = $caption.parent();
$handle.remove();
}
if ( $table ) {
TABLE.flatten( $table );
$thead = $table.find( "thead" );
if ( ! $thead.length ) {
$thead = $( "<thead>" );
$rows = $table.find( "tr" );
for ( i = 0; i < $rows.length; i++ ) {
$tr = $rows.eq( i );
$x = $tr.children();
for ( k = 0; k < $x.length; k++ ) {
e = $x.eq( k ).get( 0 );
if ( e.tagName.toUpperCase() !== "TH" ) {
$tr = false;
break; // for k
}
} // for k
if ( $tr ) {
$tr.detach();
$thead.append( $tr );
} else {
break; // for i
}
} // for i
$caption.after( $thead );
}
$tfoot = $table.find( "tfoot" );
if ( $tfoot.length ) {
$rows = $tfoot.find( "tr" );
$td = $( "<td>" );
$td.addClass( Signature + "-active" );
if ( $rows.length > 1 ) {
$td.attr( { rowspan: $rows.length } );
}
$rows.eq( 0 ).prepend( $td );
}
$tbody = $table.find( "tbody" );
if ( ! $tbody.length ) {
$tbody = $( "<tbody>" );
$rows = $table.children( "tr" );
for ( i = 0; i < $rows.length; i++ ) {
$tr = $rows.eq( i );
$tr.detach();
$tbody.append( $tr );
} // for i
$thead.after( $tbody );
}
$rows = $tbody.children();
n = $rows.length;
if ( n ) {
table = TABLE.fiat( $table );
table[ "$rows" ] = $rows;
table.nR = n;
$rows = $thead.children();
k = TABLE.flat( $rows.eq( 0 ) );
table.nC = k;
k++;
$td = $( "<td>" );
$x = $( "<span>" );
$x.hide()
.on( "click",
[ $table, true, 0, false ],
TABLE.flip )
.text( TABLE.title.X );
$td.addClass( Signature + "-active " + Signature + "-quit" )
.attr( { id: sign,
rowspan: $rows.length + 1 } )
.append( $x );
$tr = $( "<tr>" );
$tr.append( $td );
for ( i = 1; i < k; i++ ) {
$tr.append( TABLE.$fold( $table, false, i ) );
} // for i
$thead.prepend( $tr );
for ( i = 0; i < n; i++ ) {
$tr = table[ "$rows" ].eq( i );
$tr.prepend( TABLE.$fold( $table, true, i ) );
} // for i
} else {
PAGE.$details.find( "a[href$=\"#" + sign + "\"]" )
.parent()
.remove();
}
}
}; // TABLE.furnish()
fire();
}( window.mediaWiki, window.jQuery ) );
// Emacs
// Local Variables:
// coding: utf-8-unix
// fill-column: 80
// End:
/// EOF </nowiki> tableXpander.js