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,261 @@
'use strict';
var utils = window.utils || {};
if (!utils.templates) {
(function() {
var Templates = utils.templates = {};
/**
* Returns a target HTMLElement from a selector or HTMLElement itself
*
* @param {HTMLElement or Selector} element target element.
*
* @return {HTMLElement} HTMLElement according to the selector or itself.
*
*
*/
function getTarget(element) {
var target = element;
if (!element.tagName) {
target = document.querySelector(element);
}
return target;
}
/**
* Given a target HTML element which contains a template set
* returns the template that will have to be applied over the data
*
* @param {HTMLElement} target which contains the template.
* @param {Object} data to be used on the template.
*
* @return {HTMLElement} HTMLElement with the template.
*
*/
function getTemplate(target, data) {
// Multi templates temporarily disabled to avoid eval usage
// TODO: Implement an alternative for eval
var templates = target.querySelectorAll('*[data-template]');
if (templates.length === 0) {
throw new Error('No template declared');
}
if (templates.length > 1 && templates.item(0).dataset.condition) {
throw new Error('Only one template supported in this version');
}
return {
template: templates.item(0),
isMulti: false
};
}
/**
* Returns a function used to replace data on a template
*
* @param {Object} data the data to be used on the template.
*
* @return {function} to be used.
*
*/
function templateReplace(data) {
return function(text, property) {
var out;
if (property.indexOf('.') === -1) {
out = data[property];
if (Array.isArray(out) && out.length > 0) {
out = out[0];
}
} else {
throw new Error('Dotted expressions not supported');
}
if (typeof out === 'undefined') {
out = text;
}
return out;
};
}
/**
* Adds (append or prepend) a new instance HTMLElement (or array of)
* of a template
* The template is assumed to be a child of the element
* passed as parameter
* The new element will be appended as a child
*
* @param {HTMLElement} ele container lement that contains the template
* and which will contain the new instance. Can be an HTMLElement
* or a CSS selector.
*
* @param {object or array} data with the data displayed by the template.
*
* @param {String} mode oneOf ('A','P').
*
* @return {HTMLElement} (or last element if data is an array).
*
*
*/
function add(element, data, mode, targetNode) {
// It is supported both the element itself or a selector
var target = getTarget(element);
var newElem;
var theData = [data];
if (data instanceof Array) {
theData = data;
}
// Optimization to avoid trying to find a template when
// only one is needed
var multiTemplate = true;
var template;
var idx = 0;
theData.forEach(function(oneData) {
// Pseudo-field with the index
oneData._idx_ = idx++;
// A suitable template for the data is firstly found
if (multiTemplate === true) {
var tresult = getTemplate(target, oneData);
template = tresult.template;
if (tresult.isMulti === false) {
multiTemplate = false;
}
}
if (template) {
newElem = this.render(template, oneData);
target = targetNode || target;
if (mode === 'A') {
target.appendChild(newElem);
} else if (mode === 'P') { // Append mode
if (target.firstChild) {
target.insertBefore(newElem, element.firstChild);
} else {
target.appendChild(newElem);
}
} // prepend mode
} // if template
}.bind(Templates)); // forEach data
return newElem;
}
/**
* Appends a new instance HTMLElement (or array of) of a template
*
* The template is assumed to be a child of the element passed
* as parameter
* The new element will be appended as a child
*
* @param {HTMLElement or String} ele container element that
* contains the template and which will contain the new instance.
* Can be an HTMLElement or a CSS selector.
*
* @param {object or array} data with the data displayed by the template.
*
* @return {HTMLelement} (or last element if data is an array).
*
*
*/
Templates.append = function(element, data, targetNode) {
var f = add.bind(this);
return f(element, data, 'A', targetNode);
};
/**
* Prepends a new instance (or array of) of a template
*
* The template is assumed to be a child of the element passed
* as parameter
*
* @param {HTMLElement or String} ele container element that
* contains the template and which will contain the new instance.
* Can be an HTMLElement or a CSS selector.
*
* @param {Object or Array} data with the data displayed.
*
* @return {HTMLElement} added.
*
*
*/
Templates.prepend = function(element, data, targetNode) {
var f = add.bind(this);
return f(element, data, 'P', targetNode);
};
/**
* Renders the content specified by a template with object data
*
* @param {HTMLElement} eleTemplate the template itself.
* @param {Object} data the data to be used.
*
* @return {HTMLElement} according to the template and with the data.
*
*
*/
Templates.render = function(eleTemplate, data) {
var newElem = eleTemplate.cloneNode(true);
newElem.removeAttribute('data-template');
newElem.removeAttribute('data-condition');
/* var pattern = /#(\w+)#/g; */
var pattern = /#(\w+[\w.]*)#/g;
var inner = newElem.innerHTML;
// Replace function
var replaceFunction = templateReplace(data);
var ninner = inner.replace(pattern, replaceFunction);
newElem.innerHTML = ninner;
var attrs = newElem.attributes;
var total = attrs.length;
for (var c = 0; c < total; c++) {
var val = attrs[c].value;
var nval = val.replace(pattern, replaceFunction);
newElem.setAttribute(attrs[c].name, nval);
}
if (!newElem.id) {
if (data.id) {
newElem.id = data.id;
}
}
return newElem;
};
/**
* Clears a container element
*
* @param {HTMLElement or String} element (selector or HTML element).
*
*
*/
Templates.clear = function(element) {
var target = getTarget(element);
var templates = target.querySelectorAll('*[data-template]');
target.innerHTML = '';
var total = templates.length;
for (var c = 0; c < total; c++) {
target.appendChild(templates.item(c));
}
};
}) ();
} // window.templates