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,288 @@
/* global debug */
/* exported AutoSettings */
'use strict';
var AutoSettings = (function() {
var OPTION_CONFIGURERS = {
'select': function _selectConfigurer(guiWidget) {
var optionName = guiWidget.dataset.option;
var span, parent = guiWidget.parentElement;
if (parent.classList.contains('fake-select')) {
var firstChild = parent.firstChild;
if (!firstChild || firstChild.tagName !== 'SPAN') {
span = document.createElement('span');
parent.insertBefore(span, parent.firstChild);
}
}
guiWidget.addEventListener('blur', function _onSelectChange() {
debug('Value:', guiWidget.value);
settings.option(optionName, guiWidget.value);
});
settings.observe(optionName, function _onOptionChange(value) {
if (value === undefined) {
value = settings.defaultValue(optionName);
}
guiWidget.value = value;
if (span) {
var selected = guiWidget.options[guiWidget.selectedIndex];
var l10nId = selected.getAttribute('data-l10n-id');
span.textContent = selected.textContent;
if (l10nId) {
span.setAttribute('data-l10n-id', l10nId);
}
}
});
},
// Select is used to simulate custom combo boxes. It displays a selection
// dialog with an ok button and possibly a cancel button. The value is only
// changed if ok button is pressed. If cancel provided and clicked then
// the former value is restored.
'customselect': function _customselectConfigurer(guiWidget) {
var dialog = document.getElementById(guiWidget.dataset.selectdialog);
var optionName = guiWidget.dataset.option;
// Dialog
var okButton = dialog.querySelector('button.recommend');
if (okButton) {
okButton.addEventListener('click', function _onDialogOk() {
var checked = dialog.querySelector('input[type="radio"]:checked');
settings.option(optionName, checked.value);
vmanager.closeCurrentView();
});
}
var cancelButton = dialog.querySelector('button.cancel');
if (cancelButton) {
cancelButton.addEventListener('click',
function _onDialogCancel() {
var currentValue = settings.option(optionName);
settings.option(optionName, currentValue);
vmanager.closeCurrentView();
}
);
}
guiWidget.addEventListener('click', function _onWidgetClick() {
vmanager.changeViewTo(dialog.id);
});
// Keep the widget and the dialog synchronized
settings.observe(optionName,
function _onOptionChange(value) {
// Use default value if no value
if (value === null || value === undefined) {
value = getDefaultValue(optionName);
}
var radio =
dialog.querySelector('input[type="radio"][value="' + value + '"]');
if (!radio) {
value = getDefaultValue(optionName);
radio = dialog.querySelector('input[type="radio"][value="' +
value + '"]');
}
radio.checked = true;
var textSpan = dialog.querySelector('input:checked + span');
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = textSpan.textContent;
}
);
// Keep the UI localized
window.addEventListener('localized', function _onLocalized() {
var textSpan = dialog.querySelector('input:checked + span');
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = textSpan.textContent;
});
},
// Switch configurer handles an checkbox. When it changes, the checked
// state is used as the content for the option.
'switch' : function _switchConfigurer(guiWidget) {
var optionName = guiWidget.dataset.option;
// Add an observer to keep synchronization
settings.observe(
optionName,
function _onOptionChange(value) {
if (value === null || value === undefined) {
value = getDefaultValue(optionName);
}
guiWidget.checked = value;
}
);
// Add an event listener to switch the option
guiWidget.addEventListener('change', function ccapp_onSwitchChange() {
settings.option(optionName, guiWidget.checked);
});
},
// Input configurer handles an input box. When the content changes, the
// content is parsed and sent to the proper option.
'input' : function _inputConfigurer(guiWidget) {
var optionName = guiWidget.dataset.option;
// Add an observer to keep synchronization
settings.observe(
optionName,
function _onOptionChange(value) {
if (value === null || value === undefined) {
value = getDefaultValue(optionName);
}
guiWidget.value = value;
}
);
// Add an event listener to switch the option
guiWidget.addEventListener('change', function _onContentChange() {
var value = guiWidget.value;
if (guiWidget.type === 'number') {
value = parseFloat(value);
}
settings.option(optionName, value);
});
}
};
// Add a new type with its configuration function
function addType(newType, configFunction) {
OPTION_CONFIGURERS[newType] = configFunction;
}
var customRecognizer;
// Add a recognizer to detect new types
function setCustomRecognizer(recognizer) {
customRecognizer = recognizer;
}
// Return the <li> wrapping the option
function getEntryParent(item) {
while (item && item.tagName !== 'LI') {
item = item.parentNode;
}
return item;
}
// Return the default value for an option
function getDefaultValue(optionName) {
return settings.defaultValue(optionName);
}
// Configure the web page
var settings, vmanager;
function initialize(settingsInterface, viewManager, root) {
root = root || 'body';
settings = settingsInterface;
vmanager = viewManager;
// Return the type of configurer needed based on the properties of
// the HTML element marked as the option.
function getWidgetType(widget) {
if (widget.dataset.widgetType) {
return widget.dataset.widgetType;
}
var customType;
if (customRecognizer === 'function') {
customType = customRecognizer(widget, settings, vmanager);
}
if (customType) {
return customType;
}
if (widget.tagName === 'SELECT') {
return 'select';
}
if (typeof widget.dataset.selectdialog !== 'undefined') {
return 'customselect';
}
if (widget.type === 'checkbox' ||
widget.nodeName.toLowerCase() === 'gaia-switch') {
return 'switch';
}
if (['text', 'number'].indexOf(widget.type) !== -1) {
return 'input';
}
}
// Install a dependency based on an expression. When expression is true
// call the callback.
function installDependency(expression, callback) {
var equality = false;
var parsed = expression.split('!=');
if (parsed.length === 1) {
parsed = expression.split('=');
equality = true;
}
var dependency = parsed[0];
var referenceValue = parsed[1];
settings.observe(dependency,
function ccapp_dependencyAction(value) {
var test = (('' + value) === referenceValue);
callback(equality === test); // or is an equality test and values are
// equal or is an inequality test and
// values are different.
}
);
}
// Widgets
var allGUIWidgets = document.querySelectorAll(root + ' .settings-option');
[].forEach.call(allGUIWidgets, function _forEachWidget(guiWidget) {
var type = getWidgetType(guiWidget);
var entry = getEntryParent(guiWidget);
var configurer = OPTION_CONFIGURERS[type];
if (configurer) {
configurer(guiWidget, settings, vmanager, root);
}
// Simple dependency resolution:
// enable / disable some options depending on the values of other
var disableOn = guiWidget.dataset.disableOn;
if (disableOn) {
installDependency(disableOn, function _disable(passed) {
guiWidget.disabled = passed;
if (entry) {
entry.setAttribute('aria-disabled', passed + '');
}
});
}
// hide / show some options depending on the values of other
var hideOn = guiWidget.dataset.hideOn;
if (hideOn) {
installDependency(hideOn, function _hide(passed) {
guiWidget.hidden = passed;
if (entry) {
entry.hidden = passed;
}
});
}
});
}
return {
initialize: initialize,
setCustomRecognizer: setCustomRecognizer,
addType: addType
};
}());

View file

@ -0,0 +1,234 @@
/* global _, addNetworkUsageAlarm, Common, Formatting, SimManager,
CostControl */
/* exported dataLimitConfigurer */
'use strict';
function dataLimitConfigurer(guiWidget, settings, viewManager, widgetRoot) {
var REMOVE_CHAR_CODE = 8,
// It Represents any positive real number (up to three digits length),
// with optional decimal point, accepting up to 2 decimal places. It is
// not necessary adding the significant number when it is zero (eg. '.5'
// is a valid entry)
DATA_LIMIT_NUMERIC_FORMAT = new RegExp('^[0-9]{0,3}(\\.[0-9]{1,2})?$');
var dialog = document.getElementById('data-limit-dialog');
var dataLimitInput = dialog.querySelector('input');
var format = function ccal_formatterDataUnit(value) {
var unit = settings.option('dataLimitUnit');
return Formatting.formatData([value, _(unit)]);
};
window.addEventListener('localized', function _onLocalize() {
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = format(dataLimitInput.value);
});
// Configure dialog
var okButton = dialog.querySelector('button.recommend');
if (okButton) {
okButton.addEventListener('click', function ccld_onDialogOk() {
var value = parseFloat(dataLimitInput.value);
settings.option('dataLimitValue', value);
settings.option('dataLimitUnit', currentUnit);
var dataLimit = Common.getDataLimit({'dataLimitValue': value,
'dataLimitUnit': currentUnit});
SimManager.requestDataSimIcc(function(dataSim) {
var simInterface = Common.getDataSIMInterface(dataSim.iccId);
addNetworkUsageAlarm(simInterface, dataLimit, null,
() => checkDataLimit(dataLimit));
});
viewManager.closeCurrentView();
});
}
var dialogHeader = dialog.querySelector('#limit-dialog-header');
if (dialogHeader) {
dialogHeader.addEventListener('action',
function ccld_onDialogCancel() {
var oldValue = settings.option('dataLimitValue');
var oldUnit = settings.option('dataLimitUnit');
currentUnit = oldUnit;
settings.option('dataLimitValue', oldValue);
settings.option('dataLimitUnit', oldUnit);
dataLimitInput.classList.remove('error');
okButton.disabled = false;
viewManager.closeCurrentView();
}
);
}
function checkDataLimit(dataLimit) {
CostControl.getInstance(function _onCostControl(costcontrol) {
var requestObj = {
type: 'datausage'
};
costcontrol.request(requestObj, function _onDataStats(result) {
var stats = result.data.mobile.total;
if (stats > dataLimit) {
var mobileUsage = {
limit: Formatting.formatData(Formatting.roundData(dataLimit))
};
var message = _('data-limit-notification-title2', mobileUsage) +
'\n' + _('data-limit-notification-text2');
window.alert(message);
}
});
});
}
function isNotRemovingChar(newChar) {
return REMOVE_CHAR_CODE !== newChar;
}
function isAllowedValue(newValue) {
return isValidValue(newValue) || wouldBeValid(newValue);
}
// Checks if value is numeric and it has a valid format
// Not allowed entry characters '-', ',' or more than one '.'
function isValidValue(newValue) {
var containsNonValidCharacters = [',','-']
.some(c => newValue.indexOf(c) > -1);
var containsMoreThanOneDot = (newValue.match(/\./g) || []).length > 1;
return !Number.isNaN(newValue) &&
!containsNonValidCharacters && !containsMoreThanOneDot &&
isValidFormat(newValue);
}
function wouldBeValid(lowLimitValue) {
var allowedEntry = new RegExp('^0?(\\.0?)?$');
return allowedEntry.test(lowLimitValue);
}
function preventBadInput(valid, newChar, currentInput) {
// This method returns the string resultant of adding the character of the
// keypress event
function simulateNewValue(newChar, currentInput) {
var value = currentInput.value,
idx = currentInput.selectionStart,
newCharValue = String.fromCharCode(newChar);
return value.substr(0, idx) + newCharValue + value.substr(idx);
}
var newValue = simulateNewValue(newChar, currentInput);
var isInvalid = !valid(newValue);
return isInvalid;
}
dataLimitInput.addEventListener('keypress',
function cc_onKeypress(event) {
var currentInput = event.target;
var newChar = event.charCode || event.keyCode;
// If the entry is not valid or the result of the input is invalid, we
// have to prevent the event propagation
if (isNotRemovingChar(newChar) &&
preventBadInput(isAllowedValue, newChar, currentInput)) {
event.preventDefault();
event.stopPropagation();
return;
}
}
);
function isValidFormat(lowLimitValue) {
var numberDataLimit = Number(lowLimitValue);
return (numberDataLimit < 1000 &&
numberDataLimit > 0 &&
DATA_LIMIT_NUMERIC_FORMAT.test(numberDataLimit));
}
// Disable OK button when dataLimitInput not matches any positive real number
// (up to three digits length), with optional decimal point, accepting up
// to 2 decimal places.
dataLimitInput.addEventListener('input',
function cc_ondataLimitInputChange(evt) {
var lowLimitValue = evt.target.value.trim();
var isNumericLowLimit = !Number.isNaN(Number(lowLimitValue));
if (isNumericLowLimit &&
lowLimitValue.indexOf('.0') !== lowLimitValue.length - 2 &&
lowLimitValue.indexOf('.') !== lowLimitValue.length - 1) {
dataLimitInput.value = Number(lowLimitValue);
}
var isValidValue = (isNumericLowLimit && isValidFormat(lowLimitValue));
if (isValidValue) {
dataLimitInput.classList.remove('error');
} else {
dataLimitInput.classList.add('error');
}
okButton.disabled = (!isValidValue);
}
);
// Configure the swicth unit button
var currentUnit = settings.option('dataLimitUnit');
var switchUnitButton = dialog.querySelector('.switch-unit-button');
function localizeSwitchUnitButton(unit) {
switchUnitButton.setAttribute('data-l10n-id', 'unit-' + unit);
switchUnitButton.querySelector('span.tag').setAttribute(
'data-l10n-id', unit);
}
localizeSwitchUnitButton(currentUnit);
switchUnitButton.addEventListener('click',
function ccapp_switchUnit() {
currentUnit = (currentUnit === 'MB') ? 'GB' : 'MB';
localizeSwitchUnitButton(currentUnit);
}
);
// Prevent to loose the focus when tapping on switch unit button
// TODO: Replace with 'focusout' on dataLimitInput when fixing bug:
// https://bugzilla.mozilla.org/show_bug.cgi?id=687787
switchUnitButton.addEventListener('mousedown',
function _preventFocusLost(evt) {
evt.preventDefault();
}
);
// Keep the widget and the dialog synchronized
settings.observe('dataLimitValue',
function ccld_onValueChange(value) {
// Use default value if no value
if (value === null || typeof value === 'undefined') {
value = settings.defaultValue('dataLimitValue');
}
// Set dialog
dataLimitInput.value = value;
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = format(dataLimitInput.value);
}
);
settings.observe('dataLimitUnit',
function ccld_onUnitChange(value) {
// Use default value if no value
if (value === null || typeof value === 'undefined') {
value = settings.defaultValue('dataLimitUnit');
}
// Set dialog
localizeSwitchUnitButton(value);
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = format(dataLimitInput.value);
}
);
// Show the dialog
var oldUnitValue;
guiWidget.addEventListener('click', function ccld_onWidgetClick() {
viewManager.changeViewTo(dialog.id, widgetRoot);
dataLimitInput.focus();
dataLimitInput.setSelectionRange(dataLimitInput.value.length,
dataLimitInput.value.length);
oldUnitValue = settings.option('dataLimitUnit');
localizeSwitchUnitButton(oldUnitValue);
});
}

View file

@ -0,0 +1,89 @@
/* exported NetworkUsageAlarm */
'use strict';
var NetworkUsageAlarm = (function() {
function _addAlarm(networkInterface, value, onsuccess, onerror) {
if (!networkInterface) {
console.error('Error, the network interface is not defined when trying ' +
'to add an alarm');
(typeof onerror === 'function') && onerror();
return;
}
if (value === null || typeof value === 'undefined') {
console.error('Limit value is undefined, impossible add an alarm');
(typeof onerror === 'function') && onerror();
return;
}
var request = navigator.mozNetworkStats.addAlarm(networkInterface, value);
request.onsuccess = onsuccess;
request.onerror = function error(e) {
console.error('Error, when trying to addAlarm to the interfaceId: ' +
networkInterface.id + ' and limit: ' + value);
(typeof onerror === 'function') && onerror();
};
}
function _clearAlarms(networkInterface, callback) {
if (!networkInterface) {
console.error('Error, the network interface is not defined when trying ' +
'to remove alarms');
return;
}
var request = navigator.mozNetworkStats.getAllAlarms(networkInterface);
request.onsuccess = function success() {
var alarmList = request.result;
var pendingRequest = alarmList.length;
function checkForCompletion() {
pendingRequest--;
if (pendingRequest === 0) {
(typeof callback === 'function') && callback();
}
}
function _onErrorRemoveAlarm() {
console.error('Error when trying to remove one alarm.');
checkForCompletion();
}
for (var i = 0; i < alarmList.length; i++) {
if (alarmList[i] && alarmList[i].alarmId) {
var rA = navigator.mozNetworkStats.removeAlarms(alarmList[i].alarmId);
rA.onsuccess = checkForCompletion;
rA.onerror = _onErrorRemoveAlarm;
}
}
if (pendingRequest === 0) {
(typeof callback === 'function') && callback();
}
};
request.onerror = function error() {
console.error('Error when trying to get alarms from the API to clear it');
};
}
function _updateAlarm(dataInterface, value, onsuccess, onerror) {
if (dataInterface && value) {
var addNewAlarm = _addAlarm.bind(null, dataInterface, value, onsuccess,
onerror);
_clearAlarms(dataInterface, addNewAlarm);
} else {
if (!dataInterface) {
console.error('Error, the network interface is not defined when ' +
'trying to update an alarm');
} else {
console.error('Error, the data limit value is not defined when ' +
'trying to update an alarm');
}
(typeof onerror === 'function') && onerror();
}
}
return {
updateAlarm: _updateAlarm,
clearAlarms: _clearAlarms
};
}());

View file

@ -0,0 +1,367 @@
/* global BalanceView, LazyLoader, AutoSettings, BalanceLowLimitView,
ResetMenuDialog, ConfirmDialog, ViewManager, dataLimitConfigurer,
Formatting
*/
/* exported debug, sendBalanceThresholdNotification */
/*
* Settings is in charge of setup the setting section. It uses an AutoSettings
* object to automatically bind markup with local settings.
*
* Settings have three drawing areas with views for current values of balance,
* data usage and telephony.
*/
'use strict';
// Import global objects from parent window
var ConfigManager = window.parent.ConfigManager;
var CostControl = window.parent.CostControl;
var SimManager = window.parent.SimManager;
var Common = window.parent.Common;
var NetworkUsageAlarm = window.parent.NetworkUsageAlarm;
// Import global functions from parent window
var addNetworkUsageAlarm = window.parent.addNetworkUsageAlarm;
var resetTelephony = window.parent.resetTelephony;
navigator.mozL10n = window.parent.navigator.mozL10n;
// Import debug
var DEBUGGING = window.parent.DEBUGGING;
var debug = window.parent.debug;
var Settings = (function() {
var costcontrol, vmanager, initialized, endLoadSettingsNotified;
var plantypeSelector, phoneActivityTitle, phoneActivitySettings;
var balanceTitle, balanceSettings, reportsTitle;
var balanceView, resetMenuDialog, confirmDialog;
function configureUI() {
CostControl.getInstance(function _onCostControl(instance) {
costcontrol = instance;
// Debug options
if (DEBUGGING) {
loadDeveloperAids();
}
vmanager = new ViewManager();
// HTML entities
plantypeSelector = document.getElementById('plantype-settings');
phoneActivityTitle = document.getElementById('phone-activity-settings');
phoneActivitySettings =
document.querySelector('#phone-activity-settings + .settings');
balanceTitle = document.getElementById('balance-settings');
balanceSettings =
document.querySelector('#balance-settings + .settings');
reportsTitle = document.getElementById('phone-internet-settings');
// Subviews
var balanceConfig = ConfigManager.configuration.balance;
balanceView = new BalanceView(
document.getElementById('balance'),
document.querySelector('#balance + .meta'),
balanceConfig ? balanceConfig.minimum_delay : undefined
);
var resetDialog = document.getElementById('reset-dialog');
var resetDataDialog = document.getElementById('reset-data-dialog');
resetMenuDialog = new ResetMenuDialog(resetDataDialog, vmanager);
confirmDialog = new ConfirmDialog(resetDialog, vmanager);
resetMenuDialog.initializeResetModes(confirmDialog);
// Autosettings
AutoSettings.addType('data-limit', dataLimitConfigurer);
AutoSettings.initialize(ConfigManager, vmanager, '#settings-view');
configureTelephonyReset();
configureDataResets();
addDoneConstrains();
// Add an observer on dataLimit switch to active o deactivate alarms
ConfigManager.observe(
'dataLimit',
function _onDataLimitChange(value, old, key, settings) {
SimManager.requestDataSimIcc(function(dataSim) {
var iccId = dataSim.iccId;
var currentDataInterface = Common.getDataSIMInterface(iccId);
if (!value) {
NetworkUsageAlarm.clearAlarms(currentDataInterface);
} else {
addNetworkUsageAlarm(currentDataInterface,
Common.getDataLimit(settings));
}
});
},
true
);
// Update layout when changing plantype
ConfigManager.observe('plantype', updateUI, true);
// Update views
ConfigManager.observe('lastTelephonyActivity',
function _updateTelephony(activity, old, key, settings) {
updateTelephony(activity, settings.lastTelephonyReset);
},
true
);
ConfigManager.observe('lastDataUsage',
function _updateDataUsage(stats, old, key, settings) {
updateDataUsage(stats, settings.lastCompleteDataReset);
},
true
);
ConfigManager.observe('lastBalance',
function _updateBalance(balance) {
updateBalance(balance, balance.currency);
},
true
);
// Close button needs to acquire a reference to the settings view
// manager to close itself.
var close = document.getElementById('close-settings');
close.addEventListener('click', function() {
closeSettings();
});
function _setResetTimeToDefault(value, old, key, settings) {
var today = new Date();
var defaultResetTime = (settings.trackingPeriod === 'weekly') ?
today.getDay() : today.getDate();
if (settings.resetTime !== defaultResetTime) {
ConfigManager.setOption({ resetTime: defaultResetTime });
} else {
Common.updateNextReset(settings.trackingPeriod, settings.resetTime);
}
}
function _updateNextReset(value, old, key, settings) {
Common.updateNextReset(settings.trackingPeriod, settings.resetTime);
}
ConfigManager.observe('resetTime', _updateNextReset, true);
ConfigManager.observe('trackingPeriod', _setResetTimeToDefault, true);
initialized = true;
Settings.updateUI();
});
}
function closeSettings() {
window.parent.location.hash = '#';
}
// Loads extra HTML useful for debugging
function loadDeveloperAids() {
var xhr = new XMLHttpRequest();
xhr.overrideMimeType('text/plain');
xhr.open('GET', '/debug.html', false);
xhr.send();
if (xhr.status === 200) {
var src = document.createElement('DIV');
// XXX: We use innerHTML precisely because we need parse the content
// without introducing the overhead of DOM methods.
src.innerHTML = xhr.responseText;
var reference = document.getElementById('plantype-settings');
var parent = reference.parentNode;
[].forEach.call(src.childNodes, function(node) {
reference = parent.insertBefore(node, reference.nextSibling);
});
}
}
// Configure reset dialogs for telephony and data usage
function configureTelephonyReset() {
var resetTelephonyButton = document.getElementById('reset-telephony');
resetTelephonyButton.addEventListener('click', function() {
confirmDialog.setMessage('reset-telephony-confirmation-warning', {});
function resetAction() {
resetTelephony();
updateUI();
confirmDialog.closeConfirmDialog();
}
confirmDialog.updateAcceptAction(resetAction);
confirmDialog.showConfirmDialog();
});
}
// Configure reset dialogs for telephony and data usage
function configureDataResets() {
// Button reset Data Usage Settings send to reset data dialog
var resetDataUsage = document.getElementById('reset-data-usage');
resetDataUsage.addEventListener('click', function _onDataReset() {
var currentTotals = {
mobile: costcontrol.lastDataResults.mobile.total,
wifi: costcontrol.lastDataResults.wifi.total
};
resetMenuDialog.showResetMenuDialog(currentTotals);
});
}
// Add particular constrains to the "Done" button
var balanceLowLimitView;
function addDoneConstrains() {
var closeButton = document.getElementById('close-settings');
balanceLowLimitView = new BalanceLowLimitView(
document.getElementById('low-limit'),
document.getElementById('low-limit-input')
);
balanceLowLimitView.onvalidation = function(evt) {
closeButton.disabled = !evt.isValid;
};
}
window.addEventListener('localized', function _onLocalize() {
if (initialized) {
updateUI();
}
});
var currentMode;
function updateUI() {
ConfigManager.requestAll(function _onInfo(configuration, settings) {
// L10n
Common.localizeWeekdaySelector(
document.getElementById('select-weekday'));
// Layout
var mode = ConfigManager.getApplicationMode();
if (currentMode !== mode) {
currentMode = mode;
var hidePlantypeSelector = (mode === 'DATA_USAGE_ONLY');
var hidePhoneActivity = (mode !== 'POSTPAID');
var hideBalance = (mode !== 'PREPAID');
var hideReportsTitle = (mode === 'PREPAID');
var textReportsTitle = (mode === 'POSTPAID') ?
'phone-and-internet-data-report' : 'internet-data-report';
reportsTitle.querySelector('span').setAttribute(
'data-l10n-id', textReportsTitle
);
balanceLowLimitView.disabled = (mode !== 'PREPAID');
plantypeSelector.hidden = hidePlantypeSelector;
phoneActivityTitle.hidden = hidePhoneActivity;
phoneActivitySettings.hidden = hidePhoneActivity;
balanceTitle.hidden = hideBalance;
balanceSettings.hidden = hideBalance;
reportsTitle.hidden = hideReportsTitle;
}
// Views
var requestObj = {
type: 'datausage'
};
costcontrol.request(requestObj, function _onDataStats(result) {
var stats = result.data;
updateDataUsage(stats, settings.lastCompleteDataReset);
});
switch (mode) {
case 'PREPAID':
updateBalance(settings.lastBalance, configuration.credit.currency);
break;
case 'POSTPAID':
updateTelephony(settings.lastTelephonyActivity,
settings.lastTelephonyReset);
break;
}
if (endLoadSettingsNotified) {
window.performance.measure('loadSettings', 'loadSettingsStart');
endLoadSettingsNotified = true;
}
});
}
// Update data usage view on settings
function updateDataUsage(datausage, lastCompleteDataReset) {
var mobileUsage = document.querySelector('#mobile-data-usage > span');
var data = Formatting.roundData(datausage.mobile.total);
mobileUsage.textContent = Formatting.formatData(data);
var wifiUsage = document.querySelector('#wifi-data-usage > span');
data = Formatting.roundData(datausage.wifi.total);
wifiUsage.textContent = Formatting.formatData(data);
updateDataUsageTimestamp(lastCompleteDataReset, datausage.timestamp);
}
var dataUsagePeriod = { begin: null, end: null };
function updateDataUsageTimestamp(begin, end) {
dataUsagePeriod.begin = begin;
dataUsagePeriod.end = end;
var timestamp = document.querySelector('#wifi-data-usage + .meta');
timestamp.innerHTML = '';
timestamp.appendChild(Formatting.formatTimeHTML(begin, end));
}
// Update balance view on settings
function updateBalance(lastBalance, currency) {
var limitCurrency = document.getElementById('settings-low-limit-currency');
limitCurrency.textContent = currency;
balanceView.update(lastBalance);
}
// Update telephony counters on settings
function updateTelephony(activity, lastTelephonyReset) {
var calltimeSpan = document.getElementById('calltime');
var smscountSpan = document.getElementById('smscount');
Common.localize(calltimeSpan, 'magnitude', {
value: Formatting.computeTelephonyMinutes(activity),
unit: 'min.'
});
Common.localize(smscountSpan, 'magnitude', {
value: activity.smscount,
unit: 'SMS'
});
updateTelephonyTimestamp(lastTelephonyReset, activity.timestamp);
}
var telephonyPeriod = { begin: null, end: null };
function updateTelephonyTimestamp(begin, end) {
telephonyPeriod.begin = begin;
telephonyPeriod.end = end;
var timestamp = document.getElementById('telephony-timestamp');
timestamp.innerHTML = '';
timestamp.appendChild(Formatting.formatTimeHTML(begin, end));
}
window.addEventListener('timeformatchange', function () {
updateTelephonyTimestamp(telephonyPeriod.begin, telephonyPeriod.end);
updateDataUsageTimestamp(dataUsagePeriod.begin, dataUsagePeriod.end);
});
return {
initialize: function() {
var SCRIPTS_NEEDED = [
'js/utils/toolkit.js',
'shared/js/date_time_helper.js',
'js/utils/formatting.js',
'js/views/BalanceLowLimitView.js',
'js/settings/limitdialog.js',
'js/settings/autosettings.js',
'js/view_manager.js',
'js/views/BalanceView.js',
'js/views/ResetMenuDialog.js',
'js/views/ConfirmDialog.js'
];
LazyLoader.load(SCRIPTS_NEEDED, function() {
if (!Common.allNetworkInterfaceLoaded) {
Common.loadNetworkInterfaces(configureUI);
} else {
configureUI();
}
});
},
updateUI: updateUI
};
}());
Settings.initialize();