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

165
gaia/apps/clock/js/app.js Executable file
View file

@ -0,0 +1,165 @@
define(function(require) {
'use strict';
/* global IntlHelper */
var Tabs = require('tabs');
var View = require('view');
var connectionHandler = require('connection/handler');
/**
* Global Application event handling and paging
*/
var App = {
/**
* Load the Tabs and Panels, attach events and navigate to the default view.
*/
init: function() {
connectionHandler.init();
IntlHelper.define('digit-nopadding', 'number', {
style: 'decimal',
useGrouping: false
});
this.tabs = new Tabs(document.getElementById('clock-tabs'));
window.addEventListener('hashchange', this);
window.addEventListener('visibilitychange', this);
// Tell audio channel manager that we want to adjust the alarm channel
// if the user press the volumeup/volumedown buttons in Clock.
if (navigator.mozAudioChannelManager) {
navigator.mozAudioChannelManager.volumeControlChannel = 'alarm';
}
this.visible = !document.hidden;
this.panels = Array.prototype.map.call(
document.querySelectorAll('[data-panel-id]'),
function(element) {
var panel = {
el: element,
fragment: element.dataset.panelId.replace('_', '-') + '-panel',
instance: null
};
return panel;
}.bind(this)
);
window.performance.mark('navigationLoaded');
this.navigate({ hash: '#alarm-panel' }, function() {
// Dispatch an event to mark when we've finished loading.
// At this point, the navigation is usable, and the primary
// alarm list tab has begun loading.
window.performance.mark('navigationInteractive');
}.bind(this));
return this;
},
/**
* Load and instantiate the specified panel (when necessary).
*
* @param {Object} panel - An object describing the panel. It must contain
* either an `el` attribute (defining the panel's
* containing element) or an `instance` attribute
* (defining the instantiated Panel itself).
* @param {Function} [callback] - A function that will be invoked with the
* instantiated panel once it is loaded.
*/
loadPanel: function(panel, callback) {
if (panel.instance) {
callback && setTimeout(callback, 0, panel);
return;
}
var moduleId = 'panels/' + panel.el.dataset.panelId + '/main';
require([moduleId], function(PanelModule) {
panel.instance = View.instance(panel.el, PanelModule);
callback && callback(panel);
});
},
alarmListLoaded: function() {
// Performance testing markers. See <https://bugzil.la/996038>.
// At this point, the alarm list has been loaded, and all facets
// of Clock are now interactive. The other panels are lazily
// loaded when the user switches tabs.
window.performance.mark('visuallyLoaded');
window.performance.mark('contentInteractive');
window.performance.mark('fullyLoaded');
},
/**
* split each event handler into it's own method
*/
handleEvent: function(event) {
var handler = this['on' + event.type];
if (handler) {
return handler.apply(this, arguments);
}
},
/**
* navigate between pages.
*
* @param {object} data Options for navigation.
* @param {string} data.hash The hash of the panel id. I.E. '#alarm-panel'.
* @param {function} callback Callback to invoke when done.
*/
navigate: function(data, callback) {
var currentIndex = this.panels.indexOf(this.currentPanel);
this.panels.forEach(function(panel, panelIndex) {
if ('#' + panel.fragment === data.hash) {
this.loadPanel(panel, function() {
var instance = panel.instance;
instance.navData = data.data || null;
instance.active = true;
instance.visible = true;
if (currentIndex !== -1 && currentIndex !== panelIndex) {
var direction = currentIndex < panelIndex;
requestAnimationFrame(function startAnimation(oldPanel) {
instance.transition =
direction ? 'slide-in-right' : 'slide-in-left';
oldPanel.instance.transition =
direction ? 'slide-out-left' : 'slide-out-right';
}.bind(null, this.currentPanel));
}
this.currentPanel = panel;
callback && callback();
}.bind(this));
} else {
if (panel.instance) {
panel.instance.active = false;
}
}
}, this);
this.currentHash = data.hash;
},
/**
* Navigate to the new hash.
*/
onhashchange: function(event) {
if (this.currentHash === location.hash) {
return;
}
this.navigate({ hash: location.hash });
},
/**
* Whenever the application gains/loses focus, inform the current panel of
* its visibility loss.
*/
onvisibilitychange: function(event) {
this.visible = !document.hidden;
if (this.currentPanel) {
this.currentPanel.visible = this.visible;
}
}
};
return App;
});