Line 1: |
Line 1: |
− | console.log('_'); | + | // License: GPL |
| + | // Experimental Main |
| + | console.log("'⌣'"); |
| | | |
− | // parts of structures from the wikibase entity used for our interest
| + | var mwEStruct = { |
| + | wbXntity: 'config.values.wbEntity' |
| + | }, |
| | | |
− | var controller_item_id = 96,
| + | language = "en", |
− | personal_data_id = 421,
| |
− | interface_button_id = 487,
| |
| | | |
− | language = "en";
| + | WBEStructure = { |
− | wbEStruct = {
| + | subclassOfRelations: 'claims.P4', // location of P4 relations in wbEntity |
− | subclassOfRelations: 'claims.P4', // location of P4 relations in wbEntity
| + | defaultValRelation: 'claims.P108', |
− | defaultValRelation: 'claims.P108',
| + | concernsRelation: 'claims.P110', |
− | concernsRelation: 'claims.P110',
| + | instanceOfRelations: 'claims.P3', |
− | instanceOfRelations: 'claims.P3',
| + | IDPropLoc: 'mainsnak.datavalue.value', // location of ID properties in related entity |
− | IDPropLoc: 'mainsnak.datavalue.value', // location of ID properties in related entity
| + | IDName: 'numeric-id', // ID property name which checked |
− | IDName: 'numeric-id', // ID property name which checked
| + | qIDPropName: 'id', |
− | qIDPropName: 'id',
| + | standardValue: 'labels' + '.' + language + '.' + 'value' |
− | standardValue: 'labels' + '.' + language + '.' + 'value'
| + | }, |
− | },
| |
− | mwEStruct = {
| |
− | wbXntity: 'config.values.wbEntity'
| |
− | };
| |
| | | |
− | // Take username for standard databasename format
| + | Relational_id_list = { |
− | var PersonalDataDataBaseName = "PD.IO" + mw.user.getName() + "Database";
| + | controller_id: [ WBEStructure['instanceOfRelations'], WBEStructure['IDPropLoc'], WBEStructure['IDName'], 96 ], |
− | console.log(PersonalDataDataBaseName);
| + | personal_data_id: [ WBEStructure['subclassOfRelations'], WBEStructure['IDPropLoc'], WBEStructure['IDName'], 421 ], |
− | // Use username in user to get up to date version of self
| + | interface_button_id: [ WBEStructure ['instanceOfRelations'], WBEStructure['IDPropLoc'], WBEStructure['IDName'], 487 ] |
− | var CurrentPerson = {id: 0, name: {user: mw.user.getName(), first: "", last: ""}, age: 0};
| + | }, |
− | console.log( CurrentPerson );
| |
− | recordAdd( PersonalDataDataBaseName, CurrentPerson );
| |
− | console.log( CurrentPerson );
| |
− | /*
| |
− | recordUpdate(PersonalDataDataBaseName, CurrentPerson, '', value);
| |
− | recordCheck(PersonalDataDataBaseName, CurrentPerson);
| |
− | recordDeleteFrom(PersonalDataDataBaseName, CurrentPerson, )
| |
− | */
| |
| | | |
− | // check if we are on a page of any of the targeted Entity
| + | PDWikibaseProcessor, |
− | // more exactly, use iterateAcheckBC to check in mw.config.values.wbEntity if instanceOfRelations exist, than if yes, check if numeric id of any matches controller id
| + | PDindexedDB, |
− | if ( iterateAcheckBC(mw, mwEStruct['wbXntity'], wbEStruct['instanceOfRelations'], wbEStruct['IDPropLoc'], wbEStruct['IDName'], controller_item_id) ) {
| + | PDOOUI, |
− | console.log("This is a Data Controller");
| + | Current_entity; |
− | controller_display_function();
| |
− | }
| |
| | | |
− | // use iterateAcheckBC to check in mw.config.values.wbEntity if subClassOfRelations exist, than if yes, check if numeric id of any matches personal data id
| |
− | if ( iterateAcheckBC(mw, mwEStruct['wbXntity'], wbEStruct['subclassOfRelations'], wbEStruct['IDPropLoc'], wbEStruct['IDName'], personal_data_id) ) {
| |
− | console.log("This is a Personal Data Type");
| |
− | input_display_function();
| |
− | }
| |
| | | |
− | // use iterateAcheckBC to check in mw.config.values.wbEntity if instanceOfRelations exist, than if yes, check if numeric id of any matches interface button id | + | // JQ.'when' loads the current scripts asynchronously, continues when loading is 'done' |
− | if ( iterateAcheckBC(mw, mwEStruct['wbXntity'], wbEStruct['instanceOfRelations'], wbEStruct['IDPropLoc'], wbEStruct['IDName'], interface_button_id) ) {
| + | $.when( |
− | console.log("This is a Data Input Interface");
| + | $.getScript( "//wiki.personaldata.io/w/index.php?title=User:Abel/WbProcessor.js&action=raw&ctype=text/javascript" ), |
− | data_maintenance_display();
| + | $.getScript( "//wiki.personaldata.io/w/index.php?title=User:Abel/PersonalData.js&action=raw&ctype=text/javascript" ), |
− | } | + | $.getScript( "//wiki.personaldata.io/w/index.php?title=User:Abel/OOInterface.js&action=raw&ctype=text/javascript" ), |
| + | $.Deferred( function( deferred ){ |
| + | $( deferred.resolve ); |
| + | }) |
| + | ).done( function(){ |
| | | |
− | // show popup from template for controllers
| + | console.log('Main thread'); |
− | function controller_display_function(){
| |
− | console.log( "it's a controller" )
| |
− | var obj2 = interjson( get_Y_from_X( mw, mwEStruct['wbXntity'] ) );
| |
− | var qId = dive( obj2, wbEStruct["qIDPropName"] );
| |
− | var api = new mw.Api();
| |
− | api.get( {
| |
− | action: 'expandtemplates',
| |
− | text: '{{MailtoAccess|'+qId+'}}'
| |
− | } ).done( function ( data ) {
| |
− | mw.notify( $('<a href="'+data.expandtemplates["*"]+'"> Do a SAR to this data controller!</a>') , { autoHide: false } );
| |
− | } );
| |
− | }
| |
| | | |
− | // show input for personal data | + | // WBproc reads current mediawiki Entity upon instantiation |
− | function input_display_function() {
| + | PDWikibaseProcessor = new WikibaseProcessorContainer(mw, mwEStruct['wbXntity']); |
− | var obj = interjson( get_Y_from_X( mw, mwEStruct['wbXntity'] ) );
| |
− | var string_temporary_store_1 = get_Y_from_X( obj, wbEStruct['standardValue'] );
| |
− | var string_temporary_store_2 = get_Y_from_X ( get_Y_from_X ( get_Y_from_X( obj, wbEStruct['defaultValRelation'] ), '0'), wbEStruct['IDPropLoc'] );
| |
− | var string_temporary_store_3 = 0;
| |
| | | |
− | mw.notify(
| + | // PDxDB takes mediawiki, reads user name from it, creates a hash, and 'checks in' the user upon instantiation |
− | $('<input type="text" placeholder="' + string_temporary_store_2 + '" id="' + string_temporary_store_1 + '_' + 0 + '" />'), { autoHide: false } );
| + | // (i.e. read record belonging to user, if it does not exist, create it) |
− | }
| + | PDindexedDB = new IndexedDBContainer( mw ); |
| + | |
| + | // Contains classes for creating UI elements, no instantiation consequences |
| + | PDOOUI = new InterfaceMediaContainer( PDWikibaseProcessor, PDindexedDB ); |
| | | |
− | // show maintenance options for personal data | + | // Check if the current entity belongs to any path of interest. |
− | function data_maintenance_display() {
| + | // For each element in object argument, a corresponding element in the return object will contain one of the following: |
− | var obj = interjson( get_Y_from_X( mw, mwEStruct['wbXntity'] ) ); // wbEntity as json obj
| + | // - undefined - the path didn't exist even partly) |
− | var string_temporary_store_1 = get_Y_from_X( obj, wbEStruct['standardValue'] ); // input name
| + | // - [ value or object ] - if the path existed fully, it returns what is at the end of the path. If last element in path is a value, it will return the value if found |
− | var string_temporary_store_2 = get_Y_from_X ( get_Y_from_X ( get_Y_from_X( obj, wbEStruct['defaultValRelation'] ), '0'), wbEStruct['IDPropLoc'] ); //placeholder_text
| |
− | var string_temporary_store_3 = get_Y_from_X ( get_Y_from_X ( get_Y_from_X( obj, wbEStruct['concernsRelation'] ), '0'), wbEStruct['IDPropLoc'] ); //placeholder_text
| |
− | interface_media( PersonalDataDataBaseName, CurrentPerson, string_temporary_store_1, string_temporary_store_2, string_temporary_store_3 );
| |
− | }
| |
| | | |
− | // repeating code patterns | + | Current_entity = PDWikibaseProcessor.checkentity( Relational_id_list ); |
| + | |
| + | // Business logicish part. |
| + | // If any path of interest returned anything... |
| + | if ( Current_entity != undefined ) { |
| + | Object.keys(Current_entity).forEach( function ( entity_checked ){ |
| + | //... for each path that returned something |
| + | if ( Current_entity[entity_checked] != undefined ){ |
| + | if ( Object.keys( Current_entity[entity_checked] ).length > 0 ) { |
| + | PDOOUI.renderInterface( entity_checked ); |
| + | //... call the OOUI renderer to render what belongs to this input |
| + | } |
| + | } |
| + | }); |
| + | } |
| | | |
− | function interface_media( db /* database */, prs /* user */ , rel_A /* current value location */, rel_B /* placeholder value */, rel_C /* which attribute it is in the inddb database - concerns for input item */ ) {
| + | }); |
− | mw.loader.using( 'oojs-ui-core' ).done( function () {
| |
− | $( function () {
| |
− |
| |
− | var person = recordCheck( db, prs );
| |
− | // var data = interjson( get_Y_from_X( mw, mwEStruct['wbXntity'] ) ); // wbEntity as json obj
| |
− | | |
− | var button = [],
| |
− | textInput = [];
| |
− | var ii;
| |
− | for ( var i = 0 ; i < check( person, rel_C ).length; i++ ) {
| |
− | ii = i + 1;
| |
− | button_save[i] = new OO.ui.ButtonWidget( { label: "Save" } );
| |
− | button_new[i] = new OO.ui.ButtonWidget( { label: "New" } );
| |
− | button_delete[i] = new OO.ui.ButtonWidget( { label: "Delete" } );
| |
− | textInput[i] = new OO.ui.TextInputWidget( {
| |
− | value: check( person, rel_C + '.' + i ),
| |
− | placeholder: rel_B
| |
− | } );
| |
− | $(textInput[i]).on("keydown",function search(e) {
| |
− | if(e.keyCode == 13) {
| |
− | recordUpdate( db, prs , rel_C + '.' + i , ($(this).val()) );
| |
− | }
| |
− | });
| |
− | button_new[i].on( 'click', function () {
| |
− |
| |
− | // new
| |
− | recordUpdate( db, prs, rel_C + '.' + ii , '');
| |
− | interface_media( db, prs, rel_A, rel_B, rel_C );
| |
− | return;
| |
− | | |
− | } );
| |
− | button_delete[i].on( 'click', function () {
| |
− |
| |
− | // delete
| |
− | recordDeleteFrom( db, prs, rel_C + '.' + i );
| |
− | interface_media( db, prs, rel_A, rel_B, rel_C );
| |
− | return;
| |
− | | |
− | } );
| |
− | button_save[i].on( 'click', function () {
| |
− |
| |
− | // save
| |
− | recordUpdate( db, prs, rel_C + '.' + i , textInput[i].val()) ;
| |
− | interface_media( db, prs, rel_A, rel_B, rel_C );
| |
− | return;
| |
− | | |
− | } );
| |
− | $( '#mw-content-text' ).prepend( button_new[i].$element );
| |
− | $( '#mw-content-text' ).prepend( button_delete[i].$element );
| |
− | $( '#mw-content-text' ).prepend( button_save[i].$element );
| |
− | $( '#mw-content-text' ).prepend( textInput[i].$element );
| |
− | $( '#mw-content-text' ).prepend( '<br>' );
| |
− | | |
− | }
| |
− | | |
− | //
| |
− | /*
| |
− | | |
− | recordCheck(PersonalDataDataBaseName, CurrentPerson);
| |
− | | |
− | */
| |
− | //
| |
− | | |
− | } );
| |
− | } );
| |
− | }
| |
− | | |
− | // get obj.'rel_0' (gets wbEntity), check if it has 'A', iterate over 'A', get 'B' and 'C' and check if any contains 'to_check'. if yes, return true
| |
− | function iterateAcheckBC( obj, rel_0, rel_A, rel_B, rel_C, to_check ) {
| |
− | var future = false;
| |
− | if ( check( obj, rel_0 ) != undefined ) {
| |
− | var edata = interjson(get_Y_from_X( obj, rel_0 ));
| |
− | console.log(edata);
| |
− | if ( check( edata, rel_A ) != undefined ) {
| |
− | var current = get_Y_from_X( edata, rel_A );
| |
− | console.log( "parsed object ")
| |
− | console.log( current );
| |
− | // check if we have rel_A relations and iterate through
| |
− | for( var i = 0; i < current.length; i++ ) {
| |
− | console.log("dived in ");
| |
− | console.log(current[i]);
| |
− | // check if we have controller id constructed from wbEntity
| |
− | if ( check( current[i], rel_B ) != undefined ) {
| |
− | if ( check( check (current[i], rel_B ), rel_C ) != undefined ) {
| |
− | if ( check_Y_in_X( get_Y_from_X( get_Y_from_X( current[i], rel_B ), rel_C ), to_check ) ) {
| |
− | console.log("mark +");
| |
− | future = true;
| |
− | };
| |
− | }
| |
− | }
| |
− | }
| |
− | }
| |
− | }
| |
− | return future;
| |
− | }
| |
− | | |
− | // get a.b from a and b
| |
− | function get_Y_from_X( obj, B ){
| |
− | if ( check(obj, B) !== undefined ) {
| |
− | console.log( "entity is defined" )
| |
− | return dive(obj, B);
| |
− | }
| |
− | }
| |
− | | |
− | // try to convert something into JSON
| |
− | function interjson( obj ) {
| |
− | try {
| |
− | return JSON.parse( obj )
| |
− | } catch (e) {
| |
− | // if not JSON, do silly things
| |
− | };
| |
− | }
| |
− | | |
− | //find second argument in first argument as a boolean
| |
− | function check_Y_in_X(obj, to_check){
| |
− | if (obj === to_check) { return true };
| |
− | for (var i = 0; i < obj.length; i++ ){
| |
− | if (obj[i] === to_check) { return true };
| |
− | }
| |
− | return false;
| |
− | }
| |
− | | |
− | function indexinterpolate(obj,i) { return (obj[i] != undefined) ? obj[i] : obj};
| |
− | // helper function for checking a part of an array exists
| |
− | function indexcheck(obj,i) { return (obj[i] != undefined) ? obj[i] : undefined };
| |
− | // dive selects matrix.a.b.c.d from the array called matrix and 'a.b.c.d' as string
| |
− | // if a.b.c.d does not exists, it returns the substructure until the substructure exists, if d does not exist, it returns matrix.a.b.c e.g.
| |
− | function dive(array, read){
| |
− | return read.split('.').reduce(indexinterpolate, array);
| |
− | }
| |
− | function check(array, read){
| |
− | return read.split('.').reduce(indexcheck, array);
| |
− | }
| |
− | | |
− | // ADD MORE DOC
| |
− | // Add new record (create pddbname@record) if it does not exist.
| |
− | // If it exists, the contents of record are disregarded, and the indexeddb version is returned
| |
− | | |
− | function recordAdd(pddbname, record){
| |
− | var pddb = window.indexedDB.open(pddbname, 3);
| |
− | pddb.onupgradeneeded = function() {
| |
− | var db = pddb.result;
| |
− | var store = db.createObjectStore(PersonalDataDataBaseName, {keyPath: "id"});
| |
− | | |
− | // shouldn't the index be the wiki.personaldata.io username?
| |
− | | |
− | var index = store.createIndex("NameIndex", ["name.user"]);
| |
− | };
| |
− | pddb.onsuccess = function() {
| |
− | var db = pddb.result;
| |
− | var tx = db.transaction(PersonalDataDataBaseName, "readwrite");
| |
− | var store = tx.objectStore(PersonalDataDataBaseName);
| |
− | var index = store.index("NameIndex");
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[ Essential recordAdd ]||||||||||||||||||||||||||||||
| |
− | | |
− | // Get the original record from the db...
| |
− | var getRecord = index.get([record.name.user]);
| |
− | getRecord.onsuccess = function() {
| |
− | if ( check(getRecord, result) != undefined) {
| |
− | // if found, let's use that from now on
| |
− | console.log("updating");
| |
− | inp_obj = getRecord.result;
| |
− | // let's return it so that our addrecord can be used as a getter as well
| |
− | return inp_obj;
| |
− | } else {
| |
− | // if it didn't exist, let's use the provided record to push to store
| |
− | inp_obj = record;
| |
− | store.put(inp_obj);
| |
− | return inp_obj;
| |
− | }
| |
− | var sanitycheck = index.get([inp_obj.name.user]);
| |
− | sanitycheck.onsuccess = function() {
| |
− | console.log(sanitycheck);
| |
− | }
| |
− | }
| |
− | | |
− | | |
− | //|||||||||||||||||||||||||||||||||||||||||||||
| |
− | | |
− | tx.oncomplete = function() {
| |
− | db.close();
| |
− | };
| |
− | };
| |
− | };
| |
− | | |
− | // Update pddbname@record:field value
| |
− | // Use store copy if exists
| |
− | // If record does not exist, create it
| |
− | // Otherwise all other fields of the record object are disregarded
| |
− | function recordUpdate( pddbname, record, field, value ) {
| |
− | | |
− | var pddb = window.indexedDB.open(pddbname, 3);
| |
− | pddb.onupgradeneeded = function() {
| |
− | var db = pddb.result;
| |
− | var store = db.createObjectStore(PersonalDataDataBaseName, {keyPath: "id"});
| |
− | var index = store.createIndex("NameIndex", ["name.user"]);
| |
− | };
| |
− | pddb.onsuccess = function() {
| |
− | // Start a new transaction
| |
− | var db = pddb.result;
| |
− | var tx = db.transaction(PersonalDataDataBaseName, "readwrite");
| |
− | var store = tx.objectStore(PersonalDataDataBaseName);
| |
− | var index = store.index("NameIndex");
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[ Essential recordUpdate ]||||||||||||||||||||||||||||||
| |
− | | |
− | var inp_obj;
| |
− | var getRecord = index.get([record.name.user]);
| |
− | // let's try to get the record to be updated from the store
| |
− | getRecord.onsuccess = function() {
| |
− | if( getRecord.result != undefined ) {
| |
− | // if we have it, use that copy to update on
| |
− | console.log("updating");
| |
− | inp_obj = getRecord.result;
| |
− | } else {
| |
− | // if it does not exist in store, use the given record
| |
− | inp_obj = record;
| |
− | }
| |
− | //give the value to the field to update
| |
− | inp_obj[field] = value; // => "Bob"
| |
− | // write new version of record back to database
| |
− | store.put(inp_obj);
| |
− | | |
− | | |
− | // perform a sanity check if the update was successful, could be used to initiate a retry upon false
| |
− | getRecordAgain = index.get([record.name.user]);
| |
− | getRecordAgain.onsuccess = function() {
| |
− | console.log(getRecordAgain); // => "Bob"
| |
− | if ( getRecordAgain.result[field] == value ) {
| |
− | console.log("Update succeeded");
| |
− | } else {
| |
− | console.log("Update unsuccessful");
| |
− | }
| |
− | };
| |
− | };
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |
− | tx.oncomplete = function() {
| |
− | db.close();
| |
− | };
| |
− | };
| |
− | };
| |
− | | |
− | | |
− | function recordCheck(pddbname, record){
| |
− | var pddb = window.indexedDB.open(pddbname, 3);
| |
− | pddb.onupgradeneeded = function() {
| |
− | var db = pddb.result;
| |
− | var store = db.createObjectStore(PersonalDataDataBaseName, {keyPath: "id"});
| |
− | var index = store.createIndex("NameIndex", ["name.user"]);
| |
− | };
| |
− | pddb.onsuccess = function() {
| |
− | var db = pddb.result;
| |
− | var tx = db.transaction(PersonalDataDataBaseName, "readwrite");
| |
− | var store = tx.objectStore(PersonalDataDataBaseName);
| |
− | var index = store.index("NameIndex");
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[ Essential recordCheck ]||||||||||||||
| |
− | | |
− | var recordcheck = index.get([record.name.user]);
| |
− | recordcheck.onsuccess = function() {
| |
− | if ( recordcheck.result != undefined ) {
| |
− | console.log(recordcheck);
| |
− | return recordCheck;
| |
− | } else {
| |
− | console.log("...else undefined");
| |
− | return undefined;
| |
− | };
| |
− | };
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |
− | | |
− | tx.oncomplete = function() {
| |
− | db.close();
| |
− | };
| |
− | };
| |
− | };
| |
− | | |
− | function recordDeleteFrom(pddbname, record, field ){
| |
− | var pddb = window.indexedDB.open(pddbname, 3);
| |
− | pddb.onupgradeneeded = function() {
| |
− | var db = pddb.result;
| |
− | var store = db.createObjectStore(PersonalDataDataBaseName, {keyPath: "id"});
| |
− | var index = store.createIndex("NameIndex", ["name.user"]);
| |
− | };
| |
− | pddb.onsuccess = function() {
| |
− | var db = pddb.result;
| |
− | var tx = db.transaction(PersonalDataDataBaseName, "readwrite");
| |
− | var store = tx.objectStore(PersonalDataDataBaseName);
| |
− | var index = store.index("NameIndex");
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||[ Essential recordCheck ]||||||||||||||
| |
− |
| |
− | var inp_obj;
| |
− | var recordcheck = index.get([record.name.user]);
| |
− | recordcheck.onsuccess = function() {
| |
− | if ( recordcheck.result != undefined ) {
| |
− | console.log("updating");
| |
− | inp_obj = recordcheck.result;
| |
− | } else {
| |
− | inp_obj = record;
| |
− | }
| |
− | delete check( inp_obj, field ); // => "Bob"
| |
− | store.put(inp_obj);
| |
− | }
| |
− | | |
− | //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |
− | | |
− | tx.oncomplete = function() {
| |
− | db.close();
| |
− | };
| |
− | };
| |
− | };
| |