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,469 @@
'use strict';
/* global evt, ManifestHelper */
(function(exports) {
/**
* Application Entry Point
*
* This object stands for an entry point of the app. There can be more than
* one entry point in one app. Each entry point can own its name and icon, and
* can be launched singly.
*
* @property {String} manifestURL The app's manifestURL.
* @property {String} entryPoint The entry point defined in app's manifest.
* @property {String} name The name of the entry.
* @typedef {Object} AppEntryPoint
*/
/**
* Applications is a helper for mozApps.mgmt. It is responsible for:
*
* - get all installed apps
* - get app icon blob
* - listen to app install/update/uninstall events and publish them
* - launch app
*
* @namespace Applications
* @requires ManifestHelper
*/
var Applications = evt({
/**
* App roles which we don't need to handle and monitor.
*
* @constant
* @type {Array}
* @memberof Applications
*/
HIDDEN_ROLES: [
'system', 'homescreen', 'input', 'deck', 'addon', 'langpack', 'widget'
],
/**
* Default icon url.
*
* @constant
* @type {String}
* @memberof Applications
*/
DEFAULT_ICON_URL: '/style/images/default.png',
/**
* Installed apps indexed by their "manifestURL".
*
* @readonly
* @type {Object}
* @memberof Applications
*/
installedApps: {},
_ready: false,
_readyCallbacks: [],
_isHiddenApp: function appIsHiddenApp(role) {
if (!role) {
return false;
}
return (this.HIDDEN_ROLES.indexOf(role) !== -1);
},
_loadIcon: function appLoadIcon(request) {
if (!request.url) {
if (request.onerror) {
request.onerror();
}
return;
}
var xhr = new XMLHttpRequest({
mozAnon: true,
mozSystem: true
});
var icon = request.url;
xhr.open('GET', icon, true);
xhr.responseType = 'blob';
xhr.onload = function onload(evt) {
var status = xhr.status;
if (status !== 0 && status !== 200) {
if (request.onerror) {
request.onerror();
}
return;
}
if (request.onsuccess) {
request.onsuccess(xhr.response);
}
};
xhr.ontimeout = xhr.onerror = function onerror(evt) {
if (request.onerror) {
request.onerror();
}
};
try {
xhr.send(null);
} catch (evt) {
if (request.onerror) {
request.onerror();
}
}
},
_bestMatchingIcon:
function appBestMatchingIcon(app, manifest, preferredSize) {
preferredSize = preferredSize || Number.MAX_VALUE;
var max = 0;
var closestSize = 0;
for (var size in manifest.icons) {
size = parseInt(size, 10);
if (size > max) {
max = size;
}
if (!closestSize && size >= preferredSize) {
closestSize = size;
}
}
if (! closestSize) {
closestSize = max;
}
var url = manifest.icons[closestSize];
if (!url) {
return;
}
if (url.indexOf('data:') === 0 ||
url.indexOf('app://') === 0 ||
url.indexOf('http://') === 0 ||
url.indexOf('https://') === 0) {
return url;
}
if (url.charAt(0) != '/') {
console.warn('`' + manifest.name + '` app icon is invalid. ' +
'Manifest `icons` attribute should contain URLs -or- ' +
'absolute paths from the origin field.');
return '';
}
if (app.origin.slice(-1) === '/') {
return app.origin.slice(0, -1) + url;
}
return app.origin + url;
},
/**
* An easy way to register callback functions for "ready" event.
*
* Use this method to initialize your code if it depends on Applications. It
* will be triggered immediately if Applications is already ready.
*
* @param {Function} callback This function will be called when initialized.
* @memberof Applications
*/
ready: function appReady(callback) {
if (this._ready) {
window.setTimeout(callback);
} else {
this._readyCallbacks.push(callback);
}
},
onAppInstall: function onAppInstall(evt) {
var app = evt.application;
var manifest = app.manifest || app.updateManifest;
if (!app.launch || !manifest || !manifest.icons ||
this._isHiddenApp(manifest.role)) {
return;
}
var message =
this.installedApps[app.manifestURL] ? 'update' : 'install';
this.installedApps[app.manifestURL] = app;
this.fire(message, this.getAppEntries(app.manifestURL));
},
onAppUninstall: function onAppUninstall(evt) {
var app = evt.application;
if (this.installedApps[app.manifestURL]) {
this.fire('uninstall', this.getAppEntries(app.manifestURL));
delete this.installedApps[app.manifestURL];
}
},
/**
* Initialize Applications.
*
* The callback functions registered by "ready" method will be triggered
* after it's done.
*
* @param {Function} callback This function will be called when "init" is
* done.
* @memberof Applications
*/
init: function appInit(callback) {
var appMgmt = navigator.mozApps.mgmt;
var self = this;
appMgmt.getAll().onsuccess = function onsuccess(event) {
event.target.result.forEach(function eachApp(app) {
var manifest = app.manifest;
if (!app.launch || !manifest || !manifest.icons ||
self._isHiddenApp(manifest.role)) {
return;
}
self.installedApps[app.manifestURL] = app;
});
self._ready = true;
if (callback) {
callback();
}
while (self._readyCallbacks.length) {
setTimeout(self._readyCallbacks.shift());
}
};
appMgmt.addEventListener('install', this);
appMgmt.addEventListener('uninstall', this);
},
/**
* Release all resources.
*
* @memberof Applications
*/
uninit: function appUninit() {
var appMgmt = navigator.mozApps.mgmt;
appMgmt.oninstall = null;
appMgmt.onuninstall = null;
this.installedApps = {};
this._ready = false;
this._readyCallbacks = [];
},
/* jshint -W004 */
// XXX: Uses this to prevent 'helper' is already defined jshint error
/**
* Get all "entry_point"s from the specified app.
*
* @param {String} manifestURL The app's manifestURL.
* @return {Array} An array contains all {@link AppEntryPoint} of the
* specified app.
* @memberof Applications
*/
getAppEntries: function appGetAppEntries(manifestURL) {
if (!manifestURL || !this.installedApps[manifestURL]) {
return [];
}
var manifest = this.installedApps[manifestURL].manifest ||
this.installedApps[manifestURL].updateManifest;
var entryPoints = manifest.entry_points;
var entries = [];
var removable = this.installedApps[manifestURL].removable;
if (!entryPoints || manifest.type !== 'certified') {
var helper = new ManifestHelper(manifest);
entries.push({
manifestURL: manifestURL,
entryPoint: '',
name: helper.name,
removable: removable
});
} else {
for (var entryPoint in entryPoints) {
if (entryPoints[entryPoint].icons) {
var helper = new ManifestHelper(entryPoints[entryPoint]);
entries.push({
manifestURL: manifestURL,
entryPoint: entryPoint,
name: helper.name,
removable: removable
});
}
}
}
return entries;
},
/* jshint +W004 */
/**
* Get all "entry_point"s from all installed apps.
*
* @return {Array} An array contains all {@link AppEntryPoint} of the
* installed apps.
* @memberof Applications
*/
getAllAppEntries: function appGetAllAppEntries() {
if (!this._ready) {
return null;
}
var entries = [];
for (var manifestURL in this.installedApps) {
entries.push.apply(entries, this.getAppEntries(manifestURL));
}
return entries;
},
/**
* Launch an app by its manifestURL and entryPoint.
*
* @param {String} manifestURL The app's manifestURL.
* @param {String} [entryPoint] The specific "entry_point" you want to
* launch. Default launch path will be involved
* if it's omitted.
* @return {Boolean} true if succeed.
* @memberof Applications
*/
launch: function appLaunch(manifestURL, entryPoint) {
var installedApps = this.installedApps;
if (!manifestURL || !installedApps[manifestURL] ||
!installedApps[manifestURL].launch) {
return false;
}
entryPoint = entryPoint || '';
installedApps[manifestURL].launch(entryPoint);
return true;
},
/**
* Get manifest object by specified manifestURL and entryPoint.
*
* @param {String} manifestURL The app's manifestURL.
* @param {String} [entryPoint] Specify an "entry_point" if you want to get
* its part only. Otherwise, the whole manifest
* object will be returned.
* @return {Object} A manifest object or "null" if the app doesn't exist.
* @memberof Applications
*/
getEntryManifest: function appGetEntryManifest(manifestURL, entryPoint) {
if (!manifestURL || !this.installedApps[manifestURL]) {
return null;
}
var manifest = this.installedApps[manifestURL].manifest ||
this.installedApps[manifestURL].updateManifest;
if (entryPoint) {
var entry_manifest = manifest.entry_points[entryPoint];
return entry_manifest || null;
}
return manifest;
},
/**
* Get app/entry's name.
*
* @param {String} manifestURL An app's manifestURL.
* @param {String} [entryPoint] Specify an "entry_point" if you want to get
* its part only. Otherwise, the default name
* will be returned.
* @return {String} The app/entry's name or empty string if the app doesn't
* exist.
* @memberof Applications
*/
getName: function appGetName(manifestURL, entryPoint) {
var entry_manifest = this.getEntryManifest(manifestURL, entryPoint);
if (!entry_manifest) {
return '';
}
return new ManifestHelper(entry_manifest).name;
},
/**
* Get blob data of the app/entry's icon.
*
* @param {String} manifestURL An app's manifestURL.
* @param {String} [entryPoint] Specify an "entry_point".
* @param {Number} [preferredSize=Number.MAX_VALUE]
* In pixels. This method will choose the smallest icon that its
* width greater than this value or the biggest one if all the icons'
* width are smaller than this value.
* @param {Function} [callback] The callback will contains blob data as the
* first argument if succeed or "undefined" if
* something failed.
* @return {Boolean} true if the process is started or false if no valid
* icon url can be found or the app doesn't exist.
* @memberof Applications
*/
getIconBlob: function appGetIconBlob(manifestURL, entryPoint, preferredSize,
callback) {
var entry_manifest = this.getEntryManifest(manifestURL, entryPoint);
if (! entry_manifest) {
return false;
}
var url = this._bestMatchingIcon(
this.installedApps[manifestURL], entry_manifest, preferredSize);
if (!url) {
if (callback) {
setTimeout(callback);
}
return true;
}
this._loadIcon({
url: url,
onsuccess: function(blob) {
if (callback) {
callback(blob);
}
},
onerror: function() {
if (callback) {
callback();
}
}
});
return true;
},
listAppsByRole: function listAppsByRole(role) {
var matched = [];
for (var manifestURL in this.installedApps) {
var app = this.installedApps[manifestURL];
if (!role || app.manifest.role === role) {
matched.push({
'manifestURL': manifestURL,
'app': app
});
}
}
return matched;
},
handleEvent: function handleEvent(evt) {
switch(evt.type) {
case 'install':
this.onAppInstall(evt);
break;
case 'uninstall':
this.onAppUninstall(evt);
break;
}
}
});
exports.Applications = Applications;
})(window);