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,287 @@
'use strict';
/* global Promise */
(function(exports) {
var datastore;
// Datastore name declared on the manifest.webapp
var DATASTORE_NAME = 'bookmarks_store';
// Indicates the initialization state
var readyState;
// Event listeners
var listeners = Object.create(null);
function init() {
return new Promise(function doInit(resolve, reject) {
if (readyState === 'initialized') {
resolve();
return;
}
if (readyState === 'initializing') {
document.addEventListener('ds-initialized', function oninitalized() {
document.removeEventListener('ds-initialized', oninitalized);
resolve();
});
return;
}
readyState = 'initializing';
if (!navigator.getDataStores) {
console.error('Bookmark store: DataStore API is not working');
reject({ name: 'NO_DATASTORE' });
readyState = 'failed';
return;
}
navigator.getDataStores(DATASTORE_NAME).then(function(ds) {
if (ds.length < 1) {
console.error('Bookmark store: Cannot get access to the Store');
reject({ name: 'NO_ACCESS_TO_DATASTORE' });
readyState = 'failed';
return;
}
datastore = ds[0];
datastore.addEventListener('change', onchangeHandler);
readyState = 'initialized';
document.dispatchEvent(new CustomEvent('ds-initialized'));
resolve();
}, reject);
});
}
function doGetAll(resolve, reject) {
var result = Object.create(null);
var cursor = datastore.sync();
function cursorResolve(task) {
switch (task.operation) {
case 'update':
case 'add':
result[task.data.id] = task.data;
break;
case 'remove':
delete result[task.data.id];
break;
case 'clear':
result = Object.create(null);
break;
case 'done':
resolve(result);
return;
}
cursor.next().then(cursorResolve, reject);
}
cursor.next().then(cursorResolve, reject);
}
function get(id) {
return new Promise(function doGet(resolve, reject) {
init().then(function onInitialized() {
datastore.get(id).then(resolve, reject);
}, reject);
});
}
function getAll() {
return new Promise(function doGet(resolve, reject) {
init().then(doGetAll.bind(null, resolve, reject), reject);
});
}
function onchangeHandler(event) {
var operation = event.operation;
var callbacks = listeners[operation];
callbacks && callbacks.forEach(function iterCallback(callback) {
datastore.get(event.id).then(function got(result) {
callback.method.call(callback.context || this, {
type: operation,
target: result || event
});
});
});
}
function addEventListener(type, callback) {
var context;
if (!(type in listeners)) {
listeners[type] = [];
}
var cb = callback;
if (typeof cb === 'object') {
context = cb;
cb = cb.handleEvent;
}
if (cb) {
listeners[type].push({
method: cb,
context: context
});
init();
}
}
function removeEventListener(type, callback) {
if (!(type in listeners)) {
return false;
}
var callbacks = listeners[type];
var length = callbacks.length;
for (var i = 0; i < length; i++) {
var thisCallback = callback;
if (typeof thisCallback === 'object') {
thisCallback = callback.handleEvent;
}
if (callbacks[i] && callbacks[i].method === thisCallback) {
callbacks.splice(i, 1);
return true;
}
}
return false;
}
function add(data) {
return new Promise(function doAdd(resolve, reject) {
init().then(function onInitialized() {
var id = data.url;
Object.defineProperty(data, 'id', {
enumerable: true,
configurable: false,
writable: false,
value: id
});
datastore.add(data, id).then(function add_success() {
resolve(true); // Bookmark was added
}, function add_error() {
datastore.put(data, id).then(function put_success() {
resolve(); // Bookmark was updated
}, reject);
});
}, reject);
});
}
function getRevisionId() {
return new Promise(function doGet(resolve, reject) {
init().then(function onInitialized() {
resolve(datastore.revisionId);
}, reject);
});
}
function put(data) {
return new Promise(function doAdd(resolve, reject) {
init().then(function onInitialized() {
datastore.put(data, data.id).then(function success() {
resolve(); // Bookmark was updated
}, reject);
}, reject);
});
}
function remove(id) {
return new Promise(function doRemove(resolve, reject) {
init().then(function onInitialized() {
datastore.remove(id).then(resolve, reject);
}, reject);
});
}
function clear() {
return new Promise(function doClear(resolve, reject) {
init().then(function onInitialized() {
datastore.clear().then(resolve, reject);
}, reject);
});
}
exports.BookmarksDatabase = {
/*
* This method returns a bookmark object
*
* @param{String} String param that represents an identifier
*/
get: get,
/*
* This method returns an object of bookmarks indexed by id
*/
getAll: getAll,
/*
* Returns the latest revision UUID
*/
getRevisionId: getRevisionId,
/*
* Method registers the specified listener on the API
*
* @param{String} A string representing the event type to listen for
*
* @param{Function} The method that receives a notification when an event of
* the specified type occurs
*
*/
addEventListener: addEventListener,
/*
* Method removes the specified listener on the API
*
* @param{String} A string representing the event type to listen for
*
* @param{Function} The method that received a notification when an event of
* the specified type occurs
*
*/
removeEventListener: removeEventListener,
/*
* This method adds a bookmark in the datastore
*
* @param{Object} The bookmark's data
*/
add: add,
/*
* This method updates a bookmark in the datastore
*
* @param{Object} The bookmark's data
*/
put: put,
/*
* This method removes a bookmark from the datastore
*
* @param{String} The bookmark's id
*/
remove: remove,
/*
*
* This method clears the entire datastore, removing all entries.
*
*/
clear: clear
};
}(window));

View file

@ -0,0 +1,154 @@
/* exported LazyLoader */
/* globals HtmlImports, Promise */
'use strict';
/**
* This contains a simple LazyLoader implementation
* To use:
*
* LazyLoader.load(
* ['/path/to/file.js', '/path/to/file.css', 'domNode'], callback
* );
*/
var LazyLoader = (function() {
function LazyLoader() {
this._loaded = {};
this._isLoading = {};
}
LazyLoader.prototype = {
_js: function(file, callback) {
var script = document.createElement('script');
script.src = file;
// until bug 916255 lands async is the default so
// we must disable it so scripts load in the order they where
// required.
script.async = false;
script.addEventListener('load', callback);
document.head.appendChild(script);
this._isLoading[file] = script;
},
_css: function(file, callback) {
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = file;
document.head.appendChild(style);
callback();
},
_html: function(domNode, callback) {
// The next few lines are for loading html imports in DEBUG mode
if (domNode.getAttribute('is')) {
this.load(['/shared/js/html_imports.js'], function() {
HtmlImports.populate(callback);
}.bind(this));
return;
}
for (var i = 0; i < domNode.childNodes.length; i++) {
if (domNode.childNodes[i].nodeType == document.COMMENT_NODE) {
domNode.innerHTML = domNode.childNodes[i].nodeValue;
break;
}
}
window.dispatchEvent(new CustomEvent('lazyload', {
detail: domNode
}));
callback();
},
/**
* Retrieves content of JSON file.
*
* @param {String} file Path to JSON file
* @param {Boolean} mozSystem If xhr should use mozSystem permissions
* @return {Promise} A promise that resolves to the JSON content
* or null in case of invalid path. Rejects if an error occurs.
*/
getJSON: function(file, mozSystem) {
return new Promise(function(resolve, reject) {
var xhr;
if (mozSystem) {
xhr = new XMLHttpRequest({mozSystem: true});
} else {
xhr = new XMLHttpRequest();
}
xhr.open('GET', file, true);
xhr.responseType = 'json';
xhr.onerror = function(error) {
reject(error);
};
xhr.onload = function() {
if (xhr.response !== null) {
resolve(xhr.response);
} else {
reject(new Error('No valid JSON object was found (' +
xhr.status + ' ' + xhr.statusText + ')'));
}
};
xhr.send();
});
},
load: function(files, callback) {
var deferred = {};
deferred.promise = new Promise(resolve => {
deferred.resolve = resolve;
});
if (!Array.isArray(files)) {
files = [files];
}
var loadsRemaining = files.length, self = this;
function perFileCallback(file) {
if (self._isLoading[file]) {
delete self._isLoading[file];
}
self._loaded[file] = true;
if (--loadsRemaining === 0) {
deferred.resolve();
if (callback) {
callback();
}
}
}
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (this._loaded[file.id || file]) {
perFileCallback(file);
} else if (this._isLoading[file]) {
this._isLoading[file].addEventListener(
'load', perFileCallback.bind(null, file));
} else {
var method, idx;
if (typeof file === 'string') {
method = file.match(/\.([^.]+)$/)[1];
idx = file;
} else {
method = 'html';
idx = file.id;
}
this['_' + method](file, perFileCallback.bind(null, idx));
}
}
return deferred.promise;
}
};
return new LazyLoader();
}());