Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
182 lines
4.9 KiB
JavaScript
Executable file
182 lines
4.9 KiB
JavaScript
Executable file
'use strict';
|
|
|
|
/* exported MultiContact */
|
|
/* globals Promise, LazyLoader, contacts */
|
|
|
|
// ATTENTION: This library lazy loads contacts_merger.js
|
|
|
|
var MultiContact = (function() {
|
|
var datastores = Object.create(null);
|
|
var datastoresLoading = false;
|
|
var DS_READY_EVENT = 'ds_ready';
|
|
|
|
var MOZ_CONTACTS_OWNER = 'app://communications.gaiamobile.org';
|
|
|
|
function getDatastore(owner) {
|
|
if (datastores[owner]) {
|
|
return Promise.resolve(datastores[owner]);
|
|
}
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
if (datastoresLoading === true) {
|
|
document.addEventListener(DS_READY_EVENT, function handler() {
|
|
document.removeEventListener(DS_READY_EVENT, handler);
|
|
resolve(datastores[owner]);
|
|
});
|
|
}
|
|
else {
|
|
datastoresLoading = true;
|
|
|
|
navigator.getDataStores('contacts').then(function success(dsList) {
|
|
dsList.forEach(function(aDs) {
|
|
datastores[aDs.owner] = aDs;
|
|
});
|
|
// This is needed because mozContact DB is not exposed as a Datastore
|
|
// Once bug 1016838 lands this will not be needed
|
|
datastores[MOZ_CONTACTS_OWNER] = new MozContactsDatastore();
|
|
resolve(datastores[owner]);
|
|
datastoresLoading = false;
|
|
document.dispatchEvent(new CustomEvent(DS_READY_EVENT));
|
|
}, function err(error) {
|
|
console.error('Error while obtaining datastores: ', error.name);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Adapter object to obtain data from the mozContacts as if it were a DS
|
|
// Once bug 1016838 lands this will not be needed
|
|
function MozContactsDatastore() {
|
|
}
|
|
|
|
MozContactsDatastore.prototype = {
|
|
get: function(id) {
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
var options = {
|
|
filterBy: ['id'],
|
|
filterOp: 'equals',
|
|
filterValue: id
|
|
};
|
|
|
|
var req = navigator.mozContacts.find(options);
|
|
|
|
req.onsuccess = function() {
|
|
resolve(JSON.parse(JSON.stringify(req.result[0])));
|
|
};
|
|
|
|
req.onerror = function() {
|
|
reject(req.error);
|
|
};
|
|
});
|
|
},
|
|
get name() {
|
|
return 'mozContacts';
|
|
}
|
|
};
|
|
|
|
function getData(entry) {
|
|
if (!entry || !entry.id || !Array.isArray(entry.entryData)) {
|
|
return Promise.reject({
|
|
name: 'InvalidEntry'
|
|
});
|
|
}
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
var operations = [];
|
|
|
|
var entryData = entry.entryData;
|
|
|
|
var mozContactId;
|
|
entryData.forEach(function fetchEntry(aEntry) {
|
|
var owner = aEntry.origin;
|
|
if (owner === MOZ_CONTACTS_OWNER) {
|
|
mozContactId = aEntry.uid;
|
|
}
|
|
|
|
getDatastore(owner).then(function success(datastore) {
|
|
operations.push(datastore.get(aEntry.uid));
|
|
// It is needed to wait to have all operations ready
|
|
if (operations.length === entryData.length) {
|
|
execute(operations, resolve, reject, {
|
|
targetId: entry.id,
|
|
mozContactId: mozContactId
|
|
});
|
|
}
|
|
}, function error(err) {
|
|
console.error('Error while obtaining datastore: ', err.name);
|
|
reject(err);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
function execute(operations, resolve, reject, options) {
|
|
Promise.all(operations).then(function success(results) {
|
|
if (results.length === 1) {
|
|
results[0].id = options.targetId;
|
|
resolve(results[0]);
|
|
return;
|
|
}
|
|
|
|
if (options.mozContactId) {
|
|
results = reorderResults(results, options.mozContactId);
|
|
}
|
|
|
|
LazyLoader.load('/shared/js/contacts/contacts_merger.js',
|
|
function() {
|
|
var matchings = createMatchingContacts(results);
|
|
|
|
contacts.Merger.inMemoryMerge(results[0], matchings).then(
|
|
function success(mergedResult) {
|
|
mergedResult.id = options.targetId;
|
|
resolve(mergedResult);
|
|
}, function error(err) {
|
|
console.log('Error while merging: ', err);
|
|
reject(err);
|
|
});
|
|
});
|
|
}, function error(err) {
|
|
console.error('Error while getting data: ', err.name);
|
|
reject(err);
|
|
});
|
|
}
|
|
|
|
|
|
// This function reorders the contact data results array in order to
|
|
// put the mozContact in the first position, as mozContact data will be taken
|
|
// precedence over other datastore data
|
|
function reorderResults(results, mozContactId) {
|
|
var out = [];
|
|
|
|
for (var j = 0; j < results.length; j++) {
|
|
if (results[j].id === mozContactId) {
|
|
out.unshift(results[j]);
|
|
}
|
|
else {
|
|
out.push(results[j]);
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
// This function adapts the result array to the input object expected by
|
|
// the contacts_merger module
|
|
function createMatchingContacts(results) {
|
|
var out = [];
|
|
|
|
for (var j = 1; j < results.length; j++) {
|
|
out.push({
|
|
matchingContact: results[j]
|
|
});
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
return {
|
|
'getData': getData
|
|
};
|
|
})();
|