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

175
gaia/apps/homescreen/js/window.js Executable file
View file

@ -0,0 +1,175 @@
/* global Apps, Pages */
'use strict';
(function(exports) {
/**
* Time after receiving a handled hashchange that we ignore hashchange
* events for.
*/
const HASH_CHANGE_DEBOUNCE = 100;
function AppWindow() {
this.header = document.getElementById('page-indicator-header');
this.indicator = document.getElementById('page-indicator');
this.panels = document.getElementById('panels');
this.shadow = document.getElementById('shadow');
this.apps = new Apps();
this.pages = new Pages();
// Panel visibility state
this.appsVisible = undefined;
// Home-button handling
this.ignoreHashChangeTimeout = null;
// Signal handlers
this.indicator.addEventListener('keypress', this);
this.panels.addEventListener('scroll', this);
window.addEventListener('hashchange', this, true);
window.addEventListener('localized', this);
document.addEventListener('visibilitychange', this);
// Update the panel indicator
this.updatePanelIndicator();
// Application has finished initialisation
window.performance.mark('navigationInteractive');
}
AppWindow.prototype = {
updatePanelIndicator: function() {
var appsVisible =
Math.abs(this.panels.scrollLeft) <= this.panels.scrollWidth / 4;
if (this.appsVisible !== appsVisible) {
this.appsVisible = appsVisible;
this.header.setAttribute('data-l10n-id', appsVisible ?
'apps-panel' : 'pages-panel');
this.indicator.children[0].classList.toggle('active', appsVisible);
this.indicator.children[1].classList.toggle('active', !appsVisible);
this.indicator.setAttribute('aria-valuenow', appsVisible ? 1 : 2);
this.indicator.setAttribute('data-l10n-args', JSON.stringify({
currentPage: appsVisible ? 1 : 2,
totalPages: 2
}));
this.apps.panel.setAttribute('aria-hidden', !appsVisible);
this.pages.panel.setAttribute('aria-hidden', appsVisible);
if (appsVisible) {
this.pages.scrollable.removeEventListener('scroll', this);
this.apps.scrollable.addEventListener('scroll', this);
} else {
this.apps.scrollable.removeEventListener('scroll', this);
this.pages.scrollable.addEventListener('scroll', this);
}
this.updateShadowState();
}
},
updateShadowState: function() {
var position = this.appsVisible ?
this.apps.scrollable.scrollTop : this.pages.scrollable.scrollTop;
var scrolled = position > 1;
if (this.shadow.classList.contains('visible') !== scrolled) {
this.shadow.classList.toggle('visible', scrolled);
}
},
handleEvent: function(e) {
switch (e.type) {
// Switch between panels
case 'keypress':
if (!e.ctrlKey) {
return;
}
switch (e.keyCode) {
case e.DOM_VK_RIGHT:
this.panels.scrollTo(
{ left: this.panels.scrollLeftMax, top: 0, behavior: 'smooth' });
return;
case e.DOM_VK_LEFT:
this.panels.scrollTo(
{ left: 0, top: 0, behavior: 'smooth' });
return;
}
return;
// Display the top shadow when scrolling down
case 'scroll':
if (e.target === this.panels) {
this.updatePanelIndicator();
} else {
this.updateShadowState();
}
return;
// Cancel edit modes/scroll to the top/scroll to apps on home-button
case 'hashchange':
if (document.hidden || this.ignoreHashChangeTimeout !== null) {
return;
}
e.preventDefault();
e.stopImmediatePropagation();
this.ignoreHashChangeTimeout = setTimeout(() => {
this.ignoreHashChangeTimeout = null;
}, HASH_CHANGE_DEBOUNCE);
// If a dialog is showing, cancel the dialog
for (var dialog of this.apps.dialogs.concat(this.pages.dialogs)) {
if (!dialog.opened) {
continue;
}
dialog.close();
return;
}
// If we're in edit mode, cancel edit mode
if (this.apps.editMode) {
this.apps.exitEditMode();
return;
}
if (this.pages.editMode) {
this.pages.exitEditMode();
return;
}
// If we're on the pages panel and scrolled to the top, show apps
if (!this.appsVisible && this.pages.scrollable.scrollTop === 0) {
this.panels.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
return;
}
// Otherwise, scroll the visible panel to the top
var visiblePanel = this.appsVisible ?
this.apps.scrollable : this.pages.scrollable;
visiblePanel.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
return;
case 'localized':
this.updatePanelIndicator();
return;
// Exit edit mode if the user switches away from the home screen (e.g.
// by locking the phone).
case 'visibilitychange':
if (document.hidden) {
this.apps.exitEditMode();
this.pages.exitEditMode();
}
return;
}
}
};
exports.AppWindow = AppWindow;
}(window));