/// User:PerfektesChaos/js/browserStorageManager/d.js
/// 2020-12-10 PerfektesChaos@de.wikipedia
// Show and manipulate web storage and cookies.
// ResourceLoader: compatible;
// dependencies:
// user, user.options, mediawiki.user, mediawiki.util
/// Fingerprint: #0#0#
/// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA)
/// <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 vsn = -2.3,
BSM = "browserStorageManager",
Max = 100,
Bag = [ "localStorage", "sessionStorage", "cookies" ];
// Requires: JavaScript 1.4 ("in")
// ECMA 262-3 § 11.8.5 (string comparison operators)
// ///////////////////////////////////////////////////////////////////
function bb_mw() {
// Build functions for mediawiki environment, and execute
// Precondition:
// Uses:
// > Bag
// > Max
// >< BSM
// < domfuns
// 2014-01-11
var config, domfuns, gui, lang, mod, prego,
Key = 80;
if ( typeof mw.libs[ BSM ] !== "object"
|| ! mw.libs[ BSM ] ) {
mw.libs[ BSM ] = { };
}
mw.libs[ BSM ].type = BSM;
BSM = mw.libs[ BSM ];
if ( BSM.vsn ) {
return;
}
BSM.vsn = vsn;
config = { support: "User:PerfektesChaos/js/" + BSM.type };
gui = { };
lang = { };
mod = { };
BSM.doc = "[[w:en:" + config.support + "]]";
domfuns = [ "key", "length",
"clear", "getItem", "setItem", "removeItem" ];
lang.texts = {
// 2014-01-04 PerfektesChaos@de.wikipedia
"#bytes": {"en": "bytes",
"de": "Bytes"},
"#chars": {"en": "chars",
"de": "Zeichen"},
"#content": {"en": "content...",
"de": "Inhalt..."},
"#id": {"en": "ID",
"de": "ID"},
"!abort": {"en": "abort",
"de": "Abbruch"},
"!delete": {"en": "delete entry",
"de": "Eintrag löschen"},
"!edit": {"en": "Modify text",
"de": "Text bearbeiten"},
"!fresh": {"en": "refresh table",
"de": "Tabelle aktualisieren"},
"!new": {"en": "new entry",
"de": "Neuer Eintrag"},
"!save": {"en": "save new text",
"de": "Text speichern"},
"^show": {"en": "Browser-Storage-Manager",
"de": "Browser-Storage-Manager"},
"^suffix": {"en": "– Show and manipulate"
+ " web/DOM storage and cookies.",
"de": "– Zeige und bearbeite"
+ " Web/DOM Storage und Cookies."},
"^^key": {"en": "Text height (default: "
+ Key + " %)",
"de": "Schriftgröße (Vorgabe: "
+ Key + " %)"},
"^^max": {"en": "Text length limit (default: "
+ Max + ")",
"de": "Maximale Textlänge (Vorgabe: "
+ Max + ")"},
"^^portlet": {"en": "Create portlet link",
"de": "Portlet-Link einfügen"}
}; // lang.texts
lang.user = {
"de" : "de",
"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"
}; // lang.user 2012-12-19 PerfektesChaos@de.wikipedia
function fire() {
// Complete initialization after code loading
// Uses:
// > config.signature
// > config.rLoader
// < config.link
// < gui.ltr
// config.fetch()
// config.form()
// mw.loader.state()
// Remark: May be used as event handler -- 'this' not accessed
// 2020-12-10 PerfektesChaos@de.wikipedia
config.fetch();
if ( mw.config.get( "wgCanonicalSpecialPageName" )
=== "Blankpage" ) {
if ( prego ) {
config.form();
}
} else {
config.link = true;
}
gui.ltr = ( $( "html" ).attr( "dir" ) !== "rtl" );
if ( typeof config.rLoader !== "object"
|| ! config.rLoader ) {
config.rLoader = { };
}
config.rLoader[ config.signature ] = "ready";
mw.loader.state( config.rLoader );
} // fire()
function first() {
// Start actions on current page
// Uses:
// > .key
// config.fence()
// config.font()
// config.fire()
// mw.loader.using()
// (config.firing)
// 2015-09-29 PerfektesChaos@de.wikipedia
var key = false;
if ( typeof BSM.key === "number" ) {
key = BSM.key;
}
config.fence();
config.font( key );
config.fire();
mw.loader.using( [ "user",
"user.options",
"mediawiki.user",
"mediawiki.util" ],
config.firing );
} // first()
config.favorite = function () {
// Detect support page in user language
// Uses:
// this
// > lang.slang
// > config.support
// lang.favorite()
// 2013-12-14 PerfektesChaos@de.wikipedia
var r;
lang.favorite();
switch ( lang.slang ) {
case "de" :
r = "de.wikipedia.org";
break;
default:
r = "en.wikipedia.org";
} // switch .slang
return "//" + r + "/wiki/" + this.support;
}; // config.favorite()
config.fence = function ( apply ) {
// Retrieve or check and memorize default text length
// Precondition:
// apply -- number with text length, to be stored, or nil
// Postcondition:
// Returns valid number
// Uses:
// this
// > .max
// > Max
// >< config.max
// 2013-12-17 PerfektesChaos@de.wikipedia
var n;
if ( typeof config.max !== "number" ) {
if ( typeof BSM.max === "number" ) {
if ( BSM.max >= 10 && BSM.max <= 1024 ) {
config.max = BSM.max;
}
}
if ( typeof config.max !== "number" ) {
config.max = Max;
}
}
if ( apply ) {
switch ( typeof apply ) {
case "number" :
n = apply;
break;
case "string" :
n = parseInt( apply, 10 );
break;
default:
n = false;
} // switch typeof apply
if ( n ) {
if ( n >= 10 && n <= 1024 ) {
config.max = n;
}
}
}
return config.max;
}; // config.fence()
config.fetch = function () {
// Retrieve preferences and overwrite presets
// Uses:
// this
// > config.supply
// > .type
// < prego
// < gui.$link
// config.fence()
// config.font()
// gui.facility()
// mw.libs.preferencesGadgetOptions.fetch()
// 2014-01-02 PerfektesChaos@de.wikipedia
var link, vals;
if ( typeof BSM.portlet === "boolean" ) {
link = BSM.portlet;
} else {
link = true;
}
if ( mw.user.isAnon() ) {
prego = false;
} else {
prego = mw.libs[ this.supply ];
}
if ( prego ) {
vals = prego.fetch( BSM.type );
if ( vals && typeof vals === "object" ) {
config.fence( vals.max );
config.font( vals.key );
if ( typeof vals.portlet === "boolean" ) {
link = vals.portlet;
}
}
}
if ( link ) {
gui.$link = true;
gui.facility( true );
}
}; // config.fetch()
config.filled = function ( assigned ) {
// New preferences have been sent to server
// Precondition:
// assigned -- object with final form data, to be stored
// Uses:
// config.fence()
// gui.facility()
// Remark: May be used as event handler -- 'this' not accessed
// 2013-12-17 PerfektesChaos@de.wikipedia
if ( typeof assigned === "object" && assigned ) {
config.fence( assigned.max );
gui.facility( assigned.portlet );
}
}; // config.filled()
config.fire = function () {
// Prepare ResourceLoader availability
// Postcondition:
// loader.load requested, if not yet defined
// Uses:
// this
// < config.supply
// < config.signature
// < config.rLoader
// mw.loader.getState()
// mw.loader.state()
// mw.loader.load()
// 2020-12-10 PerfektesChaos@de.wikipedia
config.supply = "preferencesGadgetOptions";
config.signature = "ext.gadget." + config.supply;
if ( ! mw.loader.getState( config.signature ) ) {
config.rLoader = { };
config.rLoader[ config.signature ] = "loading";
mw.loader.state( config.rLoader );
mw.loader.load( "https://en.wikipedia.org"
+ "/w/index.php?title="
+ "User:PerfektesChaos/js/"
+ config.supply
+ "/r.js"
+ "&action=raw&bcache=1&maxage=604806"
+ "&ctype=text/javascript",
"text/javascript" );
}
}; // config.fire()
config.firing = function () {
// Intermediate loading process step
// Precondition:
// MW ressources are available
// Uses:
// > config.supply
// mw.hook()
// (fire)
// Remark: Used as event handler -- 'this' is not config
// 2015-09-29 PerfektesChaos@de.wikipedia
mw.hook( config.supply + ".ready" ).add( fire );
}; // config.firing()
config.font = function ( apply ) {
// Retrieve or check and memorize font size
// Precondition:
// apply -- number with font size, to be stored, or nil
// Postcondition:
// Returns valid number
// Uses:
// this
// > Key
// >< config.key
// 2013-12-17 PerfektesChaos@de.wikipedia
var n;
if ( typeof config.key !== "number" ) {
config.key = Key;
}
if ( apply ) {
switch ( typeof apply ) {
case "number" :
n = apply;
break;
case "string" :
n = parseInt( apply, 10 );
break;
default:
n = false;
} // switch typeof apply
if ( n ) {
if ( n >= 65 && n <= 100 ) {
config.key = n;
}
}
}
return config.key;
}; // config.font()
config.form = function () {
// Equip Special:Blankpage page with entry and form
// Uses:
// > .type
// > lang.slang
// > lang.texts
// > .max
// > gui.$link
// lang.favorite()
// config.favorite()
// prego.form()
// (.config.filled)
// mw.libs.preferencesGadgetOptions.form()
// 2013-12-14 PerfektesChaos@de.wikipedia
var dialog,
sl,
text = lang.texts;
lang.favorite();
sl = lang.slang;
dialog = { script: BSM.type,
show: text[ "^show" ][ sl ],
support: this.favorite(),
suffix: text[ "^suffix" ][ sl ],
filled: this.filled,
opts: [ { signature: "max",
type: "text",
show: text[ "^^max" ][ sl ],
val: config.fence()
},
{ signature: "portlet",
type: "checkbox",
show: text[ "^^portlet" ][ sl ],
val: ( gui.$link ? true
: false )
},
{ signature: "key",
type: "text",
show: text[ "^^key" ][ sl ],
val: config.font()
}
] };
prego.form( dialog );
}; // config.form()
gui.facility = function ( add ) {
// Remove previous portlet link, and create new one
// Precondition:
// add -- create new portlet link
// Uses:
// this
// >< gui.$link
// gui.factory()
// 2013-12-17 PerfektesChaos@de.wikipedia
if ( typeof this.$link === "object" ) {
this.$link.hide();
this.$link = false;
}
if ( add ) {
$( this.factory );
}
}; // gui.facility()
gui.factory = function () {
// Insert portlet link
// Uses:
// > lang.slang
// > lang.texts
// > .portlet
// -- object with portlet requirements
// .scope -- container id
// .show -- label
// .shortcut -- access key
// .stick -- id to sort before in container
// > .type
// > .vsn
// < gui.$link
// lang.favorite()
// jQuery.trim()
// gui.facility()
// mw.util.addPortletLink()
// (gui.fiat)
// Remark: May be used as event handler -- 'this' not accessed
// 2013-12-17 PerfektesChaos@de.wikipedia
var dom,
s,
show,
signal,
scope = "p-tb",
shortcut = null,
stick = null;
lang.favorite();
show = lang.texts[ "^show" ][ lang.slang ];
if ( typeof BSM.portlet === "object" && BSM.portlet ) {
s = BSM.portlet.scope;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
scope = s;
}
}
s = BSM.portlet.shortcut;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
shortcut = s;
}
}
s = BSM.portlet.show;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
show = s;
}
}
s = BSM.portlet.stick;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
stick = s;
}
}
}
signal = show + "\n"
+ BSM.type + " " + BSM.vsn;
dom = mw.util.addPortletLink( scope,
"#",
show,
"t-" + BSM.type,
signal,
shortcut,
stick );
gui.$link = $( dom ).find ( "a" );
gui.$link.click( gui.fiat );
}; // gui.factory()
gui.fiat = function () {
// Equip current page with tables
// Precondition:
// document ready
// Uses:
// > Bag
// > .type
// > config.key
// > config.link
// > prego
// >< gui.$wrapper
// < gui.$table
// < mod.makes
// gui.fresh()
// lang.favorite()
// prego.$button()
// gui.folder()
// jQuery.tablesorter()
// gui.facility()
// (gui.features)
// Remark: May be used as event handler -- 'this' not accessed
// 2014-01-29 PerfektesChaos@de.wikipedia
var i, $btn, selector;
if ( gui.$wrapper ) {
for ( i = 0; i < 3; i++ ) {
gui.fresh( Bag[ i ] );
} // for i
} else {
selector = "#" + BSM.type;
lang.favorite();
gui.$wrapper = $( "<div />" );
gui.$wrapper.attr( "id", selector );
gui.$wrapper.css( { "border": "solid 2px #006400",
"font-size": config.key + "%",
"margin-bottom": "2em",
"padding": "1em"
} );
if ( config.link && prego ) {
$btn = prego.$button( BSM.type );
$btn.css( { "float" : "right",
"vertical-align": "top" } );
gui.$wrapper.prepend( $btn );
}
gui.$table = { };
mod.makes = { };
for ( i = 0; i < 3; i++ ) {
gui.folder( Bag[ i ] );
} // for i
$( "#firstHeading" ).before( gui.$wrapper );
mw.loader.using( [ "jquery.tablesorter" ],
function () {
for ( i = 0; i < 3; i++ ) {
gui.$table[ Bag[ i ] ].tablesorter();
} // for i
} );
gui.facility( false );
}
}; // gui.fiat()
gui.folder = function ( about ) {
// Create initial table
// Uses:
// > gui.$wrapper
// > lang.slang
// > lang.texts
// >< gui.$table
// gui.furnish()
// gui.fresh()
// (mod.flip)
// (gui.fresh)
// 2013-12-17 PerfektesChaos@de.wikipedia
var s = ( about === "cookies" ? "#bytes"
: "#chars" ),
$btn,
$caption = $( "<caption />" ),
$span = $( "<span />" ),
$table = $( "<table />" ),
$tbody = $( "<tbody />" ),
$td = $( "<td />" ),
$tfoot = $( "<tfoot />" ),
$th = $( "<th />" ),
$thead = $( "<thead />" ),
$tr = $( "<tr />" ),
$tf1 = $td.clone(),
$tf2 = $th.clone(),
$tf3 = $td.clone(),
$th1 = $th.clone(),
$th2 = $th.clone(),
$th3 = $th.clone(),
$trf = $tr.clone(),
$trh = $tr.clone();
$table.attr( "class", "wikitable sortable" );
$caption.text( about );
$table.append( $caption );
$th1.text( lang.texts[ "#id" ][ lang.slang ] );
$th2.text( lang.texts[ s ][ lang.slang ] );
$th3.append( $span.clone() );
$trh.append( $th1 );
$trh.append( $th2 );
$trh.append( $th3 );
$thead.append( $trh );
$table.append( $thead );
$table.append( $tbody );
$btn = gui.furnish( "$btnNew" );
$btn.click( function () { mod.flip( about, -1, true ); } );
$tf1.append( $btn );
$tf2.css( { "font-family": "monospace",
"text-align": "right" } );
$tf2.append( $span );
$btn = gui.furnish( "$btnRefresh" );
$btn.click( function () { gui.fresh( about ); } );
$tf3.append( $btn );
$trf.append( $tf1 );
$trf.append( $tf2 );
$trf.append( $tf3 );
$tfoot.append( $trf );
$table.append( $tfoot );
gui.$wrapper.append( $table );
gui.$table[ about ] = $table;
gui.fresh( about );
}; // gui.folder()
gui.fresh = function ( about ) {
// Refill table body
// Precondition:
// about -- 1 of "localStorage", "sessionStorage", "cookies"
// Postcondition:
// Returns Array with sorted assignments, or false
// Uses:
// > config.max
// > lang.slang
// > lang.texts
// > gui.$table
// > domfuns
// fresh()
// jQuery.inArray()
// gui.furnish()
// (gui.fresh_1)
// (gui.fresh_2)
// 2014-01-20 PerfektesChaos@de.wikipedia
var el, i, m, n, $btn, $td1d, $td2d, $td3d, $trd, $txt,
light = ( about === "cookies" ),
r = fresh( about, config.max ),
s = lang.texts[ "#content" ][ lang.slang ]
+ " (" + config.max + ")",
$span = $( "<span />" ),
$table = gui.$table[ about ],
$tbody = $table.children( "tbody" ),
$tfoot = $table.children( "tfoot" ),
$thead = $table.children( "thead" ),
$td = $( "<td />" ),
$tr = $( "<tr />" ),
$td1 = $td.clone(),
$td2 = $td.clone(),
$td3 = $td.clone();
$tbody.empty();
$td1.css( { "font-family": "monospace" } );
$td2.css( { "font-family": "monospace",
"text-align": "right" } );
if ( r ) {
m = 0;
n = r.length;
for ( i = 0; i < n; i++ ) {
el = r[ i ];
if ( light ||
$.inArray( el.id, domfuns ) < 0 ) {
$td1d = $td1.clone();
$td2d = $td2.clone();
$td3d = $td3.clone();
$td1d.text( el.id );
$btn = gui.furnish( "$btnDelete" );
$btn.on( "click",
{ about: about,
id: el.id },
gui.fresh_1 );
$td1d.append( $btn );
$td2d.text( el.n );
if ( el.n <= config.max ) {
$txt = $span.clone();
$txt.text( el.v );
$td3d.append( $txt );
$btn = gui.furnish( "$btnEdit" );
$btn.on( "click",
{ about: about,
item: i,
id: el.id,
val: el.v },
gui.fresh_2 );
$td3d.append( $btn );
} else {
$td3d.text( el.v );
}
$trd = $tr.clone();
$trd.append( $td1d );
$trd.append( $td2d );
$trd.append( $td3d );
$tbody.append( $trd );
m += el.n;
}
} // for i
} else {
m = "";
}
$tr = $thead.children( "tr" );
$txt = $tr.children( "th" ).eq( 2 ).children( "span" );
$txt.text( s );
$tr = $tfoot.children( "tr" );
$tr.children( "td" ).children( "*" ).toggle( true );
$txt = $tr.children( "th" ).children( "span" );
$txt.text( m );
mod.makes[ about ] = 0;
return r;
}; // gui.fresh()
gui.fresh_1 = function ( event ) {
// [delete] button has been clicked.
// Precondition:
// event
// Uses:
// mod.flush()
// 2013-12-17 PerfektesChaos@de.wikipedia
mod.flush( event.data.about, event.data.id );
}; // gui.fresh_1()
gui.fresh_2 = function ( event ) {
// [edit] button has been clicked.
// Precondition:
// event
// Uses:
// mod.flip()
// 2013-12-17 PerfektesChaos@de.wikipedia
mod.flip( event.data.about,
event.data.item,
true,
event.data.id,
event.data.val );
}; // gui.fresh_2()
gui.furnish = function ( acquire ) {
// Generate GUI elements.
// Precondition:
// acquire -- request
// "$btnAbort",
// "$btnDelete",
// "$btnEdit",
// "$btnNew",
// "$btnRefresh",
// "$btnStore" -- button
// Uses:
// this
// > gui.ltr
// > .type
// > lang.slang
// lang.favorite()
// 2013-12-17 PerfektesChaos@de.wikipedia
var show, $e, $v;
if ( ! this[ acquire ] ) {
lang.favorite();
$e = $( "<button>" );
$e.attr( "type", "button" );
switch ( acquire ) {
case "$btnAbort" :
$e.css( { "color": "#FF0000",
"font-weight": "bolder",
"float": ( this.ltr ? "right"
: "left" )
} );
$e.attr( "class", BSM.type + "-tmp" );
$v = $( "<span />" );
$v.text( "X" );
show = "!abort";
break;
case "$btnDelete" :
$e.css( { "color": "#FF0000",
"font-family": "sans-serif",
"font-weight": "bolder",
"float": ( this.ltr ? "right"
: "left" )
} );
$e.css( ( this.ltr ? "margin-left" : "margin-right" ),
"1em" );
$v = $( "<span />" );
$v.text( String.fromCharCode( 8722 ) );
show = "!delete";
break;
case "$btnEdit" :
$e.css( { "color": "#00A000",
"font-weight": "bolder",
"float": ( this.ltr ? "right"
: "left" )
} );
$e.css( ( this.ltr ? "margin-left" : "margin-right" ),
"1em" );
$v = $( "<span />" );
$v.text( String.fromCharCode( 8660 ) );
show = "!edit";
break;
case "$btnNew" :
$e.css( { "color": "#00A000",
"font-size": "150%",
"font-weight": "bolder"
} );
$v = $( "<span />" );
$v.text( "+" );
show = "!new";
break;
case "$btnRefresh" :
$e.css( { "color": "#00A000",
"font-size": "150%",
"font-weight": "bolder",
"float": ( this.ltr ? "left"
: "right" )
} );
$v = $( "<span />" );
$v.text( "*" );
show = "!fresh";
break;
case "$btnSave" :
$e.css( { "color": "#00A000",
"font-weight": "bolder",
"float": ( this.ltr ? "right"
: "left" )
} );
$e.attr( "class", BSM.type + "-tmp" );
$v = $( "<span />" );
$v.text( "+" );
show = "!save";
break;
} // switch acquire
$e.attr( "title", lang.texts[ show ][ lang.slang ] );
$e.append( $v );
this[ acquire ] = $e;
}
return this[ acquire ].clone();
}; // gui.furnish()
lang.favorite = function () {
// Guess user language
// Uses:
// this
// > lang.user
// >< lang.slang
// mw.config.get()
// 2012-12-19 PerfektesChaos@de.wikipedia
var s;
if ( ! this.slang ) {
s = mw.config.get( "wgUserLanguage" ).toLowerCase();
if ( s.length > 4 ) { // Remove RFC 1766 subtag from code
if ( s.charCodeAt( 2 ) === 45 ) { // '-'
s = s.substr( 0, 2 );
}
}
s = this.user[ s ];
this.slang = ( s ? s : "en" );
}
}; // lang.favorite()
mod.flip = function ( about, access, active, assign, alter ) {
// [edit] or [new] button has been clicked; or saved/canceled.
// Precondition:
// about -- 1 of "localStorage","sessionStorage","cookies"
// access -- number of item; -1 for new
// active -- true: edit; false: saved/canceled, restore
// assign -- identifier
// alter -- text to be changed, if any
// Uses:
// > config.max
// > .type
// >< mod.makes
// gui.furnish()
// (mod.flip)
// (mod.forward)
// 2013-12-29 PerfektesChaos@de.wikipedia
var start,
$btnAbort, $btnSave, $eternity, $input, $lbl, $tbody, $td,
$table = gui.$table[ about ],
$tfoot = $table.children( "tfoot" ),
$tr = $tfoot.children( "tr" ).children( "td" ),
$new = $tr.eq( 0 ).children( "button" ),
learn = ( access < 0 ),
light = ( about === "cookies" ),
slip = BSM.type + "-tmp";
if ( learn ) {
$td = $tr.eq( 1 );
$td.children( "button" ).toggle( ! active );
$td = $tr.eq( 0 );
start = "";
} else {
$tbody = $table.children( "tbody" );
$tr = $tbody.children( "tr" ).eq( access );
$td = $tr.children( "td" ).eq( 2 );
$td.children( "*" ).toggle( ! active );
start = $td.children( "span" ).text();
}
if ( active ) {
mod.makes[ about ] = mod.makes[ about ] + 1;
$input = $( "<input />" );
$input.attr( { size: Math.ceil( config.max / 2 ),
type: "text" } );
$input.val( start );
$td.append( $input );
$btnAbort = gui.furnish( "$btnAbort" );
$btnAbort.click( function () {
mod.flip( about, access, false );
} );
$td.append( $btnAbort );
$btnSave = gui.furnish( "$btnSave" );
$btnSave.click( function () { var life;
if ( learn && light ) {
life = $eternity.val();
} else {
life = false;
}
mod.forward( about,
assign,
$input.val(),
access,
life );
} );
$td.append( $btnSave );
if ( learn && light ) {
$eternity = $( "<input />" );
$eternity.attr( { "class": slip,
"float": "right",
"id": slip + "-eternity",
"type": "checkbox" } );
$lbl = $( "<label />" );
$lbl.attr( { "class": slip,
"float": "right" ,
"for": slip + "-eternity" } );
$lbl.text( String.fromCharCode( 8734 ) );
$td.append( $lbl );
$td.append( $eternity );
}
} else {
mod.makes[ about ] = mod.makes[ about ] - 1;
$td.children( "input" ).remove();
$td.children( "." + slip ).remove();
if ( typeof alter === "string" ) {
$td.children( "span" ).text( alter );
$td = $tr.children( "td" ).eq( 1 );
$td.text( alter.length );
}
}
$new.toggle( ! ( active || mod.makes[ about ] ) );
}; // mod.flip()
mod.flush = function ( about, assign ) {
// [delete] button has been clicked.
// Precondition:
// about -- 1 of "localStorage","sessionStorage","cookies"
// assign -- identifier
// Uses:
// jQuery.removeCookie() :: mediawiki.cookie
// gui.fresh()
// 2014-08-01 PerfektesChaos@de.wikipedia
switch ( about ) {
case "localStorage" :
case "sessionStorage" :
window[ about ].removeItem( assign );
break;
case "cookies" :
$.removeCookie( assign,
{ path: "/", expires: 0 } );
break;
} // switch about
gui.fresh( about );
}; // mod.flush()
mod.forward = function ( about, assign, alter, access, ages ) {
// [save] button has been clicked.
// Precondition:
// about -- 1 of "localStorage","sessionStorage","cookies"
// assign -- identifier
// alter -- text to be stored
// access -- number of item; -1 for new
// ages -- make cookie persistent
// Uses:
// > domfuns
// jQuery.trim()
// jQuery.inArray()
// jQuery.cookie()
// gui.fresh()
// mod.flip()
// 2014-01-20 PerfektesChaos@de.wikipedia
var opts, story,
subject = assign,
learn = ( access < 0 ),
storage = about;
if ( learn ) {
story = "";
subject = $.trim( alter );
if ( subject === "" ) {
storage = "";
} else {
switch ( storage ) {
case "localStorage" :
case "sessionStorage" :
if ( window[ storage ].getItem( subject ) ||
$.inArray( assign, domfuns ) >= 0 ) {
storage = "";
}
break;
case "cookies" :
if ( mw.cookie.get( subject ) ) {
storage = "";
}
break;
} // switch storage
}
} else {
story = alter;
}
if ( storage !== "" ) {
switch ( storage ) {
case "localStorage" :
case "sessionStorage" :
window[ storage ].setItem( subject, story );
break;
case "cookies" :
opts = { path: "/" };
if ( ages ) {
opts.expires = 1000;
}
mw.cookie.set( subject, story, opts );
break;
} // switch storage
mod.flip( storage, access, false, false, story );
if ( learn ) {
gui.fresh( storage );
}
}
}; // mod.forward()
BSM.fiat = function () {
// Equip current page with tables
// Uses:
// mw.loader.using()
// (gui.fiat)
// 2013-12-17 PerfektesChaos@de.wikipedia
mw.loader.using( [ "mediawiki.cookie" ],
function () {
$( gui.fiat );
} );
}; // .fiat()
BSM.fresh = function ( about ) {
// Rebuild table content
// Precondition:
// about -- 1 of "localStorage", "sessionStorage", "cookies"
// Postcondition:
// Returns Array with sorted assignments, or false
// Uses:
// > gui.$wrapper
// > config.max
// gui.fresh()
// .fiat()
// Remark: May be used as event handler -- 'this' not accessed
// 2013-12-28 PerfektesChaos@de.wikipedia
var r;
if ( gui.$wrapper ) {
r = gui.fresh( about );
} else {
BSM.fiat();
r = fresh( about, config.max );
}
return r;
}; // .fresh()
first();
} // bb_mw()
// ///////////////////////////////////////////////////////////////////
function bb_nowiki() {
// Build functions for non-mediawiki environment, and execute
// Uses:
// > Bag
// > BSM
// > Max
// 2013-12-17
function failure( all ) {
// No console available
// Precondition:
// all -- object with all kinds of data
// 2013-12-17
var k, s,
story = BSM + ": No console";
for ( k = 0; k < 2; k++ ) {
s = Bag[ k ];
story = story + "\r\n" + s + ": " + figure( all[ s ] );
} // for k
window.alert( story );
} // failure()
function fancy( all ) {
// Try console tables
// Precondition:
// all -- object with all kinds of data
// Uses:
// > BSM
// Throws:
// Unavailable
// 2013-12-17
var k, o, s;
window.console.info( "== " + BSM + " ==" );
if ( window.opera ) {
throw window.opera;
}
if ( typeof window.console.table === "object" ) {
for ( k = 0; k < 3; k++ ) {
s = Bag[ k ];
o = all[ s ];
window.console.info( s + " " + figure( o ) );
if ( o ) {
window.console.table.call( window.console, o );
}
} // for k
} else {
throw { };
}
} // fancy()
function figure( assembly ) {
// Retrieve total item count and character length of web storage
// Precondition:
// assembly -- Array with web storage info, or false
// Postcondition:
// Returns string with numbers
// 2013-12-17 PerfektesChaos@de.wikipedia
var i, m, n, r;
if ( assembly ) {
n = assembly.length;
m = 0;
for ( i = 0; i < n; i++ ) {
m += assembly[ i ].n;
} // for i
r = "#" + n + " -> " + m;
} else {
r = "./.";
}
return r;
} // figure()
function fire() {
// Run on load
// Uses:
// > Bag
// > Max
// fresh()
// fancy()
// flat()
// failure()
// 2013-12-17 PerfektesChaos@de.wikipedia
var i, s,
env = { };
for ( i = 0; i < 3; i++ ) {
s = Bag[ i ];
env[ s ] = fresh( s, Max );
} // for i
if ( window.console ) {
try {
fancy( env );
} catch (e) {
try {
window.console.log( env );
} catch (ex) {
flat( env );
}
}
} else {
failure( env );
}
} // fire()
function flat( all ) {
// console available, but no object log function
// Precondition:
// all -- object with all kinds of data
// 2013-12-17
var e, i, k, n, o, s;
for ( k = 0; k < 3; k++ ) {
s = Bag[ k ];
o = all[ s ];
n = o.length;
window.console.info( "=== " + s + " ===" );
for ( i = 0; i < n; i++ ) {
e = o[ i ];
window.console.info( e.id + " = " + e.v );
} // for i
} // for k
} // flat()
fire();
} // bb_nowiki()
// ///////////////////////////////////////////////////////////////////
function fetch() {
// Retrieve cookies
// Postcondition:
// Returns Array with cookie assignments, or false
// 2013-12-17
var g, i, m, n, p, r, s, v;
if ( typeof window.document.cookie === "string" ) {
r = [ ];
g = window.document.cookie.split( "; " );
n = g.length;
for ( i = 0; i < n; i++ ) {
p = g[ i ].split( "=" );
s = decodeURIComponent( p[ 0 ] );
v = p[ 1 ];
if ( v ) {
m = v.length;
v = decodeURIComponent( v );
} else {
m = 0;
v = "";
}
r.push( { id: s,
n: m,
v: v } );
} // for i
} else {
r = false;
}
return r;
} // fetch()
function find( access, allow ) {
// Retrieve object with web storage
// Precondition:
// access -- either "localStorage" or "sessionStorage"
// allow -- maximum number of characters
// Postcondition:
// Returns Array with storage assignments, or false
// 2013-12-17 PerfektesChaos@de.wikipedia
var n, r, s, store,
o = window[ access ];
if ( typeof o === "object" ) {
r = [ ];
for ( s in o ) {
store = o.getItem( s );
if ( typeof store === "string" ) {
n = store.length;
if ( n > allow ) {
store = store.substr( 0, allow );
}
} else {
n = 0;
store = "";
}
r.push( { id: s,
n: n,
v: store } );
} // for s in o
} else {
r = false;
}
return r;
} // find()
function fresh( about, allow ) {
// Rebuild content
// Precondition:
// about -- one of "localStorage", "sessionStorage", "cookies"
// allow -- maximum number of characters
// Uses:
// fetch()
// find()
// Postcondition:
// Returns Array with sorted assignments, or false
// Each element is an object { id, n, v }
// id -- string
// n -- number of bytes/characters
// v -- truncated value
// 2013-12-17 PerfektesChaos@de.wikipedia
var r,
f = function( a, b ) { return ( a.id.toLowerCase()
< b.id.toLowerCase()
? -1
: +1 );
};
switch ( about ) {
case "cookies" :
r = fetch();
break;
case "localStorage" :
case "sessionStorage" :
r = find( about, allow );
break;
default:
r = false;
} // switch about
if ( r ) {
r.sort( f );
}
return r;
} // fresh()
if ( typeof mw === "object" && $ ) {
bb_mw();
} else {
bb_nowiki();
}
}( window.mediaWiki, window.jQuery ) );
// Emacs
// Local Variables:
// coding: utf-8-dos
// fill-column: 80
// End:
/// EOF </nowiki> browserStorageManager/d.js