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

349
gaia/apps/system/js/statusbar.js Executable file
View file

@ -0,0 +1,349 @@
/**
Copyright 2012, Mozilla Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*global Service, UtilityTray, LazyLoader */
'use strict';
(function(exports) {
const AVG_ICON_SIZE = 22;
var Statusbar = {
name: 'Statusbar',
// The indices indicate icons priority (lower index = highest priority)
PRIORITIES: [
'time',
'emergency-callback',
'battery',
'recording',
'airplane-mode',
'wifi',
'mobile-connection',
'debugging',
'download',
'geolocation',
'network-activity',
'tethering',
'bluetooth-transfer',
'bluetooth',
'nfc',
'usb',
'alarm',
'bluetooth-headphone',
'mute',
'call-forwardings',
'playing',
'headphone',
'operator'
],
/* Whether or not status bar is actively updating or not */
active: true,
_numMinimizedIcons: 9,
_currentIcons: {},
get _iconsCount() {
return Object.keys(this._currentIcons).length;
},
/* For other modules to acquire */
get height() {
if (document.mozFullScreen ||
(Service.query('getTopMostWindow') &&
Service.query('getTopMostWindow').isFullScreen())) {
return 0;
} else {
return this._cacheHeight ||
(this._cacheHeight =
this.element.getBoundingClientRect().height);
}
},
start: function() {
this.getAllElements();
// cache height.
this._cacheHeight = this.element.getBoundingClientRect().height;
window.addEventListener('apptitlestatechanged', this);
window.addEventListener('activitytitlestatechanged', this);
window.addEventListener('homescreentitlestatechanged', this);
window.addEventListener('appchromecollapsed', this);
window.addEventListener('appchromeexpanded', this);
window.addEventListener('iconshown', this);
window.addEventListener('iconhidden', this);
window.addEventListener('iconrendered', this);
if (Service.query('FtuLauncher.isFinished')) {
this.finishInit();
} else {
window.addEventListener('ftuskip', this);
window.addEventListener('ftudone', this);
}
Service.registerState('height', this);
Service.register('iconContainer', this);
},
calculateMinimized: function sb_calculateMinimized() {
var minimizedWidth = this.element.clientWidth / 2;
var count = minimizedWidth / AVG_ICON_SIZE;
this._numMinimizedIcons = Math.floor(count);
},
iconContainer: function sb_iconContainer(icon) {
if (icon.dashPureName === 'operator') {
return this.statusbarTray;
}
return this.statusbarIcons;
},
/**
* Finish all initializing statusbar event handlers
*/
finishInit: function() {
window.addEventListener(
'appstatusbar-fullscreen-statusbar-set-appearance', this);
window.addEventListener('appstatusbar-fullscreen-statusbar-show', this);
window.addEventListener('appstatusbar-fullscreen-statusbar-hide', this);
window.addEventListener('sheets-gesture-begin', this);
window.addEventListener('sheets-gesture-end', this);
window.addEventListener('utilitytraywillshow', this);
window.addEventListener('utilitytraywillhide', this);
window.addEventListener('utility-tray-overlayopened', this);
window.addEventListener('utility-tray-overlayclosed', this);
window.addEventListener('utility-tray-abortopen', this);
window.addEventListener('utility-tray-abortclose', this);
window.addEventListener('cardviewshown', this);
window.addEventListener('cardviewclosed', this);
window.addEventListener('attentionopened', this);
window.addEventListener('appwillopen', this);
window.addEventListener('appwillclose', this);
window.addEventListener('appopened', this);
window.addEventListener('appclosed', this);
window.addEventListener('hierarchytopmostwindowchanged', this);
window.addEventListener('activityopened', this);
window.addEventListener('homescreenopened', this);
window.addEventListener('stackchanged', this);
window.addEventListener('lockscreen-request-unlock', this);
// Listen to updates dialog
window.addEventListener('updatepromptshown', this);
window.addEventListener('updateprompthidden', this);
// We need to preventDefault on mouse events until
// https://bugzilla.mozilla.org/show_bug.cgi?id=1005815 lands
var events = ['touchstart', 'touchmove', 'touchend',
'mousedown', 'mousemove', 'mouseup'];
events.forEach(function bindEvents(name) {
this.topPanel.addEventListener(name, this.panelHandler.bind(this));
}, this);
LazyLoader.load([
'js/utility_tray_motion.js',
'js/utility_tray.js'
]).then(function() {
this.utilityTray = UtilityTray;
UtilityTray.init();
}.bind(this)).catch((err) => {
console.error('UtilityTray load or init error', err);
});
this.calculateMinimized();
},
handleEvent: function sb_handleEvent(evt) {
var icon;
switch (evt.type) {
case 'iconshown':
this._currentIcons[evt.detail.dashPureName] = true;
this.toggleMaximized();
break;
case 'iconhidden':
delete this._currentIcons[evt.detail.dashPureName];
break;
case 'ftudone':
case 'ftuskip':
this.finishInit();
break;
case 'iconrendered':
icon = evt.detail;
var order = this.PRIORITIES.indexOf(icon.dashPureName);
icon.setOrder(order);
break;
case 'attentionopened':
this.element.classList.add('maximized');
this.element.classList.remove('light');
break;
case 'sheets-gesture-begin':
case 'appwillopen':
case 'appwillclose':
case 'cardviewshown':
this.element.classList.add('hidden');
break;
case 'sheets-gesture-end':
case 'stackchanged':
case 'cardviewclosed':
this.element.classList.remove('hidden');
break;
case 'appstatusbar-fullscreen-statusbar-show':
this.topPanel.style.pointerEvents = 'none';
break;
case 'appstatusbar-fullscreen-statusbar-hide':
this.topPanel.style.pointerEvents = '';
break;
case 'utilitytraywillshow':
case 'utilitytraywillhide':
case 'appstatusbar-fullscreen-statusbar-set-appearance':
case 'utility-tray-overlayopened':
case 'utility-tray-overlayclosed':
case 'utility-tray-abortopen':
case 'utility-tray-abortclose':
case 'appchromecollapsed':
case 'updateprompthidden':
this.setAppearance();
break;
case 'appopened':
var app = evt.detail;
if (!app.isFullScreen() && !app.isFullScreenLayout()) {
this.element.setAttribute('aria-owns',
evt.detail.appChrome.element.id);
} else {
this.element.removeAttribute('aria-owns');
}
/* falls through */
case 'appclosed':
case 'hierarchytopmostwindowchanged':
case 'lockscreen-request-unlock':
case 'appchromeexpanded':
this.element.classList.remove('hidden');
this.setAppearance();
break;
case 'activityopened':
case 'apptitlestatechanged':
case 'activitytitlestatechanged':
case 'homescreentitlestatechanged':
this.setAppearance();
this.element.classList.remove('hidden');
break;
case 'homescreenopened':
// In some cases, if the user has been switching apps so fast and
// quickly he press the home button, we might miss the
// |sheets-gesture-end| event so we must resume the statusbar
// if needed
this.setAppearance();
this.element.classList.remove('hidden');
this.element.classList.remove('fullscreen');
this.element.classList.remove('fullscreen-layout');
this.element.removeAttribute('aria-owns');
break;
case 'updatepromptshown':
this.element.classList.remove('light');
break;
}
},
setAppearance: function() {
var app = Service.query('getTopMostWindow');
if (!app) {
return;
}
var isFullScreen = app.isFullScreen() || document.mozFullScreen;
this.element.classList.toggle('light',
!!(app.appChrome && app.appChrome.useLightTheming()) && !isFullScreen
);
this.element.classList.toggle('fullscreen', isFullScreen);
this.element.classList.toggle('fullscreen-layout',
app.isFullScreenLayout()
);
this.toggleMaximized();
},
toggleMaximized: function() {
var app = Service.query('getTopMostWindow');
if (!app) {
return;
}
var appsWithoutRocketbar = [
'isHomescreen',
'isAttentionWindow',
'isLockscreen'
];
var noRocketbar = appsWithoutRocketbar.some(function(name) {
return !!(app[name]);
});
var chromeMaximized = !!(app.appChrome && app.appChrome.isMaximized());
var trayActive = !!(this.utilityTray && this.utilityTray.shown);
var shouldMaximize = noRocketbar || chromeMaximized || trayActive;
var fewIcons = (this._iconsCount < this._numMinimizedIcons);
// Important: we need a boolean to make the toggle method
// take the right decision
var elem = this.element;
elem.classList.toggle('maximized', !!(shouldMaximize && !fewIcons));
},
panelHandler: function sb_panelHandler(evt) {
// Do not forward events if FTU is running
if (Service.query('isFtuRunning')) {
return;
}
// Do not forward events if the utility tray is shown.
if (this.utilityTray && this.utilityTray.shown) {
return;
}
var app = Service.query('getTopMostWindow');
app && app.handleStatusbarTouch(evt, this._cacheHeight);
},
getAllElements: function sb_getAllElements() {
this.element = document.getElementById('statusbar');
this.statusbarIcons = document.getElementById('statusbar-icons');
this.statusbarIconsMax = document.getElementById('statusbar-maximized');
this.screen = document.getElementById('screen');
this.topPanel = document.getElementById('top-panel');
this.statusbarTray = document.getElementById('statusbar-tray');
// Dummy element used at initialization.
this.statusbarIconsMin = document.createElement('div');
this.statusbarIcons.appendChild(this.statusbarIconsMin);
},
// To reduce the duplicated code
isLocked: function() {
return Service.query('locked');
}
};
exports.Statusbar = Statusbar;
}(window));