Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
35 lines
No EOL
8.8 KiB
JavaScript
35 lines
No EOL
8.8 KiB
JavaScript
;'use strict';(function(exports){const DB_VERSION=1;const DB_NAME='verticalhome';const DB_ITEM_STORE='items';const DB_SV_APP_STORE_NAME='svAppsInstalled';const DATASTORE_NAME='verticalhome_items_migration';const PREFS_STORE='vertical_preferences_store';var db;var datastore;function sort(entries,order){if(!order||!order.length){return entries;}
|
|
var newEntries=[];function isEqual(lookFor,compareWith){if(!compareWith.detail||!lookFor){return false;}
|
|
if(compareWith instanceof GaiaGrid.Mozapp){if(!lookFor.manifestURL||!compareWith.detail.manifestURL){return false;}
|
|
if(compareWith.detail.entryPoint){return lookFor.manifestURL===compareWith.detail.manifestURL&&lookFor.entry_point===compareWith.detail.entryPoint;}else{return lookFor.manifestURL===compareWith.detail.manifestURL;}}else if(compareWith instanceof GaiaGrid.Bookmark){if(!lookFor.id||!compareWith.detail.id){return false;}
|
|
return lookFor.id===compareWith.detail.id;}}
|
|
for(var i=0,iLen=order.length;i<iLen;i++){for(var j=0,jLen=order[i].length;j<jLen;j++){var ind=entries.findIndex(isEqual.bind(null,order[i][j]));if(ind>=0){newEntries.push(entries.splice(ind,1)[0]);}}
|
|
if(i<iLen-1){newEntries.push(new GaiaGrid.Divider());}}
|
|
if(entries.length>0){if(configurator.isSimPresentOnFirstBoot){sortUnclassifiedApps(newEntries,entries);}else{newEntries.push(new GaiaGrid.Divider());newEntries=newEntries.concat(entries);}}
|
|
for(i=0,iLen=newEntries.length;i<iLen;i++){if(newEntries[i].detail){newEntries[i].detail.index=i;}}
|
|
return newEntries;}
|
|
function sortUnclassifiedApps(dstEntries,orgEntries){function compareApps(appA,appB){var svAppA=null;var svAppB=null;if(appA){svAppA=configurator.getSingleVariantApp(appA.detail.manifestURL);}
|
|
if(appB){svAppB=configurator.getSingleVariantApp(appB.detail.manifestURL);}
|
|
var locA=svAppA&&svAppA.location!==undefined&&svAppA.location||Number.MAX_VALUE;var locB=svAppB&&svAppB.location!==undefined&&svAppB.location||Number.MAX_VALUE;var relPos=locA-locB;return relPos?(relPos>0?1:-1):0;}
|
|
orgEntries.sort(compareApps);if(!configurator.getSingleVariantApp(orgEntries[0].detail.manifestURL)){dstEntries.push(new GaiaGrid.Divider());dstEntries=dstEntries.concat(orgEntries);}else{var sepAdded=false;for(var i=0,iLen=orgEntries.length;i<iLen;i++){var app=orgEntries[i];var svApp=configurator.getSingleVariantApp(app.detail.manifestURL);if(!svApp){if(!sepAdded){dstEntries.push(new GaiaGrid.Divider());sepAdded=true;}
|
|
dstEntries.push(app);}else{if(svApp.location!==undefined){dstEntries.splice(svApp.location,0,app);}else{dstEntries.push(app);}}}}}
|
|
function loadTable(table,indexName,iterator,aNext){newTxn(table,'readonly',function(txn,store){var index=store.index(indexName);index.openCursor().onsuccess=function onsuccess(event){var cursor=event.target.result;if(!cursor){return;}
|
|
iterator(cursor.value);cursor.continue();};},aNext);}
|
|
function newTxn(storeName,txnType,withTxnAndStore,successCb){var txn=db.transaction([storeName],txnType);var store=txn.objectStore(storeName);txn.oncomplete=function(event){if(successCb){successCb(event);}};txn.onerror=function(event){console.warn('Error during transaction.');};withTxnAndStore(txn,store);}
|
|
function ItemStore(onsuccess){var self=this;this.applicationSource=new ApplicationSource(this);this.bookmarkSource=new BookmarkSource(this);this.sources=[this.applicationSource,this.bookmarkSource];this.ready=false;var isEmpty=false;self.gridOrder=null;var request=window.indexedDB.open(DB_NAME,DB_VERSION);request.onupgradeneeded=function _onupgradeneeded(event){var db=event.target.result;var oldVersion=event.oldVersion||0;switch(oldVersion){case 0:var objectStore=db.createObjectStore(DB_ITEM_STORE,{keyPath:'index'});objectStore.createIndex('index','index',{unique:true});isEmpty=true;var objectSV=db.createObjectStore(DB_SV_APP_STORE_NAME,{keyPath:'manifestURL'});objectSV.createIndex('indexSV','indexSV',{unique:true});}};request.onsuccess=function _onsuccess(){onsuccess&&onsuccess(isEmpty);db=request.result;var cb=self.fetch.bind(self,self.synchronize.bind(self));if(isEmpty){window.addEventListener('configuration-ready',function onReady(){window.removeEventListener('configuration-ready',onReady);self.gridOrder=configurator.getGrid();self.populate(cb);});}else{self.initSources(cb);}
|
|
navigator.mozSetMessageHandler('connection',self.handleIAC.bind(self));};window.addEventListener('gaiagrid-cached-icons-rendered',this);}
|
|
ItemStore.prototype={_renderedOnce:false,_deferredSaveArgs:[],_allItems:[],nextPosition:0,all:function(success){if(!this.ready){window.addEventListener('databaseready',this.all.bind(this,success));return;}
|
|
success(this._allItems);},saveTable:function(table,objArr,column,checkPersist,aNext){newTxn(table,'readwrite',function(txn,store){store.clear();for(var i=0,iLen=objArr.length;i<iLen;i++){if(!checkPersist||(checkPersist&&objArr[i].persistToDB)){store.put(column?objArr[i][column]:objArr[i]);}}
|
|
if(typeof aNext==='function'){aNext();}});},saveMigrationData:function(objArr,column,checkPersist){return datastore.clear().then(()=>{var chain=[];objArr.forEach((object)=>{if(!checkPersist||object.persistToDB){var data=column?object[column]:object;chain.push(datastore.put(data,data.index+1));}});return Promise.all(chain);});},saveItem:function(object,callback){if(object.index==null){console.error('Attempting to save object without `index`');return;}
|
|
newTxn(DB_ITEM_STORE,'readwrite',function(txn,store){store.put(object);},callback);},deferredSave:function(){var args=Array.slice(arguments);if(this._renderedOnce){return this.save.apply(this,args);}
|
|
this._deferredSaveArgs=args;},save:function(entries,aNext){entries=sort(entries,this.gridOrder);this.gridOrder=null;this.saveTable(DB_ITEM_STORE,entries,'detail',true,aNext);},savePrevInstalledSvApp:function(svApps,aNext){this.saveTable(DB_SV_APP_STORE_NAME,svApps,null,false,aNext);},fetch:function(callback){var cached={};var collected=[];function iterator(value){collected.push(value);}
|
|
function iteratorSV(value){this.applicationSource.addPreviouslyInstalledSvApp(value.manifestURL);}
|
|
loadTable(DB_SV_APP_STORE_NAME,'indexSV',iteratorSV.bind(this));loadTable(DB_ITEM_STORE,'index',iterator,finish.bind(this));function addIfUnique(item){if(!cached[item.identifier]){cached[item.identifier]=true;this._allItems.push(item);}}
|
|
function finish(){for(var i=0,iLen=collected.length;i<iLen;i++){var thisItem=collected[i];if(thisItem.type==='app'){var itemObj=this.applicationSource.mapToApp(thisItem);addIfUnique.call(this,itemObj);}else if(thisItem.type==='divider'){var divider=new GaiaGrid.Divider(thisItem);this._allItems.push(divider);}else if(thisItem.type==='bookmark'){var bookmark=new GaiaGrid.Bookmark(thisItem);addIfUnique.call(this,bookmark);}}
|
|
this.notifyReady();if(callback&&typeof callback==='function'){callback();}}},synchronize:function(){this.sources.forEach(function eachSource(source){source.synchronize();});},initSources:function(callback){var pending=this.sources.length;var allEntries=[];var self=this;var current=0;function handleSource(){var source=self.sources[current];current++;source.populate(next);}
|
|
handleSource();function next(entries){allEntries=allEntries.concat(entries);if(!(--pending)){callback(allEntries);}else{handleSource();}}},populate:function(callback){this.initSources(function(entries){this.deferredSave(entries,callback);}.bind(this));},notifyReady:function(){this.ready=true;dispatchEvent(new CustomEvent('databaseready'));},getNextPosition:function(){var nextPosition=this.nextPosition;this.nextPosition++;return nextPosition;},handleIAC:function(connectionRequest){if(connectionRequest.keyword!=='verticalhome-migrate'){return;}
|
|
var port=connectionRequest.port;port.onmessage=(event)=>{if(event.data.action!=='migrate'){console.error('Unhandled migration action requested:',event.data.action);return;}
|
|
this.migrate(event.data.manifestURL);};port.start();},migrate:function(manifestURL){this.migratingTo=manifestURL;console.info('verticalhome migrating to '+this.migratingTo);if(this.migrating){return;}
|
|
this.migrating=true;(datastore?Promise.resolve():navigator.getDataStores(DATASTORE_NAME).then(stores=>{datastore=stores[0];return Promise.resolve();},(e)=>{return Promise.reject(e);})).then(()=>{this.all(entries=>{this.saveMigrationData(entries,'detail',true).then(()=>{this.migrating=false;window.navigator.mozSettings.createLock().set({'homescreen.manifestURL':this.migratingTo});navigator.getDataStores(PREFS_STORE).then(stores=>{if(stores.length<1){console.error('Error opening verticalhome prefs datastore');return;}
|
|
stores[0].put('migrated',true).then(()=>{window.close();},e=>{console.error('Error storing migration pref',e);window.close();});});});});},e=>{console.error('Error retrieving datastore',e);});},handleEvent:function(e){switch(e.type){case'gaiagrid-cached-icons-rendered':this._renderedOnce=true;window.removeEventListener('gaiagrid-cached-icons-rendered',this);if(this._deferredSaveArgs.length){this.save.apply(this,this._deferredSaveArgs);}
|
|
break;}}};exports.ItemStore=ItemStore;}(window)); |