Changes

Jump to navigation Jump to search
m
no edit summary
Line 1: Line 1:  
// License: GPL
 
// License: GPL
// Indexeddb JavaScript
+
// User Interface Rendering
console.log('Indb loading');
+
console.log('Interface handler loading');
 
  −
function IndexedDBContainer( ww ) {
  −
 
  −
// suppress console.log, switch to true for debug
  −
var Debug_switch = false;
  −
// seemingly the Safari engine uses a somewhat different implementation of arguments for db.transaction and index.get
  −
// because no browser on any mac / ios is allowed to use a different engine, rather than user agent, platform can be tested
  −
var iOS = !!navigator.platform && /Macintosh|MacIntel|MacPPC|Mac68K|Mac|iPad|iPhone|iPod/.test(navigator.platform);
  −
 
  −
// deterministic hash generator for creating user id#s from usernames, should be replaced by something more functional (guaranteed to be transitively different)
  −
hashCode = function(s) {
  −
if ( s == undefined) {
  −
s = '00'
  −
}
  −
var h = 0, l = s.length, i = 0;
  −
if ( l > 0 )
  −
while (i < l)
  −
h = (h << 5) - h + s.charCodeAt(i++) | 0;
  −
return h;
  −
};
      +
function InterfaceMediaContainer ( WikibaseProcessor, indexedDBobject ) {
 
 
if ( ww.user != undefined ) {
+
this.renderInterface = function( sqitch ) {
// if user exists in object passed to constructor, get username
+
switch( sqitch ) {
var self = ww.user.getName();
+
case 'controller_id':
// create userid by hashing username
+
controller_render();
var idgen = hashCode(self);
+
break;
debuglog(idgen);
+
case 'personal_data_id':
 
+
pd_site_render();
// Take username for standard databasename format:
+
break;
// Our current convention for personal databasename (separate dbname for each user)
+
case 'interface_button_id':
var PersonalDataDataBaseName = "PD.IO" + idgen + "Database";
+
personal_data_edit_interface_render();
// Use username in user to get up to date version of self
+
break;
// Blank object for personal data Record with id and username included
  −
this.CurrentPerson = {id: idgen, name: {user: self}, age: 0};
  −
debuglog(PersonalDataDataBaseName);
  −
debuglog(this.CurrentPerson);
   
}
 
}
 +
}
   −
// ADD MORE DOC
+
var button_save = [],
 +
button_remove = [],
 +
textInput = [];
   −
// EnqueuePDIO a PDIOLocalDatabase:User database access function with modes
+
async function controller_render(){
// Externally accessible wrapper for Enquire with current user / db preloaded
+
console.log("this function is done by the current page controller for now");
 +
notify_porting();
 +
}
   −
this.EnqueuePDIO = async function( sw, c1, c2, c3 ) {
+
async function pd_site_render(){
debuglog("enquing pdio db " + PersonalDataDataBaseName + " with user " + JSON.stringify(this.CurrentPerson));
  −
var k = await Enquire( PersonalDataDataBaseName, this.CurrentPerson, sw, c1, c2, c3 );
  −
return k;
  −
}
     −
// Enquire, a general purpose indexeddb update function with modes
+
};
   −
// Mode 'aggressive push':
+
async function personal_data_edit_interface_render(){
// parameter record is pushed to database, overwriting whatever is there
+
clear_render();
 +
 +
// Get concerns relation :: Parts of this must be moved upstream, MAIN should know that this is the data the renderer will need and provide it
   −
// Mode 'checkin':
+
var concern_origin = WikibaseProcessor.checkentity( { this_concerns: [ WBEStructure['concernsRelation'], WBEStructure['IDPropLoc'], WBEStructure['qIDPropName'] ] } )['this_concerns'][0];
// record is retrieved from database, parameter record is pushed if not found
     −
// Mode 'get record'
+
// Get defval for entity :: Parts of this must be moved upstream, MAIN should know that this is the data the renderer will need and provide it
// updates record given as argument
     −
// Mode 'update record' field1 field2 field3
+
var default_value = WikibaseProcessor.checkentity( { default_value: [ WBEStructure['defaultValRelation'], WBEStructure['IDPropLoc'] ] } )['default_value'][0]; //defal
// retrieve record, make record.field1.field2 = field3, push back
     −
// Mode 'update record' field1 field2
+
var get_record = indexedDBobject.EnqueuePDIO('update record');
// retrieve record, make record.field1 = field2, push back
     −
// Mode 'remove from record' field1
+
get_record.then( function(result) {
// retrieve record, splice/delete record.field1, push back
  −
  −
// Mode 'remove from record' field1 field2
  −
// retrieve record, splice/delete record.field1.field2, push back
     −
async function Enquire( pddbname, record, sqitch, control_1, control_2, control_3 ) {
+
mw.loader.using( 'oojs-ui-core' ).done( function () {
return new Promise(
  −
function(resolve, reject) {
     −
var pddb = window.indexedDB.open(pddbname, 3);
+
button_save = [],
var inp_obj;
+
button_remove = [],
 +
textInput = [];
   −
pddb.onerror = function()
+
var extrafield = ( result[concern_origin] != undefined ) ? Object.keys(result[concern_origin]).length : 0;
    console.log("Warning: Access to IndexedDB for application has been rejected.");
  −
};
     −
// indexeddb internal mechanism for version tracking of schema
+
button_save[ extrafield ] = new OO.ui.ButtonWidget( { label: "Save", classes: [ 'pduimark' ] } );
pddb.onupgradeneeded = function() {
  −
console.log('upgrading database');
  −
var db = pddb.result;
  −
var store = db.createObjectStore(pddbname, {keyPath: "id"});
  −
var index = store.createIndex("NameIndex", ["id"]);
  −
  −
};
  −
// Database successfully opened function.
  −
pddb.onsuccess = function() {
  −
debuglog(pddb.result);
  −
var db = pddb.result;
  −
var tx;
  −
  −
if ( iOS ) {
  −
tx = db.transaction([pddbname], "readwrite");
  −
} else {
  −
tx = db.transaction(pddbname, "readwrite");
  −
}
   
 
var store = tx.objectStore(pddbname);
+
textInput[ extrafield ] = new OO.ui.TextInputWidget( {
var index = store.index("NameIndex");
+
placeholder: default_value,
 +
classes: [ 'pduimark' ]
 +
} );
   −
// Get the original record from the db...
+
button_save[ extrafield ].on( 'click', function () {
var getRecord;
+
indexedDBobject.EnqueuePDIO('update record', concern_origin, extrafield, textInput[ extrafield ].value );
if ( iOS ) {
+
personal_data_edit_interface_render();
getRecord = index.get(record.id);
+
});
} else {
  −
getRecord = index.get([record.id]);
  −
}
     −
getRecord.onsuccess = function() {
+
$( '#mw-content-text' ).prepend( button_save[ extrafield ].$element );
debuglog( "Record in database: \n <<");
+
$( '#mw-content-text' ).prepend( textInput[ extrafield ].$element );
debuglog( getRecord.result );
  −
debuglog( ">>");
  −
// Essential recordAdd
  −
if ( sqitch === "aggressive push" ) {
  −
// Mode 'aggressive push':
  −
// parameter record is pushed to database, overwriting whatever is there
  −
inp_obj = record;
  −
store.put( inp_obj );
  −
return inp_obj;
  −
} else if ( sqitch === "checkin" ) {
  −
// Mode 'checkin':
  −
// record is retrieved from database, parameter record is pushed if not found
  −
if ( getRecord.result != undefined ) {
  −
debuglog("getting from store");
  −
inp_obj = getRecord.result;
  −
} else {
  −
debuglog("overriding whatever in there");
  −
inp_obj = record;
  −
store.put(inp_obj);
  −
}
     −
} else {
+
if ( extrafield > 0) {
// Methods manipulationg the actual record come here
+
Object.keys( result[concern_origin] ).forEach( function(data) {
// Update & Remove from
+
button_save[data] = new OO.ui.ButtonWidget( { label: "Save", classes: [ 'pduimark' ] } );
// If we got the record from store, use that version to be manipulated
+
button_remove[data] = new OO.ui.ButtonWidget( { label: "Delete", classes: [ 'pduimark' ] } );
if ( getRecord.result !== undefined ) {
+
textInput[data] = new OO.ui.TextInputWidget( {
inp_obj = getRecord.result;
+
value: result[concern_origin][data], ///
+
placeholder: default_value,
if ( sqitch === "get record" ) {
+
classes: [ 'pduimark' ]
+
} );
debuglog("Getting record");
+
button_save[data].on( 'click', function () {
// we will return later
  −
  −
}  
     −
// endof onsuccess
+
indexedDBobject.EnqueuePDIO('update record', concern_origin, data, textInput[ data ].value );
} else {
     −
debuglog("Record not found");
+
personal_data_edit_interface_render();
 +
});
   −
if ( sqitch === "update record" ) {
+
button_remove[data].on( 'click', function () {
// Update record will use supplied copy to update it
+
indexedDBobject.EnqueuePDIO('remove from record', concern_origin, data );
inp_obj = record;
+
personal_data_edit_interface_render();
} else {
+
});
if ( sqitch === "get record" ) {
+
$( '#mw-content-text' ).prepend( button_remove[data].$element );
inp_obj = undefined;
+
$( '#mw-content-text' ).prepend( button_save[data].$element );
} else if ( sqitch === "remove from record" ) {
+
$( '#mw-content-text' ).prepend( textInput[data].$element );
inp_obj = record;
  −
} else {
  −
// any other method ...... would quit as record was not even foun
  −
return undefined;
  −
}
  −
}
  −
}
  −
}
     −
if ( sqitch === "update record" ) { // Record Update
+
});
if ( control_1 != undefined ) {
  −
if ( control_2 != undefined ) {
  −
if ( control_3 != undefined ) {
     −
// Mode 'update record' field1 field2 field3
+
}
// retrieve record, make record.field1.field2 = field3, push back
+
});
 +
});
 +
};
   −
if ( inp_obj[ control_1 ] == undefined ) { inp_obj[ control_1 ] = (isNaN( control_2 )) ? {} : [] };
+
function clear_render() {
inp_obj[ control_1 ][ control_2 ] = control_3; // => "Bob"
+
var ifel = document.getElementsByClassName('pduimark');
store.put(inp_obj);
+
while( ifel[0] ) {
} else {
+
ifel[0].parentNode.removeChild(ifel[0]);
 +
};
 +
};
 +
 +
function notify_porting() {
   −
// Mode 'update record' field1 field2
+
mw.loader.using( 'oojs-ui-core' ).done( function () {
// retrieve record, make record.field1 = field2, push back
     −
inp_obj[ control_1 ] = inp_obj[ control_1 ] || {};
+
var button_import = new OO.ui.SelectFileWidget( { label: "Import Personal Data", classes: [ 'pduimark' ] } ),
if ( Array.isArray( inp_obj[ control_1 ] ) ) {
  −
inp_obj[ control_1 ].push( control_2 );
  −
} else {
  −
inp_obj[ control_1 ] = control_2;
  −
}
  −
store.put(inp_obj);
     −
}
+
button_export = new OO.ui.ButtonWidget( { label: "Export Personal Data", classes: [ 'pduimark' ] } );
} else {
  −
// Only one control defined. We will return that part of the record, and change nothing
  −
inp_obj = inp_obj[ control_1 ];
  −
}
  −
} else {
     −
// There's not even control_1, we will just return the record itself
+
button_import.on( 'change', function (event) {
   −
}
+
if (window.webkitURL != null) {
debuglog("return 3")
+
console.log("loading file on webkit")
// return inp_obj;
+
} else {
 +
console.log("loading file non webkit")
 +
}
   −
};
+
console.log( event );
   −
if ( sqitch === "remove from record" ) { // Record Update
+
});
if ( control_1 != undefined ) {
  −
if ( control_2 != undefined ) {
     −
// Mode 'remove from record' field1 field2
+
button_export.on( 'click', function () {
// retrieve record, splice/delete record.field1.field2, push back
  −
  −
if ( Array.isArray( inp_obj[ control_1 ] ) && !isNaN( control_2 ) ) {
  −
inp_obj[ control_1 ].splice( control_2, 1 );
  −
} else {
  −
delete inp_obj[ control_1 ][ control_2 ];
  −
}
     −
} else {
+
var get_record = indexedDBobject.EnqueuePDIO('get record');
   −
// Mode 'remove from record' field1
+
get_record.then( function(result) {
// retrieve record, splice/delete record.field1, push back
+
console.log("happening");
 +
if ( result === undefined ) { window.alert("No local data to export") } else {
   −
delete inp_obj[ control_1 ];
+
var filename_tosaveas = "pdiolocalexport_" + result.name.user + "_" + Date.now() + '.json';
}
+
}
+
result.id = '';
debuglog("putting object to store:");
+
result.name.user = '';
debuglog(inp_obj);
+
store.put(inp_obj);
+
var export_to_text = JSON.stringify(result);
 +
var textFileAsBlob = new Blob([export_to_text], {type:'text/plain'});
 +
var downloadLink = document.createElement("a");
 +
downloadLink.download = filename_tosaveas;
 +
if (window.webkitURL != null)
 +
{
 +
// Chrome allows the link to be clicked
 +
// without actually adding it to the DOM.
 +
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
 +
}
 +
else
 +
{
 +
// Firefox requires the link to be added to the DOM
 +
// before it can be clicked.
 +
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
 +
downloadLink.style.display = "none";
 +
document.body.appendChild(downloadLink);
 
}
 
}
   −
// We are past all methodic code, Async return
+
downloadLink.click();
+
 
resolve( inp_obj );
+
}
   −
};
+
});
  −
// Indexeddb internal mechanism, close db
  −
  −
tx.oncomplete = function() {
  −
debuglog("return 1")
  −
db.close();
  −
};
  −
};
  −
debuglog("return 0")
     −
// End of promise
  −
  −
}).then( function(result) {
  −
debuglog("Mark 3");
  −
debuglog(result);
  −
return result;
   
});
 
});
 +
 +
mw.notify( $( button_import.$element ), { autoHide: false }  );
 +
mw.notify( $( button_export.$element ), { autoHide: false }  );
 +
});
 
}
 
}
   −
function debuglog( l0g ){
+
}
if ( Debug_switch ) {
  −
console.log( l0g );
  −
}
  −
}
  −
};
 
530

edits

Navigation menu