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 @@
define([],function(){"use strict";function e(e,a,n){var c=n,r=document.createElement("span");t(r,c.name);var s=document.createElement("small");"remote"===e&&s.setAttribute("data-l10n-id","device-status-tap-connect");var o=document.createElement("li"),u=document.createElement("a");if(o.classList.add("bluetooth-device"),d("device.type = "+c.type),o.classList.add("bluetooth-type-"+c.type),i(o,s,c.descriptionText,e),u.appendChild(r),u.appendChild(s),o.appendChild(u),"remote"===e){var l=document.createElement("progress");l.classList.add("overlapping-icon"),l.classList.add("hidden"),o.appendChild(l)}return"function"==typeof a&&(o.onclick=function(){a(n)}),c.observe("name",function(e){t(r,e)}),c.observe("descriptionText",function(t){i(o,s,t,e)}),o}function t(e,t){""!==t?(e.removeAttribute("data-l10n-id"),e.textContent=t):e.setAttribute("data-l10n-id","unnamed-device")}function i(e,t,i,a){switch(d("_updateItemDescriptionText(): descriptionText = "+i),i){case"tapToConnect":e.removeAttribute("aria-disabled"),t.setAttribute("data-l10n-id","device-status-tap-connect"),"remote"===a&&(e.querySelector("progress").classList.add("hidden"),e.classList.remove("icon-hidden"));break;case"pairing":e.setAttribute("aria-disabled",!0),t.setAttribute("data-l10n-id","device-status-pairing"),"remote"===a&&(e.classList.add("icon-hidden"),e.querySelector("progress").classList.remove("hidden"));break;case"paired":e.removeAttribute("aria-disabled"),t.setAttribute("data-l10n-id","device-status-paired"),"remote"===a&&(e.querySelector("progress").classList.add("hidden"),e.classList.remove("icon-hidden"));break;case"connecting":e.setAttribute("aria-disabled",!0),t.setAttribute("data-l10n-id","device-status-connecting");break;case"connectedWithDeviceMedia":e.removeAttribute("aria-disabled"),t.setAttribute("data-l10n-id","device-status-connected-device-media");break;case"connectedWithDevice":e.removeAttribute("aria-disabled"),t.setAttribute("data-l10n-id","device-status-connected-device");break;case"connectedWithMedia":e.removeAttribute("aria-disabled"),t.setAttribute("data-l10n-id","device-status-connected-media");break;case"connectedWithNoProfileInfo":e.removeAttribute("aria-disabled"),t.setAttribute("data-l10n-id","device-status-connected");break;case"disconnected":e.removeAttribute("aria-disabled"),t.removeAttribute("data-l10n-id"),t.textContent=""}}var a=!1,d=function(){};return a&&(d=function(e){console.log("--> [BluetoothTemplateFactory]: "+e)}),function(t,i){return e.bind(null,t,i)}});

View file

@ -0,0 +1,37 @@
/*
* CannotTransferDialog is responsible for:
* Alert a user that the activity request is not able to transfer via
* Bluetooth with some reason. There is an alert handling via here.
*/
define([],function() {
'use strict';
var CannotTransferDialog = {
init: function() {
this.dialog = document.getElementById('alert-view');
this.confirmBtn =
document.getElementById('alert-button-ok');
},
showConfirm: function() {
return new Promise((resolve) => {
this.confirmBtn.onclick = () => {
this.close();
resolve();
};
this.dialog.hidden = false;
});
},
get isVisible() {
return (!this.dialog.hidden);
},
close : function() {
this.dialog.hidden = true;
}
};
CannotTransferDialog.init();
return CannotTransferDialog;
});

View file

@ -0,0 +1,413 @@
/*
* DevicePickerPanel is responsible for:
* - Render paired/found devices list in this panel.
* - Emit 'devicePicked' event with device address while a user click on a
* paired device.
* - Pair with the picked device while a user click on a found device.
* Emit 'devicePicked' event with device address until the picked device
* is pared.
* - Emit 'cancelSelection' event while a user click close button on the
* header for leaving.
*
* @module DevicePickerPanel
*/
define(['require','modules/bluetooth/bluetooth_context','views/bt_template_factory','modules/mvvm/list_view'],function(require) {
'use strict';
var BtContext = require('modules/bluetooth/bluetooth_context');
var BtTemplateFactory = require('views/bt_template_factory');
var ListView = require('modules/mvvm/list_view');
var _debug = false;
var debug = function() {};
if (_debug) {
debug = function btdpp_debug(msg) {
console.log('--> [DevicePickerPanel]: ' + msg);
};
}
var DevicePickerPanel = {
/**
* A instance to maintain paired devices list view.
*
* @access private
* @memberOf DevicePickerPanel
* @type {Object}
*/
_pairedDevicesListView: null,
/**
* A instance to maintain found devices list view.
*
* @access private
* @memberOf DevicePickerPanel
* @type {Object}
*/
_foundDevicesListView: null,
/**
* Construct elements.
*
* @access private
* @memberOf DevicePickerPanel
* @type {Object}
*/
_elements: {
view: {
viewDevicePicker: document.querySelector('.devices-list-view')
},
header: {
headerActionClose: document.querySelector('.devices-list-header')
},
paired: {
pairedDevicesHeader: document.querySelector('.bluetooth-paired-title'),
pairedDevicesList: document.querySelector('.bluetooth-paired-devices')
},
found: {
foundDevicesHeader: document.querySelector('.bluetooth-found-title'),
foundDevicesList: document.querySelector('.bluetooth-devices')
},
search: {
searchingItem: document.querySelector('.bluetooth-searching'),
searchItem: document.querySelector('.bluetooth-search'),
searchButton: document.querySelector('.search-device')
}
},
/**
* The object maintains listeners' callback per property name.
* Each listener would be called as following definition.
* 'devicePicked' - be called when device is picked and paired successfully.
* 'cancelSelection': - be called when user click on close button on header.
*
* @memberOf DevicePickerPanel
* @type {Object}
*/
_listeners: {
'devicePicked': [],
'cancelSelection': []
},
/**
* Default adapter of Bluetooth.
*
* @access private
* @memberOf DevicePickerPanel
* @type {Object} BluetoothAdapter
*/
_defaultAdapter: null,
/**
* The function init the paired/found devices list and search button.
*
* @access private
* @memberOf DevicePickerPanel
*/
_init: function btdpp__init() {
// Bind click event for header.
this._elements.header.headerActionClose.addEventListener('action',
this._onHeaderActionCloseClick.bind(this));
// Bind click event for search button.
this._elements.search.searchButton.addEventListener('click',
this._onSearchButtonClick.bind(this));
// Bind click event for paired device item.
var pairedDeviceTemplate =
BtTemplateFactory('paired', this._onPairedDeviceItemClick.bind(this));
// Create paired devices list view.
this._pairedDevicesListView =
ListView(this._elements.paired.pairedDevicesList,
BtContext.getPairedDevices(),
pairedDeviceTemplate);
// Bind click event for found device item.
var foundDeviceTemplate =
BtTemplateFactory('remote', this._onFoundDeviceItemClick.bind(this));
// Create found devices list view.
this._foundDevicesListView =
ListView(this._elements.found.foundDevicesList,
BtContext.getRemoteDevices(),
foundDeviceTemplate);
// Init items state.
this._initItemsState();
// search devices automatically while the panel is inited.
BtContext.startDiscovery().then(() => {
debug('_init(): startDiscovery successfully');
}, (reason) => {
debug('_init(): startDiscovery failed, ' +
'reason = ' + reason);
});
},
/**
* The function init these elements which are displayed in this panel.
*
* @access private
* @memberOf DevicePickerPanel
*/
_initItemsState: function btdpp__initItemsState() {
// paired devices header
BtContext.observe('hasPairedDevice',
this._updatePairedDevicesHeader.bind(this));
this._updatePairedDevicesHeader(BtContext.hasPairedDevice);
// paired devices list
BtContext.observe('state', this._updatePairedDevicesList.bind(this));
this._updatePairedDevicesList(BtContext.state);
// found devices list
BtContext.observe('state', this._updateFoundDevicesList.bind(this));
this._updateFoundDevicesList(BtContext.state);
this._pairedDevicesListView.enabled = true;
this._foundDevicesListView.enabled = true;
// search
BtContext.observe('state', this._updateSearchItem.bind(this));
this._updateSearchItem(BtContext.state);
BtContext.observe('discovering', this._updateSearchingItem.bind(this));
this._updateSearchingItem(BtContext.discovering);
},
/**
* Start discovery devices while the search button is clicked.
*
* @access private
* @memberOf DevicePickerPanel
*/
_onHeaderActionCloseClick: function btdpp__onHeaderActionCloseClick() {
debug('_onHeaderActionCloseClick():');
// Emit 'cancelSelection' event to outer modules.
var event = {
type: 'cancelSelection'
};
this._emitEvent(event);
},
/**
* Start discovery devices while the search button is clicked.
*
* @access private
* @memberOf DevicePickerPanel
*/
_onSearchButtonClick: function btdpp__onSearchButtonClick() {
debug('_onSearchButtonClick():');
BtContext.startDiscovery().then(() => {
debug('_onSearchButtonClick(): startDiscovery successfully');
}, (reason) => {
debug('_onSearchButtonClick(): startDiscovery failed, ' +
'reason = ' + reason);
});
},
/**
* While the paired device is clicked, emit event to outer modules with
* the device item.
*
* @access private
* @memberOf DevicePickerPanel
*/
_onPairedDeviceItemClick:
function btdpp__onPairedDeviceItemClick(deviceItem) {
debug('_onPairedDeviceItemClick(): deviceItem.address = ' +
deviceItem.address);
debug('_onPairedDeviceItemClick(): deviceItem.paired = ' +
deviceItem.paired);
// Emit 'devicePicked' event to outer modules with the device item.
var event = {
type: 'devicePicked',
detail: {
address: deviceItem.address
}
};
this._emitEvent(event);
},
/**
* Pair with the clicked device. While the device is paired successfully,
* emit event to outer modules with the device item.
*
* @access private
* @memberOf DevicePickerPanel
*/
_onFoundDeviceItemClick:
function btdpp__onFoundDeviceItemClick(deviceItem) {
debug('_onFoundDeviceItemClick(): deviceItem.address = ' +
deviceItem.address);
// Update device pairing status first.
deviceItem.paired = 'pairing';
// Pair with the remote device.
BtContext.pair(deviceItem.address).then(() => {
debug('_onFoundDeviceItemClick(): pair successfully');
// Emit 'devicePicked' event to outer modules with the
// paired device item.
var event = {
type: 'devicePicked',
detail: {
address: deviceItem.address
}
};
this._emitEvent(event);
}, (reason) => {
debug('_onFoundDeviceItemClick(): pair failed, ' +
'reason = ' + reason);
// Reset the paired status back to false,
// since the 'pairing' status is given in Gaia side.
deviceItem.paired = false;
// Show alert message while pair device failed.
this._alertPairFailedErrorMessage(reason);
});
},
/**
* Show an alert dialog since the device is failed in pairing process.
*
* @access private
* @memberOf DevicePickerPanel
*/
_alertPairFailedErrorMessage:
function btdpp__alertPairFailedErrorMessage(errorReason) {
var _ = navigator.mozL10n.get;
var msg = _('error-pair-title'); // This is a default message.
if (errorReason === 'Repeated Attempts') {
msg = msg + '\n' + _('error-pair-toofast');
} else if (errorReason === 'Authentication Failed') {
msg = msg + '\n' + _('error-pair-pincode');
}
window.alert(msg);
},
/**
* A function to show/hide paired devices header.
*
* @access private
* @memberOf DevicePickerPanel
*/
_updatePairedDevicesHeader:
function btdpp__updatePairedDevicesHeader(hasPairedDevice) {
debug('_updatePairedDevicesHeader(): ' +
'callback from observe "hasPairedDevice" = ' + hasPairedDevice);
this._elements.paired.pairedDevicesHeader.hidden =
!(hasPairedDevice && (BtContext.state === 'enabled'));
},
/**
* A function to show/hide paired devices list.
*
* @access private
* @memberOf DevicePickerPanel
*/
_updatePairedDevicesList: function btdpp__updatePairedDevicesList(state) {
debug('_updatePairedDevicesList(): ' +
'callback from observe "state" = ' + state);
this._elements.paired.pairedDevicesHeader.hidden =
!((state === 'enabled') && (BtContext.hasPairedDevice));
this._elements.paired.pairedDevicesList.hidden = (state !== 'enabled');
},
/**
* A function to show/hide found devices list.
*
* @access private
* @memberOf DevicePickerPanel
*/
_updateFoundDevicesList: function btdpp__updateFoundDevicesList(state) {
debug('_updateFoundDevicesList(): ' +
'callback from observe "state" = ' + state);
this._elements.found.foundDevicesHeader.hidden = (state !== 'enabled');
this._elements.found.foundDevicesList.hidden = (state !== 'enabled');
},
/**
* A function to show/hide search item.
*
* @access private
* @memberOf DevicePickerPanel
*/
_updateSearchItem: function btdpp__updateSearchItem(state) {
debug('_updateSearchItem(): ' +
'callback from observe "state" = ' + state);
this._elements.search.searchItem.hidden = (state !== 'enabled');
},
/**
* A function to show/hide searching description item.
*
* @access private
* @memberOf DevicePickerPanel
*/
_updateSearchingItem: function btdpp__updateSearchingItem(discovering) {
debug('_updateSearchingItem(): ' +
'callback from observe "discovering" = ' + discovering);
this._elements.search.searchingItem.hidden = !discovering;
this._elements.search.searchButton.disabled = discovering;
},
/**
* A function to emit event to each registered listener by the input type.
*
* @memberOf DevicePickerPanel
* @param {Object} options
* @param {String} options.type - type of event name
* @param {Object} options.detail - the object pass to the listener
*/
_emitEvent: function btdpp__emitEvent(options) {
this._listeners[options.type].forEach(function(listener) {
listener(options);
});
},
/**
* The method will provide event listener for outer modules to regist.
*
* @access public
* @memberOf DevicePickerPanel
* @param {String} eventName
* @param {Function} callback
*/
addEventListener: function btdpp_addEventListener(eventName, callback) {
if (callback && (this._listeners.hasOwnProperty(eventName))) {
this._listeners[eventName].push(callback);
}
},
/**
* The method will provide event listener for outer modules to un-regist.
*
* @access public
* @memberOf DevicePickerPanel
* @param {String} eventName
* @param {Function} callback
*/
removeEventListener:
function btdpp_removeEventListener(eventName, callback) {
if (callback && (this._listeners.hasOwnProperty(eventName))) {
var index = this._listeners[eventName].indexOf(callback);
if (index >= 0) {
this._listeners[eventName].splice(index, 1);
}
}
},
/**
* The setter will show/hide the device picker view for outer modules.
*
* @access public
* @memberOf DevicePickerPanel
* @param {Boolean} enabled
*/
set visible(enabled) {
// display device picker view
this._elements.view.viewDevicePicker.hidden = !enabled;
}
};
DevicePickerPanel._init();
return DevicePickerPanel;
});

View file

@ -0,0 +1 @@
define(["require"],function(i){"use strict";var n={init:function(){this.dialog=document.getElementById("pairing-request-timeout"),this.confirmBtn=document.getElementById("incoming-pairing-timeout-confirm")},showConfirm:function(i){var n=this;this.confirmBtn.onclick=function(){n.close(),i&&i()},this.dialog.hidden=!1},get isVisible(){return!this.dialog.hidden},close:function(){this.dialog.hidden=!0}};return n.init(),n});

View file

@ -0,0 +1,7 @@
;var Pairview={_debug:false,_remoteDeviceName:null,_pairMethod:null,_options:null,_passkey:'',pairview:document.getElementById('pair-view'),nameLabel:document.getElementById('label-name'),pairDescription:document.getElementById('pair-description'),pairButton:document.getElementById('button-pair'),closeButton:document.getElementById('button-close'),comfirmationItem:document.getElementById('confirmation-method'),pinInputItem:document.getElementById('pin-input-method'),passkey:document.getElementById('passkey'),pinInput:document.getElementById('pin-input'),get isFullAttentionMode(){return(window.innerHeight>200);},show:function pv_show(){if(!this.isFullAttentionMode){this.close();return;}
var _=navigator.mozL10n.get;this.pairButton.addEventListener('click',this);this.closeButton.addEventListener('click',this);window.addEventListener('resize',this);this._remoteDeviceName=this._remoteDeviceName||_('unnamed-device');var truncatedDeviceName=getTruncated(this._remoteDeviceName,{node:this.nameLabel,maxLine:2,ellipsisIndex:3});this.nameLabel.textContent=truncatedDeviceName;this.pairview.hidden=false;var stringName='passive-pair-'+this._pairMethod;this.pairDescription.textContent=_(stringName,{device:truncatedDeviceName});switch(this._pairMethod){case'displaypasskey':case'confirmation':this.passkey.textContent=this._passkey;this.comfirmationItem.hidden=false;this.pinInputItem.hidden=true;break;case'enterpincode':this.pinInputItem.hidden=false;this.comfirmationItem.hidden=true;this.pinInput.focus();break;case'consent':this.comfirmationItem.hidden=false;this.pinInputItem.hidden=true;break;}},init:function pv_init(method,options){this._pairMethod=method;this._options=options;this._remoteDeviceName=options.deviceName;if(options.handle&&options.handle.passkey){var passkey=options.handle.passkey;var len=passkey.toString().length;var zeros=(len<6)?(new Array((6-len)+1)).join('0'):'';this._passkey=zeros+passkey;}
navigator.mozL10n.once(Pairview.show.bind(Pairview));},close:function pv_close(){this._options.handle.reject().then(()=>{this.debug('Resolved in reject '+this._pairMethod+' request.');window.close();},(aReason)=>{this.debug('Rejected in reject '+this._pairMethod+' request with reason: '+aReason);window.close();});},closeInput:function pv_closeInput(){if(!this.pinInputItem.hidden){this.pinInput.blur();}},handleEvent:function pv_handleEvent(evt){var _=navigator.mozL10n.get;if(!evt.target){return;}
switch(evt.type){case'click':evt.preventDefault();switch(evt.target.id){case'button-pair':this.pairDescription.textContent=_('device-status-waiting');this.pairButton.disabled=true;this.closeButton.disabled=true;switch(this._pairMethod){case'displaypasskey':window.close();break;case'enterpincode':var pinCode=this.pinInput.value;this._options.handle.setPinCode(pinCode).then(()=>{this.debug('Resolved setPinCode operation');window.close();},(aReason)=>{this.debug('Rejected setPinCode with reason: '+aReason);window.close();});break;case'confirmation':case'consent':this._options.handle.accept().then(()=>{this.debug('Resolved in '+this._pairMethod+' request');window.close();},(aReason)=>{this.debug('Rejected in '+this._pairMethod+' request '+' with reason: '+aReason);window.close();});break;}
break;case'button-close':this.close();break;}
break;case'resize':if(!this.isFullAttentionMode){this.close();}
break;default:break;}},debug:function(msg){if(this._debug){console.log('Pairview(): '+msg);}}};

View file

@ -0,0 +1,51 @@
/*
* TurnBluetoothOnDialog is responsible for:
* A confirmation dialog to ask user to turn Bluetooth on or not.
* There is a confirmation handling via here.
*/
define([],function() {
'use strict';
var TurnBluetoothOnDialog = {
init: function() {
this.dialog = document.getElementById('enable-bluetooth-view');
this.cancelBtn =
document.getElementById('enable-bluetooth-button-cancel');
this.confirmBtn =
document.getElementById('enable-bluetooth-button-turn-on');
},
showConfirm: function() {
return new Promise((resolve) => {
this.cancelBtn.onclick = (evt) => {
if (evt) {
evt.preventDefault();
}
this.close();
resolve('cancel');
};
this.confirmBtn.onclick = (evt) => {
if (evt) {
evt.preventDefault();
}
this.close();
resolve('confirm');
};
this.dialog.hidden = false;
});
},
get isVisible() {
return (!this.dialog.hidden);
},
close: function() {
this.dialog.hidden = true;
}
};
TurnBluetoothOnDialog.init();
return TurnBluetoothOnDialog;
});