Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,479 @@
/* global utils */
'use strict';
var fb = window.fb || {};
if (!fb.sync) {
(function() {
var Sync = fb.sync = {};
var theWorker;
// Facebook contacts currently under update process
var fbContactsById;
var totalToChange = 0,
changed = 0;
// Next timestamp to be set
var nextTimestamp;
var completionCallback,
errorCallback;
// Only makes sense when the data from FB is provided to the sync module
// i.e. it is not the worker which obtains that data
var fbFriendsDataByUid;
var logLevel = fb.logLevel || parent.fb.logLevel || 'DEBUG';
var isDebug = (logLevel === 'DEBUG');
var alarmFrame = null,
currentAlarmRequest = null;
// Delay in closing the iframe that schedules the alarm.
// Avoiding console.log issues in the logcat
var DELAY_ALARM_SCHED = 5000;
function debug() {
if (isDebug) {
var theArgs = ['<<FBSync>>'];
for (var c = 0; c < arguments.length; c++) {
theArgs.push(arguments[c]);
}
window.console.log.apply(window.console, theArgs);
}
}
// Starts the worker
function startWorker() {
theWorker = new Worker('/facebook/js/sync_worker.js');
theWorker.onmessage = function(e) {
workerMessage(e.data);
};
theWorker.onerror = function(e) {
window.console.error('Worker Error', e.message, e.lineno, e.column);
if (typeof errorCallback === 'function') {
errorCallback({
type: 'default_error'
});
}
};
}
function workerMessage(m) {
switch (m.type) {
case 'query_error':
var error = m.data || {};
window.console.error('FB: Error reported by the worker',
JSON.stringify(error));
if (typeof errorCallback === 'function') {
errorCallback({
name: 'defaultError'
});
}
break;
case 'token_error':
debug('FB: Token error reported by the worker');
if (typeof errorCallback === 'function') {
errorCallback({
name: 'invalidToken'
});
}
break;
case 'timeout_error':
debug('Timeout error reported by the worker');
if (typeof errorCallback === 'function') {
errorCallback({
name: 'timeout'
});
}
break;
case 'trace':
debug(m.data);
break;
case 'friendRemoved':
removeFbFriend(m.data.contactId);
break;
case 'friendUpdated':
updateFbFriend(m.data.contactId,
fb.friend2mozContact(m.data.updatedFbData));
break;
// Message with the totals
case 'totals':
changed = 0;
totalToChange = m.data.totalToChange;
nextTimestamp = m.data.queryTimestamp;
var newFriendNumber = m.data.newFriendNumber;
if (newFriendNumber) {
debug('New friend number: ', newFriendNumber);
fb.utils.setCachedNumFriends(newFriendNumber);
}
debug('Total to be changed: ', totalToChange);
// If totals === 0 then the completion callback will be invoked
checkTotals();
break;
case 'friendImgReady':
debug('Friend Img Data ready: ', m.data.contactId);
updateFbFriendWhenImageReady(m.data);
break;
}
}
function updateFbFriendWhenImageReady(data) {
var contact = fbContactsById[data.contactId];
var uid = fb.getFriendUid(contact);
var updatedFbData = fbFriendsDataByUid[uid];
if (!data.photo) {
updateFbFriend(data.contactId, updatedFbData);
return;
}
utils.thumbnailImage(data.photo, function gotTumbnail(thumbnail) {
var fbInfo = {};
fbInfo.photo = [data.photo, thumbnail];
fb.setFriendPictureUrl(fbInfo, updatedFbData.pic_big);
updatedFbData.fbInfo = fbInfo;
updateFbFriend(data.contactId, updatedFbData);
});
}
function onsuccessCb() {
changed++;
checkTotals();
}
// Updates the FB data from a friend
function updateFbFriend(contactId, cfdata) {
fb.friend2mozContact(cfdata);
cfdata.fbInfo = cfdata.fbInfo || {};
cfdata.fbInfo.org = [fb.getWorksAt(cfdata)];
var birthDate = null;
if (cfdata.birthday_date && cfdata.birthday_date.length > 0) {
birthDate = fb.getBirthDate(cfdata.birthday_date);
}
cfdata.fbInfo.bday = birthDate;
var address = fb.getAddresses(cfdata);
if (address) {
cfdata.fbInfo.adr = address;
}
if (cfdata.shortTelephone) {
cfdata.fbInfo.shortTelephone = cfdata.shortTelephone;
delete cfdata.shortTelephone;
}
// Then the new data saved to the cache
var fbContact = new fb.Contact(fbContactsById[contactId]);
var fbReq = fbContact.update(cfdata);
// Nothing special
fbReq.onsuccess = function() {
debug('Friend updated correctly', cfdata.uid);
onsuccessCb();
};
// Error. mark the contact as pending to be synchronized
fbReq.onerror = function() {
window.console.error('FB: Error while saving contact data: ',
cfdata.uid);
changed++;
checkTotals();
};
}
function removeFbFriend(contactId) {
debug('Removing Friend: ', contactId);
var removedFriend = fbContactsById[contactId];
var fbContact = new fb.Contact(removedFriend);
if (fb.isFbLinked(removedFriend)) {
debug('Friend is linked: ', contactId);
// No care about what happens
var req = fbContact.unlink('hard');
req.onsuccess = onsuccessCb;
req.onerror = function() {
window.console.error('FB. Error while hard unlinking friend: ',
contactId);
// The counter has to be increased anyway
changed++;
checkTotals();
};
}
else {
debug('Friend is not linked: ', contactId);
var fbContactReq = fbContact.remove();
fbContactReq.onsuccess = onsuccessCb;
fbContactReq.onerror = function() {
window.console.error('FB. Error while removing contact: ',
contactId);
// The counter has to be increased anyway
changed++;
checkTotals();
};
}
}
function checkTotals() {
if (changed === totalToChange) {
debug('Sync process finished!');
if (window.contacts && window.contacts.List) {
window.setTimeout(window.contacts.List.load, 0);
}
// Once sync has finished the last update date is set
// Thus we ensure next will happen in the next <period> hours
fb.utils.setLastUpdate(nextTimestamp, function sync_end() {
completionCallback(totalToChange);
});
if (theWorker) {
theWorker.terminate();
theWorker = null;
}
}
}
// Starts a synchronization
Sync.start = function(params) {
if (params) {
completionCallback = params.success;
errorCallback = params.error;
}
totalToChange = 0;
changed = 0;
// First only take into account those Friends already on the device
// This work has to be done here and not by the worker as it has no
// access to the Web APIs
var req = fb.utils.getAllFbContacts();
req.onsuccess = function() {
var uids = {};
var fbContacts = req.result;
if (fbContacts.length === 0) {
debug('Nothing to be synchronized. No FB Contacts present');
return;
}
startWorker();
// Contacts by id are cached for later update
fbContactsById = {};
// Contacts for which an update will be forced
var forceUpdate = {};
fbContacts.forEach(function(contact) {
fbContactsById[contact.id] = contact;
var pictureUrl = fb.getFriendPictureUrl(contact);
var uid = fb.getFriendUid(contact);
uids[uid] = {
contactId: contact.id,
photoUrl: pictureUrl
};
if (!pictureUrl) {
forceUpdate[uid] = {
contactId: contact.id
// photoUrl is left undefined as it is not known
};
}
});
fb.utils.getLastUpdate(function run_worker(ts) {
fb.utils.getCachedAccessToken(function(access_token) {
// The worker must start
theWorker.postMessage({
type: 'start',
data: {
uids: uids,
imgNeedsUpdate: forceUpdate,
timestamp: ts,
access_token: access_token,
operationsTimeout: fb.operationsTimeout,
targetPictureSize: utils.misc.getPreferredPictureDetail()
}
});
});
});
};
req.onerror = function() {
window.console.error('FB: Error while getting friends on the device',
req.error.name);
if (typeof errorCallback === 'function') {
errorCallback({
name: 'defaultError'
});
}
};
};
// Schedules a next synchronization
Sync.scheduleNextSync = function() {
//
currentAlarmRequest = new fb.utils.Request();
window.setTimeout(function() {
// The alarm has to be scheduled by the same page that will handle it
// https://bugzilla.mozilla.org/show_bug.cgi?id=800431
alarmFrame = document.createElement('iframe');
alarmFrame.src = '/facebook/fb_sync.html';
alarmFrame.width = 1;
alarmFrame.height = 1;
alarmFrame.style.display = 'none';
document.body.appendChild(alarmFrame);
},0);
return currentAlarmRequest;
};
function cleanAlarmSchedFrame() {
alarmFrame.src = null;
document.body.removeChild(alarmFrame);
alarmFrame = null;
}
Sync.onAlarmScheduled = function(date) {
debug('Next synch scheduled at: ', date);
if (alarmFrame) {
window.setTimeout(cleanAlarmSchedFrame, DELAY_ALARM_SCHED);
}
currentAlarmRequest.done(date);
};
Sync.onAlarmError = function(e) {
if (alarmFrame) {
window.setTimeout(cleanAlarmSchedFrame, DELAY_ALARM_SCHED);
}
window.console.error('<<FB Sync>> Error while scheduling a new sync: ',
e);
currentAlarmRequest.failed(e);
};
Sync.debug = function() {
debug.apply(this, arguments);
};
// Starts a synchronization with data coming from import / link
Sync.startWithData = function(contactList, myFriendsByUid, callbacks) {
completionCallback = callbacks.success;
errorCallback = callbacks.error;
nextTimestamp = Date.now();
changed = 0;
// As it is not a priori known how many are going to needed a change
totalToChange = Number.MAX_VALUE;
debug('Starting Synchronization with data');
fbFriendsDataByUid = myFriendsByUid;
// Friends to be updated by the worker (those which profile img changed)
var toBeUpdated = {};
fb.utils.getLastUpdate(function import_updates(lastUpdate) {
var toBeChanged = 0;
var lastUpdateTime = Math.round(lastUpdate / 1000);
debug('Last update time: ', lastUpdateTime);
fbContactsById = {};
contactList.forEach(function(aContact) {
fbContactsById[aContact.id] = aContact;
var uid = fb.getFriendUid(aContact);
var friendData = fbFriendsDataByUid[uid];
if (friendData) {
var friendUpdate = friendData.profile_update_time;
debug('Friend update Time ', friendUpdate, 'for UID: ', uid);
var profileImgUrl = fb.getFriendPictureUrl(aContact);
if (friendUpdate > lastUpdateTime ||
profileImgUrl !== friendData.pic_big) {
debug('Friend changed!! : ', uid);
if (profileImgUrl !== friendData.pic_big) {
debug('Profile img changed: ', profileImgUrl);
toBeUpdated[uid] = {
contactId: aContact.id
};
}
else {
debug('Updating friend: ', friendData.uid);
toBeChanged++;
updateFbFriend(aContact.id, friendData);
}
}
else {
debug('Friend has not changed', uid);
}
}
else {
debug('Removing friend: ', aContact.id);
toBeChanged++;
removeFbFriend(aContact.id);
}
});
debug('First pass of Updates and removed finished');
// Those friends which image has changed will require help from the
// worker
var toBeUpdatedList = Object.keys(toBeUpdated);
if (toBeUpdatedList.length > 0) {
totalToChange = toBeChanged + toBeUpdatedList.length;
debug('Starting worker for updating img data');
startWorker();
fb.utils.getCachedAccessToken(function(access_token) {
theWorker.postMessage({
type: 'startWithData',
data: {
access_token: access_token,
uids: toBeUpdated,
operationsTimeout: fb.operationsTimeout,
targetPictureSize: utils.misc.getPreferredPictureDetail()
}
});
});
}
else {
totalToChange = toBeChanged;
checkTotals();
}
});
};
})();
}