Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/apps/system/js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/system/js')
-rw-r--r--apps/system/js/accessibility.js19
-rw-r--r--apps/system/js/activities.js86
-rw-r--r--apps/system/js/airplane_mode.js138
-rw-r--r--apps/system/js/app_install_manager.js443
-rw-r--r--apps/system/js/applications.js99
-rw-r--r--apps/system/js/attention_screen.js289
-rw-r--r--apps/system/js/authentication_dialog.js178
-rw-r--r--apps/system/js/background_service.js196
-rw-r--r--apps/system/js/battery_manager.js277
-rw-r--r--apps/system/js/bluetooth.js136
-rw-r--r--apps/system/js/bluetooth_transfer.js511
-rw-r--r--apps/system/js/bootstrap.js82
-rw-r--r--apps/system/js/call_forwarding.js45
-rw-r--r--apps/system/js/captive_portal.js73
-rw-r--r--apps/system/js/cards_view.js676
-rw-r--r--apps/system/js/context_menu.js24
-rw-r--r--apps/system/js/cost_control.js89
-rw-r--r--apps/system/js/crash_reporter.js140
-rw-r--r--apps/system/js/gridview.js40
-rw-r--r--apps/system/js/hardware_buttons.js318
-rw-r--r--apps/system/js/icc_cache.js86
-rw-r--r--apps/system/js/identity.js98
-rw-r--r--apps/system/js/keyboard_manager.js86
-rw-r--r--apps/system/js/list_menu.js180
-rw-r--r--apps/system/js/lockscreen.js1019
-rw-r--r--apps/system/js/modal_dialog.js443
-rw-r--r--apps/system/js/mouse2touch.js70
-rw-r--r--apps/system/js/notifications.js410
-rw-r--r--apps/system/js/operator_variant/operator_variant.js168
-rw-r--r--apps/system/js/payment.js151
-rw-r--r--apps/system/js/permission_manager.js203
-rw-r--r--apps/system/js/popup_manager.js313
-rw-r--r--apps/system/js/quick_settings.js279
-rw-r--r--apps/system/js/remote_debugger.js41
-rw-r--r--apps/system/js/screen_manager.js503
-rw-r--r--apps/system/js/screenshot.js115
-rw-r--r--apps/system/js/sim_lock.js110
-rw-r--r--apps/system/js/simcard_dialog.js355
-rw-r--r--apps/system/js/sleep_menu.js276
-rw-r--r--apps/system/js/sound_manager.js242
-rw-r--r--apps/system/js/source_view.js67
-rw-r--r--apps/system/js/statusbar.js618
-rw-r--r--apps/system/js/storage.js60
-rw-r--r--apps/system/js/system_banner.js33
-rw-r--r--apps/system/js/system_dialog.js113
-rw-r--r--apps/system/js/trusted_ui.js334
-rw-r--r--apps/system/js/ttlview.js50
-rw-r--r--apps/system/js/updatable.js269
-rw-r--r--apps/system/js/update_manager.js623
-rw-r--r--apps/system/js/utility_tray.js148
-rw-r--r--apps/system/js/value_selector/date_picker.js568
-rw-r--r--apps/system/js/value_selector/input_parser.js160
-rw-r--r--apps/system/js/value_selector/spin_date_picker.js341
-rw-r--r--apps/system/js/value_selector/value_picker.js222
-rw-r--r--apps/system/js/value_selector/value_selector.js526
-rw-r--r--apps/system/js/voicemail.js93
-rw-r--r--apps/system/js/wifi.js223
-rw-r--r--apps/system/js/window.js152
-rw-r--r--apps/system/js/window_manager.js2011
-rw-r--r--apps/system/js/wrapper.js198
60 files changed, 0 insertions, 15816 deletions
diff --git a/apps/system/js/accessibility.js b/apps/system/js/accessibility.js
deleted file mode 100644
index c2fa111..0000000
--- a/apps/system/js/accessibility.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-SettingsListener.observe('accessibility.invert', false, function(value) {
- var screen = document.getElementById('screen');
- if (value)
- screen.classList.add('accessibility-invert');
- else
- screen.classList.remove('accessibility-invert');
-});
-
-SettingsListener.observe('accessibility.screenreader', false, function(value) {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true,
- {type: 'accessibility-screenreader', enabled: value});
- window.dispatchEvent(event);
-});
diff --git a/apps/system/js/activities.js b/apps/system/js/activities.js
deleted file mode 100644
index f4db861..0000000
--- a/apps/system/js/activities.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var Activities = {
- init: function act_init() {
- window.addEventListener('mozChromeEvent', this);
- },
-
- handleEvent: function act_handleEvent(evt) {
- switch (evt.type) {
- case 'mozChromeEvent':
- var detail = evt.detail;
- switch (detail.type) {
- case 'activity-choice':
- this.chooseActivity(detail);
- break;
- }
- break;
- }
- },
-
- chooseActivity: function chooseActivity(detail) {
- this._id = detail.id;
-
- var choices = detail.choices;
- if (choices.length === 1) {
- this.choose('0');
- } else {
- // Since the mozChromeEvent could be triggered by a 'click', and gecko
- // event are synchronous make sure to exit the event loop before
- // showing the list.
- setTimeout((function nextTick() {
- var activityName = navigator.mozL10n.get('activity-' + detail.name);
- ListMenu.request(this._listItems(choices), activityName,
- this.choose.bind(this), this.cancel.bind(this));
- }).bind(this));
- }
- },
-
- choose: function act_choose(choice) {
- var returnedChoice = {
- id: this._id,
- type: 'activity-choice',
- value: choice
- };
-
- this._sendEvent(returnedChoice);
- delete this._id;
- },
-
- cancel: function act_cancel(value) {
- var returnedChoice = {
- id: this._id,
- type: 'activity-choice',
- value: -1
- };
-
- this._sendEvent(returnedChoice);
- delete this._id;
- },
-
- _sendEvent: function act_sendEvent(value) {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, value);
- window.dispatchEvent(event);
- },
-
- _listItems: function act_listItems(choices) {
- var items = [];
-
- choices.forEach(function(choice, index) {
- var app = Applications.getByManifestURL(choice.manifest);
- items.push({
- label: new ManifestHelper(app.manifest).name,
- icon: choice.icon,
- value: index
- });
- });
-
- return items;
- }
-};
-
-Activities.init();
diff --git a/apps/system/js/airplane_mode.js b/apps/system/js/airplane_mode.js
deleted file mode 100644
index 781a53f..0000000
--- a/apps/system/js/airplane_mode.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var AirplaneMode = {
- enabled: false,
-
- init: function apm_init() {
- if (!window.navigator.mozSettings)
- return;
-
- var mobileDataEnabled = false;
- SettingsListener.observe('ril.data.enabled', false, function(value) {
- mobileDataEnabled = value;
- });
-
- var bluetoothEnabled = false;
- SettingsListener.observe('bluetooth.enabled', false, function(value) {
- bluetoothEnabled = value;
- });
-
- var wifiEnabled = false;
- SettingsListener.observe('wifi.enabled', false, function(value) {
- wifiEnabled = value;
- });
-
- var geolocationEnabled = false;
- SettingsListener.observe('geolocation.enabled', false, function(value) {
- geolocationEnabled = value;
- });
-
- var bluetooth = window.navigator.mozBluetooth;
- var wifiManager = window.navigator.mozWifiManager;
- var mobileData = window.navigator.mozMobileConnection &&
- window.navigator.mozMobileConnection.data;
- var fmRadio = window.navigator.mozFMRadio;
-
- var restoreMobileData = false;
- var restoreBluetooth = false;
- var restoreWifi = false;
- var restoreGeolocation = false;
- // Note that we don't restore Wifi tethering when leaving airplane mode
- // because Wifi tethering can't be switched on before data connection is
- // established.
-
- var self = this;
- SettingsListener.observe('ril.radio.disabled', false, function(value) {
- if (value) {
- // Entering airplane mode.
- self.enabled = true;
-
- // Turn off mobile data
- // We toggle the mozSettings value here just for the sake of UI,
- // platform ril disconnects mobile data when
- // 'ril.radio.disabled' is true.
- if (mobileData) {
- restoreMobileData = mobileDataEnabled;
- if (mobileDataEnabled) {
- SettingsListener.getSettingsLock().set({
- 'ril.data.enabled': false
- });
- }
- }
-
- // Turn off Bluetooth.
- if (bluetooth) {
- restoreBluetooth = bluetoothEnabled;
- if (bluetoothEnabled) {
- SettingsListener.getSettingsLock().set({
- 'bluetooth.enabled': false
- });
- }
- }
-
- // Turn off Wifi.
- if (wifiManager) {
- restoreWifi = wifiEnabled;
- if (wifiEnabled) {
- SettingsListener.getSettingsLock().set({
- 'wifi.enabled': false
- });
- }
-
- // Turn off Wifi tethering.
- SettingsListener.getSettingsLock().set({
- 'tethering.wifi.enabled': false
- });
- }
-
- // Turn off Geolocation.
- restoreGeolocation = geolocationEnabled;
- if (geolocationEnabled) {
- SettingsListener.getSettingsLock().set({
- 'geolocation.enabled': false
- });
- }
-
- // Turn off FM Radio.
- if (fmRadio && fmRadio.enabled)
- fmRadio.disable();
-
- } else {
- self.enabled = false;
- // Don't attempt to turn on mobile data if it's already on
- if (mobileData && !mobileDataEnabled && restoreMobileData) {
- SettingsListener.getSettingsLock().set({
- 'ril.data.enabled': true
- });
- }
-
- // Don't attempt to turn on Bluetooth if it's already on
- if (bluetooth && !bluetooth.enabled && restoreBluetooth) {
- SettingsListener.getSettingsLock().set({
- 'bluetooth.enabled': true
- });
- }
-
- // Don't attempt to turn on Wifi if it's already on
- if (wifiManager && !wifiManager.enabled && restoreWifi) {
- SettingsListener.getSettingsLock().set({
- 'wifi.enabled': true
- });
- }
-
- // Don't attempt to turn on Geolocation if it's already on
- if (!geolocationEnabled && restoreGeolocation) {
- SettingsListener.getSettingsLock().set({
- 'geolocation.enabled': true
- });
- }
- }
- });
- }
-};
-
-AirplaneMode.init();
-
diff --git a/apps/system/js/app_install_manager.js b/apps/system/js/app_install_manager.js
deleted file mode 100644
index 146a01b..0000000
--- a/apps/system/js/app_install_manager.js
+++ /dev/null
@@ -1,443 +0,0 @@
-'use strict';
-
-var AppInstallManager = {
- mapDownloadErrorsToMessage: {
- 'NETWORK_ERROR': 'download-failed',
- 'DOWNLOAD_ERROR': 'download-failed',
- 'MISSING_MANIFEST': 'install-failed',
- 'INVALID_MANIFEST': 'install-failed',
- 'INSTALL_FROM_DENIED': 'install-failed',
- 'INVALID_SECURITY_LEVEL': 'install-failed',
- 'INVALID_PACKAGE': 'install-failed',
- 'APP_CACHE_DOWNLOAD_ERROR': 'download-failed'
- },
-
- init: function ai_init() {
- this.dialog = document.getElementById('app-install-dialog');
- this.msg = document.getElementById('app-install-message');
- this.size = document.getElementById('app-install-size');
- this.authorName = document.getElementById('app-install-author-name');
- this.authorUrl = document.getElementById('app-install-author-url');
- this.installButton = document.getElementById('app-install-install-button');
- this.cancelButton = document.getElementById('app-install-cancel-button');
- this.installCancelDialog =
- document.getElementById('app-install-cancel-dialog');
- this.downloadCancelDialog =
- document.getElementById('app-download-cancel-dialog');
- this.confirmCancelButton =
- document.getElementById('app-install-confirm-cancel-button');
- this.resumeButton = document.getElementById('app-install-resume-button');
-
- this.notifContainer =
- document.getElementById('install-manager-notification-container');
- this.appInfos = {};
-
- window.addEventListener('mozChromeEvent',
- (function ai_handleChromeEvent(e) {
- if (e.detail.type == 'webapps-ask-install') {
- this.handleAppInstallPrompt(e.detail);
- }
- }).bind(this));
-
- window.addEventListener('applicationinstall',
- this.handleApplicationInstall.bind(this));
-
-
- this.installButton.onclick = this.handleInstall.bind(this);
- this.cancelButton.onclick = this.showInstallCancelDialog.bind(this);
- this.confirmCancelButton.onclick = this.handleInstallCancel.bind(this);
- this.resumeButton.onclick = this.hideInstallCancelDialog.bind(this);
- this.notifContainer.onclick = this.showDownloadCancelDialog.bind(this);
-
- this.downloadCancelDialog.querySelector('.confirm').onclick =
- this.handleConfirmDownloadCancel.bind(this);
- this.downloadCancelDialog.querySelector('.cancel').onclick =
- this.handleCancelDownloadCancel.bind(this);
-
- // bind these handlers so that we can have only one instance and check
- // them later on
- ['handleDownloadSuccess',
- 'handleDownloadError',
- 'handleProgress',
- 'handleApplicationReady'
- ].forEach(function(name) {
- this[name] = this[name].bind(this);
- }, this);
-
- window.addEventListener('applicationready',
- this.handleApplicationReady);
- },
-
- handleApplicationReady: function ai_handleApplicationReady(e) {
- window.removeEventListener('applicationready',
- this.handleApplicationReady);
-
- var apps = e.detail.applications;
-
- Object.keys(apps)
- .filter(function(key) { return apps[key].installState === 'pending'; })
- .map(function(key) { return apps[key]; })
- .forEach(this.prepareForDownload, this);
- },
-
- handleApplicationInstall: function ai_handleApplicationInstallEvent(e) {
- var app = e.detail.application;
-
- if (app.installState === 'installed') {
- this.showInstallSuccess(app);
- return;
- }
-
- this.prepareForDownload(app);
- },
-
- handleAppInstallPrompt: function ai_handleInstallPrompt(detail) {
- var _ = navigator.mozL10n.get;
- var app = detail.app;
- // updateManifest is used by packaged apps until they are installed
- var manifest = app.manifest ? app.manifest : app.updateManifest;
-
- if (!manifest)
- return;
-
- this.dialog.classList.add('visible');
-
- var id = detail.id;
-
- if (manifest.size) {
- this.size.textContent = this.humanizeSize(manifest.size);
- } else {
- this.size.textContent = _('unknown');
- }
-
- // Wrap manifest to get localized properties
- manifest = new ManifestHelper(manifest);
- var msg = _('install-app', {'name': manifest.name});
- this.msg.textContent = msg;
-
- if (manifest.developer) {
- this.authorName.textContent = manifest.developer.name || _('unknown');
- this.authorUrl.textContent = manifest.developer.url || '';
- } else {
- this.authorName.textContent = _('unknown');
- this.authorUrl.textContent = '';
- }
-
- this.installCallback = (function ai_installCallback() {
- this.dispatchResponse(id, 'webapps-install-granted');
- }).bind(this);
-
- this.installCancelCallback = (function ai_cancelCallback() {
- this.dispatchResponse(id, 'webapps-install-denied');
- }).bind(this);
-
- },
-
- handleInstall: function ai_handleInstall(evt) {
- if (evt)
- evt.preventDefault();
- if (this.installCallback)
- this.installCallback();
- this.installCallback = null;
- this.dialog.classList.remove('visible');
- },
-
- prepareForDownload: function ai_prepareForDownload(app) {
- var manifestURL = app.manifestURL;
- this.appInfos[manifestURL] = {};
-
- // these methods are already bound to |this|
- app.ondownloadsuccess = this.handleDownloadSuccess;
- app.ondownloaderror = this.handleDownloadError;
- app.onprogress = this.handleProgress;
- },
-
- showInstallSuccess: function ai_showInstallSuccess(app) {
- var manifest = app.manifest || app.updateManifest;
- var name = new ManifestHelper(manifest).name;
- var _ = navigator.mozL10n.get;
- var msg = _('app-install-success', { appName: name });
- SystemBanner.show(msg);
- },
-
- handleDownloadSuccess: function ai_handleDownloadSuccess(evt) {
- var app = evt.application;
- this.showInstallSuccess(app);
- this.onDownloadStop(app);
- this.onDownloadFinish(app);
- },
-
- handleDownloadError: function ai_handleDownloadError(evt) {
- var app = evt.application;
- var _ = navigator.mozL10n.get;
- var manifest = app.manifest || app.updateManifest;
- var name = new ManifestHelper(manifest).name;
-
- var errorName = app.downloadError.name;
-
- switch (errorName) {
- case 'INSUFFICIENT_STORAGE':
- var title = _('not-enough-space'),
- buttonText = _('ok'),
- message = _('not-enough-space-message');
-
- ModalDialog.alert(title, message, {title: buttonText});
- break;
- default:
- // showing the real error to a potential developer
- console.info('downloadError event, error code is', errorName);
-
- var key = this.mapDownloadErrorsToMessage[errorName] || 'generic-error';
- var msg = _('app-install-' + key, { appName: name });
- SystemBanner.show(msg);
- }
-
- this.onDownloadStop(app);
- },
-
- onDownloadStart: function ai_onDownloadStart(app) {
- if (! this.hasNotification(app)) {
- StatusBar.incSystemDownloads();
- this.addNotification(app);
- this.requestWifiLock(app);
- }
- },
-
- onDownloadStop: function ai_onDownloadStop(app) {
- if (this.hasNotification(app)) {
- StatusBar.decSystemDownloads();
- this.removeNotification(app);
- this.releaseWifiLock(app);
- }
- },
-
- hasNotification: function ai_hasNotification(app) {
- var appInfo = this.appInfos[app.manifestURL];
- return appInfo && !!appInfo.installNotification;
- },
-
- onDownloadFinish: function ai_onDownloadFinish(app) {
- delete this.appInfos[app.manifestURL];
-
- // check if these are our handlers before removing them
- if (app.ondownloadsuccess === this.handleDownloadSuccess) {
- app.ondownloadsuccess = null;
- }
-
- if (app.ondownloaderror === this.handleDownloadError) {
- app.ondownloaderror = null;
- }
-
- if (app.onprogress === this.handleProgress) {
- app.onprogress = null;
- }
- },
-
- addNotification: function ai_addNotification(app) {
- // should be unique (this is used already in applications.js)
- var manifestURL = app.manifestURL,
- manifest = app.manifest || app.updateManifest,
- appInfo = this.appInfos[manifestURL];
-
- if (appInfo.installNotification) {
- return;
- }
-
- var newNotif =
- '<div class="fake-notification">' +
- '<div class="message"></div>' +
- '<progress></progress>' +
- '</div>';
-
- this.notifContainer.insertAdjacentHTML('afterbegin', newNotif);
-
- var newNode = this.notifContainer.firstElementChild;
- newNode.dataset.manifest = manifestURL;
-
- var _ = navigator.mozL10n.get;
-
- var message = _('downloadingAppMessage', {
- appName: new ManifestHelper(manifest).name
- });
-
- newNode.querySelector('.message').textContent = message;
-
- var size = manifest.size,
- progressNode = newNode.querySelector('progress');
- if (size) {
- progressNode.max = size;
- appInfo.hasMax = true;
- }
-
- appInfo.installNotification = newNode;
- NotificationScreen.incExternalNotifications();
- },
-
- getNotificationProgressNode: function ai_getNotificationProgressNode(app) {
- var appInfo = this.appInfos[app.manifestURL];
- var progressNode = appInfo &&
- appInfo.installNotification &&
- appInfo.installNotification.querySelector('progress');
- return progressNode || null;
- },
-
- handleProgress: function ai_handleProgress(evt) {
- var app = evt.application,
- appInfo = this.appInfos[app.manifestURL];
-
- this.onDownloadStart(app);
-
-
- var progressNode = this.getNotificationProgressNode(app);
- var message;
- var _ = navigator.mozL10n.get;
-
- if (isNaN(app.progress) || app.progress == null) {
- // now we get NaN if there is no progress information but let's
- // handle the null and undefined cases as well
- message = _('downloadingAppProgressIndeterminate');
- progressNode.value = undefined; // switch to indeterminate state
- } else if (appInfo.hasMax) {
- message = _('downloadingAppProgress',
- {
- progress: this.humanizeSize(app.progress),
- max: this.humanizeSize(progressNode.max)
- });
- progressNode.value = app.progress;
- } else {
- message = _('downloadingAppProgressNoMax',
- { progress: this.humanizeSize(app.progress) });
- }
- progressNode.textContent = message;
- },
-
- removeNotification: function ai_removeNotification(app) {
- var manifestURL = app.manifestURL,
- appInfo = this.appInfos[manifestURL],
- node = appInfo.installNotification;
-
- if (!node) {
- return;
- }
-
- node.parentNode.removeChild(node);
- delete appInfo.installNotification;
- NotificationScreen.decExternalNotifications();
- },
-
- requestWifiLock: function ai_requestWifiLock(app) {
- var appInfo = this.appInfos[app.manifestURL];
- if (! appInfo.wifiLock) {
- // we don't want 2 locks for the same app
- appInfo.wifiLock = navigator.requestWakeLock('wifi');
- }
- },
-
- releaseWifiLock: function ai_releaseWifiLock(app) {
- var appInfo = this.appInfos[app.manifestURL];
-
- if (appInfo.wifiLock) {
- try {
- appInfo.wifiLock.unlock();
- } catch (e) {
- // this can happen if the lock is already unlocked
- console.error('error during unlock', e);
- }
-
- delete appInfo.wifiLock;
- }
- },
-
- dispatchResponse: function ai_dispatchResponse(id, type) {
- var event = document.createEvent('CustomEvent');
-
- event.initCustomEvent('mozContentEvent', true, true, {
- id: id,
- type: type
- });
-
- window.dispatchEvent(event);
- },
-
- humanizeSize: function ai_humanizeSize(bytes) {
- var _ = navigator.mozL10n.get;
- var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
-
- if (!bytes)
- return '0.00 ' + _(units[0]);
-
- var e = Math.floor(Math.log(bytes) / Math.log(1024));
- return (bytes / Math.pow(1024, Math.floor(e))).toFixed(2) + ' ' +
- _(units[e]);
- },
-
- showInstallCancelDialog: function ai_showInstallCancelDialog(evt) {
- if (evt)
- evt.preventDefault();
- this.installCancelDialog.classList.add('visible');
- this.dialog.classList.remove('visible');
- },
-
- hideInstallCancelDialog: function ai_hideInstallCancelDialog(evt) {
- if (evt)
- evt.preventDefault();
- this.dialog.classList.add('visible');
- this.installCancelDialog.classList.remove('visible');
- },
-
- showDownloadCancelDialog: function ai_showDownloadCancelDialog(e) {
- var currentNode = e.target;
-
- if (!currentNode.classList.contains('fake-notification')) {
- // tapped outside of a notification
- return;
- }
-
- var manifestURL = currentNode.dataset.manifest,
- app = Applications.getByManifestURL(manifestURL),
- manifest = app.manifest || app.updateManifest,
- dialog = this.downloadCancelDialog;
-
- var title = dialog.querySelector('h1');
-
- title.textContent = navigator.mozL10n.get('stopDownloading', {
- app: new ManifestHelper(manifest).name
- });
-
- dialog.classList.add('visible');
- dialog.dataset.manifest = manifestURL;
- UtilityTray.hide();
- },
-
- handleInstallCancel: function ai_handleInstallCancel() {
- if (this.installCancelCallback)
- this.installCancelCallback();
- this.installCancelCallback = null;
- this.installCancelDialog.classList.remove('visible');
- },
-
- handleConfirmDownloadCancel: function ai_handleConfirmDownloadCancel(e) {
- e && e.preventDefault();
- var dialog = this.downloadCancelDialog,
- manifestURL = dialog.dataset.manifest;
- if (manifestURL) {
- var app = Applications.getByManifestURL(manifestURL);
- app && app.cancelDownload();
- }
-
- this.hideDownloadCancelDialog();
- },
-
- handleCancelDownloadCancel: function ai_handleCancelDownloadCancel(e) {
- e && e.preventDefault();
- this.hideDownloadCancelDialog();
- },
-
- hideDownloadCancelDialog: function() {
- var dialog = this.downloadCancelDialog;
- dialog.classList.remove('visible');
- delete dialog.dataset.manifest;
- }
-};
-
-AppInstallManager.init();
diff --git a/apps/system/js/applications.js b/apps/system/js/applications.js
deleted file mode 100644
index f1e286f..0000000
--- a/apps/system/js/applications.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-// Application module handles the information of apps on behalf of other
-// modules.
-
-var Applications = {
- installedApps: {},
- ready: false,
- init: function a_init() {
- var self = this;
- var apps = navigator.mozApps;
-
- var getAllApps = function getAllApps() {
- navigator.mozApps.mgmt.getAll().onsuccess = function mozAppGotAll(evt) {
- var apps = evt.target.result;
- apps.forEach(function(app) {
- self.installedApps[app.manifestURL] = app;
- // TODO Followup for retrieving homescreen & comms app
- });
-
- self.ready = true;
- self.fireApplicationReadyEvent();
- };
- };
-
- // We need to wait for the chrome shell to let us know when it's ok to
- // launch activities. This prevents race conditions.
- // The event does not fire again when we reload System app in on
- // B2G Desktop, so we save the information into sessionStorage.
- if (window.sessionStorage.getItem('webapps-registry-ready')) {
- getAllApps();
- } else {
- window.addEventListener('mozChromeEvent', function mozAppReady(event) {
- if (event.detail.type != 'webapps-registry-ready')
- return;
-
- window.sessionStorage.setItem('webapps-registry-ready', 'yes');
- window.removeEventListener('mozChromeEvent', mozAppReady);
-
- getAllApps();
- });
- }
-
- apps.mgmt.oninstall = function a_install(evt) {
- var newapp = evt.application;
- self.installedApps[newapp.manifestURL] = newapp;
-
- self.fireApplicationInstallEvent(newapp);
- };
-
- apps.mgmt.onuninstall = function a_uninstall(evt) {
- var deletedapp = evt.application;
- delete self.installedApps[deletedapp.manifestURL];
-
- self.fireApplicationUninstallEvent(deletedapp);
- };
- },
-
- getByManifestURL: function a_getByManifestURL(manifestURL) {
- if (manifestURL in this.installedApps) {
- return this.installedApps[manifestURL];
- }
-
- return null;
- },
-
- fireApplicationReadyEvent: function a_fireAppReadyEvent() {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('applicationready',
- /* canBubble */ true, /* cancelable */ false,
- { applications: this.installedApps });
- window.dispatchEvent(evt);
- },
-
- // We need to dispatch the following events because
- // mozApps is not doing so right now.
- // ref: https://bugzilla.mozilla.org/show_bug.cgi?id=731746
-
- fireApplicationInstallEvent: function a_fireApplicationInstallEvent(app) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('applicationinstall',
- /* canBubble */ true, /* cancelable */ false,
- { application: app });
- window.dispatchEvent(evt);
- },
-
- fireApplicationUninstallEvent: function a_fireApplicationUninstallEvent(app) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('applicationuninstall',
- /* canBubble */ true, /* cancelable */ false,
- { application: app });
- window.dispatchEvent(evt);
- }
-};
-
-Applications.init();
diff --git a/apps/system/js/attention_screen.js b/apps/system/js/attention_screen.js
deleted file mode 100644
index c14dbe8..0000000
--- a/apps/system/js/attention_screen.js
+++ /dev/null
@@ -1,289 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-'use strict';
-
-var AttentionScreen = {
- get mainScreen() {
- delete this.mainScreen;
- return this.mainScreen = document.getElementById('screen');
- },
-
- get attentionScreen() {
- delete this.attentionScreen;
- return this.attentionScreen = document.getElementById('attention-screen');
- },
-
- get bar() {
- delete this.bar;
- return this.bar = document.getElementById('attention-bar');
- },
-
- isVisible: function as_isVisible() {
- return this.attentionScreen.classList.contains('displayed');
- },
-
- isFullyVisible: function as_isFullyVisible() {
- return (this.isVisible() &&
- !this.mainScreen.classList.contains('active-statusbar'));
- },
-
- init: function as_init() {
- window.addEventListener('mozbrowseropenwindow', this.open.bind(this), true);
- window.addEventListener('mozbrowserclose', this.close.bind(this), true);
- window.addEventListener('mozbrowsererror', this.close.bind(this), true);
- window.addEventListener('keyboardchange', this.resize.bind(this), true);
- window.addEventListener('keyboardhide', this.resize.bind(this), true);
-
- this.bar.addEventListener('click', this.show.bind(this));
- window.addEventListener('home', this.hide.bind(this));
- window.addEventListener('holdhome', this.hide.bind(this));
- window.addEventListener('appwillopen', this.hide.bind(this));
- },
-
- resize: function as_resize(evt) {
- if (evt.type == 'keyboardchange') {
- if (!this.isFullyVisible())
- return;
-
- this.attentionScreen.style.height =
- window.innerHeight - evt.detail.height + 'px';
- } else if (evt.type == 'keyboardhide') {
- // We still need to reset the height property even when the attention
- // screen is not fully visible, or it will overrides the height
- // we defined with #attention-screen.status-mode
- this.attentionScreen.style.height = '';
- }
- },
-
- // show the attention screen overlay with newly created frame
- open: function as_open(evt) {
- if (evt.detail.features != 'attention')
- return;
-
- // stopPropagation means we are not allowing
- // Popup Manager to handle this event
- evt.stopPropagation();
-
- // Canceling any full screen web content
- if (document.mozFullScreen)
- document.mozCancelFullScreen();
-
- // Check if the app has the permission to open attention screens
- var manifestURL = evt.target.getAttribute('mozapp');
- var app = Applications.getByManifestURL(manifestURL);
-
- if (!app || !this._hasAttentionPermission(app))
- return;
-
- // Hide sleep menu/list menu if it is shown now
- ListMenu.hide();
- SleepMenu.hide();
-
- // We want the user attention, so we need to turn the screen on
- // if it's off. The lockscreen will grab the focus when we do that
- // so we need to do it before adding the new iframe to the dom
- if (!ScreenManager.screenEnabled)
- ScreenManager.turnScreenOn();
-
- var attentionFrame = evt.detail.frameElement;
- attentionFrame.dataset.frameType = 'attention';
- attentionFrame.dataset.frameName = evt.detail.name;
- attentionFrame.dataset.frameOrigin = evt.target.dataset.frameOrigin;
-
- // We would like to put the dialer call screen on top of all other
- // attention screens by ensure it is the last iframe in the DOM tree
- if (this._hasTelephonyPermission(app)) {
- this.attentionScreen.appendChild(attentionFrame);
- } else {
- this.attentionScreen.insertBefore(attentionFrame,
- this.bar.nextElementSibling);
- }
-
- this._updateAttentionFrameVisibility();
-
- // Make the overlay visible if we are not displayed yet.
- // alternatively, if the newly appended frame is the visible frame
- // and we are in the status bar mode, expend to full screen mode.
- if (!this.isVisible()) {
- this.attentionScreen.classList.add('displayed');
- this.mainScreen.classList.add('attention');
- this.dispatchEvent('attentionscreenshow', {
- origin: attentionFrame.dataset.frameOrigin
- });
- } else if (!this.isFullyVisible() &&
- this.attentionScreen.lastElementChild === attentionFrame) {
- this.show();
- }
- },
-
- // Make sure visibililty state of all attention screens are set correctly
- _updateAttentionFrameVisibility: function as_updateAtteFrameVisibility() {
- var frames = this.attentionScreen.querySelectorAll('iframe');
- var i = frames.length - 1;
-
- // In case someone call this function w/o checking for frame first
- if (i < 0)
- return;
-
- // set the last one in the DOM to visible
- // The setTimeout() and the closure is used to workaround
- // https://bugzilla.mozilla.org/show_bug.cgi?id=810431
- setTimeout(function(frame) {
- frame.setVisible(true);
- frame.focus();
- }, 0, frames[i]);
-
- while (i--) {
- // The setTimeout() and the closure is used to workaround
- // https://bugzilla.mozilla.org/show_bug.cgi?id=810431
- setTimeout(function(frame) {
- frame.setVisible(false);
- frame.blur();
- }, 0, frames[i]);
- }
- },
-
- // close the attention screen overlay
- close: function as_close(evt) {
- if (!'frameType' in evt.target.dataset ||
- evt.target.dataset.frameType !== 'attention' ||
- (evt.type === 'mozbrowsererror' && evt.detail.type !== 'fatal'))
- return;
-
- // Remove the frame
- var origin = evt.target.dataset.frameOrigin;
- this.attentionScreen.removeChild(evt.target);
-
- // We've just removed the focused window leaving the system
- // without any focused window, let's fix this.
- window.focus();
-
- // if there are other attention frames,
- // we need to update the visibility and show() the overlay.
- if (this.attentionScreen.querySelectorAll('iframe').length) {
- this._updateAttentionFrameVisibility();
-
- this.dispatchEvent('attentionscreenclose', { origin: origin });
-
- if (!this.isFullyVisible())
- this.show();
-
- return;
- }
-
- // There is no iframes left;
- // we should close the attention screen overlay.
-
- // If the the attention screen is closed during active-statusbar
- // mode, we would need to leave that mode.
- if (!this.isFullyVisible()) {
- this.mainScreen.classList.remove('active-statusbar');
- this.attentionScreen.classList.remove('status-mode');
- this.dispatchEvent('status-inactive',
- { origin: this.attentionScreen.lastElementChild.dataset.frameOrigin });
- }
-
- this.attentionScreen.classList.remove('displayed');
- this.mainScreen.classList.remove('attention');
- this.dispatchEvent('attentionscreenhide', { origin: origin });
- },
-
- // expend the attention screen overlay to full screen
- show: function as_show() {
- // leaving "status-mode".
- this.attentionScreen.classList.remove('status-mode');
- // there shouldn't be a transition from "status-mode" to "active-statusbar"
- this.attentionScreen.style.transition = 'none';
-
- var self = this;
- setTimeout(function nextTick() {
- self.attentionScreen.style.transition = '';
-
- // leaving "active-statusbar" mode,
- // with a transform: translateY() slide down transition.
- self.mainScreen.classList.remove('active-statusbar');
- self.dispatchEvent('status-inactive', {
- origin: self.attentionScreen.lastElementChild.dataset.frameOrigin
- });
- });
- },
-
- // shrink the attention screen overlay to status bar
- // invoked when we get a "home" event
- hide: function as_hide() {
- if (!this.isFullyVisible())
- return;
-
- // entering "active-statusbar" mode,
- // with a transform: translateY() slide up transition.
- this.mainScreen.classList.add('active-statusbar');
-
- // The only way to hide attention screen is the home/holdhome event.
- // So we don't fire any origin information here.
- // The expected behavior is restore homescreen visibility to 'true'
- // in the Window Manager.
- this.dispatchEvent('status-active');
-
- var attentionScreen = this.attentionScreen;
- attentionScreen.addEventListener('transitionend', function trWait() {
- attentionScreen.removeEventListener('transitionend', trWait);
-
- // transition completed, entering "status-mode" (40px height iframe)
- attentionScreen.classList.add('status-mode');
- });
- },
-
- dispatchEvent: function as_dispatchEvent(name, detail) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent(name, true, true, detail);
- window.dispatchEvent(evt);
- },
-
- // If an app with an active attention screen is switched to,
- // we would need to cover it with it's attention screen.
- // Invoked when displayedApp in Window Manager changes
- // XXX should be replaced with a call that listens to appwillopen
- // TBD: display the attention screen underneath other attention screens.
- showForOrigin: function as_showForOrigin(origin) {
- if (!this.isVisible() || this.isFullyVisible())
- return;
-
- var attentionFrame = this.attentionScreen.lastElementChild;
- var frameOrigin = attentionFrame.dataset.frameOrigin;
- if (origin === frameOrigin) {
- this.show();
- }
- },
-
- getAttentionScreenOrigins: function as_getAttentionScreenOrigins() {
- var attentionScreen = this.attentionScreen;
- var frames = this.attentionScreen.querySelectorAll('iframe');
- var attentiveApps = [];
- Array.prototype.forEach.call(frames, function pushFrame(frame) {
- attentiveApps.push(frame.dataset.frameOrigin);
- });
- return attentiveApps;
- },
-
- _hasAttentionPermission: function as_hasAttentionPermission(app) {
- var mozPerms = navigator.mozPermissionSettings;
- if (!mozPerms)
- return false;
-
- var value = mozPerms.get('attention', app.manifestURL, app.origin, false);
-
- return (value === 'allow');
- },
-
- _hasTelephonyPermission: function as_hasAttentionPermission(app) {
- var mozPerms = navigator.mozPermissionSettings;
- if (!mozPerms)
- return false;
-
- var value = mozPerms.get('telephony', app.manifestURL, app.origin, false);
-
- return (value === 'allow');
- }
-};
-
-AttentionScreen.init();
diff --git a/apps/system/js/authentication_dialog.js b/apps/system/js/authentication_dialog.js
deleted file mode 100644
index 3a893ee..0000000
--- a/apps/system/js/authentication_dialog.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-// This module listens to mozbrowserusernameandpasswordrequired event.
-// It's for http authentication only.
-// XXX: ftp authentication will be implemented here but not supported yet.
-
-var AuthenticationDialog = {
- // Used for element id access.
- // e.g., 'authentication-dialog-alert-ok'
- prefix: 'authentication-dialog-',
-
- // DOM
- elements: {},
-
- // Get all elements when inited.
- getAllElements: function ad_getAllElements() {
- var elementsID = [
- 'http-authentication', 'http-username-input', 'http-password-input',
- 'http-authentication-message', 'http-authentication-ok',
- 'http-authentication-cancel', 'title'
- ];
-
- var toCamelCase = function toCamelCase(str) {
- return str.replace(/\-(.)/g, function replacer(str, p1) {
- return p1.toUpperCase();
- });
- };
-
- elementsID.forEach(function createElementRef(name) {
- this.elements[toCamelCase(name)] =
- document.getElementById(this.prefix + name);
- }, this);
-
- this.screen = document.getElementById('screen');
- this.overlay = document.getElementById('dialog-overlay');
- },
-
- // Save the events returned by
- // mozbrowserusernameandpasswordrequired for later use.
- // The events are stored according to webapp origin
- // e.g., 'http://uitest.gaiamobile.org': evt
- currentEvents: {},
-
- init: function ad_init() {
- // Get all elements initially.
- this.getAllElements();
- var elements = this.elements;
-
- // Bind events
- window.addEventListener('mozbrowserusernameandpasswordrequired', this);
- window.addEventListener('appopen', this);
- window.addEventListener('appwillclose', this);
- window.addEventListener('appterminated', this);
- window.addEventListener('resize', this);
- window.addEventListener('keyboardchange', this);
- window.addEventListener('keyboardhide', this);
-
- for (var id in elements) {
- if (elements[id].tagName.toLowerCase() == 'button') {
- elements[id].addEventListener('click', this);
- }
- }
- },
-
- // Default event handler
- handleEvent: function ad_handleEvent(evt) {
- var elements = this.elements;
- switch (evt.type) {
- case 'mozbrowserusernameandpasswordrequired':
- if (evt.target.dataset.frameType != 'window')
- return;
-
- evt.preventDefault();
- var origin = evt.target.dataset.frameOrigin;
- this.currentEvents[origin] = evt;
-
- if (origin == WindowManager.getDisplayedApp())
- this.show(origin);
- break;
-
- case 'click':
- if (evt.currentTarget === elements.httpAuthenticationCancel) {
- this.cancelHandler();
- } else {
- this.confirmHandler();
- }
- break;
-
- case 'appopen':
- if (this.currentEvents[evt.detail.origin])
- this.show(evt.detail.origin);
- break;
-
- case 'appwillclose':
- // Do nothing if the app is closed at background.
- if (evt.detail.origin !== this.currentOrigin)
- return;
-
- // Reset currentOrigin
- this.hide();
- break;
-
- case 'appterminated':
- if (this.currentEvents[evt.detail.origin])
- delete this.currentEvents[evt.detail.origin];
-
- break;
-
- case 'resize':
- case 'keyboardhide':
- if (!this.currentOrigin)
- return;
-
- this.setHeight(window.innerHeight - StatusBar.height);
- break;
-
- case 'keyboardchange':
- this.setHeight(window.innerHeight -
- evt.detail.height - StatusBar.height);
- break;
- }
- },
-
- setHeight: function ad_setHeight(height) {
- if (this.isVisible())
- this.overlay.style.height = height + 'px';
- },
-
- show: function ad_show(origin) {
- this.currentOrigin = origin;
- var evt = this.currentEvents[origin];
- var elements = this.elements;
- this.screen.classList.add('authentication-dialog');
- elements.httpAuthentication.classList.add('visible');
- elements.title.textContent = evt.detail.host;
- elements.httpAuthenticationMessage.textContent = evt.detail.realm;
- elements.httpUsernameInput.value = '';
- elements.httpPasswordInput.value = '';
-
- this.setHeight(window.innerHeight - StatusBar.height);
- },
-
- hide: function ad_hide() {
- this.elements.httpUsernameInput.blur();
- this.elements.httpPasswordInput.blur();
- this.currentOrigin = null;
- this.elements.httpAuthentication.classList.remove('visible');
- this.screen.classList.remove('authentication-dialog');
- },
-
- confirmHandler: function ad_confirmHandler() {
- var elements = this.elements;
- var evt = this.currentEvents[this.currentOrigin];
- evt.detail.authenticate(elements.httpUsernameInput.value,
- elements.httpPasswordInput.value);
- elements.httpAuthentication.classList.remove('visible');
- delete this.currentEvents[this.currentOrigin];
- this.screen.classList.remove('authentication-dialog');
- },
-
- cancelHandler: function ad_cancelHandler() {
- var evt = this.currentEvents[this.currentOrigin];
- var elements = this.elements;
- evt.detail.cancel();
- elements.httpAuthentication.classList.remove('visible');
- delete this.currentEvents[this.currentOrigin];
- this.screen.classList.remove('authentication-dialog');
- },
-
- isVisible: function ad_isVisible() {
- return this.screen.classList.contains('authentication-dialog');
- }
-};
-
-AuthenticationDialog.init();
diff --git a/apps/system/js/background_service.js b/apps/system/js/background_service.js
deleted file mode 100644
index 117b556..0000000
--- a/apps/system/js/background_service.js
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-/*
- Allow web apps to inject a tiny persistent background iframe
- as the phone starts.
-*/
-var BackgroundServiceManager = (function bsm() {
- /* We keep the references to background page iframes here.
- The iframes will be append to body */
- var frames = {};
-
- /* The name of the background window open by background_page in
- manifest. */
- var AUTO_OPEN_BG_PAGE_NAME = 'background';
-
- /* Init */
- var init = function bsm_init() {
- var applications = Applications.installedApps;
- Object.keys(applications).forEach(function bsm_each(manifestURL) {
- var app = applications[manifestURL];
- if (!app.manifest.background_page)
- return;
-
- // XXX: this work as if background_page is always a path not a full URL.
- var url = app.origin + app.manifest.background_page;
- open(manifestURL, AUTO_OPEN_BG_PAGE_NAME, url);
- });
- };
-
- /* mozbrowseropenwindow */
- window.addEventListener('mozbrowseropenwindow', function bsm_winopen(evt) {
- if (evt.detail.features !== 'background')
- return;
-
- // stopPropagation means we are not allowing
- // Popup Manager to handle this event
- evt.stopPropagation();
-
- var manifestURL = evt.target.getAttribute('mozapp');
- var detail = evt.detail;
-
- open(manifestURL, detail.name, detail.url, detail.frameElement);
- }, true);
-
- /* mozbrowserclose */
- window.addEventListener('mozbrowserclose', function bsm_winclose(evt) {
- if (!'frameType' in evt.target.dataset ||
- evt.target.dataset.frameType !== 'background')
- return;
-
- var manifestURL = evt.target.getAttribute('mozapp');
-
- close(manifestURL, evt.target.dataset.frameName);
- }, true);
-
- /* mozbrowsererror */
- window.addEventListener('mozbrowsererror', function bsm_winclose(evt) {
- if (!'frameType' in evt.target.dataset ||
- evt.target.dataset.frameType !== 'background' ||
- evt.detail.type !== 'fatal')
- return;
-
- var target = evt.target;
- var manifestURL = target.getAttribute('mozapp');
-
- // This bg service has just crashed, clean up the frame
- var name = target.dataset.frameName;
- close(manifestURL, name);
- }, true);
-
- /* OnInstall */
- window.addEventListener('applicationinstall', function bsm_oninstall(evt) {
- var app = evt.detail.application;
- var origin = app.origin;
- if (!app.manifest.background_page)
- return;
-
- // XXX: this work as if background_page is always a path not a full URL.
- var url = origin + app.manifest.background_page;
- open(manifestURL, AUTO_OPEN_BG_PAGE_NAME, url);
- });
-
- /* OnUninstall */
- window.addEventListener('applicationuninstall', function bsm_oninstall(evt) {
- var app = evt.detail.application;
- close(app.manifestURL);
- });
-
- /* Check if the app has the permission to open a background page */
- var hasBackgroundPermission = function bsm_checkPermssion(app) {
- var mozPerms = navigator.mozPermissionSettings;
- if (!mozPerms)
- return false;
-
- var value = mozPerms.get('backgroundservice', app.manifestURL,
- app.origin, false);
-
- return (value === 'allow');
- };
-
- /* The open function is responsible of containing the iframe */
- var open = function bsm_open(manifestURL, name, url, frame) {
- var app = Applications.getByManifestURL(manifestURL);
- if (!app || !hasBackgroundPermission(app))
- return false;
-
- if (frames[manifestURL] && frames[manifestURL][name]) {
- console.error('Window with the same name is there but Gecko ' +
- ' failed to use it. See bug 766873. origin: "' + origin +
- '", name: "' + name + '".');
- return false;
- }
-
- if (!frame) {
- frame = document.createElement('iframe');
-
- // If we have a frame element, it's provided by mozbrowseropenwindow, and
- // it has the mozbrowser, mozapp, and src attributes set already.
- frame.setAttribute('mozbrowser', 'mozbrowser');
- frame.setAttribute('mozapp', manifestURL);
- frame.setAttribute('name', name);
-
- var appName = app.manifest.name;
- frame.setAttribute('remote', 'true');
- console.info('%%%%% Launching', appName, 'bg service as remote (OOP)');
- frame.src = url;
- }
- frame.className = 'backgroundWindow';
- frame.dataset.frameType = 'background';
- frame.dataset.frameName = name;
-
- if (!frames[manifestURL])
- frames[manifestURL] = {};
- frames[manifestURL][name] = frame;
-
- document.body.appendChild(frame);
-
- // Background services should load in the background.
- //
- // (The funky setTimeout(0) is to work around
- // https://bugzilla.mozilla.org/show_bug.cgi?id=810431 .)
- setTimeout(function() { frame.setVisible(false) }, 0);
-
- return true;
- };
-
- /* The close function will remove the iframe from DOM and
- delete the reference */
- var close = function bsm_close(manifestURL, name) {
- if (!frames[manifestURL])
- return false;
-
- if (typeof name == 'undefined') {
- // Close all windows
- Object.keys(frames[manifestURL]).forEach(function closeEach(name) {
- document.body.removeChild(frames[manifestURL][name]);
- frames[manifestURL][name] = null;
- });
- delete frames[manifestURL];
- return true;
- }
-
- // Close one window
- var frame = frames[manifestURL][name];
- if (!frame)
- return false;
-
- document.body.removeChild(frame);
- delete frames[manifestURL][name];
-
- if (!Object.keys(frames[manifestURL]).length)
- delete frames[manifestURL];
- return true;
- };
-
- /* start initialization */
- if (Applications.ready) {
- init();
- } else {
- window.addEventListener('applicationready',
- function bsm_appListReady(event) {
- window.removeEventListener('applicationready', bsm_appListReady);
- init();
- });
- }
-
- /* Return the public APIs */
- return {
- 'open': open,
- 'close': close
- };
-}());
-
diff --git a/apps/system/js/battery_manager.js b/apps/system/js/battery_manager.js
deleted file mode 100644
index d2eacf8..0000000
--- a/apps/system/js/battery_manager.js
+++ /dev/null
@@ -1,277 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var BatteryManager = {
- TOASTER_TIMEOUT: 5000,
- TRANSITION_SPEED: 1.8,
- TRANSITION_FRACTION: 0.30,
-
- AUTO_SHUTDOWN_LEVEL: 0.02,
- EMPTY_BATTERY_LEVEL: 0.1,
-
- _battery: window.navigator.battery,
- _notification: null,
-
- getAllElements: function bm_getAllElements() {
- this.screen = document.getElementById('screen');
- this.overlay = document.getElementById('system-overlay');
- this.notification = document.getElementById('battery');
- },
-
- checkBatteryDrainage: function bm_checkBatteryDrainage() {
- var battery = this._battery;
- if (!battery)
- return;
-
- if (battery.level <= this.AUTO_SHUTDOWN_LEVEL)
- SleepMenu.startPowerOff(false);
- },
-
- init: function bm_init() {
- this.getAllElements();
- var battery = this._battery;
- if (battery) {
- // When the device is booted, check if the battery is drained.
- // If so, SleepMenu.startPowerOff() would be called.
- this.checkBatteryDrainage();
-
- battery.addEventListener('levelchange', this);
- battery.addEventListener('chargingchange', this);
- }
- window.addEventListener('screenchange', this);
- this._toasterGD = new GestureDetector(this.notification);
- ['mousedown', 'swipe'].forEach(function(evt) {
- this.notification.addEventListener(evt, this);
- }, this);
-
- this._screenOn = true;
- this._wasEmptyBatteryNotificationDisplayed = false;
-
- this.displayIfNecessary();
- },
-
- handleEvent: function bm_handleEvent(evt) {
- switch (evt.type) {
- case 'screenchange':
- this._screenOn = evt.detail.screenEnabled;
- this.displayIfNecessary();
- break;
-
- case 'levelchange':
- var battery = this._battery;
- if (!battery)
- return;
-
- this.checkBatteryDrainage();
- this.displayIfNecessary();
-
- PowerSaveHandler.onBatteryChange();
- break;
- case 'chargingchange':
- PowerSaveHandler.onBatteryChange();
-
- var battery = this._battery;
- // We turn the screen on if needed in order to let
- // the user knows the device is charging
-
- if (battery && battery.charging) {
- this.hide();
- this._wasEmptyBatteryNotificationDisplayed = false;
-
- if (!this._screenOn) {
- ScreenManager.turnScreenOn();
- }
- } else {
- this.displayIfNecessary();
- }
- break;
-
- case 'mousedown':
- this.mousedown(evt);
- break;
- case 'swipe':
- this.swipe(evt);
- break;
- }
- },
-
- _shouldWeDisplay: function bm_shouldWeDisplay() {
- var battery = this._battery;
- if (!battery) {
- return false;
- }
-
- return (!this._wasEmptyBatteryNotificationDisplayed &&
- !battery.charging &&
- battery.level <= this.EMPTY_BATTERY_LEVEL &&
- this._screenOn);
- },
-
- displayIfNecessary: function bm_display() {
- if (! this._shouldWeDisplay()) {
- return;
- }
-
- // we know it's here, it's checked in shouldWeDisplay()
- var level = this._battery.level;
-
- this.overlay.classList.add('battery');
-
- this._toasterGD.startDetecting();
- this._wasEmptyBatteryNotificationDisplayed = true;
-
- if (this._toasterTimeout) {
- clearTimeout(this._toasterTimeout);
- }
-
- this._toasterTimeout = setTimeout(this.hide.bind(this),
- this.TOASTER_TIMEOUT);
- },
-
- hide: function bm_hide() {
- var overlayCss = this.overlay.classList;
- if (overlayCss.contains('battery')) {
- this.overlay.classList.remove('battery');
- this._toasterTimeout = null;
- this._toasterGD.stopDetecting();
- }
- },
-
- // Swipe handling
- mousedown: function bm_mousedown(evt) {
- evt.preventDefault();
- this._containerWidth = this.overlay.clientWidth;
- },
-
- swipe: function bm_swipe(evt) {
- var detail = evt.detail;
- var distance = detail.start.screenX - detail.end.screenX;
- var fastEnough = Math.abs(detail.vx) > this.TRANSITION_SPEED;
- var farEnough = Math.abs(distance) >
- this._containerWidth * this.TRANSITION_FRACTION;
-
- // If the swipe distance is too short or swipe speed is too slow,
- // do nothing.
- if (!(farEnough || fastEnough))
- return;
-
- var self = this;
- this.notification.addEventListener('animationend', function animationend() {
- self.notification.removeEventListener('animationend', animationend);
- self.notification.classList.remove('disappearing');
- self.hide();
- });
- this.notification.classList.add('disappearing');
- }
-};
-
-var PowerSaveHandler = (function PowerSaveHandler() {
-
- var _powerSaveResume = {};
- var _powerSaveEnabled = false;
- var _states = {
- 'wifi.enabled' : false,
- 'ril.data.enabled' : false,
- 'bluetooth.enabled' : false,
- 'geolocation.enabled' : false
- };
-
- function init() {
- SettingsListener.observe('powersave.enabled', false,
- function sl_getPowerSave(value) {
- var enabled = value;
- if (enabled) {
- enablePowerSave();
- } else {
- disablePowerSave();
- }
- _powerSaveEnabled = enabled;
- });
-
- // Monitor the states of various modules
- for (var j in _states) {
- SettingsListener.observe(j, true, function getState(state, value) {
- _states[state] = value;
- }.bind(null, j));
- }
- }
-
- // XXX Break down obj keys in a for each loop because mozSettings
- // does not currently supports multiple keys in one set()
- // https://bugzilla.mozilla.org/show_bug.cgi?id=779381
- function setMozSettings(keypairs) {
- var setlock = SettingsListener.getSettingsLock();
- for (var key in keypairs) {
- var obj = {};
- obj[key] = keypairs[key];
- setlock.set(obj);
- }
- }
-
- function enablePowerSave() {
- // Keep the original states of various modules
- for (var j in _states) {
- _powerSaveResume[j] = _states[j];
- }
-
- var settingsToSet = {
- // Turn off Wifi
- 'wifi.enabled' : false,
- // Turn off Data
- 'ril.data.enabled' : false,
- // Turn off Bluetooth
- 'bluetooth.enabled' : false,
- // Turn off Geolocation
- 'geolocation.enabled' : false
- };
-
- setMozSettings(settingsToSet);
- }
-
- function disablePowerSave() {
-
- var settingsToSet = {};
-
- for (var state in _powerSaveResume) {
- if (_powerSaveResume[state] == true)
- settingsToSet[state] = true;
- }
-
- setMozSettings(settingsToSet);
- }
-
- function onBatteryChange() {
- var battery = BatteryManager._battery;
-
- if (battery.charging) {
- if (_powerSaveEnabled)
- setMozSettings({'powersave.enabled' : false});
-
- return;
- }
-
- SettingsListener.observe('powersave.threshold', 0,
- function getThreshold(value) {
- if (battery.level <= value && !_powerSaveEnabled) {
- setMozSettings({'powersave.enabled' : true});
- return;
- }
-
- if (value != 0 && battery.level > value && _powerSaveEnabled) {
- setMozSettings({'powersave.enabled' : false});
- return;
- }
- });
- }
-
- return {
- init: init,
- onBatteryChange: onBatteryChange
- };
-})();
-
-// init PowerSaveHandler first, since it will be used by BatteryManager
-PowerSaveHandler.init();
-BatteryManager.init();
diff --git a/apps/system/js/bluetooth.js b/apps/system/js/bluetooth.js
deleted file mode 100644
index 3a77cc7..0000000
--- a/apps/system/js/bluetooth.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var Bluetooth = {
-
- /* this property store a reference of the default adapter */
- defaultAdapter: null,
-
- /* keep a global connected property here */
- connected: false,
-
- init: function bt_init() {
- if (!window.navigator.mozSettings)
- return;
-
- var bluetooth = window.navigator.mozBluetooth;
-
- SettingsListener.observe('bluetooth.enabled', true, function(value) {
- if (!bluetooth) {
- // roll back the setting value to notify the UIs
- // that Bluetooth interface is not available
- if (value) {
- SettingsListener.getSettingsLock().set({
- 'bluetooth.enabled': false
- });
- }
- return;
- }
- });
-
- var self = this;
- // when bluetooth adapter is ready, emit event to notify QuickSettings
- // and try to get defaultAdapter at this moment
- bluetooth.onadapteradded = function bt_onAdapterAdded() {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('bluetooth-adapter-added',
- /* canBubble */ true, /* cancelable */ false, null);
- window.dispatchEvent(evt);
- self.initDefaultAdapter();
- };
- // if bluetooth is enabled in booting time, try to get adapter now
- this.initDefaultAdapter();
-
- // when bluetooth is really disabled, emit event to notify QuickSettings
- bluetooth.ondisabled = function bt_onDisabled() {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('bluetooth-disabled',
- /* canBubble */ true, /* cancelable */ false, null);
- window.dispatchEvent(evt);
- };
-
- /* for v1, we only support two use cases for bluetooth connection:
- * 1. connecting with a headset
- * 2. transfering a file to/from another device
- * So we need to monitor their event messages to know we are (aren't)
- * connected, then summarize to an event and dispatch to StatusBar
- */
-
- // In headset connected case:
- navigator.mozSetMessageHandler('bluetooth-hfp-status-changed',
- this.updateConnected.bind(this)
- );
-
- /* In file transfering case:
- * since System Message can't be listened in two js files within a app,
- * so we listen here but dispatch events to bluetooth_transfer.js
- * when getting bluetooth file transfer start/complete system messages
- */
- var self = this;
- navigator.mozSetMessageHandler('bluetooth-opp-transfer-start',
- function bt_fileTransferUpdate(transferInfo) {
- self.updateConnected();
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('bluetooth-opp-transfer-start',
- /* canBubble */ true, /* cancelable */ false,
- {transferInfo: transferInfo});
- window.dispatchEvent(evt);
- }
- );
-
- navigator.mozSetMessageHandler('bluetooth-opp-transfer-complete',
- function bt_fileTransferUpdate(transferInfo) {
- self.updateConnected();
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('bluetooth-opp-transfer-complete',
- /* canBubble */ true, /* cancelable */ false,
- {transferInfo: transferInfo});
- window.dispatchEvent(evt);
- }
- );
-
- },
-
- // Get adapter for BluetoothTransfer when everytime bluetooth is enabled
- initDefaultAdapter: function bt_initDefaultAdapter() {
- var bluetooth = window.navigator.mozBluetooth;
- var self = this;
-
- if (!bluetooth || !bluetooth.enabled ||
- !('getDefaultAdapter' in bluetooth))
- return;
-
- var req = bluetooth.getDefaultAdapter();
- req.onsuccess = function bt_gotDefaultAdapter(evt) {
- self.defaultAdapter = req.result;
- };
- },
-
- updateConnected: function bt_updateConnected() {
- var bluetooth = window.navigator.mozBluetooth;
-
- if (!bluetooth || !('isConnected' in bluetooth))
- return;
-
- var wasConnected = this.connected;
- this.connected =
- bluetooth.isConnected(0x111E) || bluetooth.isConnected(0x1105);
-
- if (wasConnected !== this.connected) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('bluetoothconnectionchange',
- /* canBubble */ true, /* cancelable */ false,
- {deviceConnected: this.connected});
- window.dispatchEvent(evt);
- }
- },
-
- // This function is called by external (BluetoothTransfer) for re-use adapter
- getAdapter: function bt_getAdapter() {
- return this.defaultAdapter;
- }
-};
-
-Bluetooth.init();
diff --git a/apps/system/js/bluetooth_transfer.js b/apps/system/js/bluetooth_transfer.js
deleted file mode 100644
index 47483f7..0000000
--- a/apps/system/js/bluetooth_transfer.js
+++ /dev/null
@@ -1,511 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-'use strict';
-
-var BluetoothTransfer = {
- bannerContainer: null,
- pairList: {
- index: []
- },
- _deviceStorage: navigator.getDeviceStorage('sdcard'),
- _debug: false,
-
- get transferStatusList() {
- delete this.transferStatusList;
- return this.transferStatusList =
- document.getElementById('bluetooth-transfer-status-list');
- },
-
- get banner() {
- delete this.banner;
- return this.banner = document.getElementById('system-banner');
- },
-
- init: function bt_init() {
- // Bind message handler for transferring file callback
- navigator.mozSetMessageHandler('bluetooth-opp-receiving-file-confirmation',
- this.onReceivingFileConfirmation.bind(this)
- );
-
- // Listen to 'bluetooth-opp-transfer-start' from bluetooth.js
- window.addEventListener('bluetooth-opp-transfer-start',
- this.onUpdateProgress.bind(this, 'start')
- );
-
- navigator.mozSetMessageHandler('bluetooth-opp-update-progress',
- this.onUpdateProgress.bind(this, 'progress')
- );
-
- // Listen to 'bluetooth-opp-transfer-complete' from bluetooth.js
- window.addEventListener('bluetooth-opp-transfer-complete',
- this.onTransferComplete.bind(this)
- );
- this.bannerContainer = this.banner.firstElementChild;
- },
-
- getDeviceName: function bt_getDeviceName(address) {
- var _ = navigator.mozL10n.get;
- var length = this.pairList.index.length;
- for (var i = 0; i < length; i++) {
- if (this.pairList.index[i].address == address)
- return this.pairList.index[i].name;
- }
- return _('unknown-device');
- },
-
- getPairedDevice: function bt_getPairedDevice(callback) {
- var adapter = Bluetooth.getAdapter();
- if (adapter == null) {
- var msg = 'Cannot get Bluetooth adapter.';
- this.debug(msg);
- return;
- }
- var self = this;
- var req = adapter.getPairedDevices();
- req.onsuccess = function bt_getPairedSuccess() {
- self.pairList.index = req.result;
- var length = self.pairList.index.length;
- if (length == 0) {
- var msg =
- 'There is no paired device! Please pair your bluetooth device first.';
- self.debug(msg);
- return;
- }
- if (callback) {
- callback();
- }
- };
- req.onerror = function() {
- var msg = 'Can not get paired devices from adapter.';
- self.debug(msg);
- };
- },
-
- debug: function bt_debug(msg) {
- if (!this._debug)
- return;
-
- console.log('[System Bluetooth Transfer]: ' + msg);
- },
-
- humanizeSize: function bt_humanizeSize(bytes) {
- var _ = navigator.mozL10n.get;
- var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
- var size, e;
- if (bytes) {
- e = Math.floor(Math.log(bytes) / Math.log(1024));
- size = (bytes / Math.pow(1024, e)).toFixed(2);
- } else {
- e = 0;
- size = '0.00';
- }
- return _('fileSize', {
- size: size,
- unit: _('byteUnit-' + units[e])
- });
- },
-
- onReceivingFileConfirmation: function bt_onReceivingFileConfirmation(evt) {
- // Prompt appears when a transfer request from a paired device is received.
- var _ = navigator.mozL10n.get;
-
- var fileSize = evt.fileLength;
- var self = this;
- var icon = 'style/bluetooth_transfer/images/icon_bluetooth.png';
-
- // Check storage is available or not before the prompt.
- this.checkStorageSpace(fileSize,
- function checkStorageSpaceComplete(isStorageAvailable, errorMessage) {
- if (isStorageAvailable) {
- NotificationHelper.send(_('notification-fileTransfer-title'),
- _('notification-fileTransfer-description'),
- icon,
- function() {
- UtilityTray.hide();
- self.showReceivePrompt(evt);
- });
- } else {
- self.showStorageUnavaliablePrompt(errorMessage);
- }
- });
- },
-
- showReceivePrompt: function bt_showReceivePrompt(evt) {
- var _ = navigator.mozL10n.get;
-
- var address = evt.address;
- var fileName = evt.fileName;
- var fileSize = this.humanizeSize(evt.fileLength);
- var cancel = {
- title: _('deny'),
- callback: this.declineReceive.bind(this, address)
- };
-
- var confirm = {
- title: _('transfer'),
- callback: this.acceptReceive.bind(this, address)
- };
-
- var deviceName = '';
- var self = this;
- this.getPairedDevice(function getPairedDeviceComplete() {
- deviceName = self.getDeviceName(address);
- CustomDialog.show(_('acceptFileTransfer'),
- _('wantToReceiveFile',
- { deviceName: deviceName,
- fileName: fileName,
- fileSize: fileSize }),
- cancel, confirm);
- });
- },
-
- declineReceive: function bt_declineReceive(address) {
- CustomDialog.hide();
- var adapter = Bluetooth.getAdapter();
- if (adapter != null) {
- adapter.confirmReceivingFile(address, false);
- } else {
- var msg = 'Cannot get adapter from system Bluetooth monitor.';
- this.debug(msg);
- }
- },
-
- acceptReceive: function bt_acceptReceive(address, fileSize) {
- CustomDialog.hide();
- var adapter = Bluetooth.getAdapter();
- if (adapter != null) {
- adapter.confirmReceivingFile(address, true);
- } else {
- var msg = 'Cannot get adapter from system Bluetooth monitor.';
- this.debug(msg);
- }
- },
-
- showStorageUnavaliablePrompt: function bt_showStorageUnavaliablePrompt(msg) {
- var _ = navigator.mozL10n.get;
- var confirm = {
- title: _('confirm'),
- callback: function() {
- CustomDialog.hide();
- }
- };
-
- var body = msg;
- CustomDialog.show(_('cannotReceiveFile'), body, confirm);
- },
-
- checkStorageSpace: function bt_checkStorageSpace(fileSize, callback) {
- if (!callback)
- return;
-
- var _ = navigator.mozL10n.get;
- var storage = this._deviceStorage;
-
- var availreq = storage.available();
- availreq.onsuccess = function(e) {
- switch (availreq.result) {
- case 'available':
- // skip down to the code below
- break;
- case 'unavailable':
- callback(false, _('sdcard-not-exist'));
- return;
- case 'shared':
- callback(false, _('sdcard-in-use'));
- return;
- default:
- callback(false, _('unknown-error'));
- return;
- }
-
- // If we get here, then the sdcard is available, so we need to find out
- // if there is enough free space on it
- var freereq = storage.freeSpace();
- freereq.onsuccess = function() {
- if (freereq.result >= fileSize)
- callback(true, '');
- else
- callback(false, _('sdcard-no-space2'));
- };
- freereq.onerror = function() {
- callback(false, _('cannotGetStorageState'));
- };
- };
-
- availreq.onerror = function(e) {
- callback(false, _('cannotGetStorageState'));
- };
- },
-
- onUpdateProgress: function bt_onUpdateProgress(mode, evt) {
- switch (mode) {
- case 'start':
- var transferInfo = evt.detail.transferInfo;
- this.initProgress(transferInfo);
- break;
-
- case 'progress':
- var address = evt.address;
- var processedLength = evt.processedLength;
- var fileLength = evt.fileLength;
- var progress = 0;
- if (fileLength == 0) {
- //XXX: May need to handle unknow progress
- } else if (processedLength > fileLength) {
- // According Bluetooth spec.,
- // the processed length is a referenced value only.
- // XXX: If processed length is bigger than file length,
- // show an unknown progress
- } else {
- progress = processedLength / fileLength;
- }
- this.updateProgress(progress, evt);
- break;
- }
- },
-
- initProgress: function bt_initProgress(evt) {
- var _ = navigator.mozL10n.get;
- // Create progress dynamically in notification center
- var address = evt.address;
- var transferMode =
- (evt.received == true) ?
- _('bluetooth-receiving-progress') : _('bluetooth-sending-progress');
- var content =
- '<img src="style/bluetooth_transfer/images/transfer.png" />' +
- '<div class="bluetooth-transfer-progress">' + transferMode + '</div>' +
- // XXX: Bug 804533 - [Bluetooth]
- // Need sending/receiving icon for Bluetooth file transfer
- '<progress value="0" max="1"></progress>';
-
- var transferTask = document.createElement('div');
- transferTask.id = 'bluetooth-transfer-status';
- transferTask.className = 'notification';
- transferTask.setAttribute('data-id', address);
- transferTask.innerHTML = content;
- transferTask.addEventListener('click',
- this.onCancelTransferTask.bind(this));
- this.transferStatusList.appendChild(transferTask);
- },
-
- updateProgress: function bt_updateProgress(value, evt) {
- var address = evt.address;
- var id = 'div[data-id="' + address + '"] progress';
- var progressEl = this.transferStatusList.querySelector(id);
- progressEl.value = value;
- },
-
- removeProgress: function bt_removeProgress(evt) {
- var address = evt.address;
- var id = 'div[data-id="' + address + '"]';
- var finishedTask = this.transferStatusList.querySelector(id);
- finishedTask.removeEventListener('click',
- this.onCancelTransferTask.bind(this));
- this.transferStatusList.removeChild(finishedTask);
- },
-
- showBanner: function bt_showBanner(isComplete) {
- var _ = navigator.mozL10n.get;
- var status = (isComplete) ? 'complete' : 'failed';
- this.banner.addEventListener('animationend', function animationend() {
- this.banner.removeEventListener('animationend', animationend);
- this.banner.classList.remove('visible');
- }.bind(this));
- this.bannerContainer.textContent = _('bluetooth-file-transfer-result',
- { status: status });
- this.banner.classList.add('visible');
- },
-
- onCancelTransferTask: function bt_onCancelTransferTask(evt) {
- var id = evt.target.dataset.id;
- // Show confirm dialog for user to cancel transferring task
- UtilityTray.hide();
- this.showCancelTransferPrompt(id);
- },
-
- showCancelTransferPrompt: function bt_showCancelTransferPrompt(address) {
- var _ = navigator.mozL10n.get;
-
- var cancel = {
- title: _('continue'),
- callback: this.continueTransfer.bind(this)
- };
-
- var confirm = {
- title: _('cancel'),
- callback: this.cancelTransfer.bind(this, address)
- };
-
- CustomDialog.show(_('cancelFileTransfer'), _('cancelFileTransfer'),
- cancel, confirm);
- },
-
- continueTransfer: function bt_continueTransfer() {
- CustomDialog.hide();
- },
-
- cancelTransfer: function bt_cancelTransfer(address) {
- CustomDialog.hide();
- var adapter = Bluetooth.getAdapter();
- if (adapter != null) {
- adapter.stopSendingFile(address);
- } else {
- var msg = 'Cannot get adapter from system Bluetooth monitor.';
- this.debug(msg);
- }
- },
-
- onTransferComplete: function bt_onTransferComplete(evt) {
- var transferInfo = evt.detail.transferInfo;
- var _ = navigator.mozL10n.get;
- // Remove transferring progress
- this.removeProgress(transferInfo);
- var fileName =
- (transferInfo.fileName) ? transferInfo.fileName : _('unknown-file');
- var icon = 'style/bluetooth_transfer/images/icon_bluetooth.png';
- // Show banner and notification
- if (transferInfo.success == true) {
- // Show completed message of transferred result on the banner
- this.showBanner(true);
- if (transferInfo.received) {
- // Received file can be opened only
- // TODO: Need to modify the icon after visual provide
- NotificationHelper.send(_('transferFinished-receivedSuccessful-title'),
- fileName,
- icon,
- this.openReceivedFile.bind(this, transferInfo));
- } else {
- NotificationHelper.send(_('transferFinished-sentSuccessful-title'),
- fileName,
- icon);
- }
- } else {
- // Show failed message of transferred result on the banner
- this.showBanner(false);
- if (transferInfo.received) {
- NotificationHelper.send(_('transferFinished-receivedFailed-title'),
- fileName,
- icon);
- } else {
- NotificationHelper.send(_('transferFinished-sentFailed-title'),
- fileName,
- icon);
- }
- }
- },
-
- openReceivedFile: function bt_openReceivedFile(evt) {
- // Launch the gallery with an open activity to view this specific photo
- // XXX: The prefix file path should be refined when API is ready to provide
- var filePath = 'downloads/bluetooth/' + evt.fileName;
- var contentType = evt.contentType;
- var storageType = 'sdcard';
- var self = this;
- var storage = navigator.getDeviceStorage(storageType);
- var getreq = storage.get(filePath);
-
- getreq.onerror = function() {
- var msg = 'failed to get file:' +
- filePath + getreq.error.name +
- a.error.name;
- self.debug(msg);
- };
-
- getreq.onsuccess = function() {
- var file = getreq.result;
- // When we got the file by storage type of "sdcard"
- // use the file.type to replace the empty fileType which is given by API
- var fileType = '';
- var fileName = file.name;
- if (contentType != '' && contentType != 'image/*') {
- fileType = contentType;
- } else {
- var fileNameExtension =
- fileName.substring(fileName.lastIndexOf('.') + 1);
- if (file.type != '') {
- fileType = file.type;
- // Refine the file type to "audio/ogg" when the file format is *.ogg
- if (fileType == 'video/ogg' &&
- (fileNameExtension.indexOf('ogg') != -1)) {
- fileType == 'audio/ogg';
- }
- } else {
- // Parse Filename Extension to find out MIMETYPE
- // Following formats are supported by Gallery and Music APPs
- var imageFormatList = ['jpg', 'jpeg', 'png'];
- var audioFormatList = ['mp3', 'ogg', 'aac', 'mp4', 'm4a'];
- var imageFormatIndex = imageFormatList.indexOf(fileNameExtension);
- switch (imageFormatIndex) {
- case 0:
- case 1:
- // The file type of format *.jpg, *.jpeg should be "image/jpeg"
- fileType = 'image/jpeg';
- break;
- case 2:
- // The file type of format *.png should be "image/png"
- fileType = 'image/png';
- break;
- }
-
- var audioFormatIndex = audioFormatList.indexOf(fileNameExtension);
- switch (audioFormatIndex) {
- case 0:
- // The file type of format *.mp3 should be "audio/mpeg"
- fileType = 'audio/mpeg';
- break;
- case 1:
- // The file type of format *.ogg should be "audio/ogg"
- fileType = 'audio/ogg';
- break;
- case 2:
- case 3:
- case 4:
- // The file type of format *.acc, *.mp4, *.m4a
- // should be "audio/mp4"
- fileType = 'audio/mp4';
- break;
- }
- }
- }
-
- var a = new MozActivity({
- name: 'open',
- data: {
- type: fileType,
- blob: file,
- // XXX: https://bugzilla.mozilla.org/show_bug.cgi?id=812098
- // Pass the file name for Music APP since it can not open blob
- filename: file.name
- }
- });
-
- a.onerror = function(e) {
- var msg = 'open activity error:' + a.error.name;
- self.debug(msg);
- // Cannot identify MIMETYPE
- // So, show cannot open file dialog with unknow media type
- UtilityTray.hide();
- self.showUnknownMediaPrompt(fileName);
- };
- a.onsuccess = function(e) {
- var msg = 'open activity onsuccess';
- self.debug(msg);
- };
- };
- },
-
- showUnknownMediaPrompt: function bt_showUnknownMediaPrompt(fileName) {
- var _ = navigator.mozL10n.get;
- var confirm = {
- title: _('confirm'),
- callback: function() {
- CustomDialog.hide();
- }
- };
-
- var body = _('unknownMediaTypeToOpen') + ' ' + fileName;
- CustomDialog.show(_('cannotOpenFile'), body, confirm);
- }
-};
-
-BluetoothTransfer.init();
diff --git a/apps/system/js/bootstrap.js b/apps/system/js/bootstrap.js
deleted file mode 100644
index 21e2238..0000000
--- a/apps/system/js/bootstrap.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-window.addEventListener('load', function startup() {
- function safelyLaunchFTU() {
- WindowManager.retrieveHomescreen(WindowManager.retrieveFTU);
- }
-
- if (Applications.ready) {
- safelyLaunchFTU();
- } else {
- window.addEventListener('applicationready', function appListReady(event) {
- window.removeEventListener('applicationready', appListReady);
- safelyLaunchFTU();
- });
- }
-
- window.addEventListener('ftudone', function doneWithFTU() {
- window.removeEventListener('ftudone', doneWithFTU);
-
- var lock = window.navigator.mozSettings.createLock();
- lock.set({
- 'gaia.system.checkForUpdates': true
- });
- });
-
- SourceView.init();
- Shortcuts.init();
- ScreenManager.turnScreenOn();
-
- // We need to be sure to get the focus in order to wake up the screen
- // if the phone goes to sleep before any user interaction.
- // Apparently it works because no other window has the focus at this point.
- window.focus();
-
- // This is code copied from
- // http://dl.dropbox.com/u/8727858/physical-events/index.html
- // It appears to workaround the Nexus S bug where we're not
- // getting orientation data. See:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=753245
- // It seems it needs to be in both window_manager.js and bootstrap.js.
- function dumbListener2(event) {}
- window.addEventListener('devicemotion', dumbListener2);
-
- window.setTimeout(function() {
- window.removeEventListener('devicemotion', dumbListener2);
- }, 2000);
-});
-
-/* === Shortcuts === */
-/* For hardware key handling that doesn't belong to anywhere */
-var Shortcuts = {
- init: function rm_init() {
- window.addEventListener('keyup', this);
- },
-
- handleEvent: function rm_handleEvent(evt) {
- if (!ScreenManager.screenEnabled || evt.keyCode !== evt.DOM_VK_F6)
- return;
-
- document.location.reload();
- }
-};
-
-/* === Localization === */
-/* set the 'lang' and 'dir' attributes to <html> when the page is translated */
-window.addEventListener('localized', function onlocalized() {
- document.documentElement.lang = navigator.mozL10n.language.code;
- document.documentElement.dir = navigator.mozL10n.language.direction;
-});
-
-// Define the default background to use for all homescreens
-SettingsListener.observe(
- 'wallpaper.image',
- 'resources/images/backgrounds/default.png',
- function setWallpaper(value) {
- document.getElementById('screen').style.backgroundImage =
- 'url(' + value + ')';
- }
-);
diff --git a/apps/system/js/call_forwarding.js b/apps/system/js/call_forwarding.js
deleted file mode 100644
index ee46def..0000000
--- a/apps/system/js/call_forwarding.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-(function() {
-
- // Must be in sync with nsIDOMMozMobileCFInfo interface.
- var _cfReason = {
- CALL_FORWARD_REASON_UNCONDITIONAL: 0,
- CALL_FORWARD_REASON_MOBILE_BUSY: 1,
- CALL_FORWARD_REASON_NO_REPLY: 2,
- CALL_FORWARD_REASON_NOT_REACHABLE: 3
- };
- var _cfAction = {
- CALL_FORWARD_ACTION_DISABLE: 0,
- CALL_FORWARD_ACTION_ENABLE: 1,
- CALL_FORWARD_ACTION_QUERY_STATUS: 2,
- CALL_FORWARD_ACTION_REGISTRATION: 3,
- CALL_FORWARD_ACTION_ERASURE: 4
- };
-
- var settings = window.navigator.mozSettings;
- if (!settings) {
- return;
- }
- var mobileconnection = window.navigator.mozMobileConnection;
- if (!mobileconnection) {
- return;
- }
-
- mobileconnection.addEventListener('cfstatechange', function(event) {
- if (event &&
- event.reason == _cfReason.CALL_FORWARD_REASON_UNCONDITIONAL) {
- var enabled = false;
- if (event.success &&
- (event.action == _cfAction.CALL_FORWARD_ACTION_REGISTRATION ||
- event.action == _cfAction.CALL_FORWARD_ACTION_ENABLE)) {
- enabled = true;
- }
- settings.createLock().set({'ril.cf.enabled': enabled});
- }
- });
-
-})();
diff --git a/apps/system/js/captive_portal.js b/apps/system/js/captive_portal.js
deleted file mode 100644
index b23cb0d..0000000
--- a/apps/system/js/captive_portal.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*Mode: js; js-indent-level: 2; indent-tabs-mode: nil -**/
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-'use strict';
-
-var CaptivePortalLogin = (function() {
- var eventId;
- var isManualConnect = false;
- var settings = window.navigator.mozSettings;
- var notification = null;
- var wifiManager = window.navigator.mozWifiManager;
- var _ = window.navigator.mozL10n.get;
- var captiveNotification_onTap = null;
-
- function handleLogin(id, url) {
- //captive portal login needed
- eventId = id;
- var currentNetwork = wifiManager.connection.network;
- var networkName = (currentNetwork && currentNetwork.ssid) ?
- currentNetwork.ssid : '';
- var message = _('captive-wifi-available', { networkName: networkName});
- if (!isManualConnect) {
- notification = NotificationScreen.addNotification({
- id: id, title: '', text: message, icon: null
- });
- captiveNotification_onTap = function() {
- notification.removeEventListener('tap', captiveNotification_onTap);
- captiveNotification_onTap = null;
- NotificationScreen.removeNotification(id);
- new MozActivity({
- name: 'view',
- data: { type: 'url', url: url }
- });
- };
- notification.addEventListener('tap', captiveNotification_onTap);
- } else {
- settings.createLock().set({'wifi.connect_via_settings': false});
- new MozActivity({
- name: 'view',
- data: { type: 'url', url: url }
- });
- }
- }
-
- function handleLoginAbort(id) {
- if (id === eventId && notification) {
- if (notification.parentNode) {
- if (captiveNotification_onTap) {
- notification.removeEventListener('tap', captiveNotification_onTap);
- captiveNotification_onTap = null;
- }
- NotificationScreen.removeNotification(id);
- notification = null;
- }
- }
- }
-
- window.addEventListener('mozChromeEvent', function handleChromeEvent(e) {
- switch (e.detail.type) {
- case 'captive-portal-login':
- handleLogin(e.detail.id, e.detail.url);
- break;
- case 'captive-portal-login-abort':
- handleLoginAbort(e.detail.id);
- break;
- }
- });
-
- // Using settings API to know whether user is manually selecting
- // wifi AP from settings app.
- SettingsListener.observe('wifi.connect_via_settings', true, function(value) {
- isManualConnect = value;
- });
-})();
diff --git a/apps/system/js/cards_view.js b/apps/system/js/cards_view.js
deleted file mode 100644
index 8bce02b..0000000
--- a/apps/system/js/cards_view.js
+++ /dev/null
@@ -1,676 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-//
-// CardsView is responsible for managing opened apps
-//
-
-'use strict';
-
-var CardsView = (function() {
-
- //display icon of an app on top of app's card
- var DISPLAY_APP_ICON = false;
- var USER_DEFINED_ORDERING = false;
- // If 'true', scrolling moves the list one card
- // at time, and snaps the list so the current card
- // is centered in the view
- // If 'false', use free, physics-based scrolling
- // (Gaia default)
- var SNAPPING_SCROLLING = true;
- // if 'true' user can close the app
- // by dragging it upwards
- var MANUAL_CLOSING = true;
-
- var cardsView = document.getElementById('cards-view');
- var screenElement = document.getElementById('screen');
- var cardsList = cardsView.firstElementChild;
- var displayedApp;
- var runningApps;
- // Unkillable apps which have attention screen now
- var attentionScreenApps = [];
- // Card which we are re-ordering now
- var reorderedCard = null;
- var currentDisplayed = 0;
- // Timer between scrolling CardList further,
- // when reordering Cards
- var scrollWhileSortingTimer;
- // We don't allow user to scroll CardList
- // before the timer ticks while in reordering
- // mode
- var allowScrollingWhileSorting = false;
- // Initial margin of the reordered card
- var dragMargin = 0;
- // Are we reordering or removing the card now?
- var draggingCardUp = false;
- // Are we moving card left or right?
- var sortingDirection;
- // List of sorted apps
- var userSortedApps = [];
- var HVGA = document.documentElement.clientWidth < 480;
- var cardsViewShown = false;
-
- // init events
- var gd = new GestureDetector(cardsView);
- gd.startDetecting();
-
- // A list of all the URLs we've created via URL.createObjectURL which we
- // haven't yet revoked.
- var screenshotObjectURLs = [];
-
- /*
- * Returns an icon URI
- *
- * @param{String} the app's origin
- */
- function getIconURI(origin) {
- var icons = runningApps[origin].manifest.icons;
- if (!icons) {
- return null;
- }
-
- var sizes = Object.keys(icons).map(function parse(str) {
- return parseInt(str, 10);
- });
-
- sizes.sort(function(x, y) { return y - x; });
-
- var index = sizes[(HVGA) ? sizes.length - 1 : 0];
- var iconPath = icons[index];
-
- if (iconPath.indexOf('data:') !== 0) {
- iconPath = origin + iconPath;
- }
-
- return iconPath;
- }
-
- // Build and display the card switcher overlay
- // Note that we rebuild the switcher each time we need it rather
- // than trying to keep it in sync with app launches. Performance is
- // not an issue here given that the user has to hold the HOME button down
- // for one second before the switcher will appear.
- function showCardSwitcher() {
- if (cardSwitcherIsShown())
- return;
-
- // events to handle
- window.addEventListener('lock', CardsView);
-
- // Close utility tray if it is opened.
- UtilityTray.hide(true);
-
- // Apps info from WindowManager
- displayedApp = WindowManager.getDisplayedApp();
- currentDisplayed = 0;
- runningApps = WindowManager.getRunningApps();
-
- // Switch to homescreen
- WindowManager.launch(null);
- cardsViewShown = true;
-
- // If user is not able to sort apps manualy,
- // display most recetly active apps on the far left
- if (!USER_DEFINED_ORDERING) {
- var sortable = [];
- for (var origin in runningApps)
- sortable.push({origin: origin, app: runningApps[origin]});
-
- sortable.sort(function(a, b) {
- return b.app.launchTime - a.app.launchTime;
- });
- runningApps = {};
-
- // I assume that object properties are enumerated in
- // the same order they were defined.
- // There is nothing about that in spec, but I've never
- // seen any unexpected behavior.
- sortable.forEach(function(element) {
- runningApps[element.origin] = element.app;
- });
-
- // First add an item to the cardsList for each running app
- for (var origin in runningApps) {
- addCard(origin, runningApps[origin], function showCards() {
- screenElement.classList.add('cards-view');
- cardsView.classList.add('active');
- });
- }
-
- } else { // user ordering
-
- // first run
- if (userSortedApps.length === 0) {
- for (var origin in runningApps) {
- userSortedApps.push(origin);
- }
- } else {
- for (var origin in runningApps) {
- // if we have some new app opened
- if (userSortedApps.indexOf(origin) === -1) {
- userSortedApps.push(origin);
- }
- }
- }
-
- userSortedApps.forEach(function(origin) {
- addCard(origin, runningApps[origin], function showCards() {
- screenElement.classList.add('cards-view');
- cardsView.classList.add('active');
- });
- });
-
- cardsView.addEventListener('contextmenu', CardsView);
-
- }
-
- if (SNAPPING_SCROLLING) {
- cardsView.style.overflow = 'hidden'; //disabling native scrolling
- }
-
- if (SNAPPING_SCROLLING || MANUAL_CLOSING) {
- cardsView.addEventListener('mousedown', CardsView);
- }
-
- // Make sure we're in portrait mode
- screen.mozLockOrientation('portrait-primary');
-
- // If there is a displayed app, take keyboard focus away
- if (displayedApp)
- runningApps[displayedApp].frame.blur();
-
- function addCard(origin, app, displayedAppCallback) {
- // Display card switcher background first to make user focus on the
- // frame closing animation without disturbing by homescreen display.
- if (displayedApp == origin && displayedAppCallback) {
- setTimeout(displayedAppCallback);
- }
- // Not showing homescreen
- if (app.frame.classList.contains('homescreen')) {
- return;
- }
-
- // Build a card representation of each window.
- // And add it to the card switcher
- var card = document.createElement('li');
- card.classList.add('card');
- card.dataset.origin = origin;
-
- //display app icon on the tab
- if (DISPLAY_APP_ICON) {
- var iconURI = getIconURI(origin);
- if (iconURI) {
- var appIcon = document.createElement('img');
- appIcon.classList.add('appIcon');
- appIcon.src = iconURI;
- card.appendChild(appIcon);
- }
- }
-
- var title = document.createElement('h1');
- title.textContent = app.name;
- card.appendChild(title);
-
- var frameForScreenshot = app.iframe;
-
- if (PopupManager.getPopupFromOrigin(origin)) {
- var popupFrame = PopupManager.getPopupFromOrigin(origin);
- frameForScreenshot = popupFrame;
-
- var subtitle = document.createElement('p');
- subtitle.textContent =
- PopupManager.getOpenedOriginFromOpener(origin);
- card.appendChild(subtitle);
- card.classList.add('popup');
- } else if (getOffOrigin(app.frame.dataset.url ?
- app.frame.dataset.url : app.frame.src, origin)) {
- var subtitle = document.createElement('p');
- subtitle.textContent = getOffOrigin(app.frame.dataset.url ?
- app.frame.dataset.url : app.frame.src, origin);
- card.appendChild(subtitle);
- }
-
- if (TrustedUIManager.hasTrustedUI(origin)) {
- var popupFrame = TrustedUIManager.getDialogFromOrigin(origin);
- frameForScreenshot = popupFrame.frame;
- var header = document.createElement('section');
- header.setAttribute('role', 'region');
- header.classList.add('skin-organic');
- header.innerHTML = '<header><button><span class="icon icon-close">';
- header.innerHTML += '</span></button><h1>' + popupFrame.name;
- header.innerHTML += '</h1></header>';
- card.appendChild(header);
- card.classList.add('trustedui');
- } else if (attentionScreenApps.indexOf(origin) == -1) {
- var closeButton = document.createElement('div');
- closeButton.classList.add('close-card');
- card.appendChild(closeButton);
- }
-
- cardsList.appendChild(card);
- // rect is the final size (considering CSS transform) of the card.
- var rect = card.getBoundingClientRect();
-
- // And then switch it with screenshots when one will be ready
- // (instead of -moz-element backgrounds)
- frameForScreenshot.getScreenshot(rect.width, rect.height).onsuccess =
- function gotScreenshot(screenshot) {
- if (screenshot.target.result) {
- var objectURL = URL.createObjectURL(screenshot.target.result);
- screenshotObjectURLs.push(objectURL);
- card.style.backgroundImage = 'url(' + objectURL + ')';
- }
- };
-
- // Set up event handling
- // A click elsewhere in the card switches to that task
- card.addEventListener('tap', runApp);
- }
- }
-
- function runApp(e) {
- // Handle close events
- if (e.target.classList.contains('close-card')) {
- var element = e.target.parentNode;
- cardsList.removeChild(element);
- closeApp(element, true);
- return;
- }
-
- var origin = this.dataset.origin;
- alignCard(currentDisplayed, function cardAligned() {
- WindowManager.launch(origin);
- });
- }
-
- function closeApp(element, removeImmediately) {
- // Stop the app itself
- WindowManager.kill(element.dataset.origin);
-
- // Fix for non selectable cards when we remove the last card
- // Described in https://bugzilla.mozilla.org/show_bug.cgi?id=825293
- if (cardsList.children.length === currentDisplayed) {
- currentDisplayed--;
- }
-
- // If there are no cards left, then dismiss the task switcher.
- if (!cardsList.children.length)
- hideCardSwitcher(removeImmediately);
- }
-
- function getOriginObject(url) {
- var parser = document.createElement('a');
- parser.href = url;
-
- return {
- protocol: parser.protocol,
- hostname: parser.hostname,
- port: parser.port
- };
- }
-
- function getOffOrigin(src, origin) {
- // Use src and origin as cache key
- var cacheKey = JSON.stringify(Array.prototype.slice.call(arguments));
- if (!getOffOrigin.cache[cacheKey]) {
- var native = getOriginObject(origin);
- var current = getOriginObject(src);
- if (current.protocol == 'http:') {
- // Display http:// protocol anyway
- getOffOrigin.cache[cacheKey] = current.protocol + '//' +
- current.hostname;
- } else if (native.protocol == current.protocol &&
- native.hostname == current.hostname &&
- native.port == current.port) {
- // Same origin policy
- getOffOrigin.cache[cacheKey] = '';
- } else if (current.protocol == 'app:') {
- // Avoid displaying app:// protocol
- getOffOrigin.cache[cacheKey] = '';
- } else {
- getOffOrigin.cache[cacheKey] = current.protocol + '//' +
- current.hostname;
- }
- }
-
- return getOffOrigin.cache[cacheKey];
- }
-
- getOffOrigin.cache = {};
-
- function hideCardSwitcher(removeImmediately) {
- if (!cardSwitcherIsShown())
- return;
-
- // events to handle
- window.removeEventListener('lock', CardsView);
-
- // Make the cardsView overlay inactive
- cardsView.classList.remove('active');
- cardsViewShown = false;
-
- // Release our screenshot blobs.
- screenshotObjectURLs.forEach(function(url) {
- URL.revokeObjectURL(url);
- });
- screenshotObjectURLs = [];
-
- // And remove all the cards from the document after the transition
- function removeCards() {
- cardsView.removeEventListener('transitionend', removeCards);
- screenElement.classList.remove('cards-view');
-
- while (cardsList.firstElementChild) {
- cardsList.removeChild(cardsList.firstElementChild);
- }
- }
- if (removeImmediately) {
- removeCards();
- } else {
- cardsView.addEventListener('transitionend', removeCards);
- }
- }
-
- function cardSwitcherIsShown() {
- return cardsViewShown;
- }
-
- //scrolling cards
- var initialCardViewPosition;
- var initialTouchPosition = {};
- var threshold = window.innerWidth / 4;
- // Distance after which dragged card starts moving
- var moveCardThreshold = window.innerHeight / 6;
- var removeCardThreshold = window.innerHeight / 4;
-
- function alignCard(number, callback) {
- if (!cardsList.children[number])
- return;
-
- var scrollLeft = cardsView.scrollLeft;
- var targetScrollLeft = cardsList.children[number].offsetLeft;
-
- if (Math.abs(scrollLeft - targetScrollLeft) < 4) {
- cardsView.scrollLeft = cardsList.children[number].offsetLeft;
- if (callback)
- callback();
- return;
- }
-
- cardsView.scrollLeft = scrollLeft + (targetScrollLeft - scrollLeft) / 2;
-
- window.mozRequestAnimationFrame(function newFrameCallback() {
- alignCard(number, callback);
- });
- }
-
- function onStartEvent(evt) {
- evt.stopPropagation();
- evt.target.setCapture(true);
- cardsView.addEventListener('mousemove', CardsView);
- cardsView.addEventListener('swipe', CardsView);
-
- initialCardViewPosition = cardsView.scrollLeft;
- initialTouchPosition = {
- x: evt.touches ? evt.touches[0].pageX : evt.pageX,
- y: evt.touches ? evt.touches[0].pageY : evt.pageY
- };
- }
-
- function onMoveEvent(evt) {
- evt.stopPropagation();
- var touchPosition = {
- x: evt.touches ? evt.touches[0].pageX : evt.pageX,
- y: evt.touches ? evt.touches[0].pageY : evt.pageY
- };
-
- if (evt.target.classList.contains('card') && MANUAL_CLOSING) {
- var differenceY = initialTouchPosition.y - touchPosition.y;
- if (differenceY > moveCardThreshold) {
- // We don't want user to scroll the CardsView when one of the card is
- // already dragger upwards
- draggingCardUp = true;
- evt.target.style.MozTransform = 'scale(0.6) translate(0, -' +
- differenceY + 'px)';
- }
- }
-
- // If we are not reordering or removing Cards now
- // and Snapping Scrolling is enabled, we want to scroll
- // the CardList
- if (SNAPPING_SCROLLING && reorderedCard === null && !draggingCardUp) {
- var differenceX = initialTouchPosition.x - touchPosition.x;
- cardsView.scrollLeft = initialCardViewPosition + differenceX;
- }
-
- // If re are in reordering mode (there is a DOM element in)
- // reorderedCard variable) we are able to put this element somewere
- // among the others
- if (USER_DEFINED_ORDERING && reorderedCard !== null) {
- var differenceX = touchPosition.x - initialTouchPosition.x;
- // Probably there is more clever solution for calculating
- // position of transformed DOM element, but this was my
- // first thought and it seems to work
- var moveOffset = (cardsList.children[currentDisplayed].offsetLeft / 0.6) +
- differenceX - (dragMargin / 0.6);
-
- reorderedCard.style.MozTransform =
- 'scale(0.6) translate(' + moveOffset + 'px, 0)';
-
- if (Math.abs(differenceX) > threshold) {
- // We don't want to jump to the next page immediately,
- // We are waiting half a second for user to decide if
- // he wants to leave the Card here or scroll further
- if (allowScrollingWhileSorting) {
- allowScrollingWhileSorting = false;
-
- scrollWhileSortingTimer = setTimeout(function() {
- allowScrollingWhileSorting = true;
- }, 500);
-
- if (differenceX > 0 &&
- currentDisplayed <= cardsList.children.length) {
- currentDisplayed++;
- sortingDirection = 'right';
- alignCard(currentDisplayed);
- } else if (differenceX < 0 && currentDisplayed > 0) {
- currentDisplayed--;
- sortingDirection = 'left';
- alignCard(currentDisplayed);
- }
- }
- }
- }
- }
-
- function onEndEvent(evt) {
- evt.stopPropagation();
- var element = evt.target;
- var eventDetail = evt.detail;
- var direction = eventDetail.direction;
-
- document.releaseCapture();
- cardsView.removeEventListener('mousemove', CardsView);
- cardsView.removeEventListener('swipe', CardsView);
-
- var touchPosition = {
- x: eventDetail.end.pageX,
- y: eventDetail.end.pageY
- };
-
- if (SNAPPING_SCROLLING && !draggingCardUp && reorderedCard === null) {
- if (Math.abs(eventDetail.dx) > threshold) {
- if (
- direction === 'left' &&
- currentDisplayed < cardsList.children.length - 1
- ) {
- currentDisplayed++;
- alignCard(currentDisplayed);
- } else if (direction === 'right' && currentDisplayed > 0) {
- currentDisplayed--;
- alignCard(currentDisplayed);
- }
- } else {
- alignCard(currentDisplayed);
- }
- }
-
- // if the element we start dragging on
- // is a card and we are not in reordering mode
- if (
- element.classList.contains('card') &&
- MANUAL_CLOSING &&
- reorderedCard === null
- ) {
-
- draggingCardUp = false;
- // Prevent user from closing the app with a attention screen
- if (-eventDetail.dy > removeCardThreshold &&
- attentionScreenApps.indexOf(element.dataset.origin) == -1
- ) {
-
- // remove the app also from the ordering list
- if (
- userSortedApps.indexOf(element.dataset.origin) !== -1 &&
- USER_DEFINED_ORDERING
- ) {
- userSortedApps.splice(
- userSortedApps.indexOf(element.dataset.origin),
- 1
- );
- }
-
- // Without removing the listener before closing card
- // sometimes the 'click' event fires, even if 'mouseup'
- // uses stopPropagation()
- element.removeEventListener('tap', runApp);
-
- // Remove the icon from the task list
- cardsList.removeChild(element);
-
- closeApp(element);
-
- return;
- } else {
- element.style.MozTransform = '';
- }
- }
-
- if (USER_DEFINED_ORDERING && reorderedCard !== null) {
- // Position of the card depends on direction of scrolling
- if (sortingDirection === 'right') {
- if (currentDisplayed <= cardsList.children.length) {
- cardsList.insertBefore(
- reorderedCard,
- cardsList.children[currentDisplayed + 1]
- );
- } else {
- cardsList.appendChild(reorderedCard);
- }
- } else if (sortingDirection === 'left') {
- cardsList.insertBefore(
- reorderedCard,
- cardsList.children[currentDisplayed]
- );
- }
- reorderedCard.style.MozTransform = '';
- reorderedCard.dataset['edit'] = 'false';
- reorderedCard = null;
-
- alignCard(currentDisplayed);
-
- // remove the app origin from ordering array
- userSortedApps.splice(
- userSortedApps.indexOf(element.dataset.origin),
- 1
- );
- // and put in on the new position
- userSortedApps.splice(currentDisplayed, 0, element.dataset.origin);
- }
- }
-
- function manualOrderStart(evt) {
- evt.preventDefault();
- reorderedCard = evt.target;
- allowScrollingWhileSorting = true;
- if (reorderedCard.classList.contains('card')) {
- dragMargin = reorderedCard.offsetLeft;
- reorderedCard.dataset['edit'] = true;
- sortingDirection = 'left';
- }
- }
-
- window.addEventListener('applicationuninstall',
- function removeUninstaledApp(evt) {
- var origin = evt.detail.application.origin;
- if (userSortedApps.indexOf(origin) !== -1) {
- userSortedApps.splice(userSortedApps.indexOf(origin), 1);
- }
- },
- false);
-
- function cv_handleEvent(evt) {
- switch (evt.type) {
- case 'mousedown':
- onStartEvent(evt);
- break;
-
- case 'mousemove':
- onMoveEvent(evt);
- break;
-
- case 'swipe':
- onEndEvent(evt);
- break;
-
- case 'contextmenu':
- manualOrderStart(evt);
- break;
-
- case 'home':
- if (!cardSwitcherIsShown())
- return;
-
- evt.stopImmediatePropagation();
- hideCardSwitcher();
- break;
-
- case 'lock':
- case 'attentionscreenshow':
- attentionScreenApps = AttentionScreen.getAttentionScreenOrigins();
- hideCardSwitcher();
- break;
-
- case 'attentionscreenhide':
- attentionScreenApps = AttentionScreen.getAttentionScreenOrigins();
- break;
-
- case 'holdhome':
- if (LockScreen.locked)
- return;
-
- SleepMenu.hide();
- showCardSwitcher();
- break;
-
- case 'appwillopen':
- hideCardSwitcher();
- break;
- }
- }
-
- // Public API of CardsView
- return {
- showCardSwitcher: showCardSwitcher,
- hideCardSwitcher: hideCardSwitcher,
- cardSwitcherIsShown: cardSwitcherIsShown,
- handleEvent: cv_handleEvent
- };
-})();
-
-window.addEventListener('attentionscreenshow', CardsView);
-window.addEventListener('attentionscreenhide', CardsView);
-window.addEventListener('holdhome', CardsView);
-window.addEventListener('home', CardsView);
-window.addEventListener('appwillopen', CardsView);
-
diff --git a/apps/system/js/context_menu.js b/apps/system/js/context_menu.js
deleted file mode 100644
index 816ef71..0000000
--- a/apps/system/js/context_menu.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var ContextMenu = {
- init: function cm_init() {
- window.addEventListener('mozbrowsercontextmenu', this, true);
- },
-
- handleEvent: function cm_handleEvent(evt) {
- var detail = evt.detail;
- if (detail.contextmenu.items.length == 0)
- return;
-
- var onsuccess = function(action) {
- detail.contextMenuItemSelected(action);
- };
-
- ListMenu.request(detail.contextmenu.items, '', onsuccess);
- }
-};
-
-ContextMenu.init();
diff --git a/apps/system/js/cost_control.js b/apps/system/js/cost_control.js
deleted file mode 100644
index 0f07962..0000000
--- a/apps/system/js/cost_control.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-(function() {
-
- 'use strict';
-
- var host = document.location.host;
- var domain = host.replace(/(^[\w\d]+\.)?([\w\d]+\.[a-z]+)/, '$2');
- var protocol = document.location.protocol + '//';
- var origin = protocol + 'costcontrol.' + domain;
-
- var widgetContainer = document.getElementById('cost-control-widget');
-
- var widgetFrame;
- function _ensureWidget() {
- if (!Applications.ready)
- return;
-
- // Check widget is there
- widgetFrame = widgetContainer.querySelector('iframe');
- if (widgetFrame && !widgetFrame.dataset.killed)
- return;
-
- // Create the widget
- if (!widgetFrame) {
- widgetFrame = document.createElement('iframe');
- widgetFrame.addEventListener('mozbrowsererror',
- function ccdriver_onError(e) {
- e.target.dataset.killed = true;
- }
- );
- }
-
- widgetFrame.dataset.frameType = 'widget';
- widgetFrame.dataset.frameOrigin = origin;
- delete widgetFrame.dataset.killed;
-
- widgetFrame.setAttribute('mozbrowser', true);
- widgetFrame.setAttribute('remote', 'true');
- widgetFrame.setAttribute('mozapp', origin + '/manifest.webapp');
-
- widgetFrame.src = origin + '/widget.html';
- widgetContainer.appendChild(widgetFrame);
-
- _adjustWidgetPosition();
- }
-
- function _showWidget() {
- _ensureWidget();
- widgetFrame.setVisible(true);
- }
-
- function _hideWidget() {
- if (widgetFrame) {
- widgetFrame.setVisible(false);
- }
- }
-
- function _adjustWidgetPosition() {
- // TODO: Remove this when weird bug #809031 (Bugzilla) is solved
- // See cost_control.css as well to remove the last rule
- var offsetY = document.getElementById('notification-bar').clientHeight;
- offsetY +=
- document.getElementById('notifications-container').clientHeight;
- widgetFrame.style.transform = 'translate(0, ' + offsetY + 'px)';
- }
-
- // Listen to utilitytray show
- window.addEventListener('utilitytrayshow', _showWidget);
- window.addEventListener('utilitytrayhide', _hideWidget);
-
- window.addEventListener('applicationready', function _onReady() {
- asyncStorage.getItem('ftu.enabled', function _onValue(enabled) {
- if (enabled !== false) {
- window.addEventListener('ftudone', function ftudone(e) {
- window.removeEventListener('ftudone', ftudone);
- _ensureWidget();
- widgetFrame.setVisible(false);
- });
- } else {
- _ensureWidget();
- widgetFrame.setVisible(false);
- }
- });
- });
-
- window.addEventListener('resize', _adjustWidgetPosition);
-}());
diff --git a/apps/system/js/crash_reporter.js b/apps/system/js/crash_reporter.js
deleted file mode 100644
index 4068291..0000000
--- a/apps/system/js/crash_reporter.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-// This file calls getElementById without waiting for an onload event, so it
-// must have a defer attribute or be included at the end of the <body>.
-
-var CrashReporter = (function() {
- var _ = navigator.mozL10n.get;
- var settings = navigator.mozSettings;
- var screen = document.getElementById('screen');
-
- // The name of the app that just crashed.
- var crashedAppName = '';
-
- // Whether or not to show a "Report" button in the banner.
- var showReportButton = false;
-
- // Only show the "Report" button if the user hasn't set a preference to
- // always/never report crashes.
- SettingsListener.observe('app.reportCrashes', 'ask',
- function handleCrashSetting(value) {
- showReportButton = (value != 'always' && value != 'never');
- });
-
- // This function should only ever be called once.
- function showDialog(crashID, isChrome) {
- var title = isChrome ? _('crash-dialog-os2') :
- _('crash-dialog-app', { name: crashedAppName });
- document.getElementById('crash-dialog-title').textContent = title;
-
- // "Don't Send Report" button in dialog
- var noButton = document.getElementById('dont-send-report');
- noButton.addEventListener('click', function onNoButtonClick() {
- settings.createLock().set({'app.reportCrashes': 'never'});
- removeDialog();
- });
-
- // "Send Report" button in dialog
- var yesButton = document.getElementById('send-report');
- yesButton.addEventListener('click', function onYesButtonClick() {
- submitCrash(crashID);
- if (checkbox.checked) {
- settings.createLock().set({'app.reportCrashes': 'always'});
- }
- removeDialog();
- });
-
- var checkbox = document.getElementById('always-send');
- checkbox.addEventListener('click', function onCheckboxClick() {
- // Disable the "Don't Send Report" button if the "Always send..."
- // checkbox is checked
- noButton.disabled = this.checked;
- });
-
- // "What's in a crash report?" link
- var crashInfoLink = document.getElementById('crash-info-link');
- crashInfoLink.addEventListener('click', function onLearnMoreClick() {
- var dialog = document.getElementById('crash-dialog');
- document.getElementById('crash-reports-done').
- addEventListener('click', function onDoneClick() {
- this.removeEventListener('click', onDoneClick);
- dialog.classList.remove('learn-more');
- });
- dialog.classList.add('learn-more');
- });
-
- screen.classList.add('crash-dialog');
- }
-
- // We can get rid of the dialog after it is shown once.
- function removeDialog() {
- screen.classList.remove('crash-dialog');
- var dialog = document.getElementById('crash-dialog');
- dialog.parentNode.removeChild(dialog);
- }
-
- function showBanner(crashID, isChrome) {
- var message = isChrome ? _('crash-banner-os2') :
- _('crash-banner-app', { name: crashedAppName });
-
- var button = null;
- if (showReportButton) {
- button = {
- label: _('crash-banner-report'),
- callback: function reportCrash() {
- submitCrash(crashID);
- }
- };
- }
-
- SystemBanner.show(message, button);
- }
-
- function submitCrash(crashID) {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, {
- type: 'submit-crash',
- crashID: crashID
- });
- window.dispatchEvent(event);
- }
-
- // - Show a dialog only the first time there's a crash to report.
- // - On subsequent crashes, show a banner letting the user know there was a
- // crash.
- // - If the user hasn't set a pref, add a "Report" button to the banner.
- function handleCrash(crashID, isChrome) {
- // Check to see if we should show a dialog.
- var dialogReq = settings.createLock().get('crashReporter.dialogShown');
- dialogReq.onsuccess = function dialogShownSuccess() {
- var dialogShown = dialogReq.result['crashReporter.dialogShown'];
- if (!dialogShown) {
- settings.createLock().set({'crashReporter.dialogShown': true});
- showDialog(crashID, isChrome);
- } else {
- showBanner(crashID, isChrome);
- }
- };
- }
-
- // We depend on window_manager.js calling this function before
- // we get a 'handle-crash' event from shell.js
- function setAppName(name) {
- crashedAppName = name;
- }
-
- // We will be notified of system crashes from shell.js
- window.addEventListener('mozChromeEvent', function handleChromeEvent(e) {
- if (e.detail.type == 'handle-crash') {
- handleCrash(e.detail.crashID, e.detail.chrome);
- }
- });
-
- return {
- setAppName: setAppName
- };
-})();
-
diff --git a/apps/system/js/gridview.js b/apps/system/js/gridview.js
deleted file mode 100644
index 399bf3e..0000000
--- a/apps/system/js/gridview.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var GridView = {
- grid: null,
-
- get visible() {
- return this.grid && this.grid.style.display === 'block';
- },
-
- hide: function gv_hide() {
- if (this.grid)
- this.grid.style.visibility = 'hidden';
- },
-
- show: function gv_show() {
- var grid = this.grid;
- if (!grid) {
- grid = document.createElement('div');
- grid.id = 'debug-grid';
- grid.dataset.zIndexLevel = 'debug-grid';
-
- this.grid = grid;
- document.getElementById('screen').appendChild(grid);
- }
-
- grid.style.visibility = 'visible';
- },
-
- toggle: function gv_toggle() {
- this.visible ? this.hide() : this.show();
- }
-};
-
-SettingsListener.observe('debug.grid.enabled', false, function(value) {
- !!value ? GridView.show() : GridView.hide();
-});
-
diff --git a/apps/system/js/hardware_buttons.js b/apps/system/js/hardware_buttons.js
deleted file mode 100644
index 3363463..0000000
--- a/apps/system/js/hardware_buttons.js
+++ /dev/null
@@ -1,318 +0,0 @@
-// hardware_buttons.js:
-//
-// Gecko code in b2g/chrome/content/shell.js sends mozChromeEvents
-// when the user presses or releases a hardware button such as Home, Sleep,
-// and Volume Up and Down.
-//
-// This module listens for those low-level mozChromeEvents, processes them
-// and generates higher-level events to handle autorepeat on the volume keys
-// long presses on Home and Sleep, and the Home+Sleep key combination.
-//
-// Other system app modules should listen for the high-level button events
-// generated by this module.
-//
-// The low-level input events processed by this module have type set
-// to "mozChromeEvent" and detail.type set to one of:
-//
-// home-button-press
-// home-button-release
-// sleep-button-press
-// sleep-button-release
-// volume-up-button-press
-// volume-up-button-release
-// volume-down-button-press
-// volume-down-button-release
-//
-// The high-level events generated by this module are simple Event objects
-// that are not cancelable and do not bubble. The are dispatched at the
-// window object. The type property is set to one of these:
-//
-// Event Type Meaning
-// --------------------------------------------------------------
-// home short press and release of home button
-// holdhome long press and hold of home button
-// sleep short press and release of sleep button
-// wake sleep or home pressed while sleeping
-// holdsleep long press and hold of sleep button
-// volumeup volume up pressed and released or autorepeated
-// volumedown volume down pressed and released or autorepeated
-// home+sleep home and sleep pressed at same time (used for screenshots)
-// home+volume home and either volume key at the same time (view source)
-//
-// Because these events are fired at the window object, they cannot be
-// captured. Many modules listen for the home event. Those that want
-// to respond to it and prevent others from responding should call
-// stopImmediatePropagation(). Overlays that want to prevent the window
-// manager from showing the homescreen on the home event should call that
-// method. Note, however, that this only works for scripts that run and
-// register their event handlers before window_manager.js does.
-//
-'use strict';
-
-(function() {
- var HOLD_INTERVAL = 750; // How long for press and hold Home or Sleep
- var REPEAT_DELAY = 700; // How long before volume autorepeat begins
- var REPEAT_INTERVAL = 100; // How fast the autorepeat is.
-
- // Dispatch a high-level event of the specified type
- function fire(type) {
- window.dispatchEvent(new Event(type));
- }
-
- // We process events with a finite state machine.
- // Each state object has a process() method for handling events.
- // And optionally has enter() and exit() methods called when the FSM
- // enters and exits that state
- var state;
-
- // This function transitions to a new state
- function setState(s, type) {
- // Exit the current state()
- if (state && state.exit)
- state.exit(type);
- state = s;
- // Enter the new state
- if (state && state.enter)
- state.enter(type);
- }
-
- // This event handler listens for hardware button events and passes the
- // event type to the process() method of the current state for processing
- window.addEventListener('mozChromeEvent', function(e) {
- var type = e.detail.type;
- switch (type) {
- case 'home-button-press':
- case 'home-button-release':
- case 'sleep-button-press':
- case 'sleep-button-release':
- case 'volume-up-button-press':
- case 'volume-up-button-release':
- case 'volume-down-button-press':
- case 'volume-down-button-release':
- state.process(type);
- break;
- }
- });
-
- // The base state is the default, when no hardware buttons are pressed
- var baseState = {
- process: function(type) {
- switch (type) {
- case 'home-button-press':
- // If the phone is sleeping, then pressing Home wakes it
- // (on press, not release)
- if (!ScreenManager.screenEnabled) {
- fire('wake');
- setState(wakeState, type);
- } else {
- setState(homeState, type);
- }
- return;
- case 'sleep-button-press':
- // If the phone is sleeping, then pressing Sleep wakes it
- // (on press, not release)
- if (!ScreenManager.screenEnabled) {
- fire('wake');
- setState(wakeState, type);
- } else {
- setState(sleepState, type);
- }
- return;
- case 'volume-up-button-press':
- case 'volume-down-button-press':
- setState(volumeState, type);
- return;
- case 'home-button-release':
- case 'sleep-button-release':
- case 'volume-up-button-release':
- case 'volume-down-button-release':
- // Ignore button releases that occur in this state.
- // These can happen after home+sleep and home+volume.
- return;
- }
- console.error('Unexpected hardware key: ', type);
- }
- };
-
- // We enter the home state when the user presses the Home button
- // We can fire home, holdhome, or homesleep events from this state
- var homeState = {
- timer: null,
- enter: function() {
- this.timer = setTimeout(function() {
- fire('holdhome');
- navigator.vibrate(50);
- setState(baseState);
- }, HOLD_INTERVAL);
- },
- exit: function() {
- if (this.timer) {
- clearTimeout(this.timer);
- this.timer = null;
- }
- },
- process: function(type) {
- switch (type) {
- case 'home-button-release':
- fire('home');
- navigator.vibrate(50);
- setState(baseState, type);
- return;
- case 'sleep-button-press':
- fire('home+sleep');
- setState(baseState, type);
- return;
- case 'volume-up-button-press':
- case 'volume-down-button-press':
- fire('home+volume');
- setState(baseState, type);
- return;
- }
- console.error('Unexpected hardware key: ', type);
- setState(baseState, type);
- }
- };
-
- // We enter the sleep state when the user presses the Sleep button
- // We can fire sleep, holdsleep, or homesleep events from this state
- var sleepState = {
- timer: null,
- enter: function() {
- this.timer = setTimeout(function() {
- fire('holdsleep');
- setState(baseState);
- }, HOLD_INTERVAL);
- },
- exit: function() {
- if (this.timer) {
- clearTimeout(this.timer);
- this.timer = null;
- }
- },
- process: function(type) {
- switch (type) {
- case 'sleep-button-release':
- fire('sleep');
- setState(baseState, type);
- return;
- case 'home-button-press':
- fire('home+sleep');
- setState(baseState, type);
- return;
- case 'volume-up-button-press':
- case 'volume-down-button-press':
- setState(volumeState, type);
- return;
- }
- console.error('Unexpected hardware key: ', type);
- setState(baseState, type);
- }
- };
-
- // We enter the volume state when the user presses the volume up or
- // volume down buttons.
- // We can fire volumeup and volumedown events from this state
- var volumeState = {
- direction: null,
- timer: null,
- repeating: false,
- repeat: function() {
- this.repeating = true;
- if (this.direction === 'volume-up-button-press')
- fire('volumeup');
- else
- fire('volumedown');
- this.timer = setTimeout(this.repeat.bind(this), REPEAT_INTERVAL);
- },
- enter: function(type) {
- var self = this;
- this.direction = type; // Is volume going up or down?
- this.repeating = false;
- this.timer = setTimeout(this.repeat.bind(this), REPEAT_DELAY);
- },
- exit: function() {
- if (this.timer) {
- clearTimeout(this.timer);
- this.timer = null;
- }
- },
- process: function(type) {
- switch (type) {
- case 'home-button-press':
- fire('home+volume');
- setState(baseState, type);
- return;
- case 'sleep-button-press':
- setState(sleepState, type);
- return;
- case 'volume-up-button-release':
- if (this.direction === 'volume-up-button-press') {
- if (!this.repeating)
- fire('volumeup');
- setState(baseState, type);
- return;
- }
- break;
- case 'volume-down-button-release':
- if (this.direction === 'volume-down-button-press') {
- if (!this.repeating)
- fire('volumedown');
- setState(baseState, type);
- return;
- }
- break;
- default:
- // Ignore anything else (such as sleep button release)
- return;
- }
- console.error('Unexpected hardware key: ', type);
- setState(baseState, type);
- }
- };
-
- // We enter this state when the user presses Home or Sleep on a sleeping
- // phone. We give immediate feedback by waking the phone up on the press
- // rather than waiting for the release, but this means we need a special
- // state so that we don't actually send a home or sleep event on the
- // key release. Note, however, that this state does set a timer so that
- // it can send holdhome or holdsleep events. (This means that pressing and
- // holding sleep will bring up the power menu, even on a sleeping phone.)
- var wakeState = {
- timer: null,
- delegateState: null,
- enter: function(type) {
- if (type === 'home-button-press')
- this.delegateState = homeState;
- else
- this.delegateState = sleepState;
- this.timer = setTimeout(function() {
- if (type === 'home-button-press') {
- fire('holdhome');
- } else if (type === 'sleep-button-press') {
- fire('holdsleep');
- }
- setState(baseState, type);
- }, HOLD_INTERVAL);
- },
- exit: function() {
- if (this.timer) {
- clearTimeout(this.timer);
- this.timer = null;
- }
- },
- process: function(type) {
- switch (type) {
- case 'home-button-release':
- case 'sleep-button-release':
- setState(baseState, type);
- return;
- default:
- this.delegateState.process(type);
- return;
- }
- }
- };
-
- // Kick off the FSM in the base state
- setState(baseState);
-}());
diff --git a/apps/system/js/icc_cache.js b/apps/system/js/icc_cache.js
deleted file mode 100644
index 1f1d0df..0000000
--- a/apps/system/js/icc_cache.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-(function() {
- /**
- * Constants
- */
- var DEBUG = false;
-
- /**
- * Debug method
- */
- function debug(msg, optObject) {
- if (DEBUG) {
- var output = '[DEBUG] STKCACHE: ' + msg;
- if (optObject) {
- output += JSON.stringify(optObject);
- }
- console.log(output);
- }
- }
-
- if (!window.navigator.mozMobileConnection) {
- return;
- }
-
- var icc = window.navigator.mozMobileConnection.icc;
- // Remove previous menu
- var resetApplications = window.navigator.mozSettings.createLock().set({
- 'icc.applications': '{}'
- });
- resetApplications.onsuccess = function icc_resetApplications() {
- debug('STK Cache Reseted');
- // Register to receive STK commands
- window.navigator.mozSetMessageHandler('icc-stkcommand',
- function handleSTKCommand(command) {
- debug('STK Proactive Command:', command);
- if (command.typeOfCommand == icc.STK_CMD_SET_UP_MENU) {
- debug('STK_CMD_SET_UP_MENU:', command.options);
- var reqApplications = window.navigator.mozSettings.createLock().set({
- 'icc.applications': JSON.stringify(command.options)
- });
- reqApplications.onsuccess = function icc_getApplications() {
- debug('Cached');
- icc.sendStkResponse(command, {
- resultCode: icc.STK_RESULT_OK
- });
- }
- } else {
- // Unsolicited command? -> Open settings
- debug('CMD: ', command);
- var application = document.location.protocol + '//' +
- document.location.host.replace('system', 'settings');
- debug('application: ', application);
- var reqIccData = window.navigator.mozSettings.createLock().set({
- 'icc.data': JSON.stringify(command)
- });
- reqIccData.onsuccess = function icc_getIccData() {
- if (WindowManager.getRunningApps()[application]) {
- debug('Settings is running. Ignoring');
- return; // If settings is opened, we don't manage it
- }
-
- debug('Locating settings . . .');
- navigator.mozApps.mgmt.getAll().onsuccess = function gotApps(evt) {
- var apps = evt.target.result;
- apps.forEach(function appIterator(app) {
- if (app.origin != application)
- return;
-
- var reqIccData = window.navigator.mozSettings.createLock().set({
- 'icc.data': JSON.stringify(command)
- });
- reqIccData.onsuccess = function icc_getIccData() {
- debug('Launching ', app.origin);
- app.launch();
- }
- }, this);
- }
- }
- }
- });
- }
-})();
diff --git a/apps/system/js/identity.js b/apps/system/js/identity.js
deleted file mode 100644
index 8030377..0000000
--- a/apps/system/js/identity.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-// When bug 794999 is resolved, switch to use the abstract Trusted UI Component
-
-'use strict';
-
-const kIdentityScreen = 'https://login.native-persona.org/sign_in#NATIVE';
-const kIdentityFrame =
- 'https://login.native-persona.org/communication_iframe';
-
-var Identity = (function() {
- var iframe;
-
- return {
- trustedUILayers: {},
-
- init: function() {
- window.addEventListener('mozChromeEvent', this);
- },
-
- handleEvent: function onMozChromeEvent(e) {
- var chromeEventId = e.detail.id;
- var requestId = e.detail.requestId;
- switch (e.detail.type) {
- // Chrome asks Gaia to show the identity dialog.
- case 'open-id-dialog':
- if (!chromeEventId)
- return;
-
- // When opening the dialog, we record the chrome event id, which
- // we will need to send back to the TrustedUIManager when asking
- // to close.
- this.trustedUILayers[requestId] = chromeEventId;
-
- if (!e.detail.showUI && iframe) {
- this._dispatchEvent({
- id: chromeEventId,
- frame: iframe
- });
- return;
- }
- var frame = document.createElement('iframe');
- frame.setAttribute('mozbrowser', 'true');
- frame.setAttribute('remote', true);
- frame.classList.add('screen');
- frame.src = e.detail.showUI ? kIdentityScreen : kIdentityFrame;
- frame.addEventListener('mozbrowserloadstart',
- function loadStart(evt) {
- // After creating the new frame containing the identity flow, we
- // send it back to chrome so the identity callbacks can be injected.
- this._dispatchEvent({
- id: chromeEventId,
- frame: evt.target
- });
- }.bind(this));
-
-
- if (e.detail.showUI) {
- // The identity flow is shown within the trusted UI.
- TrustedUIManager.open(navigator.mozL10n.get('persona-signin'),
- frame,
- this.trustedUILayers[requestId]);
- } else {
- var container = document.getElementById('screen');
- container.appendChild(frame);
- frame.classList.add('communication-frame');
- iframe = frame;
- }
- break;
-
- case 'received-id-assertion':
- if (e.detail.showUI) {
- TrustedUIManager.close(this.trustedUILayers[requestId],
- (function dialogClosed() {
- delete this.trustedUILayers[requestId];
- }).bind(this));
- }
- this._dispatchEvent({ id: chromeEventId });
- break;
- }
- },
- _dispatchEvent: function su_dispatchEvent(obj) {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, obj);
- window.dispatchEvent(event);
- }
- };
-})();
-
-// Make sure L10n is ready before init
-if (navigator.mozL10n.readyState == 'complete' ||
- navigator.mozL10n.readyState == 'interactive') {
- Identity.init();
-} else {
- window.addEventListener('localized', Identity.init.bind(Identity));
-}
-
diff --git a/apps/system/js/keyboard_manager.js b/apps/system/js/keyboard_manager.js
deleted file mode 100644
index 62aeca7..0000000
--- a/apps/system/js/keyboard_manager.js
+++ /dev/null
@@ -1,86 +0,0 @@
-'use strict';
-
-var KeyboardManager = (function() {
- function getKeyboardURL() {
- // TODO: Retrieve it from Settings, allowing 3rd party keyboards
- var host = document.location.host;
- var domain = host.replace(/(^[\w\d]+\.)?([\w\d]+\.[a-z]+)/, '$2');
- var protocol = document.location.protocol;
-
- return protocol + '//keyboard.' + domain + '/';
- }
-
- function generateKeyboard(container, keyboardURL, manifestURL) {
- var keyboard = document.createElement('iframe');
- keyboard.src = keyboardURL;
- keyboard.setAttribute('mozbrowser', 'true');
- keyboard.setAttribute('mozpasspointerevents', 'true');
- keyboard.setAttribute('mozapp', manifestURL);
- //keyboard.setAttribute('remote', 'true');
-
- container.appendChild(keyboard);
- return keyboard;
- }
-
- // Generate a <iframe mozbrowser> containing the keyboard.
- var container = document.getElementById('keyboard-frame');
- var keyboardURL = getKeyboardURL() + 'index.html';
- var manifestURL = getKeyboardURL() + 'manifest.webapp';
- var keyboard = generateKeyboard(container, keyboardURL, manifestURL);
-
- // Listen for mozbrowserlocationchange of keyboard iframe.
- var previousHash = '';
-
- var urlparser = document.createElement('a');
- keyboard.addEventListener('mozbrowserlocationchange', function(e) {
- urlparser.href = e.detail;
- if (previousHash == urlparser.hash)
- return;
- previousHash = urlparser.hash;
-
- var type = urlparser.hash.split('=');
- switch (type[0]) {
- case '#show':
- var updateHeight = function updateHeight() {
- container.removeEventListener('transitionend', updateHeight);
- if (container.classList.contains('hide')) {
- // The keyboard has been closed already, let's not resize the
- // application and ends up with half apps.
- return;
- }
-
- var detail = {
- 'detail': {
- 'height': parseInt(type[1])
- }
- };
-
- dispatchEvent(new CustomEvent('keyboardchange', detail));
- }
-
- if (container.classList.contains('hide')) {
- container.classList.remove('hide');
- container.addEventListener('transitionend', updateHeight);
- return;
- }
-
- updateHeight();
- break;
-
- case '#hide':
- // inform window manager to resize app first or
- // it may show the underlying homescreen
- dispatchEvent(new CustomEvent('keyboardhide'));
- container.classList.add('hide');
- break;
- }
- });
-
- // For Bug 812115: hide the keyboard when the app is closed here,
- // since it would take a longer round-trip to receive focuschange
- window.addEventListener('appwillclose', function closeKeyboard() {
- dispatchEvent(new CustomEvent('keyboardhide'));
- container.classList.add('hide');
- });
-})();
-
diff --git a/apps/system/js/list_menu.js b/apps/system/js/list_menu.js
deleted file mode 100644
index 303fafe..0000000
--- a/apps/system/js/list_menu.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var ListMenu = {
- get element() {
- delete this.element;
- return this.element = document.getElementById('listmenu');
- },
-
- get container() {
- delete this.container;
- return this.container = document.querySelector('#listmenu menu');
- },
-
- get visible() {
- return this.element.classList.contains('visible');
- },
-
- // Listen to click event only
- init: function lm_init() {
- window.addEventListener('click', this, true);
- window.addEventListener('screenchange', this, true);
- window.addEventListener('home', this);
- window.addEventListener('holdhome', this);
- },
-
- // Pass an array of list items and handler for clicking on the items
- // Modified to fit contextmenu use case, loop into the menu items
- request: function lm_request(listItems, title, successCb, errorCb) {
- this.container.innerHTML = '';
- this.currentLevel = 0;
- this.internalList = [];
- this.setTitle(title);
- this.buildMenu(listItems);
- this.internalList.forEach(function render_item(item) {
- this.container.appendChild(item);
- }, this);
-
- this.onreturn = successCb || function() {};
- this.oncancel = errorCb || function() {};
-
- this.show();
- },
-
- buildMenu: function lm_buildMenu(items) {
- var containerDiv = document.createElement('ul');
- var _ = navigator.mozL10n.get;
-
- if (this.currentLevel === 0) {
- containerDiv.classList.add('list-menu-root');
- containerDiv.id = 'list-menu-root';
- } else {
- containerDiv.id = 'list-menu-' + this.internalList.length;
- }
- this.internalList.push(containerDiv);
-
- items.forEach(function traveseItems(item) {
- var item_div = document.createElement('li');
- var button = document.createElement('a');
- button.setAttribute('role', 'button');
- if (item.type && item.type == 'menu') {
- // XXX: We disallow multi-level menu at this moment
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=824928
- // for UX design and dev implementation tracking
- return;
- } else if (item.type && item.type == 'menuitem') {
- button.dataset.value = item.id;
- button.textContent = item.label;
- } else {
- button.dataset.value = item.value;
- button.textContent = item.label;
- }
-
- item_div.appendChild(button);
- if (item.icon) {
- button.style.backgroundImage = 'url(' + item.icon + ')';
- button.classList.add('icon');
- }
- containerDiv.appendChild(item_div);
- }, this);
-
- if (this.currentLevel > 0) {
- var back = document.createElement('li');
- var button = document.createElement('a');
- button.setAttribute('role', 'button');
- button.textContent = _('back');
- button.href = '#' + this.currentParent;
- back.classList.add('back');
- back.appendChild(button);
- containerDiv.appendChild(back);
- } else {
- var cancel = document.createElement('li');
- var button = document.createElement('button');
- button.textContent = _('cancel');
- button.dataset.action = 'cancel';
- cancel.appendChild(button);
- containerDiv.appendChild(cancel);
- }
-
- containerDiv.dataset.level = this.currentLevel;
- this.currentChild = containerDiv.id;
- },
-
- setTitle: function lm_setTitle(title) {
- if (!title)
- return;
-
- var titleElement = document.createElement('h3');
- titleElement.textContent = title;
- this.container.appendChild(titleElement);
- },
-
- show: function lm_show() {
- if (this.visible)
- return;
-
- this.container.classList.remove('slidedown');
- this.element.classList.add('visible');
- },
-
- hide: function lm_hide() {
- if (!this.visible)
- return;
-
- var self = this;
- var container = this.container;
- container.addEventListener('transitionend', function list_hide() {
- container.removeEventListener('transitionend', list_hide);
- self.element.classList.remove('visible');
- });
-
- setTimeout(function() {
- container.classList.add('slidedown');
- });
- },
-
- handleEvent: function lm_handleEvent(evt) {
- switch (evt.type) {
- case 'screenchange':
- if (!evt.detail.screenEnabled) {
- this.hide();
- this.oncancel();
- }
- break;
-
- case 'click':
- if (!this.visible)
- return;
-
- var cancel = evt.target.dataset.action;
- if (cancel && cancel == 'cancel') {
- this.hide();
- this.oncancel();
- return;
- }
-
- var value = evt.target.dataset.value;
- if (!value) {
- return;
- }
-
- this.hide();
- this.onreturn(value);
- break;
-
- case 'home':
- case 'holdhome':
- if (!this.visible)
- return;
-
- this.hide();
- this.oncancel();
- break;
- }
- }
-};
-
-ListMenu.init();
diff --git a/apps/system/js/lockscreen.js b/apps/system/js/lockscreen.js
deleted file mode 100644
index f2275c9..0000000
--- a/apps/system/js/lockscreen.js
+++ /dev/null
@@ -1,1019 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var LockScreen = {
- /*
- * Boolean return true when initialized.
- */
- ready: false,
-
- /*
- * Boolean return the status of the lock screen.
- * Must not multate directly - use unlock()/lockIfEnabled()
- * Listen to 'lock' and 'unlock' event to properly handle status changes
- */
- locked: true,
-
- /*
- * Boolean return whether if the lock screen is enabled or not.
- * Must not multate directly - use setEnabled(val)
- * Only Settings Listener should change this value to sync with data
- * in Settings API.
- */
- enabled: true,
-
- /*
- * Boolean returns wether we want a sound effect when unlocking.
- */
- unlockSoundEnabled: true,
-
- /*
- * Boolean return whether if the lock screen is enabled or not.
- * Must not multate directly - use setPassCodeEnabled(val)
- * Only Settings Listener should change this value to sync with data
- * in Settings API.
- * Will be ignored if 'enabled' is set to false.
- */
- passCodeEnabled: false,
-
- /*
- * Four digit Passcode
- * XXX: should come for Settings
- */
- passCode: '0000',
-
- /*
- * The time to request for passcode input since device is off.
- */
- passCodeRequestTimeout: 0,
-
- /*
- * Store the first time the screen went off since unlocking.
- */
- _screenOffTime: 0,
-
- /*
- * Check the timeout of passcode lock
- */
- _passCodeTimeoutCheck: false,
-
- /*
- * Current passcode entered by the user
- */
- passCodeEntered: '',
-
- /**
- * Are we currently switching panels ?
- */
- _switchingPanel: false,
-
- /*
- * Timeout after incorrect attempt
- */
- kPassCodeErrorTimeout: 500,
-
- /*
- * Airplane mode
- */
- airplaneMode: false,
-
- /*
- * Timeout ID for backing from triggered state to normal state
- */
- triggeredTimeoutId: 0,
-
- /*
- * Interval ID for elastic of curve and arrow
- */
- elasticIntervalId: 0,
-
- /*
- * elastic animation interval
- */
- ELASTIC_INTERVAL: 5000,
-
- /*
- * timeout for triggered state after swipe up
- */
- TRIGGERED_TIMEOUT: 7000,
-
- /*
- * Max value for handle swiper up
- */
- HANDLE_MAX: 70,
-
- /* init */
- init: function ls_init() {
- if (this.ready) { // already initialized: just trigger a translation
- this.updateTime();
- this.updateConnState();
- return;
- }
- this.ready = true;
-
- this.getAllElements();
-
- this.lockIfEnabled(true);
- this.writeSetting(this.enabled);
-
- /* Status changes */
- window.addEventListener('volumechange', this);
- window.addEventListener('screenchange', this);
-
- /* Gesture */
- this.area.addEventListener('mousedown', this);
- this.areaCamera.addEventListener('click', this);
- this.areaUnlock.addEventListener('click', this);
- this.iconContainer.addEventListener('mousedown', this);
-
- /* Unlock & camera panel clean up */
- this.overlay.addEventListener('transitionend', this);
-
- /* Passcode input pad*/
- this.passcodePad.addEventListener('click', this);
-
- /* switching panels */
- window.addEventListener('home', this);
-
- /* blocking holdhome and prevent Cards View from show up */
- window.addEventListener('holdhome', this, true);
-
- /* mobile connection state on lock screen */
- var conn = window.navigator.mozMobileConnection;
- if (conn && conn.voice) {
- conn.addEventListener('voicechange', this);
- conn.addEventListener('cardstatechange', this);
- conn.addEventListener('iccinfochange', this);
- this.updateConnState();
- this.connstate.hidden = false;
- }
-
- var self = this;
- if (navigator && navigator.mozCellBroadcast) {
- navigator.mozCellBroadcast.onreceived = function onReceived(event) {
- var msg = event.message;
- if (conn &&
- conn.voice.network.mcc === MobileOperator.BRAZIL_MCC &&
- msg.messageId === MobileOperator.BRAZIL_CELLBROADCAST_CHANNEL) {
- self.cellbroadcastLabel = msg.body;
- self.updateConnState();
- }
- };
- }
-
- SettingsListener.observe('lockscreen.enabled', true, function(value) {
- self.setEnabled(value);
- });
-
- SettingsListener.observe('ring.enabled', true, function(value) {
- self.mute.hidden = value;
- });
-
- SettingsListener.observe('vibration.enabled', true, function(value) {
- if (value) {
- self.mute.classList.add('vibration');
- } else {
- self.mute.classList.remove('vibration');
- }
- });
-
- SettingsListener.observe('ril.radio.disabled', false, function(value) {
- self.airplaneMode = value;
- self.updateConnState();
- });
-
- SettingsListener.observe('wallpaper.image',
- 'resources/images/backgrounds/default.png',
- function(value) {
- self.updateBackground(value);
- self.overlay.classList.remove('uninit');
- });
-
- SettingsListener.observe(
- 'lockscreen.passcode-lock.code', '0000', function(value) {
- self.passCode = value;
- });
-
- SettingsListener.observe(
- 'lockscreen.passcode-lock.enabled', false, function(value) {
- self.setPassCodeEnabled(value);
- });
-
- SettingsListener.observe('lockscreen.unlock-sound.enabled',
- true, function(value) {
- self.setUnlockSoundEnabled(value);
- });
-
- SettingsListener.observe('lockscreen.passcode-lock.timeout',
- 0, function(value) {
- self.passCodeRequestTimeout = value;
- });
- },
-
- /*
- * Set enabled state.
- * If enabled state is somehow updated when the lock screen is enabled
- * This function will unlock it.
- */
- setEnabled: function ls_setEnabled(val) {
- if (typeof val === 'string') {
- this.enabled = val == 'false' ? false : true;
- } else {
- this.enabled = val;
- }
-
- if (!this.enabled && this.locked) {
- this.unlock();
- }
- },
-
- setPassCodeEnabled: function ls_setPassCodeEnabled(val) {
- if (typeof val === 'string') {
- this.passCodeEnabled = val == 'false' ? false : true;
- } else {
- this.passCodeEnabled = val;
- }
- },
-
- setUnlockSoundEnabled: function ls_setUnlockSoundEnabled(val) {
- if (typeof val === 'string') {
- this.unlockSoundEnabled = val == 'false' ? false : true;
- } else {
- this.unlockSoundEnabled = val;
- }
- },
-
- handleEvent: function ls_handleEvent(evt) {
- switch (evt.type) {
- case 'screenchange':
- // XXX: If the screen is not turned off by ScreenManager
- // we would need to lock the screen again
- // when it's being turned back on
- if (!evt.detail.screenEnabled) {
- // Don't update the time after we're already locked otherwise turning
- // the screen off again will bypass the passcode before the timeout.
- if (!this.locked) {
- this._screenOffTime = new Date().getTime();
- }
-
- // Remove camera once screen turns off
- if (this.camera.firstElementChild)
- this.camera.removeChild(this.camera.firstElementChild);
-
- } else {
- var _screenOffInterval = new Date().getTime() - this._screenOffTime;
- if (_screenOffInterval > this.passCodeRequestTimeout * 1000) {
- this._passCodeTimeoutCheck = true;
- } else {
- this._passCodeTimeoutCheck = false;
- }
- }
-
- this.lockIfEnabled(true);
- break;
- case 'voicechange':
- case 'cardstatechange':
- case 'iccinfochange':
- this.updateConnState();
-
- case 'click':
- if (evt.target === this.areaUnlock || evt.target === this.areaCamera) {
- this.handleIconClick(evt.target);
- break;
- }
-
- if (!evt.target.dataset.key)
- break;
-
- // Cancel the default action of <a>
- evt.preventDefault();
- this.handlePassCodeInput(evt.target.dataset.key);
- break;
-
- case 'mousedown':
- var leftTarget = this.areaCamera;
- var rightTarget = this.areaUnlock;
- var handle = this.areaHandle;
- var overlay = this.overlay;
- var target = evt.target;
-
- // Reset timer when touch while overlay triggered
- if (overlay.classList.contains('triggered')) {
- clearTimeout(this.triggeredTimeoutId);
- this.triggeredTimeoutId = setTimeout(this.unloadPanel.bind(this),
- this.TRIGGERED_TIMEOUT);
- break;
- }
-
- overlay.classList.remove('elastic');
- this.setElasticEnabled(false);
-
- this._touch = {
- touched: false,
- leftTarget: leftTarget,
- rightTarget: rightTarget,
- overlayWidth: this.overlay.offsetWidth,
- handleWidth: this.areaHandle.offsetWidth,
- maxHandleOffset: rightTarget.offsetLeft - handle.offsetLeft -
- (handle.offsetWidth - rightTarget.offsetWidth) / 2
- };
- window.addEventListener('mouseup', this);
- window.addEventListener('mousemove', this);
-
- this._touch.touched = true;
- this._touch.initX = evt.pageX;
- this._touch.initY = evt.pageY;
- overlay.classList.add('touched');
- break;
-
- case 'mousemove':
- this.handleMove(evt.pageX, evt.pageY);
- break;
-
- case 'mouseup':
- window.removeEventListener('mousemove', this);
- window.removeEventListener('mouseup', this);
-
- this.handleMove(evt.pageX, evt.pageY);
- this.handleGesture();
- delete this._touch;
- this.overlay.classList.remove('touched');
-
- break;
-
- case 'transitionend':
- if (evt.target !== this.overlay)
- return;
-
- if (this.overlay.dataset.panel !== 'camera' &&
- this.camera.firstElementChild) {
- this.camera.removeChild(this.camera.firstElementChild);
- }
-
- if (!this.locked)
- this.switchPanel();
- break;
-
- case 'home':
- if (this.locked) {
- this.switchPanel();
- evt.stopImmediatePropagation();
- }
- break;
-
- case 'holdhome':
- if (!this.locked)
- return;
-
- evt.stopImmediatePropagation();
- evt.stopPropagation();
- break;
- }
- },
-
- handleMove: function ls_handleMove(pageX, pageY) {
- var touch = this._touch;
-
- if (!touch.touched) {
- // Do nothing if the user have not move the finger to the handle yet
- if (document.elementFromPoint(pageX, pageY) !== this.areaHandle)
- return;
-
- touch.touched = true;
- touch.initX = pageX;
- touch.initY = pageY;
-
- var overlay = this.overlay;
- overlay.classList.add('touched');
- }
-
- var dy = pageY - touch.initY;
- var ty = Math.max(- this.HANDLE_MAX, dy);
- var base = - ty / this.HANDLE_MAX;
- // mapping position 20-100 to opacity 0.1-0.5
- var opacity = base <= 0.2 ? 0.1 : base * 0.5;
- touch.ty = ty;
-
- this.iconContainer.style.transform = 'translateY(' + ty + 'px)';
- this.areaCamera.style.opacity =
- this.areaUnlock.style.opacity = opacity;
- },
-
- handleGesture: function ls_handleGesture() {
- var touch = this._touch;
- if (touch.ty < -50) {
- this.areaHandle.style.transform =
- this.areaHandle.style.opacity =
- this.iconContainer.style.transform =
- this.iconContainer.style.opacity =
- this.areaCamera.style.transform =
- this.areaCamera.style.opacity =
- this.areaUnlock.style.transform =
- this.areaUnlock.style.opacity = '';
- this.overlay.classList.add('triggered');
-
- this.triggeredTimeoutId =
- setTimeout(this.unloadPanel.bind(this), this.TRIGGERED_TIMEOUT);
- } else if (touch.ty > -10) {
- touch.touched = false;
- this.unloadPanel();
- this.playElastic();
-
- var self = this;
- var container = this.iconContainer;
- container.addEventListener('animationend', function prompt() {
- container.removeEventListener('animationend', prompt);
- self.overlay.classList.remove('elastic');
- self.setElasticEnabled(true);
- });
- } else {
- this.unloadPanel();
- this.setElasticEnabled(true);
- }
- },
-
- handleIconClick: function ls_handleIconClick(target) {
- var self = this;
- switch (target) {
- case this.areaCamera:
- var panelOrFullApp = function panelOrFullApp() {
- if (self.passCodeEnabled) {
- // Go to secure camera panel
- self.switchPanel('camera');
- return;
- }
-
- self.unlock();
-
- var a = new MozActivity({
- name: 'record',
- data: {
- type: 'photos'
- }
- });
- a.onerror = function ls_activityError() {
- console.log('MozActivity: camera launch error.');
- };
- };
-
- panelOrFullApp();
- break;
-
- case this.areaUnlock:
- var passcodeOrUnlock = function passcodeOrUnlock() {
- if (!self.passCodeEnabled || !self._passCodeTimeoutCheck) {
- self.unlock();
- } else {
- self.switchPanel('passcode');
- }
- };
- passcodeOrUnlock();
- break;
- }
- },
-
- handlePassCodeInput: function ls_handlePassCodeInput(key) {
- switch (key) {
- case 'e': // Emergency Call
- this.switchPanel('emergency-call');
- break;
-
- case 'c':
- this.switchPanel();
- break;
-
- case 'b':
- if (this.overlay.dataset.passcodeStatus)
- return;
-
- this.passCodeEntered =
- this.passCodeEntered.substr(0, this.passCodeEntered.length - 1);
- this.updatePassCodeUI();
-
- break;
- default:
- if (this.overlay.dataset.passcodeStatus)
- return;
-
- this.passCodeEntered += key;
- this.updatePassCodeUI();
-
- if (this.passCodeEntered.length === 4)
- this.checkPassCode();
- break;
- }
- },
-
- lockIfEnabled: function ls_lockIfEnabled(instant) {
- if (this.enabled) {
- this.lock(instant);
- } else {
- this.unlock(instant);
- }
- },
-
- unlock: function ls_unlock(instant) {
- var currentApp = WindowManager.getDisplayedApp();
- WindowManager.setOrientationForApp(currentApp);
-
- var currentFrame = WindowManager.getAppFrame(currentApp).firstChild;
- var wasAlreadyUnlocked = !this.locked;
- this.locked = false;
- this.setElasticEnabled(false);
- this.mainScreen.focus();
-
- var repaintTimeout = 0;
- var nextPaint = (function() {
- clearTimeout(repaintTimeout);
- currentFrame.removeNextPaintListener(nextPaint);
-
- if (instant) {
- this.overlay.classList.add('no-transition');
- this.switchPanel();
- } else {
- this.overlay.classList.remove('no-transition');
- }
-
- this.mainScreen.classList.remove('locked');
-
- if (!wasAlreadyUnlocked) {
- // Any changes made to this,
- // also need to be reflected in apps/system/js/storage.js
- this.dispatchEvent('unlock');
- this.writeSetting(false);
-
- if (instant)
- return;
-
- if (this.unlockSoundEnabled) {
- var unlockAudio = new Audio('./resources/sounds/unlock.ogg');
- unlockAudio.play();
- }
- }
- }).bind(this);
-
- this.dispatchEvent('will-unlock');
- currentFrame.addNextPaintListener(nextPaint);
- repaintTimeout = setTimeout(function ensureUnlock() {
- nextPaint();
- }, 400);
- },
-
- lock: function ls_lock(instant) {
- var wasAlreadyLocked = this.locked;
- this.locked = true;
-
- this.updateTime();
-
- this.switchPanel();
-
- this.setElasticEnabled(ScreenManager.screenEnabled);
-
- this.overlay.focus();
- if (instant)
- this.overlay.classList.add('no-transition');
- else
- this.overlay.classList.remove('no-transition');
-
- this.mainScreen.classList.add('locked');
-
- screen.mozLockOrientation('portrait-primary');
-
- if (!wasAlreadyLocked) {
- if (document.mozFullScreen)
- document.mozCancelFullScreen();
-
- // Any changes made to this,
- // also need to be reflected in apps/system/js/storage.js
- this.dispatchEvent('lock');
- this.writeSetting(true);
- }
- },
-
- loadPanel: function ls_loadPanel(panel, callback) {
- this._loadingPanel = true;
- switch (panel) {
- case 'passcode':
- case 'main':
- if (callback)
- setTimeout(callback);
- break;
-
- case 'emergency-call':
- // create the <iframe> and load the emergency call
- var frame = document.createElement('iframe');
-
- frame.src = './emergency-call/index.html';
- frame.onload = function emergencyCallLoaded() {
- if (callback)
- callback();
- };
- this.panelEmergencyCall.appendChild(frame);
-
- break;
-
- case 'camera':
- // create the <iframe> and load the camera
- var frame = document.createElement('iframe');
-
- frame.src = './camera/index.html';
- var mainScreen = this.mainScreen;
- frame.onload = function cameraLoaded() {
- mainScreen.classList.add('lockscreen-camera');
- if (callback)
- callback();
- };
- this.overlay.classList.remove('no-transition');
- this.camera.appendChild(frame);
-
- break;
- }
- },
-
- unloadPanel: function ls_unloadPanel(panel, toPanel, callback) {
- switch (panel) {
- case 'passcode':
- // Reset passcode panel only if the status is not error
- if (this.overlay.dataset.passcodeStatus == 'error')
- break;
-
- delete this.overlay.dataset.passcodeStatus;
- this.passCodeEntered = '';
- this.updatePassCodeUI();
- break;
-
- case 'camera':
- this.mainScreen.classList.remove('lockscreen-camera');
- break;
-
- case 'emergency-call':
- var ecPanel = this.panelEmergencyCall;
- ecPanel.addEventListener('transitionend', function unloadPanel() {
- ecPanel.removeEventListener('transitionend', unloadPanel);
- ecPanel.removeChild(ecPanel.firstElementChild);
- });
- break;
-
- case 'main':
- default:
- var self = this;
- var unload = function unload() {
- self.areaHandle.style.transform =
- self.areaUnlock.style.transform =
- self.areaCamera.style.transform =
- self.iconContainer.style.transform =
- self.iconContainer.style.opacity =
- self.areaHandle.style.opacity =
- self.areaUnlock.style.opacity =
- self.areaCamera.style.opacity = '';
- self.overlay.classList.remove('triggered');
- self.areaHandle.classList.remove('triggered');
- self.areaCamera.classList.remove('triggered');
- self.areaUnlock.classList.remove('triggered');
-
- clearTimeout(self.triggeredTimeoutId);
- self.setElasticEnabled(false);
- };
-
- if (toPanel !== 'camera') {
- unload();
- break;
- }
-
- this.overlay.addEventListener('transitionend',
- function ls_unloadDefaultPanel(evt) {
- if (evt.target !== this)
- return;
-
- self.overlay.removeEventListener('transitionend',
- ls_unloadDefaultPanel);
- unload();
- }
- );
-
- break;
- }
-
- if (callback)
- setTimeout(callback);
- },
-
- switchPanel: function ls_switchPanel(panel) {
- if (this._switchingPanel) {
- return;
- }
-
- var overlay = this.overlay;
- var self = this;
- panel = panel || 'main';
-
- this._switchingPanel = true;
- this.loadPanel(panel, function panelLoaded() {
- self.unloadPanel(overlay.dataset.panel, panel,
- function panelUnloaded() {
- if (overlay.dataset.panel !== panel)
- self.dispatchEvent('lockpanelchange');
-
- overlay.dataset.panel = panel;
- self._switchingPanel = false;
- });
- });
- },
-
- updateTime: function ls_updateTime() {
- if (!this.locked)
- return;
-
- var d = new Date();
- var f = new navigator.mozL10n.DateTimeFormat();
- var _ = navigator.mozL10n.get;
-
- var timeFormat = _('shortTimeFormat') || '%H:%M';
- var dateFormat = _('longDateFormat') || '%A %e %B';
- var time = f.localeFormat(d, timeFormat);
- this.clockNumbers.textContent = time.match(/([012]?\d).[0-5]\d/g);
- this.clockMeridiem.textContent = (time.match(/AM|PM/i) || []).join('');
- this.date.textContent = f.localeFormat(d, dateFormat);
-
- var self = this;
- window.setTimeout(function ls_clockTimeout() {
- self.updateTime();
- }, (59 - d.getSeconds()) * 1000);
- },
-
- updateConnState: function ls_updateConnState() {
- var conn = window.navigator.mozMobileConnection;
- if (!conn)
- return;
-
- var voice = conn.voice;
- var iccInfo = conn.iccInfo;
- var connstateLine1 = this.connstate.firstElementChild;
- var connstateLine2 = this.connstate.lastElementChild;
- var _ = navigator.mozL10n.get;
-
- var updateConnstateLine1 = function updateConnstateLine1(l10nId) {
- connstateLine1.dataset.l10nId = l10nId;
- connstateLine1.textContent = _(l10nId) || '';
- };
-
- var self = this;
- var updateConnstateLine2 = function updateConnstateLine2(l10nId) {
- if (l10nId) {
- self.connstate.classList.add('twolines');
- connstateLine2.dataset.l10nId = l10nId;
- connstateLine2.textContent = _(l10nId) || '';
- } else {
- self.connstate.classList.remove('twolines');
- delete(connstateLine2.dataset.l10nId);
- connstateLine2.textContent = '';
- }
- };
-
- // Reset line 2
- updateConnstateLine2();
-
- if (this.airplaneMode) {
- updateConnstateLine1('airplaneMode');
- return;
- }
-
- // Possible value of voice.state are:
- // 'notSearching', 'searching', 'denied', 'registered',
- // where the latter three mean the phone is trying to grab the network.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=777057
- if (voice.state == 'notSearching') {
- updateConnstateLine1('noNetwork');
- return;
- }
-
- if (!voice.connected && !voice.emergencyCallsOnly) {
- // "Searching"
- // voice.state can be any of the latter three values.
- // (it's possible that the phone is briefly 'registered'
- // but not yet connected.)
- updateConnstateLine1('searching');
- return;
- }
-
- if (voice.emergencyCallsOnly) {
- updateConnstateLine1('emergencyCallsOnly');
-
- switch (conn.cardState) {
- case 'absent':
- updateConnstateLine2('emergencyCallsOnly-noSIM');
- break;
-
- case 'pinRequired':
- updateConnstateLine2('emergencyCallsOnly-pinRequired');
- break;
-
- case 'pukRequired':
- updateConnstateLine2('emergencyCallsOnly-pukRequired');
- break;
-
- case 'networkLocked':
- updateConnstateLine2('emergencyCallsOnly-networkLocked');
- break;
-
- default:
- updateConnstateLine2();
- break;
- }
- return;
- }
-
- var operatorInfos = MobileOperator.userFacingInfo(conn);
- if (this.cellbroadcastLabel) {
- connstateLine2.textContent = this.cellbroadcastLabel;
- } else if (operatorInfos.carrier) {
- connstateLine2.textContent = operatorInfos.carrier + ' ' +
- operatorInfos.region;
- }
-
- var operator = operatorInfos.operator;
-
- if (voice.roaming) {
- var l10nArgs = { operator: operator };
- connstateLine1.dataset.l10nId = 'roaming';
- connstateLine1.dataset.l10nArgs = JSON.stringify(l10nArgs);
- connstateLine1.textContent = _('roaming', l10nArgs);
-
- return;
- }
-
- delete connstateLine1.dataset.l10nId;
- connstateLine1.textContent = operator;
- },
-
- updatePassCodeUI: function lockscreen_updatePassCodeUI() {
- var overlay = this.overlay;
- if (overlay.dataset.passcodeStatus)
- return;
- if (this.passCodeEntered) {
- overlay.classList.add('passcode-entered');
- } else {
- overlay.classList.remove('passcode-entered');
- }
- var i = 4;
- while (i--) {
- var span = this.passcodeCode.childNodes[i];
- if (this.passCodeEntered.length > i) {
- span.dataset.dot = true;
- } else {
- delete span.dataset.dot;
- }
- }
- },
-
- checkPassCode: function lockscreen_checkPassCode() {
- if (this.passCodeEntered === this.passCode) {
- var self = this;
- this.overlay.dataset.passcodeStatus = 'success';
- this.passCodeError = 0;
-
- var transitionend = function() {
- self.passcodeCode.removeEventListener('transitionend', transitionend);
- self.unlock();
- };
- this.passcodeCode.addEventListener('transitionend', transitionend);
- } else {
- this.overlay.dataset.passcodeStatus = 'error';
- if ('vibrate' in navigator)
- navigator.vibrate([50, 50, 50]);
-
- var self = this;
- setTimeout(function error() {
- delete self.overlay.dataset.passcodeStatus;
- self.passCodeEntered = '';
- self.updatePassCodeUI();
- }, this.kPassCodeErrorTimeout);
- }
- },
-
- updateBackground: function ls_updateBackground(background_datauri) {
- this._imgPreload([background_datauri, 'style/lockscreen/images/mask.png'],
- function(images) {
-
- // Bug 829075 : We need a <canvas> in the DOM to prevent banding on
- // Otoro-like devices
- var canvas = document.createElement('canvas');
- canvas.classList.add('lockscreen-wallpaper');
- canvas.width = images[0].width;
- canvas.height = images[0].height;
-
- var ctx = canvas.getContext('2d');
- ctx.drawImage(images[0], 0, 0);
- ctx.drawImage(images[1], 0, 0);
-
- var panels_selector = '.lockscreen-panel[data-wallpaper]';
- var panels = document.querySelectorAll(panels_selector);
- for (var i = 0, il = panels.length; i < il; i++) {
- var copied_canvas;
- var panel = panels[i];
-
- // Remove previous <canvas> if they exist
- var old_canvas = panel.querySelector('canvas');
- if (old_canvas) {
- old_canvas.parentNode.removeChild(old_canvas);
- }
-
- // For the first panel, we can use the existing <canvas>
- if (!copied_canvas) {
- copied_canvas = canvas;
- } else {
- // Otherwise, copy the node and content
- copied_canvas = canvas.cloneNode();
- copied_canvas.getContext('2d').drawImage(canvas, 0, 0);
- }
-
- panel.insertBefore(copied_canvas, panel.firstChild);
- }
- });
- },
-
- _imgPreload: function ls_imgPreload(img_paths, callback) {
- var loaded = 0;
- var images = [];
- var il = img_paths.length;
- var inc = function() {
- loaded += 1;
- if (loaded === il && callback) {
- callback(images);
- }
- };
- for (var i = 0; i < il; i++) {
- images[i] = new Image();
- images[i].onload = inc;
- images[i].src = img_paths[i];
- }
- },
-
- getAllElements: function ls_getAllElements() {
- // ID of elements to create references
- var elements = ['connstate', 'mute', 'clock-numbers', 'clock-meridiem',
- 'date', 'area', 'area-unlock', 'area-camera', 'icon-container',
- 'area-handle', 'passcode-code',
- 'passcode-pad', 'camera', 'accessibility-camera',
- 'accessibility-unlock', 'panel-emergency-call'];
-
- var toCamelCase = function toCamelCase(str) {
- return str.replace(/\-(.)/g, function replacer(str, p1) {
- return p1.toUpperCase();
- });
- };
-
- elements.forEach((function createElementRef(name) {
- this[toCamelCase(name)] = document.getElementById('lockscreen-' + name);
- }).bind(this));
-
- this.overlay = document.getElementById('lockscreen');
- this.mainScreen = document.getElementById('screen');
- },
-
- dispatchEvent: function ls_dispatchEvent(name) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent(name, true, true, null);
- window.dispatchEvent(evt);
- },
-
- writeSetting: function ls_writeSetting(value) {
- if (!window.navigator.mozSettings)
- return;
-
- SettingsListener.getSettingsLock().set({
- 'lockscreen.locked': value
- });
- },
-
- setElasticEnabled: function ls_setElasticEnabled(value) {
- clearInterval(this.elasticIntervalId);
- if (value) {
- this.elasticIntervalId =
- setInterval(this.playElastic.bind(this), this.ELASTIC_INTERVAL);
- }
- },
-
- playElastic: function ls_playElastic() {
- if (this._touch && this._touch.touched)
- return;
-
- var overlay = this.overlay;
- var container = this.iconContainer;
-
- overlay.classList.add('elastic');
- container.addEventListener('animationend', function animationend(e) {
- container.removeEventListener(e.type, animationend);
- overlay.classList.remove('elastic');
- });
- }
-};
-
-// Bug 836195 - [Homescreen] Dock icons drop down in the UI
-// consistently when using a lockcode and visiting camera
-LockScreen.init();
-
-navigator.mozL10n.ready(LockScreen.init.bind(LockScreen));
-
diff --git a/apps/system/js/modal_dialog.js b/apps/system/js/modal_dialog.js
deleted file mode 100644
index 33f3201..0000000
--- a/apps/system/js/modal_dialog.js
+++ /dev/null
@@ -1,443 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-// The modal dialog listen to mozbrowsershowmodalprompt event.
-// Blocking the current app and then show cutom modal dialog
-// (alert/confirm/prompt)
-
-var ModalDialog = {
- // Used for element id access.
- // e.g., 'modal-dialog-alert-ok'
- prefix: 'modal-dialog-',
-
- // DOM
- elements: {},
-
- // Get all elements when inited.
- getAllElements: function md_getAllElements() {
- var elementsID = ['alert', 'alert-ok', 'alert-message',
- 'prompt', 'prompt-ok', 'prompt-cancel', 'prompt-input', 'prompt-message',
- 'confirm', 'confirm-ok', 'confirm-cancel', 'confirm-message',
- 'select-one', 'select-one-cancel', 'select-one-menu', 'select-one-title',
- 'alert-title', 'confirm-title', 'prompt-title'];
-
- var toCamelCase = function toCamelCase(str) {
- return str.replace(/\-(.)/g, function replacer(str, p1) {
- return p1.toUpperCase();
- });
- };
-
- // Loop and add element with camel style name to Modal Dialog attribute.
- elementsID.forEach(function createElementRef(name) {
- this.elements[toCamelCase(name)] =
- document.getElementById(this.prefix + name);
- }, this);
-
- this.screen = document.getElementById('screen');
- this.overlay = document.getElementById('dialog-overlay');
- },
-
- // Save the events returned by mozbrowsershowmodalprompt for later use.
- // The events are stored according to webapp origin
- // e.g., 'http://uitest.gaiamobile.org': evt
- currentEvents: {},
-
- init: function md_init() {
- // Get all elements initially.
- this.getAllElements();
- var elements = this.elements;
-
- // Bind events
- window.addEventListener('mozbrowsershowmodalprompt', this);
- window.addEventListener('appopen', this);
- window.addEventListener('appwillclose', this);
- window.addEventListener('appterminated', this);
- window.addEventListener('resize', this);
- window.addEventListener('keyboardchange', this);
- window.addEventListener('keyboardhide', this);
- window.addEventListener('home', this);
- window.addEventListener('holdhome', this);
-
- for (var id in elements) {
- var tagName = elements[id].tagName.toLowerCase();
- if (tagName == 'button' || tagName == 'ul') {
- elements[id].addEventListener('click', this);
- }
- }
- },
-
- // Default event handler
- handleEvent: function md_handleEvent(evt) {
- var elements = this.elements;
- switch (evt.type) {
- case 'mozbrowsershowmodalprompt':
- var frameType = evt.target.dataset.frameType;
- if (frameType != 'window' && frameType != 'inline-activity')
- return;
-
- evt.preventDefault();
- var origin = evt.target.dataset.frameOrigin;
- this.currentEvents[origin] = evt;
-
- // Show modal dialog only if
- // the frame is currently displayed.
- if (origin == WindowManager.getDisplayedApp() ||
- frameType == 'inline-activity')
- this.show(evt.target, origin);
- break;
-
- case 'click':
- if (evt.currentTarget === elements.confirmCancel ||
- evt.currentTarget === elements.promptCancel ||
- evt.currentTarget === elements.selectOneCancel) {
- this.cancelHandler();
- } else if (evt.currentTarget === elements.selectOneMenu) {
- this.selectOneHandler(evt.target);
- } else {
- this.confirmHandler();
- }
- break;
-
- case 'appopen':
- this.show(evt.target, evt.detail.origin);
- break;
-
- case 'home':
- case 'holdhome':
- // Inline activity, which origin is different from foreground app
- if (this.isVisible() &&
- this.currentOrigin != WindowManager.getDisplayedApp())
- this.cancelHandler();
- break;
-
- case 'appwillclose':
- // Do nothing if the app is closed at background.
- if (evt.detail.origin !== this.currentOrigin)
- return;
-
- // Reset currentOrigin
- this.hide();
- break;
-
- case 'appterminated':
- if (this.currentEvents[evt.detail.origin])
- delete this.currentEvents[evt.detail.origin];
-
- break;
-
- case 'resize':
- case 'keyboardhide':
- if (!this.currentOrigin)
- return;
-
- this.setHeight(window.innerHeight - StatusBar.height);
- break;
-
- case 'keyboardchange':
- this.setHeight(window.innerHeight -
- evt.detail.height - StatusBar.height);
- break;
- }
- },
-
- setHeight: function md_setHeight(height) {
- if (this.isVisible())
- this.overlay.style.height = height + 'px';
- },
-
- // Show relative dialog and set message/input value well
- show: function md_show(target, origin) {
- if (!(origin in this.currentEvents))
- return;
-
- var _ = navigator.mozL10n.get;
- var evt = this.currentEvents[origin];
- this.currentOrigin = origin;
-
- var message = evt.detail.message || '';
- var elements = this.elements;
- this.screen.classList.add('modal-dialog');
-
- function escapeHTML(str) {
- var span = document.createElement('span');
- span.textContent = str;
- // Escape space for displaying multiple space in message.
- span.innerHTML = span.innerHTML.replace(/\n/g, '<br/>');
- return span.innerHTML;
- }
-
- var type = evt.detail.promptType || evt.detail.type;
- if (type !== 'selectone') {
- message = escapeHTML(message);
- }
-
- switch (type) {
- case 'alert':
- elements.alertMessage.innerHTML = message;
- elements.alert.classList.add('visible');
- this.setTitle('alert', '');
- elements.alertOk.textContent = evt.yesText ? evt.yesText : _('ok');
- break;
-
- case 'prompt':
- elements.prompt.classList.add('visible');
- elements.promptInput.value = evt.detail.initialValue;
- elements.promptMessage.innerHTML = message;
- this.setTitle('prompt', '');
- elements.promptOk.textContent = evt.yesText ? evt.yesText : _('ok');
- elements.promptCancel.textContent = evt.noText ?
- evt.noText : _('cancel');
- break;
-
- case 'confirm':
- elements.confirm.classList.add('visible');
- elements.confirmMessage.innerHTML = message;
- this.setTitle('confirm', '');
- elements.confirmOk.textContent = evt.yesText ? evt.yesText : _('ok');
- elements.confirmCancel.textContent = evt.noText ?
- evt.noText : _('cancel');
- break;
-
- case 'selectone':
- this.buildSelectOneDialog(message);
- elements.selectOne.classList.add('visible');
- break;
- }
-
- this.setHeight(window.innerHeight - StatusBar.height);
- },
-
- hide: function md_hide() {
- var evt = this.currentEvents[this.currentOrigin];
- var type = evt.detail.promptType;
- if (type == 'prompt') {
- this.elements.promptInput.blur();
- }
- this.currentOrigin = null;
- this.screen.classList.remove('modal-dialog');
- this.elements[type].classList.remove('visible');
- },
-
- setTitle: function md_setTitle(type, title) {
- this.elements[type + 'Title'].textContent = title;
- },
-
- // When user clicks OK button on alert/confirm/prompt
- confirmHandler: function md_confirmHandler() {
- this.screen.classList.remove('modal-dialog');
- var elements = this.elements;
-
- var evt = this.currentEvents[this.currentOrigin];
-
- var type = evt.detail.promptType || evt.detail.type;
- switch (type) {
- case 'alert':
- elements.alert.classList.remove('visible');
- break;
-
- case 'prompt':
- evt.detail.returnValue = elements.promptInput.value;
- elements.prompt.classList.remove('visible');
- break;
-
- case 'confirm':
- evt.detail.returnValue = true;
- elements.confirm.classList.remove('visible');
- break;
- }
-
- if (evt.isPseudo && evt.callback) {
- evt.callback(evt.detail.returnValue);
- }
-
- if (evt.detail.unblock)
- evt.detail.unblock();
-
- delete this.currentEvents[this.currentOrigin];
- },
-
- // When user clicks cancel button on confirm/prompt or
- // when the user try to escape the dialog with the escape key
- cancelHandler: function md_cancelHandler() {
- var evt = this.currentEvents[this.currentOrigin];
- this.screen.classList.remove('modal-dialog');
- var elements = this.elements;
-
- var type = evt.detail.promptType || evt.detail.type;
- switch (type) {
- case 'alert':
- elements.alert.classList.remove('visible');
- break;
-
- case 'prompt':
- /* return null when click cancel */
- evt.detail.returnValue = null;
- elements.prompt.classList.remove('visible');
- break;
-
- case 'confirm':
- /* return false when click cancel */
- evt.detail.returnValue = false;
- elements.confirm.classList.remove('visible');
- break;
-
- case 'selectone':
- /* return null when click cancel */
- evt.detail.returnValue = null;
- elements.selectOne.classList.remove('visible');
- break;
- }
-
- if (evt.isPseudo && evt.cancelCallback) {
- evt.cancelCallback(evt.detail.returnValue);
- }
-
- if (evt.detail.unblock)
- evt.detail.unblock();
-
- delete this.currentEvents[this.currentOrigin];
- },
-
- // When user selects an option on selectone dialog
- selectOneHandler: function md_confirmHandler(target) {
- this.screen.classList.remove('modal-dialog');
- var elements = this.elements;
-
- var evt = this.currentEvents[this.currentOrigin];
-
- evt.detail.returnValue = target.id;
- elements.selectOne.classList.remove('visible');
-
- if (evt.isPseudo && evt.callback) {
- evt.callback(evt.detail.returnValue);
- }
-
- if (evt.detail.unblock)
- evt.detail.unblock();
-
- delete this.currentEvents[this.currentOrigin];
- },
-
- buildSelectOneDialog: function md_buildSelectOneDialog(data) {
- var elements = this.elements;
- elements.selectOneTitle.textContent = data.title;
- elements.selectOneMenu.innerHTML = '';
-
- if (!data.options) {
- return;
- }
-
- var itemsHTML = [];
- for (var i = 0; i < data.options.length; i++) {
- itemsHTML.push('<li><button id="');
- itemsHTML.push(data.options[i].id);
- itemsHTML.push('">');
- itemsHTML.push(data.options[i].text);
- itemsHTML.push('</button></li>');
- }
-
- elements.selectOneMenu.innerHTML = itemsHTML.join('');
- },
-
- /**
- * Method about customized alert
- * @param {String} title the title of the dialog. null or empty for
- * no title.
- * @param {String} text message for the dialog.
- * @param {Object} confirm {title, callback} object when confirm.
- */
- alert: function md_alert(title, text, confirm) {
- this.showWithPseudoEvent({
- type: 'alert',
- text: text,
- callback: confirm.callback,
- title: title,
- yesText: confirm.title
- });
- },
-
- /**
- * Method about customized confirm
- * @param {String} title the title of the dialog. null or empty for
- * no title.
- * @param {String} text message for the dialog.
- * @param {Object} confirm {title, callback} object when confirm.
- * @param {Object} cancel {title, callback} object when cancel.
- */
- confirm: function md_confirm(title, text, confirm, cancel) {
- this.showWithPseudoEvent({
- type: 'confirm',
- text: text,
- callback: confirm.callback,
- cancel: cancel.callback,
- title: title,
- yesText: confirm.title,
- noText: cancel.title
- });
- },
-
- /**
- * Method about customized prompt
- * @param {String} title the title of the dialog. null or empty for
- * no title.
- * @param {String} text message for the dialog.
- * @param {String} default_value message in the text field.
- * @param {Object} confirm {title, callback} object when confirm.
- * @param {Object} cancel {title, callback} object when cancel.
- */
- prompt: function md_prompt(title, text, default_value, confirm, cancel) {
- this.showWithPseudoEvent({
- type: 'prompt',
- text: text,
- initialValue: default_value,
- callback: confirm.callback,
- cancel: cancel.callback,
- title: title,
- yesText: confirm.title,
- noText: cancel.title
- });
- },
-
- selectOne: function md_selectOne(data, callback) {
- this.showWithPseudoEvent({
- type: 'selectone',
- text: data,
- callback: callback
- });
- },
-
- showWithPseudoEvent: function md_showWithPseudoEvent(config) {
- var pseudoEvt = {
- isPseudo: true,
- detail: {
- unblock: null
- }
- };
-
- pseudoEvt.detail.message = config.text;
- pseudoEvt.callback = config.callback;
- pseudoEvt.detail.promptType = config.type;
- pseudoEvt.cancelCallback = config.cancel;
- pseudoEvt.yesText = config.yesText;
- pseudoEvt.noText = config.noText;
- if (config.type == 'prompt') {
- pseudoEvt.detail.initialValue = config.initialValue;
- }
-
- // Create a virtual mapping in this.currentEvents,
- // since system-app uses the different way to call ModalDialog.
- this.currentEvents['system'] = pseudoEvt;
- this.show(null, 'system');
- if (config.title)
- this.setTitle(config.type, config.title);
- },
-
- isVisible: function md_isVisible() {
- return this.screen.classList.contains('modal-dialog');
- }
-};
-
-ModalDialog.init();
-
diff --git a/apps/system/js/mouse2touch.js b/apps/system/js/mouse2touch.js
deleted file mode 100644
index b9d6a89..0000000
--- a/apps/system/js/mouse2touch.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-/*
-* Mouse2Touch is a shim that listens to MouseEvent but passes
-* fake TouchEvent object to touch event handler
-*
-* XXX: remove this if we are not going to support testing on
-* non-touch devices, e.g. B2G Desktop, Nightly, or,
-* make the creation of this object optional if we can reliably detect
-* touch support by evaluate (document instanceof DocumentTouch)
-*
-*/
-var Mouse2Touch = (function m2t() {
- var Mouse2TouchEvent = {
- 'mousedown': 'touchstart',
- 'mousemove': 'touchmove',
- 'mouseup': 'touchend'
- };
-
- var Touch2MouseEvent = {
- 'touchstart': 'mousedown',
- 'touchmove': 'mousemove',
- 'touchend': 'mouseup'
- };
-
- var ForceOnWindow = {
- 'touchmove': true,
- 'touchend': true
- };
-
- var addEventHandler = function m2t_addEventHandlers(target,
- name,
- listener) {
- target = ForceOnWindow[name] ? window : target;
- name = Touch2MouseEvent[name] || name;
- target.addEventListener(name, {
- handleEvent: function m2t_handleEvent(evt) {
- if (Mouse2TouchEvent[evt.type]) {
- var original = evt;
- evt = {
- type: Mouse2TouchEvent[original.type],
- target: original.target,
- touches: [original],
- preventDefault: function() {
- original.preventDefault();
- }
- };
- evt.changedTouches = evt.touches;
- }
- return listener.handleEvent(evt);
- }
- }, true);
- };
-
- var removeEventHandler = function m2t_removeEventHandler(target,
- name,
- listener) {
- target = ForceOnWindow[name] ? window : target;
- name = Touch2MouseEvent[name] || name;
- target.removeEventListener(name, listener);
- };
-
- return {
- addEventHandler: addEventHandler,
- removeEventHandler: removeEventHandler
- };
-})();
diff --git a/apps/system/js/notifications.js b/apps/system/js/notifications.js
deleted file mode 100644
index dae4ab4..0000000
--- a/apps/system/js/notifications.js
+++ /dev/null
@@ -1,410 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-(function appCacheIcons() {
- // Caching the icon for notification if appCache is in effect
- var appCache = window.applicationCache;
- if (!appCache)
- return;
-
- var addIcons = function addIcons(app) {
- var icons = app.manifest.icons;
- if (icons) {
- Object.keys(icons).forEach(function iconIterator(key) {
- var url = app.origin + icons[key];
- appCache.mozAdd(url);
- });
- }
- };
-
- var removeIcons = function removeIcons(app) {
- var icons = app.manifest.icons;
- if (icons) {
- Object.keys(icons).forEach(function iconIterator(key) {
- var url = app.origin + icons[key];
- appCache.mozRemove(url);
- });
- }
- };
-
- window.addEventListener('applicationinstall', function bsm_oninstall(evt) {
- addIcons(evt.detail.application);
- });
-
- window.addEventListener('applicationuninstall', function bsm_oninstall(evt) {
- removeIcons(evt.detail.application);
- });
-}());
-
-var NotificationScreen = {
- TOASTER_TIMEOUT: 5000,
- TRANSITION_SPEED: 1.8,
- TRANSITION_FRACTION: 0.30,
-
- _notification: null,
- _containerWidth: null,
- _toasterTimeout: null,
- _toasterGD: null,
-
- lockscreenPreview: true,
- silent: false,
- alerts: true,
- vibrates: true,
-
- init: function ns_init() {
- window.addEventListener('mozChromeEvent', this);
- this.container =
- document.getElementById('desktop-notifications-container');
- this.lockScreenContainer =
- document.getElementById('notifications-lockscreen-container');
- this.toaster = document.getElementById('notification-toaster');
- this.toasterIcon = document.getElementById('toaster-icon');
- this.toasterTitle = document.getElementById('toaster-title');
- this.toasterDetail = document.getElementById('toaster-detail');
- this.clearAllButton = document.getElementById('notification-clear');
-
- this._toasterGD = new GestureDetector(this.toaster);
- ['tap', 'mousedown', 'swipe'].forEach(function(evt) {
- this.container.addEventListener(evt, this);
- this.toaster.addEventListener(evt, this);
- }, this);
-
- this.clearAllButton.addEventListener('click', this.clearAll.bind(this));
-
- // will hold the count of external contributors to the notification
- // screen
- this.externalNotificationsCount = 0;
-
- window.addEventListener('utilitytrayshow', this);
- window.addEventListener('unlock', this.clearLockScreen.bind(this));
- window.addEventListener('mozvisibilitychange', this);
- window.addEventListener('appopen', this.handleAppopen.bind(this));
-
- this._sound = 'style/notifications/ringtones/notifier_exclamation.ogg';
-
- var self = this;
- SettingsListener.observe('notification.ringtone', '', function(value) {
- self._sound = value;
- });
- },
-
- handleEvent: function ns_handleEvent(evt) {
- switch (evt.type) {
- case 'mozChromeEvent':
- var detail = evt.detail;
- if (detail.type !== 'desktop-notification')
- return;
-
- this.addNotification(detail);
- break;
- case 'tap':
- var target = evt.target;
- this.tap(target);
- break;
- case 'mousedown':
- this.mousedown(evt);
- break;
- case 'swipe':
- this.swipe(evt);
- break;
- case 'utilitytrayshow':
- this.updateTimestamps();
- StatusBar.updateNotificationUnread(false);
- break;
- case 'mozvisibilitychange':
- //update timestamps in lockscreen notifications
- if (!document.mozHidden) {
- this.updateTimestamps();
- }
- break;
- }
- },
-
- handleAppopen: function ns_handleAppopen(evt) {
- var manifestURL = evt.detail.manifestURL,
- selector = '[data-manifest-u-r-l="' + manifestURL + '"]';
-
- var nodes = this.container.querySelectorAll(selector);
-
- for (var i = nodes.length - 1; i >= 0; i--) {
- this.closeNotification(nodes[i]);
- }
- },
-
- // Swipe handling
- mousedown: function ns_mousedown(evt) {
- if (!evt.target.dataset.notificationID)
- return;
-
- evt.preventDefault();
- this._notification = evt.target;
- this._containerWidth = this.container.clientWidth;
- },
-
- swipe: function ns_swipe(evt) {
- var detail = evt.detail;
- var distance = detail.start.screenX - detail.end.screenX;
- var fastEnough = Math.abs(detail.vx) > this.TRANSITION_SPEED;
- var farEnough = Math.abs(distance) >
- this._containerWidth * this.TRANSITION_FRACTION;
-
- // We only remove the notification if the swipe was
- // - left to right
- // - far or fast enough
- if ((distance > 0) ||
- !(farEnough || fastEnough)) {
- // Werent far or fast enough to delete, restore
- delete this._notification;
- return;
- }
-
- this._notification.classList.add('disappearing');
-
- var notification = this._notification;
- this._notification = null;
-
- var toaster = this.toaster;
- var self = this;
- notification.addEventListener('transitionend', function trListener() {
- notification.removeEventListener('transitionend', trListener);
-
- self.closeNotification(notification);
-
- if (notification != toaster)
- return;
-
- // Putting back the toaster in a clean state for the next notification
- toaster.style.display = 'none';
- setTimeout(function nextLoop() {
- toaster.style.MozTransition = '';
- toaster.style.MozTransform = '';
- toaster.classList.remove('displayed');
- toaster.classList.remove('disappearing');
-
- setTimeout(function nextLoop() {
- toaster.style.display = 'block';
- });
- });
- });
- },
-
- tap: function ns_tap(notificationNode) {
- var notificationID = notificationNode.dataset.notificationID;
-
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, {
- type: 'desktop-notification-click',
- id: notificationID
- });
- window.dispatchEvent(event);
-
- this.removeNotification(notificationNode.dataset.notificationID, false);
-
- if (notificationNode == this.toaster) {
- this.toaster.classList.remove('displayed');
- } else {
- UtilityTray.hide();
- }
- },
-
- updateTimestamps: function ns_updateTimestamps() {
- var timestamps = document.getElementsByClassName('timestamp');
- for (var i = 0, l = timestamps.length; i < l; i++) {
- timestamps[i].textContent =
- this.prettyDate(new Date(timestamps[i].dataset.timestamp));
- }
- },
-
- /**
- * Display a human-readable relative timestamp.
- */
- prettyDate: function prettyDate(time) {
- var date;
- if (navigator.mozL10n) {
- date = navigator.mozL10n.DateTimeFormat().fromNow(time, true);
- } else {
- date = time.toLocaleFormat();
- }
- return date;
- },
-
- addNotification: function ns_addNotification(detail) {
- var notificationNode = document.createElement('div');
- notificationNode.className = 'notification';
-
- notificationNode.dataset.notificationID = detail.id;
- notificationNode.dataset.manifestURL = detail.manifestURL;
-
- if (detail.icon) {
- var icon = document.createElement('img');
- icon.src = detail.icon;
- notificationNode.appendChild(icon);
- this.toasterIcon.src = detail.icon;
- this.toasterIcon.hidden = false;
- } else {
- this.toasterIcon.hidden = true
- }
-
- var time = document.createElement('span');
- var timestamp = new Date();
- time.classList.add('timestamp');
- time.dataset.timestamp = timestamp;
- time.textContent = this.prettyDate(timestamp);
- notificationNode.appendChild(time);
-
- var title = document.createElement('div');
- title.textContent = detail.title;
- notificationNode.appendChild(title);
-
- this.toasterTitle.textContent = detail.title;
-
- var message = document.createElement('div');
- message.classList.add('detail');
- message.textContent = detail.text;
- notificationNode.appendChild(message);
-
- this.toasterDetail.textContent = detail.text;
-
- this.container.insertBefore(notificationNode,
- this.container.firstElementChild);
- new GestureDetector(notificationNode).startDetecting();
-
- // We turn the screen on if needed in order to let
- // the user see the notification toaster
- if (typeof(ScreenManager) !== 'undefined' &&
- !ScreenManager.screenEnabled) {
- ScreenManager.turnScreenOn();
- }
-
- this.updateStatusBarIcon(true);
-
- // Notification toaster
- if (this.lockscreenPreview || !LockScreen.locked) {
- this.toaster.dataset.notificationID = detail.id;
-
- this.toaster.classList.add('displayed');
- this._toasterGD.startDetecting();
-
- if (this._toasterTimeout)
- clearTimeout(this._toasterTimeout);
-
- this._toasterTimeout = setTimeout((function() {
- this.toaster.classList.remove('displayed');
- this._toasterTimeout = null;
- this._toasterGD.stopDetecting();
- }).bind(this), this.TOASTER_TIMEOUT);
- }
-
- // Adding it to the lockscreen if locked and the privacy setting
- // does not prevent it.
- if (typeof(LockScreen) !== 'undefined' &&
- LockScreen.locked && this.lockscreenPreview) {
- var lockScreenNode = notificationNode.cloneNode(true);
- this.lockScreenContainer.insertBefore(lockScreenNode,
- this.lockScreenContainer.firstElementChild);
- }
-
- if (this.alerts && !this.silent) {
- var ringtonePlayer = new Audio();
- ringtonePlayer.src = this._sound;
- ringtonePlayer.mozAudioChannelType = 'notification';
- ringtonePlayer.play();
- window.setTimeout(function smsRingtoneEnder() {
- ringtonePlayer.pause();
- ringtonePlayer.src = '';
- }, 2000);
- }
-
- if (this.vibrates) {
- if (document.mozHidden) {
- window.addEventListener('mozvisibilitychange', function waitOn() {
- window.removeEventListener('mozvisibilitychange', waitOn);
- navigator.vibrate([200, 200, 200, 200]);
- });
- } else {
- navigator.vibrate([200, 200, 200, 200]);
- }
- }
-
- return notificationNode;
- },
-
- closeNotification: function ns_closeNotification(notificationNode) {
- var notificationID = notificationNode.dataset.notificationID;
-
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, {
- type: 'desktop-notification-close',
- id: notificationID
- });
- window.dispatchEvent(event);
-
- this.removeNotification(notificationNode.dataset.notificationID);
- },
-
- removeNotification: function ns_removeNotification(notificationID) {
- var notifSelector = '[data-notification-i-d="' + notificationID + '"]';
- var notificationNode = this.container.querySelector(notifSelector);
-
- notificationNode.parentNode.removeChild(notificationNode);
- this.updateStatusBarIcon();
- },
-
- clearAll: function ns_clearAll() {
- while (this.container.firstElementChild) {
- this.closeNotification(this.container.firstElementChild);
- }
- },
-
- clearLockScreen: function ns_clearLockScreen() {
- while (this.lockScreenContainer.firstElementChild) {
- var element = this.lockScreenContainer.firstElementChild;
- this.lockScreenContainer.removeChild(element);
- }
- },
-
- updateStatusBarIcon: function ns_updateStatusBarIcon(unread) {
- var nbTotalNotif = this.container.children.length +
- this.externalNotificationsCount;
- StatusBar.updateNotification(nbTotalNotif);
-
- if (unread)
- StatusBar.updateNotificationUnread(true);
- },
-
- incExternalNotifications: function ns_incExternalNotifications() {
- this.externalNotificationsCount++;
- this.updateStatusBarIcon(true);
- },
-
- decExternalNotifications: function ns_decExternalNotifications() {
- this.externalNotificationsCount--;
- if (this.externalNotificationsCount < 0) {
- this.externalNotificationsCount = 0;
- }
- this.updateStatusBarIcon();
- }
-
-};
-
-NotificationScreen.init();
-
-SettingsListener.observe(
- 'lockscreen.notifications-preview.enabled', true, function(value) {
-
- NotificationScreen.lockscreenPreview = value;
-});
-
-SettingsListener.observe('alert-sound.enabled', true, function(value) {
- NotificationScreen.alerts = value;
-});
-
-SettingsListener.observe('ring.enabled', true, function(value) {
- NotificationScreen.silent = !value;
-});
-
-SettingsListener.observe('alert-vibration.enabled', true, function(value) {
- NotificationScreen.vibrates = value;
-});
diff --git a/apps/system/js/operator_variant/operator_variant.js b/apps/system/js/operator_variant/operator_variant.js
deleted file mode 100644
index 13ad257..0000000
--- a/apps/system/js/operator_variant/operator_variant.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-(function OperatorVariant() {
- /**
- * Get the mcc/mnc info that has been stored in the settings.
- */
-
- var settings = window.navigator.mozSettings;
- if (!settings)
- return;
-
- var iccSettings = { mcc: -1, mnc: -1 };
-
- // Read the mcc/mnc settings, then trigger callback.
- function getICCSettings(callback) {
- var transaction = settings.createLock();
- var mccKey = 'operatorvariant.mcc';
- var mncKey = 'operatorvariant.mnc';
-
- var mccRequest = transaction.get(mccKey);
- mccRequest.onsuccess = function() {
- iccSettings.mcc = parseInt(mccRequest.result[mccKey], 10) || 0;
- var mncRequest = transaction.get(mncKey);
- mncRequest.onsuccess = function() {
- iccSettings.mnc = parseInt(mncRequest.result[mncKey], 10) || 0;
- callback();
- };
- };
- }
-
-
- /**
- * Compare the cached mcc/mnc info with the one in the SIM card,
- * and retrieve/apply APN settings if they differ.
- */
-
- var mobileConnection = window.navigator.mozMobileConnection;
- if (!mobileConnection)
- return;
-
- // Check the mcc/mnc information on the SIM card.
- function checkICCInfo() {
- if (!mobileConnection.iccInfo || mobileConnection.cardState !== 'ready')
- return;
-
- // ensure that the iccSettings have been retrieved
- if ((iccSettings.mcc < 0) || (iccSettings.mnc < 0))
- return;
-
- // XXX sometimes we get 0/0 for mcc/mnc, even when cardState === 'ready'...
- var mcc = parseInt(mobileConnection.iccInfo.mcc, 10) || 0;
- var mnc = parseInt(mobileConnection.iccInfo.mnc, 10) || 0;
- if (!mcc || !mnc)
- return;
-
- // same SIM card => do nothing
- if ((mcc == iccSettings.mcc) && (mnc == iccSettings.mnc))
- return;
-
- // new SIM card => cache iccInfo, load and apply new APN settings
- iccSettings.mcc = mcc;
- iccSettings.mnc = mnc;
- retrieveOperatorVariantSettings(applyOperatorVariantSettings);
- };
-
- // Load and query APN database, then trigger callback on results.
- function retrieveOperatorVariantSettings(callback) {
- var OPERATOR_VARIANT_FILE = 'shared/resources/apn.json';
-
- var xhr = new XMLHttpRequest();
- xhr.open('GET', OPERATOR_VARIANT_FILE, true);
- xhr.responseType = 'json';
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status === 0)) {
- var apn = xhr.response;
- var mcc = iccSettings.mcc;
- var mnc = iccSettings.mnc;
- // get a list of matching APNs
- var compatibleAPN = apn[mcc] ? (apn[mcc][mnc] || []) : [];
- callback(compatibleAPN);
- }
- };
- xhr.send();
- }
-
- // Store APN settings for the first carrier matching the mcc/mnc info.
- function applyOperatorVariantSettings(result) {
- var apnPrefNames = {
- 'default': {
- 'ril.data.carrier': 'carrier',
- 'ril.data.apn': 'apn',
- 'ril.data.user': 'user',
- 'ril.data.passwd': 'password',
- 'ril.data.httpProxyHost': 'proxy',
- 'ril.data.httpProxyPort': 'port'
- },
- 'supl': {
- 'ril.supl.carrier': 'carrier',
- 'ril.supl.apn': 'apn',
- 'ril.supl.user': 'user',
- 'ril.supl.passwd': 'password',
- 'ril.supl.httpProxyHost': 'proxy',
- 'ril.supl.httpProxyPort': 'port'
- },
- 'mms': {
- 'ril.mms.carrier': 'carrier',
- 'ril.mms.apn': 'apn',
- 'ril.mms.user': 'user',
- 'ril.mms.passwd': 'password',
- 'ril.mms.httpProxyHost': 'proxy',
- 'ril.mms.httpProxyPort': 'port',
- 'ril.mms.mmsc': 'mmsc',
- 'ril.mms.mmsproxy': 'mmsproxy',
- 'ril.mms.mmsport': 'mmsport'
- },
- 'operatorvariant': {
- 'ril.iccInfo.mbdn': 'voicemail',
- 'ril.sms.strict7BitEncoding.enabled': 'enableStrict7BitEncodingForSms',
- 'ril.cellbroadcast.searchlist': 'cellBroadcastSearchList'
- }
- };
-
- var booleanPrefNames = [
- 'ril.sms.strict7BitEncoding.enabled'
- ];
-
- // store relevant APN settings
- var transaction = settings.createLock();
- for (var type in apnPrefNames) {
- var apn = {};
- for (var i = 0; i < result.length; i++) {
- if (result[i] && result[i].type.indexOf(type) != -1) {
- apn = result[i];
- break;
- }
- }
- var prefNames = apnPrefNames[type];
- for (var key in prefNames) {
- var name = apnPrefNames[type][key];
- var item = {};
- if (booleanPrefNames.indexOf(key) != -1) {
- item[key] = apn[name] || false;
- } else {
- item[key] = apn[name] || '';
- }
- transaction.set(item);
- }
- }
-
- // store the current mcc/mnc info in the settings
- transaction.set({
- 'operatorvariant.mcc': iccSettings.mcc,
- 'operatorvariant.mnc': iccSettings.mnc
- });
- }
-
-
- /**
- * Check the APN settings on startup and when the SIM card is changed.
- */
-
- getICCSettings(checkICCInfo);
- mobileConnection.addEventListener('iccinfochange', checkICCInfo);
-})();
-
diff --git a/apps/system/js/payment.js b/apps/system/js/payment.js
deleted file mode 100644
index a953f5c..0000000
--- a/apps/system/js/payment.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-// TODO: Blocked by [Payment] UX and visuals for the payment request
-// confirmation screen https://github.com/mozilla-b2g/gaia/issues/2692
-
-'use strict';
-
-const kPaymentConfirmationScreen = '../payment.html';
-
-var Payment = {
- chromeEventId: null,
- trustedUILayers: {},
-
- init: function init() {
- window.addEventListener('mozChromeEvent', this);
- },
-
- handleEvent: function onMozChromeEvent(e) {
- // We save the mozChromeEvent identifiers to send replies back from content
- // with this exact value.
- this.chromeEventId = e.detail.id;
- if (!this.chromeEventId)
- return;
-
- var requestId = e.detail.requestId;
-
- switch (e.detail.type) {
- // Chrome asks Gaia to show the payment request confirmation dialog.
- case 'open-payment-confirmation-dialog':
- var requests = e.detail.paymentRequests;
- if (!requests)
- return;
-
- var returnSelection = (function returnSelection(selection) {
- if (!selection)
- return;
-
- this._dispatchEvent({
- id: this.chromeEventId,
- userSelection: selection
- });
- }).bind(this);
-
- // If there is only one request, we skip the confirmation dialog and
- // send the request type back to the chrome as a user selection, so
- // the payment flow can continue.
- if (requests.length == 1) {
- returnSelection(requests[0].type);
- return;
- }
-
- var frame = document.createElement('iframe');
- frame.setAttribute('mozbrowser', 'true');
- frame.setAttribute('remote', true);
- frame.classList.add('screen');
- frame.src = kPaymentConfirmationScreen;
- frame.addEventListener('mozbrowserloadend', function addReqs(evt) {
- var frame = evt.target;
- if (!frame || !requests)
- return;
-
- // TODO: Temp layout until issue #2692 is solved.
- var frameDocument = frame.contentWindow.document;
- var requestsList = frameDocument.getElementById('requests')
- .getElementsByTagName('ul')[0];
- for (var i in requests) {
- var requestElement = frameDocument.createElement('li');
- var button = frameDocument.createElement('button');
- button.setAttribute('value', requests[i].type);
- var requestText = 'Pay with ' + requests[i].providerName + '\n' +
- requests[i].productName + '\n' +
- requests[i].productDescription + '\n' +
- requests[i].productPrice[0].amount + ' ' +
- requests[i].productPrice[0].currency;
- button.appendChild(frameDocument.createTextNode(requestText));
- button.onclick = function selectRequest() {
- // We send the selected request back to Chrome so it can start
- // the appropriate payment flow.
- returnSelection(this.getAttribute('value'));
- };
- requestElement.appendChild(button);
- requestsList.appendChild(requestElement);
- }
- });
-
- this._openTrustedUI(frame);
- break;
-
- // Chrome asks Gaia to show the payment flow according to the
- // payment request selected by the user.
- case 'open-payment-flow-dialog':
- if (!e.detail.uri)
- return;
-
- // TODO: For now, known payment providers (BlueVia and Mozilla Market)
- // only accepts the JWT by GET, so we just add it to the URI.
- e.detail.uri += e.detail.jwt;
-
- this.trustedUILayers[requestId] = this.chromeEventId;
-
- var frame = document.createElement('iframe');
- frame.setAttribute('mozbrowser', 'true');
- frame.classList.add('screen');
- frame.src = e.detail.uri;
- frame.addEventListener('mozbrowserloadstart', (function loadStart(evt) {
- // After creating the new frame containing the payment provider buy
- // flow, we send it back to chrome so the payment callbacks can be
- // injected.
- this._dispatchEvent({
- id: this.chromeEventId,
- frame: evt.target
- });
- }).bind(this));
-
- // The payment flow is shown within the trusted UI
- this._openTrustedUI(frame);
- break;
-
- case 'close-payment-flow-dialog':
- TrustedUIManager.close(this.trustedUILayers[requestId],
- (function dialogClosed() {
- this._dispatchEvent({ id: this.chromeEventId });
- delete this.trustedUILayers[requestId];
- }).bind(this));
- break;
- }
- },
-
- _openTrustedUI: function _openTrustedUI(frame) {
- // The payment flow is shown within the trusted UI with the name of
- // the mozPay caller application as title.
- var title = WindowManager.getCurrentDisplayedApp().name;
- title = title ? title : navigator.mozL10n.get('payment-flow');
- TrustedUIManager.open(title, frame, this.chromeEventId);
- },
-
- _dispatchEvent: function _dispatchEvent(obj) {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true, obj);
- window.dispatchEvent(event);
- }
-};
-
-// Make sure L10n is ready before init
-if (navigator.mozL10n.readyState == 'complete' ||
- navigator.mozL10n.readyState == 'interactive') {
- Payment.init();
-} else {
- window.addEventListener('localized', Payment.init.bind(Payment));
-}
diff --git a/apps/system/js/permission_manager.js b/apps/system/js/permission_manager.js
deleted file mode 100644
index f3c013c..0000000
--- a/apps/system/js/permission_manager.js
+++ /dev/null
@@ -1,203 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var PermissionManager = (function() {
- var _ = navigator.mozL10n.get;
-
- window.addEventListener('mozChromeEvent', function pm_chromeEventHandler(e) {
- var detail = e.detail;
- switch (detail.type) {
- case 'permission-prompt':
- overlay.dataset.type = detail.permission;
- handlePermissionPrompt(detail);
- break;
- case 'fullscreenoriginchange':
- delete overlay.dataset.type;
- handleFullscreenOriginChange(detail);
- break;
- }
- });
-
- var fullscreenRequest = undefined;
-
- var handleFullscreenOriginChange = function(detail) {
- // If there's already a fullscreen request visible, cancel it,
- // we'll show the request for the new domain.
- if (fullscreenRequest != undefined) {
- cancelRequest(fullscreenRequest);
- fullscreenRequest = undefined;
- }
- if (detail.fullscreenorigin != WindowManager.getDisplayedApp()) {
- // The message to be displayed on the approval UI.
- var message = _('fullscreen-request', { 'origin': detail.fullscreenorigin });
- fullscreenRequest = requestPermission(message,
- /* yesCallback */ null,
- /* noCallback */ function() {
- document.mozCancelFullScreen();
- });
- }
- };
-
- var handlePermissionPrompt = function pm_handlePermissionPrompt(detail) {
- remember.checked = detail.remember ? true : false;
- var str = '';
-
- var permissionID = 'perm-' + detail.permission.replace(':', '-');
- if (detail.isApp) { // App
- str = _(permissionID + '-appRequest', { 'app': detail.appName });
- } else { // Web content
- str = _(permissionID + '-webRequest', { 'site': detail.origin });
- }
-
- requestPermission(str, function pm_permYesCB() {
- dispatchResponse(detail.id, 'permission-allow', remember.checked);
- }, function pm_permNoCB() {
- dispatchResponse(detail.id, 'permission-deny', remember.checked);
- });
- };
-
- var dispatchResponse = function pm_dispatchResponse(id, type, remember) {
- var event = document.createEvent('CustomEvent');
- remember = remember ? true : false;
-
- event.initCustomEvent('mozContentEvent', true, true, {
- id: id,
- type: type,
- remember: remember
- });
- window.dispatchEvent(event);
- };
-
- // A queue of pending requests. Callers of requestPermission() must be
- // careful not to create an infinite loop!
- var pending = [];
-
- // Div over in which the permission UI resides.
- var overlay = document.getElementById('permission-screen');
- var dialog = document.getElementById('permission-dialog');
- var message = document.getElementById('permission-message');
-
- // "Yes"/"No" buttons on the permission UI.
- var yes = document.getElementById('permission-yes');
- var no = document.getElementById('permission-no');
-
- // Remember the choice checkbox
- var remember = document.getElementById('permission-remember-checkbox');
- var rememberSection = document.getElementById('permission-remember-section');
-
- // The ID of the next permission request. This is incremented by one
- // on every request, modulo some large number to prevent overflow problems.
- var nextRequestID = 0;
-
- // The ID of the request currently visible on the screen. This has the value
- // "undefined" when there is no request visible on the screen.
- var currentRequestId = undefined;
-
- var hidePermissionPrompt = function() {
- overlay.classList.remove('visible');
- currentRequestId = undefined;
- // Cleanup the event handlers.
- yes.removeEventListener('click', clickHandler);
- yes.callback = null;
- no.removeEventListener('click', clickHandler);
- no.callback = null;
- };
-
- // Show the next request, if we have one.
- var showNextPendingRequest = function() {
- if (pending.length == 0)
- return;
- var request = pending.shift();
- showPermissionPrompt(request.id,
- request.message,
- request.yescallback,
- request.nocallback);
- };
-
- // This is the event listener function for the yes/no buttons.
- var clickHandler = function(evt) {
- var callback = null;
- if (evt.target === yes && yes.callback) {
- callback = yes.callback;
- } else if (evt.target === no && no.callback) {
- callback = no.callback;
- }
- hidePermissionPrompt();
-
- // Call the appropriate callback, if it is defined.
- if (callback)
- window.setTimeout(callback, 0);
-
- showNextPendingRequest();
- };
-
- var requestPermission = function(msg,
- yescallback, nocallback) {
- var id = nextRequestID;
- nextRequestID = (nextRequestID + 1) % 1000000;
-
- if (currentRequestId != undefined) {
- // There is already a permission request being shown, queue this one.
- pending.push({
- id: id,
- message: msg,
- yescallback: yescallback,
- nocallback: nocallback
- });
- return id;
- }
-
- showPermissionPrompt(id, msg, yescallback, nocallback);
-
- return id;
- };
-
- var showPermissionPrompt = function(id, msg,
- yescallback, nocallback) {
- // Put the message in the dialog.
- // Note plain text since this may include text from
- // untrusted app manifests, for example.
- message.textContent = msg;
-
- currentRequestId = id;
-
- // Make the screen visible
- overlay.classList.add('visible');
-
- // Set event listeners for the yes and no buttons
- yes.addEventListener('click', clickHandler);
- yes.callback = yescallback;
-
- no.addEventListener('click', clickHandler);
- no.callback = nocallback;
- };
-
- // Cancels a request with a specfied id. Request can either be
- // currently showing, or pending. If there are further pending requests,
- // the next is shown.
- var cancelRequest = function(id) {
- if (currentRequestId === id) {
- // Request is currently being displayed. Hide the permission prompt,
- // and show the next request, if we have any.
- hidePermissionPrompt();
- showNextPendingRequest();
- } else {
- // The request is currently not being displayed. Search through the
- // list of pending requests, and remove it from the list if present.
- for (var i = 0; i < pending.length; i++) {
- if (pending[i].id === id) {
- pending.splice(i, 1);
- break;
- }
- }
- }
- };
-
- rememberSection.addEventListener('click', function onLabelClick() {
- remember.checked = !remember.checked;
- });
-
-}());
-
diff --git a/apps/system/js/popup_manager.js b/apps/system/js/popup_manager.js
deleted file mode 100644
index 583c9c8..0000000
--- a/apps/system/js/popup_manager.js
+++ /dev/null
@@ -1,313 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-'use strict';
-
-var PopupManager = {
- _currentPopup: {},
- _currentOrigin: '',
- _endTimes: 0,
- _startTimes: 0,
-
- throbber: document.getElementById('popup-throbber'),
-
- overlay: document.getElementById('dialog-overlay'),
-
- popupContainer: document.getElementById('popup-container'),
-
- container: document.getElementById('frame-container'),
-
- screen: document.getElementById('screen'),
-
- closeButton: document.getElementById('popup-close'),
-
- errorTitle: document.getElementById('popup-error-title'),
-
- errorMessage: document.getElementById('popup-error-message'),
-
- errorReload: document.getElementById('popup-error-reload'),
-
- errorBack: document.getElementById('popup-error-back'),
-
- init: function pm_init() {
- this.title = document.getElementById('popup-title');
- window.addEventListener('mozbrowseropenwindow', this);
- window.addEventListener('mozbrowserclose', this);
- window.addEventListener('appwillclose', this);
- window.addEventListener('appopen', this);
- window.addEventListener('appterminated', this);
- window.addEventListener('home', this);
- window.addEventListener('keyboardhide', this);
- window.addEventListener('keyboardchange', this);
- this.closeButton.addEventListener('click', this);
- this.errorReload.addEventListener('click', this);
- this.errorBack.addEventListener('click', this);
- },
-
- open: function pm_open(frame, origin) {
- // Only one popup per origin at a time.
- // If the popup is being shown, we swap frames.
- if (this._currentPopup[origin]) {
- this.container.removeChild(this._currentPopup[origin]);
- delete this._currentPopup[origin];
- }
-
- this.title.textContent = this.getTitleFromUrl(frame.dataset.url);
-
- // Reset overlay height
- this.setHeight(window.innerHeight - StatusBar.height);
-
- this._currentPopup[origin] = frame;
-
- var popup = this._currentPopup[origin];
- var dataset = popup.dataset;
- dataset.frameType = 'popup';
- dataset.frameName = name;
- dataset.frameOrigin = origin;
-
- // this seems needed, or an override to origin in close()
- this._currentOrigin = origin;
-
- this.container.appendChild(popup);
-
- this.screen.classList.add('popup');
-
- popup.addEventListener('mozbrowsererror', this);
- popup.addEventListener('mozbrowserloadend', this);
- popup.addEventListener('mozbrowserloadstart', this);
- popup.addEventListener('mozbrowserlocationchange', this);
- },
-
- close: function pm_close(evt) {
- if (evt && (!'frameType' in evt.target.dataset ||
- evt.target.dataset.frameType !== 'popup'))
- return;
-
- var self = this;
- this.popupContainer.addEventListener('transitionend', function wait(event) {
- self.popupContainer.removeEventListener('transitionend', wait);
- self.screen.classList.remove('popup');
- self.popupContainer.classList.remove('disappearing');
- self.container.removeChild(self._currentPopup[self._currentOrigin]);
- delete self._currentPopup[self._currentOrigin];
- });
-
- this.popupContainer.classList.add('disappearing');
-
- // We just removed the focused window leaving the system
- // without any focused window, let's fix this.
- window.focus();
- },
-
- backHandling: function pm_backHandling() {
- if (!this._currentPopup[this._currentOrigin])
- return;
-
- this.close();
- },
-
- isVisible: function pm_isVisible() {
- return (this._currentPopup[this._currentOrigin] != null);
- },
-
- setHeight: function pm_setHeight(height) {
- if (this.isVisible())
- this.overlay.style.height = height + 'px';
- },
-
- handleEvent: function pm_handleEvent(evt) {
- switch (evt.type) {
- case 'click':
- switch (evt.target) {
- case this.closeButton:
- this.backHandling();
- break;
-
- case this.errorBack:
- this.backHandling();
- break;
-
- case this.errorReload:
- this.container.classList.remove('error');
- delete this._currentPopup[this._currentOrigin].dataset.error;
- this._currentPopup[this._currentOrigin].reload(true);
- break;
- }
- break;
-
- case 'mozbrowserloadstart':
- this.throbber.classList.add('loading');
- break;
-
- case 'mozbrowserloadend':
- this.throbber.classList.remove('loading');
- break;
-
- case 'mozbrowserlocationchange':
- evt.target.dataset.url = evt.detail;
- this.show();
- break;
-
- case 'mozbrowsererror':
- this._currentPopup[evt.target.dataset.frameOrigin].dataset.error = true;
- this.showError();
- break;
-
- case 'mozbrowseropenwindow':
- var detail = evt.detail;
- var openerType = evt.target.dataset.frameType;
- var openerOrigin = evt.target.dataset.frameOrigin;
-
- // Only app frame is allowed to launch popup
- if (openerType !== 'window')
- return;
-
- // <a href="" target="_blank"> links should opened outside the app
- // itself and fire an activity to be opened into a new browser window.
- if (detail.name === '_blank') {
- new MozActivity({ name: 'view',
- data: { type: 'url', url: detail.url }});
- return;
- }
-
- this.throbber.classList.remove('loading');
-
- var frame = detail.frameElement;
- frame.dataset.url = detail.url;
-
- this.container.classList.remove('error');
- this.open(frame, openerOrigin);
-
- break;
-
- case 'mozbrowserclose':
- this.close(evt);
- break;
-
- case 'home':
- // Reset overlay height before hiding
- this.setHeight(window.innerHeight - StatusBar.height);
- this.hide(this._currentOrigin);
- break;
-
- case 'appwillclose':
- if (!this._currentPopup[evt.detail.origin])
- return;
-
- this.hide(evt.detail.origin);
- break;
-
- case 'appopen':
- this._currentOrigin = evt.detail.origin;
- this.show();
- break;
-
- case 'appterminated':
- if (!this._currentPopup[evt.detail.origin])
- return;
- this.close(evt.detail.origin);
- break;
-
- case 'keyboardchange':
- this.setHeight(window.innerHeight -
- StatusBar.height - evt.detail.height);
- break;
-
- case 'keyboardhide':
- this.setHeight(window.innerHeight - StatusBar.height);
- break;
- }
- },
-
- showError: function pm_showError() {
- if (!('error' in this._currentPopup[this._currentOrigin].dataset)) {
- this.container.classList.remove('error');
- return;
- }
-
- var contentOrigin =
- this.getTitleFromUrl(this._currentPopup[this._currentOrigin].dataset.url);
- var _ = navigator.mozL10n.get;
-
- if (AirplaneMode.enabled) {
- this.errorTitle.textContent = _('airplane-is-on');
- this.errorMessage.textContent = _('airplane-is-turned-on',
- {name: contentOrigin});
- } else if (!navigator.onLine) {
- this.errorTitle.textContent = _('network-connection-unavailable');
- this.errorMessage.textContent = _('network-error', {name: contentOrigin});
- } else {
- this.errorTitle.textContent = _('error-title', {name: contentOrigin});
- this.errorMessage.textContent = _('error-message', {name: contentOrigin});
- }
- this.container.classList.add('error');
- },
-
- // This is for card view to request
- // Return nothing if the content is the same origin as opener
- // Return URL if the content is off-origin
- getOpenedOriginFromOpener: function pm_getOpenedOriginOpener(origin) {
- var opened = this._getOriginObject(this._currentPopup[origin].dataset.url);
- var opener = this._getOriginObject(origin);
- // Same origin means: Protocol, Domain, Port
- if (opened.protocol == opener.protocol &&
- opened.hostname == opener.hostname &&
- opened.port == opener.port) {
- return '';
- } else {
- return opened.protocol + '//' + opened.hostname;
- }
- },
-
- getTitleFromUrl: function pm_getTitleFromUrl(url) {
- var app = WindowManager.getCurrentDisplayedApp();
- var opened = this._getOriginObject(url);
- var opener = this._getOriginObject(app.frame.dataset.frameOrigin);
- // Same origin means: Protocol, Domain, Port
- if (opened.protocol == opener.protocol &&
- opened.hostname == opener.hostname &&
- opened.port == opener.port) {
- return app.name;
- } else {
- return opened.protocol + '//' + opened.hostname;
- }
- },
-
- _getOriginObject: function pm__getOriginObject(url) {
- var parser = document.createElement('a');
- parser.href = url;
-
- return {
- protocol: parser.protocol,
- hostname: parser.hostname,
- port: parser.port
- };
- },
-
- getPopupFromOrigin: function pm_getPopupFromOrigin(origin) {
- return this._currentPopup[origin];
- },
-
- show: function pm_show() {
- if (!this._currentPopup[this._currentOrigin])
- return;
-
-
- this.showError();
- this.screen.classList.add('popup');
-
- var popup = this._currentPopup[this._currentOrigin];
- this.title.textContent = this.getTitleFromUrl(popup.dataset.url);
- popup.hidden = false;
- },
-
- hide: function pm_hide(origin) {
- if (!this._currentPopup[origin])
- return;
-
- this.screen.classList.remove('popup');
- this._currentPopup[origin].hidden = true;
- }
-};
-
-PopupManager.init();
-
diff --git a/apps/system/js/quick_settings.js b/apps/system/js/quick_settings.js
deleted file mode 100644
index 328bb35..0000000
--- a/apps/system/js/quick_settings.js
+++ /dev/null
@@ -1,279 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var QuickSettings = {
- // Indicate setting status of geolocation.enabled
- geolocationEnabled: false,
- WIFI_STATUSCHANGE_TIMEOUT: 2000,
-
- init: function qs_init() {
- var settings = window.navigator.mozSettings;
- var conn = window.navigator.mozMobileConnection;
- if (!settings || !conn)
- return;
-
- this.getAllElements();
-
- this.overlay.addEventListener('click', this);
- window.addEventListener('utilitytrayshow', this);
-
- var self = this;
-
- /*
- * Monitor data network icon
- */
- conn.addEventListener('datachange', function qs_onDataChange() {
- var label = {
- 'lte': '4G', // 4G LTE
- 'ehrpd': '4G', // 4G CDMA
- 'hspa+': 'H+', // 3.5G HSPA+
- 'hsdpa': 'H', 'hsupa': 'H', 'hspa': 'H', // 3.5G HSDPA
- 'evdo0': '3G', 'evdoa': '3G', 'evdob': '3G', '1xrtt': '3G', // 3G CDMA
- 'umts': '3G', // 3G
- 'edge': 'E', // EDGE
- 'is95a': '2G', 'is95b': '2G', // 2G CDMA
- 'gprs': '2G'
- };
- self.data.dataset.network = label[conn.data.type];
- });
-
- /* monitor data setting
- * TODO prevent quickly tapping on it
- */
- SettingsListener.observe('ril.data.enabled', true, function(value) {
- if (value) {
- self.data.dataset.enabled = 'true';
- } else {
- delete self.data.dataset.enabled;
- }
- });
-
- /* monitor bluetooth setting and initialization/disable ready event
- * - when settings changed, update UI and lock toogle to prevent quickly
- * tapping on it.
- * - when got bluetooth initialization/disable ready, active toogle, so
- * return the control to user.
- */
- var btFirstSet = true;
- SettingsListener.observe('bluetooth.enabled', true, function(value) {
- // check self.bluetooth.dataset.enabled and value are identical
- if ((self.bluetooth.dataset.enabled && value) ||
- (self.bluetooth.dataset.enabled === undefined && !value))
- return;
-
- if (value) {
- self.bluetooth.dataset.enabled = 'true';
- } else {
- delete self.bluetooth.dataset.enabled;
- }
-
- // Set to the initializing state to block user interaction until the
- // operation completes. (unless we are being called for the first time,
- // where Bluetooth is already initialize
- if (!btFirstSet)
- self.bluetooth.dataset.initializing = 'true';
- btFirstSet = false;
- });
- window.addEventListener('bluetooth-adapter-added', this);
- window.addEventListener('bluetooth-disabled', this);
-
-
- /* monitor wifi setting and initialization/disable ready event
- * - when settings changed, update UI and lock toogle to prevent quickly
- * tapping on it.
- * - when got bluetooth initialization/disable ready, active toogle, so
- * return the control to user.
- */
- var wifiFirstSet = true;
- SettingsListener.observe('wifi.enabled', true, function(value) {
- // check self.wifi.dataset.enabled and value are identical
- if ((self.wifi.dataset.enabled && value) ||
- (self.wifi.dataset.enabled === undefined && !value))
- return;
-
- if (value) {
- self.wifi.dataset.enabled = 'true';
- } else {
- delete self.wifi.dataset.enabled;
- }
- // Set to the initializing state to block user interaction until the
- // operation completes. (unless we are being called for the first time,
- // where Wifi is already initialize
- if (!wifiFirstSet)
- self.wifi.dataset.initializing = 'true';
- wifiFirstSet = false;
- });
- window.addEventListener('wifi-enabled', this);
- window.addEventListener('wifi-disabled', this);
- window.addEventListener('wifi-statuschange', this);
-
- /* monitor geolocation setting
- * TODO prevent quickly tapping on it
- */
- SettingsListener.observe('geolocation.enabled', true, function(value) {
- self.geolocationEnabled = value;
- });
-
- // monitor airplane mode
- SettingsListener.observe('ril.radio.disabled', false, function(value) {
- self.data.dataset.airplaneMode = value;
- if (value) {
- self.data.classList.add('quick-settings-airplane-mode');
- self.airplaneMode.dataset.enabled = 'true';
- } else {
- self.data.classList.remove('quick-settings-airplane-mode');
- delete self.airplaneMode.dataset.enabled;
- }
- });
- },
-
- handleEvent: function qs_handleEvent(evt) {
- evt.preventDefault();
- switch (evt.type) {
- case 'click':
- switch (evt.target) {
- case this.wifi:
- // do nothing if wifi isn't ready
- if (this.wifi.dataset.initializing)
- return;
- var enabled = !!this.wifi.dataset.enabled;
- SettingsListener.getSettingsLock().set({
- 'wifi.enabled': !enabled
- });
- if (!enabled)
- this.toggleAutoConfigWifi = true;
- break;
-
- case this.data:
- if (this.data.dataset.airplaneMode !== 'true') {
- // TODO should ignore the action if data initialization isn't done
- var enabled = !!this.data.dataset.enabled;
-
- SettingsListener.getSettingsLock().set({
- 'ril.data.enabled': !enabled
- });
- }
-
- break;
-
- case this.bluetooth:
- // do nothing if bluetooth isn't ready
- if (this.bluetooth.dataset.initializing)
- return;
-
- var enabled = !!this.bluetooth.dataset.enabled;
- SettingsListener.getSettingsLock().set({
- 'bluetooth.enabled': !enabled
- });
- break;
-
- case this.airplaneMode:
- var enabled = !!this.airplaneMode.dataset.enabled;
- SettingsListener.getSettingsLock().set({
- 'ril.radio.disabled': !enabled
- });
- break;
-
- case this.fullApp:
- // XXX: This should be replaced probably by Web Activities
- var host = document.location.host;
- var domain = host.replace(/(^[\w\d]+\.)?([\w\d]+\.[a-z]+)/, '$2');
- var protocol = document.location.protocol + '//';
- Applications.getByManifestURL(protocol + 'settings.' +
- domain + '/manifest.webapp').launch();
-
- UtilityTray.hide();
- break;
- }
- break;
-
- case 'utilitytrayshow':
- break;
-
- // unlock bluetooth toggle
- case 'bluetooth-adapter-added':
- case 'bluetooth-disabled':
- delete this.bluetooth.dataset.initializing;
- break;
- // unlock wifi toggle
- case 'wifi-enabled':
- delete this.wifi.dataset.initializing;
- if (this.toggleAutoConfigWifi) {
- // Check whether it found a wifi to connect after a timeout.
- this.wifiStatusTimer = setTimeout(this.autoConfigWifi.bind(this),
- this.WIFI_STATUSCHANGE_TIMEOUT);
- }
- break;
- case 'wifi-disabled':
- delete this.wifi.dataset.initializing;
- if (this.toggleAutoConfigWifi) {
- clearTimeout(this.wifiStatusTimer);
- this.wifiStatusTimer = null;
- this.toggleAutoConfigWifi = false;
- }
- break;
-
- case 'wifi-statuschange':
- if (this.toggleAutoConfigWifi && !this.wifi.dataset.initializing)
- this.autoConfigWifi();
- break;
- }
- },
-
- getAllElements: function qs_getAllElements() {
- // ID of elements to create references
- var elements = ['wifi', 'data', 'bluetooth', 'airplane-mode', 'full-app'];
-
- var toCamelCase = function toCamelCase(str) {
- return str.replace(/\-(.)/g, function replacer(str, p1) {
- return p1.toUpperCase();
- });
- };
-
- elements.forEach(function createElementRef(name) {
- this[toCamelCase(name)] =
- document.getElementById('quick-settings-' + name);
- }, this);
-
- this.overlay = document.getElementById('quick-settings');
- },
-
- // XXX Break down obj keys in a for each loop because mozSettings
- // does not currently supports multiple keys in one set()
- // https://bugzilla.mozilla.org/show_bug.cgi?id=779381
- setMozSettings: function qs_setter(keypairs) {
- var setlock = SettingsListener.getSettingsLock();
- for (var key in keypairs) {
- var obj = {};
- obj[key] = keypairs[key];
- setlock.set(obj);
- }
- },
-
- /* Auto-config wifi if user enabled wifi from quick settings bar.
- * If there are no known networks around, wifi settings page
- * will be opened. Otherwise nothing will be done.
- */
- autoConfigWifi: function qs_autoConfigWifi() {
- clearTimeout(this.wifiStatusTimer);
- this.wifiStatusTimer = null;
- this.toggleAutoConfigWifi = false;
-
- var wifiManager = window.navigator.mozWifiManager;
- var status = wifiManager.connection.status;
-
- if (status == 'disconnected') {
- var activity = new MozActivity({
- name: 'configure',
- data: {
- target: 'device',
- section: 'wifi'
- }
- });
- }
- }
-};
-
-QuickSettings.init();
diff --git a/apps/system/js/remote_debugger.js b/apps/system/js/remote_debugger.js
deleted file mode 100644
index 51544bb..0000000
--- a/apps/system/js/remote_debugger.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var RemoteDebugger = (function() {
-
- return {
- init: function() {
- window.addEventListener('mozChromeEvent', this);
- },
-
- handleEvent: function onMozChromeEvent(e) {
- if (e.detail.type !== 'remote-debugger-prompt') {
- return;
- }
-
- // Reusing the ModalDialog infrastructure.
- ModalDialog.showWithPseudoEvent({
- text: navigator.mozL10n.get('remoteDebuggerMessage'),
- type: 'confirm',
- callback: function() {
- RemoteDebugger._dispatchEvent(true);
- },
- cancel: function() {
- RemoteDebugger._dispatchEvent(false);
- }
- });
- },
-
- _dispatchEvent: function su_dispatchEvent(value) {
- var event = document.createEvent('CustomEvent');
- event.initCustomEvent('mozContentEvent', true, true,
- { type: 'remote-debugger-prompt',
- value: value });
- window.dispatchEvent(event);
- }
- };
-})();
-
-RemoteDebugger.init();
diff --git a/apps/system/js/screen_manager.js b/apps/system/js/screen_manager.js
deleted file mode 100644
index 9a69e8c..0000000
--- a/apps/system/js/screen_manager.js
+++ /dev/null
@@ -1,503 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var ScreenManager = {
- /*
- * return the current screen status
- * Must not mutate directly - use toggleScreen/turnScreenOff/turnScreenOn.
- * Listen to 'screenchange' event to properly handle status changes
- * This value can be "out of sync" with real mozPower value,
- * we do this to give screen some time to flash before actual turn off.
- */
- screenEnabled: false,
-
- /*
- * before idle-screen-off, invoke a nice dimming to the brightness
- * to notify the user that the screen is about to be turn off.
- * The user can cancel the idle-screen-off by touching the screen
- * and by pressing a button (trigger onactive callback on Idle API)
- *
- */
- _inTransition: false,
-
- /*
- * Whether the wake lock is enabled or not
- */
- _screenWakeLocked: false,
-
- /*
- * Whether the device light is enabled or not
- * sync with setting 'screen.automatic-brightness'
- */
- _deviceLightEnabled: true,
-
- /*
- * Preferred brightness without considering device light nor dimming
- * sync with setting 'screen.brightness'
- */
- _userBrightness: 1,
- _savedBrightness: 1,
-
- /*
- * The auto-brightness algorithm will never set the screen brightness
- * to a value smaller than this. 0.1 seems like a good screen brightness
- * in a completely dark room on a Unagi.
- */
- AUTO_BRIGHTNESS_MINIMUM: 0.1,
-
- /*
- * This constant is used in the auto brightness algorithm. We take
- * the base 10 logarithm of the incoming lux value from the light
- * sensor and multiplied it by this constant. That value is used to
- * compute a weighted average with the current brightness and
- * finally that average brightess is and then clamped to the range
- * [AUTO_BRIGHTNESS_MINIMUM, 1.0].
- *
- * Making this value larger will increase the brightness for a given
- * ambient light level. At a value of about .25, the screen will be
- * at full brightness in sunlight or in a well-lighted work area.
- * At a value of about .3, the screen will typically be at maximum
- * brightness in outdoor daylight conditions, even when overcast.
- */
- AUTO_BRIGHTNESS_CONSTANT: .27,
-
- /*
- * When we change brightness we animate it smoothly.
- * This constant is the number of milliseconds between adjustments
- */
- BRIGHTNESS_ADJUST_INTERVAL: 20,
-
- /*
- * When brightening or dimming the screen, this is how much we adjust
- * the brightness value at a time.
- */
- BRIGHTNESS_ADJUST_STEP: 0.04,
-
- /*
- * Wait for _dimNotice milliseconds during idle-screen-off
- */
- _dimNotice: 10 * 1000,
-
- /*
- * We track the value of the idle timeout pref in this variable.
- */
- _idleTimeout: 0,
- _idleTimerId: 0,
-
- /*
- * If the screen off is triggered by promixity during phon call then
- * we need wake it up while phone is ended.
- */
- _screenOffByProximity: false,
-
- /*
- * Request wakelock during in_call state.
- * To ensure turnScreenOff by proximity event is protected by wakelock for
- * early suspend only.
- */
- _cpuWakeLock: null,
-
- init: function scm_init() {
- window.addEventListener('sleep', this);
- window.addEventListener('wake', this);
-
- this.screen = document.getElementById('screen');
-
- var self = this;
- var power = navigator.mozPower;
-
- if (power) {
- power.addWakeLockListener(function scm_handleWakeLock(topic, state) {
- switch (topic) {
- case 'screen':
- self._screenWakeLocked = (state == 'locked-foreground');
-
- if (self._screenWakeLocked)
- // Turn screen on if wake lock is acquire
- self.turnScreenOn();
- self._reconfigScreenTimeout();
- break;
-
- case 'cpu':
- power.cpuSleepAllowed = (state != 'locked-foreground' &&
- state != 'locked-background');
- break;
- }
- });
- }
-
- this._firstOn = false;
- SettingsListener.observe('screen.timeout', 60,
- function screenTimeoutChanged(value) {
- if (typeof value !== 'number')
- value = parseInt(value);
- self._idleTimeout = value;
- self._setIdleTimeout(self._idleTimeout);
-
- if (!self._firstOn) {
- self._firstOn = true;
-
- // During boot up, the brightness was set by bootloader as 0.5,
- // Let's set the API value to that so setScreenBrightness() can
- // dim nicely to value set by user.
- power.screenBrightness = 0.5;
-
- // Turn screen on with dim.
- self.turnScreenOn(false);
- }
- });
-
- SettingsListener.observe('screen.automatic-brightness', true,
- function deviceLightSettingChanged(value) {
- self.setDeviceLightEnabled(value);
- });
-
- SettingsListener.observe('screen.brightness', 1,
- function brightnessSettingChanged(value) {
- self._userBrightness = value;
- self.setScreenBrightness(value, false);
- });
-
- var telephony = window.navigator.mozTelephony;
- if (telephony) {
- telephony.addEventListener('callschanged', this);
- }
- },
-
- //
- // Automatically adjust the screen brightness based on the ambient
- // light (in lux) measured by the device light sensor
- //
- autoAdjustBrightness: function scm_adjustBrightness(lux) {
- var currentBrightness = this._targetBrightness;
-
- if (lux < 1) // Can't take the log of 0 or negative numbers
- lux = 1;
-
- var computedBrightness =
- Math.log(lux) / Math.LN10 * this.AUTO_BRIGHTNESS_CONSTANT;
-
- var clampedBrightness = Math.max(this.AUTO_BRIGHTNESS_MINIMUM,
- Math.min(1.0, computedBrightness));
-
- // If nothing changed, we're done.
- if (clampedBrightness === currentBrightness)
- return;
-
- this.setScreenBrightness(clampedBrightness, false);
- },
-
- handleEvent: function scm_handleEvent(evt) {
- switch (evt.type) {
- case 'devicelight':
- if (!this._deviceLightEnabled || !this.screenEnabled ||
- this._inTransition)
- return;
- this.autoAdjustBrightness(evt.value);
- break;
-
- case 'sleep':
- this.turnScreenOff(true);
- break;
-
- case 'wake':
- this.turnScreenOn();
- break;
-
- case 'userproximity':
- this._screenOffByProximity = evt.near;
- if (evt.near) {
- this.turnScreenOff(true);
- } else {
- this.turnScreenOn();
- }
- break;
-
- case 'callschanged':
- var telephony = window.navigator.mozTelephony;
- if (!telephony.calls.length) {
- if (this._screenOffByProximity) {
- this.turnScreenOn();
- }
-
- window.removeEventListener('userproximity', this);
- this._screenOffByProximity = false;
-
- if (this._cpuWakeLock) {
- this._cpuWakeLock.unlock();
- this._cpuWakeLock = null;
- }
- break;
- }
-
- // If the _cpuWakeLock is already set we are in a multiple
- // call setup, turning the screen on to let user see the
- // notification.
- if (this._cpuWakeLock) {
- this.turnScreenOn();
-
- break;
- }
-
- // Enable the user proximity sensor once the call is connected.
- var call = telephony.calls[0];
- call.addEventListener('statechange', this);
-
- break;
-
- case 'statechange':
- var call = evt.target;
- if (call.state !== 'connected') {
- break;
- }
-
- // The call is connected. Remove the statechange listener
- // and enable the user proximity sensor.
- call.removeEventListener('statechange', this);
-
- this._cpuWakeLock = navigator.requestWakeLock('cpu');
- window.addEventListener('userproximity', this);
- break;
- }
- },
-
- toggleScreen: function scm_toggleScreen() {
- if (this.screenEnabled) {
- this.turnScreenOff();
- } else {
- this.turnScreenOn();
- }
- },
-
- turnScreenOff: function scm_turnScreenOff(instant) {
- if (!this.screenEnabled)
- return false;
-
- var self = this;
-
- // Remember the current screen brightness. We will restore it when
- // we turn the screen back on.
- self._savedBrightness = navigator.mozPower.screenBrightness;
-
- // Remove the cpuWakeLock if screen is not turned off by
- // userproximity event.
- if (!this._screenOffByProximity && this._cpuWakeLock) {
- window.removeEventListener('userproximity', this);
- this._cpuWakeLock.unlock();
- this._cpuWakeLock = null;
- }
-
- var screenOff = function scm_screenOff() {
- self._setIdleTimeout(0);
-
- window.removeEventListener('devicelight', self);
-
- self.screenEnabled = false;
- self._inTransition = false;
- self.screen.classList.add('screenoff');
- setTimeout(function realScreenOff() {
- self.setScreenBrightness(0, true);
- // Sometimes the ScreenManager.screenEnabled and mozPower.screenEnabled
- // values are out of sync. Since the rest of the world relies only on
- // the value of ScreenManager.screenEnabled it can be some situations
- // where the screen is off but ScreenManager think it is on... (see
- // bug 822463). Ideally a callback should have been used, like
- // ScreenManager.getScreenState(function(value) { ...} ); but there
- // are too many places to change that for now.
- self.screenEnabled = false;
- navigator.mozPower.screenEnabled = false;
- }, 20);
-
- self.fireScreenChangeEvent();
- };
-
- if (instant) {
- if (!WindowManager.isFtuRunning()) {
- screenOff();
- }
- return true;
- }
-
- this.setScreenBrightness(0.1, false);
- this._inTransition = true;
- setTimeout(function noticeTimeout() {
- if (!self._inTransition)
- return;
-
- screenOff();
- }, self._dimNotice);
-
- return true;
- },
-
- turnScreenOn: function scm_turnScreenOn(instant) {
- if (this.screenEnabled) {
- if (this._inTransition) {
- // Cancel the dim out
- this._inTransition = false;
- this.setScreenBrightness(this._savedBrightness, true);
- this._reconfigScreenTimeout();
- }
- return false;
- }
-
- // Set the brightness before the screen is on.
- this.setScreenBrightness(this._savedBrightness, instant);
-
- // If we are in a call and there is no cpuWakeLock,
- // we would have to get one here.
- var telephony = window.navigator.mozTelephony;
- if (!this._cpuWakeLock && telephony && telephony.calls.length) {
- telephony.calls.some(function checkCallConnection(call) {
- if (call.state == 'connected') {
- this._cpuWakeLock = navigator.requestWakeLock('cpu');
- window.addEventListener('userproximity', this);
- return true;
- }
- return false;
- }, this);
- }
-
- // Actually turn the screen on.
- var power = navigator.mozPower;
- if (power)
- power.screenEnabled = true;
- this.screenEnabled = true;
- this.screen.classList.remove('screenoff');
-
- // Attaching the event listener effectively turn on the hardware
- // device light sensor, which _must be_ done after power.screenEnabled.
- if (this._deviceLightEnabled)
- window.addEventListener('devicelight', this);
-
- this._reconfigScreenTimeout();
- this.fireScreenChangeEvent();
-
- return true;
- },
-
- _reconfigScreenTimeout: function scm_reconfigScreenTimeout() {
- // Remove idle timer if screen wake lock is acquired.
- if (this._screenWakeLocked) {
- this._setIdleTimeout(0);
- // The screen should be turn off with shorter timeout if
- // it was never unlocked.
- } else if (LockScreen.locked) {
- this._setIdleTimeout(10, true);
- var self = this;
- var stopShortIdleTimeout = function scm_stopShortIdleTimeout() {
- window.removeEventListener('unlock', stopShortIdleTimeout);
- window.removeEventListener('lockpanelchange', stopShortIdleTimeout);
- self._setIdleTimeout(self._idleTimeout, false);
- };
-
- window.addEventListener('unlock', stopShortIdleTimeout);
- window.addEventListener('lockpanelchange', stopShortIdleTimeout);
- } else {
- this._setIdleTimeout(this._idleTimeout, false);
- }
- },
-
- setScreenBrightness: function scm_setScreenBrightness(brightness, instant) {
- this._targetBrightness = brightness;
- var power = navigator.mozPower;
- if (!power)
- return;
-
- // Make sure we don't have another brightness change scheduled
- if (this._transitionBrightnessTimer) {
- clearTimeout(this._transitionBrightnessTimer);
- this._transitionBrightnessTimer = null;
- }
-
- if (typeof instant !== 'boolean')
- instant = true;
-
- if (instant) {
- power.screenBrightness = brightness;
- return;
- }
-
- // transitionBrightness() is a looping function that will
- // gracefully tune the brightness to _targetBrightness for us.
- this.transitionBrightness();
- },
-
- transitionBrightness: function scm_transitionBrightness() {
- var self = this;
- var power = navigator.mozPower;
- var screenBrightness = power.screenBrightness;
- var delta = this.BRIGHTNESS_ADJUST_STEP;
-
- // Is this the last time adjustment we need to make?
- if (Math.abs(this._targetBrightness - screenBrightness) <= delta) {
- power.screenBrightness = this._targetBrightness;
- this._transitionBrightnessTimer = null;
- return;
- }
-
- if (screenBrightness > this._targetBrightness)
- delta *= -1;
-
- screenBrightness += delta;
- power.screenBrightness = screenBrightness;
-
- this._transitionBrightnessTimer =
- setTimeout(function transitionBrightnessTimeout() {
- self.transitionBrightness();
- }, this.BRIGHTNESS_ADJUST_INTERVAL);
- },
-
- setDeviceLightEnabled: function scm_setDeviceLightEnabled(enabled) {
- if (!enabled && this._deviceLightEnabled) {
- // Disabled -- set the brightness back to preferred brightness
- this.setScreenBrightness(this._userBrightness, false);
- }
- this._deviceLightEnabled = enabled;
-
- if (!this.screenEnabled)
- return;
-
- // Disable/enable device light sensor accordingly.
- // This will also toggle the actual hardware, which
- // must be done while the screen is on.
- if (enabled) {
- window.addEventListener('devicelight', this);
- } else {
- window.removeEventListener('devicelight', this);
- }
- },
-
- _setIdleTimeout: function scm_setIdleTimeout(time, instant) {
- window.clearIdleTimeout(this._idleTimerId);
-
- // Reset the idled state back to false.
- this._idled = false;
-
- // 0 is the value used to disable idle timer by user and by us.
- if (time === 0)
- return;
-
- var self = this;
- var idleCallback = function idle_proxy() {
- self.turnScreenOff(instant);
- };
- var activeCallback = function active_proxy() {
- self.turnScreenOn(true);
- };
-
- this._idleTimerId = window.setIdleTimeout(idleCallback,
- activeCallback, time * 1000);
- },
-
- fireScreenChangeEvent: function scm_fireScreenChangeEvent() {
- var evt = new CustomEvent('screenchange',
- { bubbles: true, cancelable: false,
- detail: { screenEnabled: this.screenEnabled } });
- window.dispatchEvent(evt);
- }
-};
-
-ScreenManager.init();
diff --git a/apps/system/js/screenshot.js b/apps/system/js/screenshot.js
deleted file mode 100644
index 9e8e7f6..0000000
--- a/apps/system/js/screenshot.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// screenshot.js: system screenshot module
-//
-// This system module takes a screenshot of the currently running app
-// or homescreen and stores it with DeviceStorage when the user
-// presses the home and sleep buttons at the same time. It communicates
-// with gecko code running in b2g/chrome/content/shell.js using a private
-// event-based API. It is the gecko code that creates the screenshot.
-//
-// This script must be used with the defer attribute.
-//
-//
-(function() {
- window.addEventListener('home+sleep', takeScreenshot);
-
- // Assume that the maximum screenshot size is 4 bytes per pixel
- // plus a bit extra. In practice, with compression, our PNG files will be
- // much smaller than this.
- var MAX_SCREENSHOT_SIZE = window.innerWidth * window.innerHeight * 4 + 4096;
-
- function takeScreenshot() {
- // Give feedback that the screenshot request was received
- navigator.vibrate(100);
-
- // We don't need device storage here, but check to see that
- // it is available before sending the screenshot request to chrome.
- // If device storage is available, the callback will be called.
- // Otherwise, an error message notification will be displayed.
- getDeviceStorage(function() {
- // Let chrome know we'd like a screenshot.
- // This is a completely non-standard undocumented API
- // for communicating with our chrome code.
- var screenshotProps = {
- detail: {
- type: 'take-screenshot'
- }
- };
- window.dispatchEvent(new CustomEvent('mozContentEvent', screenshotProps));
- });
- }
-
- // Display a screenshot success or failure notification.
- // Localize the first argument, and localize the third if the second is null
- function notify(titleid, body, bodyid) {
- var title = navigator.mozL10n.get(titleid) || titleid;
- body = body || navigator.mozL10n.get(bodyid);
- navigator.mozNotification.createNotification(title, body).show();
- }
-
- // Get a DeviceStorage object and pass it to the callback.
- // Or, if device storage is not available, display a notification.
- function getDeviceStorage(callback) {
- var storage = navigator.getDeviceStorage('pictures');
- var availreq = storage.available();
- availreq.onsuccess = function() {
- var state = availreq.result;
- if (state === 'unavailable') {
- notify('screenshotFailed', null, 'screenshotNoSDCard');
- }
- else if (state === 'shared') {
- notify('screenshotFailed', null, 'screenshotSDCardInUse');
- }
- else if (state === 'available') {
- var freereq = storage.freeSpace();
- freereq.onsuccess = function() {
- if (freereq.result < MAX_SCREENSHOT_SIZE) {
- notify('screenshotFailed', null, 'screenshotSDCardLow');
- }
- else {
- callback(storage);
- }
- };
- freereq.onerror = function() {
- notify('screenshotFailed', freereq.error && freereq.error.name);
- };
- }
- }
- availreq.onerror = function() {
- notify('screenshotFailed', availreq.error && availreq.error.name);
- }
- }
-
- // Handle the event we get from chrome with the screenshot
- window.addEventListener('mozChromeEvent', function ss_onMozChromeEvent(e) {
- try {
- if (e.detail.type === 'take-screenshot-success') {
- getDeviceStorage(function(storage) {
- var filename = 'screenshots/' +
- new Date().toISOString().slice(0, -5).replace(/[:T]/g, '-') +
- '.png';
-
- var saveRequest = storage.addNamed(e.detail.file, filename);
-
- saveRequest.onsuccess = function ss_onsuccess() {
- // Vibrate again when the screenshot is saved
- navigator.vibrate(100);
-
- // Display filename in a notification
- notify('screenshotSaved', filename);
- };
-
- saveRequest.onerror = function ss_onerror() {
- notify('screenshotFailed', saveRequest.error.name);
- };
- });
- }
- else if (e.detail.type === 'take-screenshot-error') {
- notify('screenshotFailed', e.detail.error);
- }
- }
- catch (e) {
- console.log('exception in screenshot handler', e);
- notify('screenshotFailed', e.toString());
- }
- });
-}());
diff --git a/apps/system/js/sim_lock.js b/apps/system/js/sim_lock.js
deleted file mode 100644
index 3a3d3e0..0000000
--- a/apps/system/js/sim_lock.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var SimLock = {
- init: function sl_init() {
- // Do not do anything if we can't have access to MobileConnection API
- var conn = window.navigator.mozMobileConnection;
- if (!conn)
- return;
-
- this.onClose = this.onClose.bind(this);
-
- // Watch for apps that need a mobile connection
- window.addEventListener('appwillopen', this);
-
- // Display the dialog only after lockscreen is unlocked
- // To prevent keyboard being displayed behind it.
- window.addEventListener('unlock', this);
-
- // always monitor card state change
- conn.addEventListener('cardstatechange', this.showIfLocked.bind(this));
- },
-
- handleEvent: function sl_handleEvent(evt) {
- switch (evt.type) {
- case 'unlock':
- this.showIfLocked();
- break;
- case 'appwillopen':
- // if an app needs telephony or sms permission,
- // we will launch the unlock screen if needed.
-
- var app = Applications.getByManifestURL(
- evt.target.getAttribute('mozapp'));
-
- if (!app || !app.manifest.permissions)
- return;
-
- // Ignore first time usage app which already ask for SIM code
- if (evt.target.classList.contains('ftu'))
- return;
-
- if (!('telephony' in app.manifest.permissions ||
- 'sms' in app.manifest.permissions))
- return;
-
- // Ignore second `appwillopen` event when showIfLocked ends up
- // eventually opening the app on valid pin code
- var origin = evt.target.dataset.frameOrigin;
- if (origin == this._lastOrigin) {
- delete this._lastOrigin;
- return;
- }
- this._lastOrigin = origin;
-
- // if sim is locked, cancel app opening in order to display
- // it after PIN dialog
- if (this.showIfLocked())
- evt.preventDefault();
-
- break;
- }
- },
-
- showIfLocked: function sl_showIfLocked() {
- var conn = window.navigator.mozMobileConnection;
- if (!conn)
- return false;
-
- if (LockScreen.locked)
- return false;
-
- switch (conn.cardState) {
- // do nothing in absent and null card states
- case null:
- case 'absent':
- break;
- case 'pukRequired':
- case 'pinRequired':
- SimPinDialog.show('unlock', this.onClose);
- return true;
- case 'networkLocked':
- // XXXX: After unlocking the SIM the cardState is
- // 'networkLocked' but it changes inmediately to 'ready'
- // if the phone is not SIM-locked. If the cardState
- // is still 'networkLocked' after two seconds we unlock
- // the network control key lock (network personalization).
- setTimeout(function checkState() {
- if (conn.cardState == 'networkLocked') {
- SimPinDialog.show('unlock', SimLock.onClose);
- }
- }, 5000);
- break;
- }
- return false;
- },
-
- onClose: function sl_onClose(reason) {
- // Display the app only when PIN code is valid and when we click
- // on `X` button
- if (this._lastOrigin && (reason == 'success' || reason == 'skip'))
- WindowManager.setDisplayedApp(this._lastOrigin);
- delete this._lastOrigin;
- }
-
-};
-
-SimLock.init();
diff --git a/apps/system/js/simcard_dialog.js b/apps/system/js/simcard_dialog.js
deleted file mode 100644
index 4176cbf..0000000
--- a/apps/system/js/simcard_dialog.js
+++ /dev/null
@@ -1,355 +0,0 @@
-/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var SimPinDialog = {
- dialogTitle: document.querySelector('#simpin-dialog header h1'),
- dialogDone: document.querySelector('#simpin-dialog button[type="submit"]'),
- dialogClose: document.querySelector('#simpin-dialog button[type="reset"]'),
-
- pinArea: document.getElementById('pinArea'),
- pukArea: document.getElementById('pukArea'),
- nckArea: document.getElementById('nckArea'),
- newPinArea: document.getElementById('newPinArea'),
- confirmPinArea: document.getElementById('confirmPinArea'),
-
- pinInput: null,
- pukInput: null,
- nckInput: null,
- newPinInput: null,
- confirmPinInput: null,
-
- errorMsg: document.getElementById('errorMsg'),
- errorMsgHeader: document.getElementById('messageHeader'),
- errorMsgBody: document.getElementById('messageBody'),
-
- mobileConnection: null,
-
- lockType: 'pin',
- action: 'unlock',
-
- // Now we don't have a number-password type for input field
- // mimic one by binding one number input and one text input
- getNumberPasswordInputField: function spl_wrapNumberInput(name) {
- var valueEntered = '';
- var inputField = document.querySelector('input[name="' + name + '"]');
- var displayField = document.querySelector('input[name="' + name + 'Vis"]');
- var codeMaxLength = parseInt(inputField.getAttribute('maxlength'), 10);
- var self = this;
-
- inputField.addEventListener('keypress', function(evt) {
- if (evt.target !== inputField)
- return;
- evt.preventDefault();
-
- var code = evt.charCode;
- if (code !== 0 && (code < 0x30 || code > 0x39))
- return;
-
- if (code === 0) { // backspace
- valueEntered = valueEntered.substr(0, valueEntered.length - 1);
- } else {
- if (valueEntered.length >= codeMaxLength)
- return;
- valueEntered += String.fromCharCode(code);
- }
- displayField.value = encryption(valueEntered);
- if (displayField.value.length >= 4)
- self.dialogDone.disabled = false;
- else
- self.dialogDone.disabled = true;
- });
-
- function encryption(str) {
- return (new Array(str.length + 1)).join('*');
- }
-
- function setValue(value) {
- valueEntered = value;
- inputField.value = value;
- displayField.value = encryption(valueEntered);
- }
-
- function setFocus() {
- inputField.focus();
- }
-
- function blur() {
- inputField.blur();
- }
-
- return {
- get value() { return valueEntered; },
- set value(value) { setValue(value) },
- focus: setFocus,
- blur: blur
- };
- },
-
- handleCardState: function spl_handleCardState() {
- var _ = navigator.mozL10n.get;
-
- var cardState = this.mobileConnection.cardState;
- switch (cardState) {
- case 'pinRequired':
- this.lockType = 'pin';
- this.errorMsg.hidden = true;
- this.inputFieldControl(true, false, false, false);
- this.pinInput.focus();
- break;
- case 'pukRequired':
- this.lockType = 'puk';
- this.errorMsgHeader.textContent = _('simCardLockedMsg') || '';
- this.errorMsgHeader.dataset.l10nId = 'simCardLockedMsg';
- this.errorMsgBody.textContent = _('enterPukMsg') || '';
- this.errorMsgBody.dataset.l10nId = 'enterPukMsg';
- this.errorMsg.hidden = false;
- this.inputFieldControl(false, true, false, true);
- this.pukInput.focus();
- break;
- case 'networkLocked':
- this.lockType = 'nck';
- this.errorMsg.hidden = true;
- this.inputFieldControl(false, false, true, false);
- this.nckInput.focus();
- break;
- default:
- this.skip();
- break;
- }
- this.dialogTitle.textContent = _(this.lockType + 'Title') || '';
- this.dialogTitle.dataset.l10nId = this.lockType + 'Title';
- },
-
- handleError: function spl_handleLockError(evt) {
- var retry = (evt.retryCount) ? evt.retryCount : -1;
- this.showErrorMsg(retry, evt.lockType);
- if (retry === -1) {
- this.skip();
- return;
- }
- if (evt.lockType === 'pin') {
- this.pinInput.focus();
- } else if (evt.lockType === 'puk') {
- this.pukInput.focus();
- } else {
- this.nckInput.focus();
- }
- },
-
- showErrorMsg: function spl_showErrorMsg(retry, type) {
- var _ = navigator.mozL10n.get;
-
- this.errorMsgHeader.textContent = _(type + 'ErrorMsg');
- this.errorMsgHeader.dataset.l10nId = type + 'ErrorMsg';
-
- if (retry !== 1) {
- var l10nArgs = { n: retry };
- this.errorMsgBody.dataset.l10nId = type + 'AttemptMsg';
- this.errorMsgBody.dataset.l10nArgs = JSON.stringify(l10nArgs);
- this.errorMsgBody.textContent = _(type + 'AttemptMsg', l10nArgs);
- } else {
- this.errorMsgBody.dataset.l10nId = type + 'LastChanceMsg';
- this.errorMsgBody.textContent = _(type + 'LastChanceMsg');
- }
-
- this.errorMsg.hidden = false;
- },
-
- unlockPin: function spl_unlockPin() {
- var pin = this.pinInput.value;
- if (pin === '')
- return;
-
- var options = {lockType: 'pin', pin: pin };
- this.unlockCardLock(options);
- this.clear();
- },
-
- unlockPuk: function spl_unlockPuk() {
- var _ = navigator.mozL10n.get;
-
- var puk = this.pukInput.value;
- var newPin = this.newPinInput.value;
- var confirmPin = this.confirmPinInput.value;
- if (puk === '' || newPin === '' || confirmPin === '')
- return;
-
- if (newPin !== confirmPin) {
- this.errorMsgHeader.textContent = _('newPinErrorMsg');
- this.errorMsgHeader.dataset.l10nId = 'newPinErrorMsg';
- this.errorMsgBody.textContent = '';
- this.errorMsg.hidden = false;
- return;
- }
- var options = {lockType: 'puk', puk: puk, newPin: newPin };
- this.unlockCardLock(options);
- this.clear();
- },
-
- unlockNck: function spl_unlockNck() {
- var nck = this.nckInput.value;
- if (nck === '')
- return;
-
- var options = {lockType: 'nck', pin: nck };
- this.unlockCardLock(options);
- this.clear();
- },
-
- unlockCardLock: function spl_unlockCardLock(options) {
- var req = this.mobileConnection.unlockCardLock(options);
- req.onsuccess = this.close.bind(this, 'success');
- },
-
- enableLock: function spl_enableLock() {
- var pin = this.pinInput.value;
- if (pin === '')
- return;
-
- var enabled = SimPinLock.simPinCheckBox.checked;
- var options = {lockType: 'pin', pin: pin, enabled: enabled};
- this.setCardLock(options);
- this.clear();
- },
-
- changePin: function spl_changePin() {
- var _ = navigator.mozL10n.get;
-
- var pin = this.pinInput.value;
- var newPin = this.newPinInput.value;
- var confirmPin = this.confirmPinInput.value;
- if (pin === '' || newPin === '' || confirmPin === '')
- return;
-
- if (newPin !== confirmPin) {
- this.errorMsgHeader.textContent = _('newPinErrorMsg');
- this.errorMsgHeader.dataset.l10nId = 'newPinErrorMsg';
- this.errorMsgBody.textContent = '';
- this.errorMsg.hidden = false;
- return;
- }
- var options = {lockType: 'pin', pin: pin, newPin: newPin};
- this.setCardLock(options);
- this.clear();
- },
-
- setCardLock: function spl_setCardLock(options) {
- var req = this.mobileConnection.setCardLock(options);
- req.onsuccess = this.close.bind(this, 'success');
- },
- inputFieldControl: function spl_inputField(isPin, isPuk, isNck, isNewPin) {
- this.pinArea.hidden = !isPin;
- this.pukArea.hidden = !isPuk;
- this.nckArea.hidden = !isNck;
- this.newPinArea.hidden = !isNewPin;
- this.confirmPinArea.hidden = !isNewPin;
- },
-
- verify: function spl_verify() {
- switch (this.action) {
- case 'unlock':
- if (this.lockType === 'pin')
- this.unlockPin();
- else if (this.lockType === 'puk') {
- this.unlockPuk();
- } else {
- this.unlockNck();
- }
- break;
- case 'enable':
- this.enableLock();
- break;
- case 'changePin':
- this.changePin();
- break;
- }
- return false;
- },
-
- onHide: function spl_onHide(reason) {
- this.clear();
- if (this.onclose)
- this.onclose(reason);
- },
-
- clear: function spl_clear() {
- this.errorMsg.hidden = true;
- this.pinInput.value = '';
- this.pinInput.blur();
- this.pukInput.value = '';
- this.pukInput.blur();
- this.newPinInput.value = '';
- this.confirmPinInput.value = '';
- },
-
- onclose: null,
- /**
- * Show the SIM pin dialog
- * @param {String} action Name of the action to execute,
- * either: unlock, enable or changePin.
- * @param {Function} title Optional function called when dialog is closed.
- * Receive a single argument being the reason of
- * dialog closing: success, skip, home or holdhome.
- */
- show: function spl_show(action, onclose) {
- var _ = navigator.mozL10n.get;
-
- this.systemDialog.show();
- this.dialogDone.disabled = true;
- this.action = action;
- this.lockType = 'pin';
- switch (action) {
- case 'unlock':
- this.handleCardState();
- break;
- case 'enable':
- this.inputFieldControl(true, false, false, false);
- this.dialogTitle.textContent = _('pinTitle') || '';
- this.dialogTitle.dataset.l10nId = 'pinTitle';
- break;
- case 'changePin':
- this.inputFieldControl(true, false, false, true);
- this.dialogTitle.textContent = _('newpinTitle') || '';
- this.dialogTitle.dataset.l10nId = 'newpinTitle';
- break;
- }
-
- if (onclose && typeof onclose === 'function')
- this.onclose = onclose;
- },
-
- close: function spl_close(reason) {
- this.systemDialog.hide(reason);
- },
-
- skip: function spl_skip() {
- this.close('skip');
- return false;
- },
-
- init: function spl_init() {
- this.systemDialog = SystemDialog('simpin-dialog', {
- onHide: this.onHide.bind(this)
- });
-
- this.mobileConnection = window.navigator.mozMobileConnection;
- if (!this.mobileConnection)
- return;
-
- this.mobileConnection.addEventListener('icccardlockerror',
- this.handleError.bind(this));
-
- this.dialogDone.onclick = this.verify.bind(this);
- this.dialogClose.onclick = this.skip.bind(this);
- this.pinInput = this.getNumberPasswordInputField('simpin');
- this.pukInput = this.getNumberPasswordInputField('simpuk');
- this.nckInput = this.getNumberPasswordInputField('nckpin');
- this.newPinInput = this.getNumberPasswordInputField('newSimpin');
- this.confirmPinInput = this.getNumberPasswordInputField('confirmNewSimpin');
- }
-};
-
-SimPinDialog.init();
-
diff --git a/apps/system/js/sleep_menu.js b/apps/system/js/sleep_menu.js
deleted file mode 100644
index a97b772..0000000
--- a/apps/system/js/sleep_menu.js
+++ /dev/null
@@ -1,276 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var SleepMenu = {
- // Indicate setting status of ril.radio.disabled
- isFlightModeEnabled: false,
-
- // Indicate setting status of volume
- isSilentModeEnabled: false,
-
- elements: {},
-
- get visible() {
- return this.elements.overlay.classList.contains('visible');
- },
-
- getAllElements: function sm_getAllElements() {
- this.elements.overlay = document.getElementById('sleep-menu');
- this.elements.container =
- document.querySelector('#sleep-menu-container ul');
- this.elements.cancel = document.querySelector('#sleep-menu button');
- },
-
- init: function sm_init() {
- this.getAllElements();
- window.addEventListener('holdsleep', this.show.bind(this));
- window.addEventListener('click', this, true);
- window.addEventListener('screenchange', this, true);
- window.addEventListener('home', this);
- this.elements.cancel.addEventListener('click', this);
-
- var self = this;
- SettingsListener.observe('ril.radio.disabled', false, function(value) {
- self.isFlightModeEnabled = value;
- });
-
- var settings = navigator.mozSettings;
- SettingsListener.observe('audio.volume.notification', 7, function(value) {
- settings.createLock().set({'ring.enabled': (value != 0)});
- });
-
- SettingsListener.observe('ring.enabled', true, function(value) {
- self.isSilentModeEnabled = !value;
- });
- },
-
- // Generate items
- generateItems: function sm_generateItems() {
- var items = [];
- var _ = navigator.mozL10n.get;
- var options = {
- airplane: {
- label: _('airplane'),
- value: 'airplane',
- icon: '/style/sleep_menu/images/airplane.png'
- },
- airplaneOff: {
- label: _('airplaneOff'),
- value: 'airplane'
- },
- silent: {
- label: _('silent'),
- value: 'silent',
- icon: '/style/sleep_menu/images/vibration.png'
- },
- silentOff: {
- label: _('normal'),
- value: 'silentOff'
- },
- restart: {
- label: _('restart'),
- value: 'restart',
- icon: '/style/sleep_menu/images/restart.png'
- },
- power: {
- label: _('power'),
- value: 'power',
- icon: '/style/sleep_menu/images/power-off.png'
- }
- };
-
- if (this.isFlightModeEnabled) {
- items.push(options.airplaneOff);
- } else {
- items.push(options.airplane);
- }
-
- if (!this.isSilentModeEnabled) {
- items.push(options.silent);
- } else {
- items.push(options.silentOff);
- }
-
- items.push(options.restart);
- items.push(options.power);
-
- return items;
- },
-
- show: function sm_show() {
- this.elements.container.innerHTML = '';
- this.buildMenu(this.generateItems());
- this.elements.overlay.classList.add('visible');
- },
-
- buildMenu: function sm_buildMenu(items) {
- items.forEach(function traveseItems(item) {
- var item_li = document.createElement('li');
- item_li.dataset.value = item.value;
- item_li.textContent = item.label;
- this.elements.container.appendChild(item_li);
- }, this);
- },
-
- hide: function lm_hide() {
- this.elements.overlay.classList.remove('visible');
- },
-
- handleEvent: function sm_handleEvent(evt) {
- switch (evt.type) {
- case 'screenchange':
- if (!evt.detail.screenEnabled)
- this.hide();
- break;
-
- case 'click':
- if (!this.visible)
- return;
-
- if (evt.currentTarget === this.elements.cancel) {
- this.hide();
- return;
- }
-
- var action = evt.target.dataset.value;
- if (!action) {
- return;
- }
- this.hide();
- this.handler(action);
- break;
-
- case 'home':
- if (this.visible) {
- this.hide();
- }
- break;
- }
- },
-
- handler: function sm_handler(action) {
- switch (action) {
- case 'airplane':
- // Airplane mode should turn off
- //
- // Radio ('ril.radio.disabled'`)
- // Data ('ril.data.enabled'`)
- // Wifi
- // Bluetooth
- // Geolocation
- //
- // It should also save the status of the latter 4 items
- // so when leaving the airplane mode we could know which one to turn on.
-
- if (!window.navigator.mozSettings)
- return;
-
- SettingsListener.getSettingsLock().set({
- 'ril.radio.disabled': !this.isFlightModeEnabled
- });
-
- break;
-
- // About silent and silentOff
- // * Turn on silent mode will cause:
- // * Turn off ringtone no matter if ring is on or off
- // * for sms and incoming calls.
- // * Turn off silent mode will cause:
- // * Turn on ringtone no matter if ring is on or off
- // * for sms and incoming calls.
- case 'silent':
- if (!window.navigator.mozSettings)
- return;
-
- SettingsListener.getSettingsLock().set({
- 'ring.enabled': false
- });
- this.isSilentModeEnabled = true;
-
- break;
-
- case 'silentOff':
- if (!window.navigator.mozSettings)
- return;
-
- SettingsListener.getSettingsLock().set({
- 'ring.enabled': true
- });
- this.isSilentModeEnabled = false;
-
- break;
-
- case 'restart':
- this.startPowerOff(true);
-
- break;
-
- case 'power':
- this.startPowerOff(false);
-
- break;
- }
- },
-
- startPowerOff: function sm_startPowerOff(reboot) {
- var power = navigator.mozPower;
- if (!power)
- return;
-
- // Early return if we are already shutting down.
- if (document.getElementById('poweroff-splash'))
- return;
-
- // Show shutdown animation before actually performing shutdown.
- // * step1: fade-in poweroff-splash.
- // * step2: The 3-rings animation is performed on the screen.
- var div = document.createElement('div');
- div.dataset.zIndexLevel = 'poweroff-splash';
- div.id = 'poweroff-splash';
-
- // The overall animation ends when the inner span of the bottom ring
- // is animated, so we store it for detecting.
- var inner;
-
- for (var i = 1; i <= 3; i++) {
- var outer = document.createElement('span');
- outer.className = 'poweroff-ring';
- outer.id = 'poweroff-ring-' + i;
- div.appendChild(outer);
-
- inner = document.createElement('span');
- outer.appendChild(inner);
- }
-
- div.className = 'step1';
-
- var nextAnimation = function nextAnimation(e) {
- // Switch to next class
- if (e.target == div)
- div.className = 'step2';
-
- if (e.target != inner)
- return;
-
- // Actual poweroff/reboot
- setTimeout(function powerOffAnimated() {
- if (reboot) {
- power.reboot();
- } else {
- power.powerOff();
- }
- });
-
- // Paint screen to black before reboot/poweroff
- ScreenManager.turnScreenOff(true);
- };
-
- div.addEventListener('animationend', nextAnimation);
-
- document.getElementById('screen').appendChild(div);
- }
-};
-
-SleepMenu.init();
diff --git a/apps/system/js/sound_manager.js b/apps/system/js/sound_manager.js
deleted file mode 100644
index 52dfc06..0000000
--- a/apps/system/js/sound_manager.js
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-(function() {
- window.addEventListener('volumeup', function() {
- if (onBTEarphoneConnected() && onCall()) {
- changeVolume(1, 'bt_sco');
- } else {
- changeVolume(1);
- }
- });
- window.addEventListener('volumedown', function() {
- if (onBTEarphoneConnected() && onCall()) {
- changeVolume(-1, 'bt_sco');
- } else {
- changeVolume(-1);
- }
- });
-
- // Store the current active channel;
- // change with 'audio-channel-changed' mozChromeEvent
- var currentChannel = 'notification';
-
- var vibrationEnabled = true;
-
- // This event is generated in shell.js in response to bluetooth headset.
- // Bluetooth headset always assign audio volume to a specific value when
- // pressing its volume-up/volume-down buttons.
- window.addEventListener('mozChromeEvent', function(e) {
- var type = e.detail.type;
- if (type == 'bluetooth-volumeset') {
- changeVolume(e.detail.value - currentVolume['bt_sco'], 'bt_sco');
- } else if (type == 'audio-channel-changed') {
- currentChannel = e.detail.channel;
- }
- });
-
- function onCall() {
- if (currentChannel == 'telephony')
- return true;
-
- // XXX: This work should be removed
- // once we could get telephony channel change event
- // https://bugzilla.mozilla.org/show_bug.cgi?id=819858
- var telephony = window.navigator.mozTelephony;
- if (!telephony)
- return false;
-
- return telephony.calls.some(function callIterator(call) {
- return (call.state == 'connected');
- });
- }
-
- function onBTEarphoneConnected() {
- var bluetooth = navigator.mozBluetooth;
- if (!bluetooth)
- return false;
-
- // 0x111E is for querying earphone type.
- return navigator.mozBluetooth.isConnected(0x111E);
- };
-
- // Platform doesn't provide the maximum value of each channel
- // therefore, hard code here.
- var MAX_VOLUME = {
- 'alarm': 15,
- 'notification': 15,
- 'telephony': 5,
- 'content': 15,
- 'bt_sco': 15
- };
-
- // Please refer https://wiki.mozilla.org/WebAPI/AudioChannels > Settings
- var currentVolume = {
- 'alarm': 15,
- 'notification': 15,
- 'telephony': 5,
- 'content': 15,
- 'bt_sco': 15
- };
- var pendingRequestCount = 0;
-
- // We have three virtual states here:
- // OFF -> VIBRATION -> MUTE
- var muteState = 'OFF';
-
- for (var channel in currentVolume) {
- (function(channel) {
- var setting = 'audio.volume.' + channel;
- SettingsListener.observe(setting, 5, function onSettingsChange(volume) {
- if (pendingRequestCount)
- return;
-
- var max = MAX_VOLUME[channel];
- currentVolume[channel] =
- parseInt(Math.max(0, Math.min(max, volume)), 10);
- });
- })(channel);
- }
-
- SettingsListener.observe('vibration.enabled', true, function(vibration) {
- if (pendingRequestCount)
- return;
-
- vibrationEnabled = vibration;
- });
-
- var activeTimeout = 0;
-
- // When hardware volume key is pressed, we need to decide which channel we
- // should toggle.
- // This method returns the string for setting key 'audio.volume.*' represents
- // that.
- // Note: this string does not always equal to currentChannel since some
- // different channels are grouped together to listen to the same setting.
- function getChannel() {
- if (onCall())
- return 'telephony';
-
- switch (currentChannel) {
- case 'normal':
- case 'content':
- return 'content';
- case 'telephony':
- return 'telephony';
- case 'alarm':
- return 'alarm';
- case 'notification':
- case 'ringer':
- default:
- return 'notification';
- }
- }
-
- function getVolumeState(currentVolume, delta, channel) {
- if (channel == 'notification') {
- if (currentVolume + delta <= 0) {
- if (currentVolume == 0 && vibrationEnabled) {
- vibrationEnabled = false;
- } else if (currentVolume > 0 && !vibrationEnabled) {
- vibrationEnabled = true;
- }
- return 'MUTE';
- } else {
- return 'OFF';
- }
- } else {
- if (currentVolume + delta <= 0) {
- return 'MUTE';
- } else {
- return 'OFF';
- }
- }
- }
-
- function changeVolume(delta, channel) {
- channel = channel ? channel : getChannel();
-
- muteState = getVolumeState(currentVolume[channel], delta, channel);
-
- var volume = currentVolume[channel] + delta;
-
- currentVolume[channel] = volume =
- Math.max(0, Math.min(MAX_VOLUME[channel], volume));
-
- var overlay = document.getElementById('system-overlay');
- var notification = document.getElementById('volume');
- var overlayClasses = overlay.classList;
- var classes = notification.classList;
-
- switch (muteState) {
- case 'OFF':
- classes.remove('mute');
- if (vibrationEnabled) {
- classes.add('vibration');
- } else {
- classes.remove('vibration');
- }
- break;
- case 'MUTE':
- classes.add('mute');
- if (channel == 'notification') {
- if (vibrationEnabled) {
- classes.add('vibration');
- SettingsListener.getSettingsLock().set({
- 'vibration.enabled': true
- });
- } else {
- classes.remove('vibration');
- SettingsListener.getSettingsLock().set({
- 'vibration.enabled': false
- });
- }
- }
- break;
- }
-
- var steps =
- Array.prototype.slice.call(notification.querySelectorAll('div'), 0);
-
- for (var i = 0; i < steps.length; i++) {
- var step = steps[i];
- if (i < volume) {
- step.classList.add('active');
- } else {
- step.classList.remove('active');
- }
- }
-
- overlayClasses.add('volume');
- classes.add('visible');
- window.clearTimeout(activeTimeout);
- activeTimeout = window.setTimeout(function hideSound() {
- overlayClasses.remove('volume');
- classes.remove('visible');
- }, 1500);
-
- if (!window.navigator.mozSettings)
- return;
-
- pendingRequestCount++;
- var req;
-
- notification.dataset.channel = channel;
-
- var settingObject = {};
- settingObject['audio.volume.' + channel] = volume;
-
- req = SettingsListener.getSettingsLock().set(settingObject);
-
- req.onsuccess = function onSuccess() {
- pendingRequestCount--;
- };
-
- req.onerror = function onError() {
- pendingRequestCount--;
- };
- }
-})();
-
diff --git a/apps/system/js/source_view.js b/apps/system/js/source_view.js
deleted file mode 100644
index dc6b8e4..0000000
--- a/apps/system/js/source_view.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var SourceView = {
- get viewer() {
- return document.getElementById('appViewsource');
- },
-
- get active() {
- return !this.viewer ? false : this.viewer.style.visibility === 'visible';
- },
-
- init: function sv_init() {
- window.addEventListener('home+volume', function() {
- if (ScreenManager.screenEnabled)
- SourceView.toggle();
- });
- window.addEventListener('locked', function() {
- SourceView.hide();
- });
- },
-
- show: function sv_show() {
- var viewsource = this.viewer;
- if (!viewsource) {
- var style = '#appViewsource { ' +
- ' position: absolute;' +
- ' top: -moz-calc(10%);' +
- ' left: -moz-calc(10%);' +
- ' width: -moz-calc(80% - 2 * 15px);' +
- ' height: -moz-calc(80% - 2 * 15px);' +
- ' visibility: hidden;' +
- ' margin: 15px;' +
- ' background-color: white;' +
- ' opacity: 0.92;' +
- ' color: black;' +
- ' z-index: 9999;' +
- '}';
- document.styleSheets[0].insertRule(style, 0);
-
- viewsource = document.createElement('iframe');
- viewsource.id = 'appViewsource';
- document.body.appendChild(viewsource);
- }
-
- var url = WindowManager.getDisplayedApp();
- if (!url)
- // Assume the home screen is the visible app.
- url = window.location.toString();
- viewsource.src = 'view-source: ' + url;
- viewsource.style.visibility = 'visible';
- },
-
- hide: function sv_hide() {
- var viewsource = this.viewer;
- if (viewsource) {
- viewsource.style.visibility = 'hidden';
- viewsource.src = 'about:blank';
- }
- },
-
- toggle: function sv_toggle() {
- this.active ? this.hide() : this.show();
- }
-};
diff --git a/apps/system/js/statusbar.js b/apps/system/js/statusbar.js
deleted file mode 100644
index 1d95d99..0000000
--- a/apps/system/js/statusbar.js
+++ /dev/null
@@ -1,618 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var StatusBar = {
- /* all elements that are children nodes of the status bar */
- ELEMENTS: ['notification', 'time',
- 'battery', 'wifi', 'data', 'flight-mode', 'signal', 'network-activity',
- 'tethering', 'alarm', 'bluetooth', 'mute', 'headphones',
- 'recording', 'sms', 'geolocation', 'usb', 'label', 'system-downloads',
- 'call-forwarding'],
-
- /* Timeout for 'recently active' indicators */
- kActiveIndicatorTimeout: 60 * 1000,
-
- /* Whether or not status bar is actively updating or not */
- active: true,
-
- /* Some values that sync from mozSettings */
- settingValues: {},
-
- /* Keep the DOM element references here */
- icons: {},
-
- /* A mapping table between technology names
- we would get from API v.s. the icon we want to show. */
- mobileDataIconTypes: {
- 'lte': '4G', // 4G LTE
- 'ehrpd': '4G', // 4G CDMA
- 'hspa+': 'H+', // 3.5G HSPA+
- 'hsdpa': 'H', 'hsupa': 'H', 'hspa': 'H', // 3.5G HSDPA
- 'evdo0': '3G', 'evdoa': '3G', 'evdob': '3G', '1xrtt': '3G', // 3G CDMA
- 'umts': '3G', // 3G
- 'edge': 'E', // EDGE
- 'is95a': '2G', 'is95b': '2G', // 2G CDMA
- 'gprs': '2G'
- },
-
- geolocationActive: false,
- geolocationTimer: null,
-
- recordingActive: false,
- recordingTimer: null,
-
- umsActive: false,
-
- headphonesActive: false,
-
- /**
- * this keeps how many current installs/updates we do
- * it triggers the icon "systemDownloads"
- */
- systemDownloadsCount: 0,
-
- /* For other modules to acquire */
- get height() {
- if (this.screen.classList.contains('fullscreen-app') ||
- document.mozFullScreen) {
- return 0;
- } else if (this.screen.classList.contains('active-statusbar')) {
- return this.attentionBar.offsetHeight;
- } else {
- return this._cacheHeight ||
- (this._cacheHeight = this.element.getBoundingClientRect().height);
- }
- },
-
- init: function sb_init() {
- this.getAllElements();
-
- var settings = {
- 'ril.radio.disabled': ['signal', 'data'],
- 'ril.data.enabled': ['data'],
- 'wifi.enabled': ['wifi'],
- 'bluetooth.enabled': ['bluetooth'],
- 'tethering.usb.enabled': ['tethering'],
- 'tethering.wifi.enabled': ['tethering'],
- 'tethering.wifi.connectedClients': ['tethering'],
- 'tethering.usb.connectedClients': ['tethering'],
- 'ring.enabled': ['mute'],
- 'alarm.enabled': ['alarm'],
- 'vibration.enabled': ['vibration'],
- 'ril.cf.enabled': ['callForwarding']
- };
-
- var self = this;
- for (var settingKey in settings) {
- (function sb_setSettingsListener(settingKey) {
- SettingsListener.observe(settingKey, false,
- function sb_settingUpdate(value) {
- self.settingValues[settingKey] = value;
- settings[settingKey].forEach(
- function sb_callUpdate(name) {
- self.update[name].call(self);
- }
- );
- }
- );
- self.settingValues[settingKey] = false;
- })(settingKey);
- }
-
- // Listen to 'screenchange' from screen_manager.js
- window.addEventListener('screenchange', this);
-
- // Listen to 'geolocation-status' and 'recording-status' mozChromeEvent
- window.addEventListener('mozChromeEvent', this);
-
- // Listen to 'bluetoothconnectionchange' from bluetooth.js
- window.addEventListener('bluetoothconnectionchange', this);
-
- // Listen to 'moztimechange'
- window.addEventListener('moztimechange', this);
-
- this.systemDownloadsCount = 0;
- this.setActive(true);
- },
-
- handleEvent: function sb_handleEvent(evt) {
- switch (evt.type) {
- case 'screenchange':
- this.setActive(evt.detail.screenEnabled);
- break;
-
- case 'chargingchange':
- case 'levelchange':
- case 'statuschange':
- this.update.battery.call(this);
- break;
-
- case 'voicechange':
- this.update.signal.call(this);
- this.update.label.call(this);
- break;
-
- case 'cardstatechange':
- this.update.signal.call(this);
- this.update.label.call(this);
- this.update.data.call(this);
- break;
-
- case 'callschanged':
- this.update.signal.call(this);
- break;
-
- case 'iccinfochange':
- this.update.label.call(this);
- break;
-
- case 'datachange':
- this.update.data.call(this);
- break;
-
- case 'bluetoothconnectionchange':
- this.update.bluetooth.call(this);
- break;
-
- case 'moztimechange':
- this.update.time.call(this);
- break;
-
- case 'mozChromeEvent':
- switch (evt.detail.type) {
- case 'geolocation-status':
- this.geolocationActive = evt.detail.active;
- this.update.geolocation.call(this);
- break;
-
- case 'recording-status':
- this.recordingActive = evt.detail.active;
- this.update.recording.call(this);
- break;
-
- case 'volume-state-changed':
- this.umsActive = evt.detail.active;
- this.update.usb.call(this);
- break;
-
- case 'headphones-status-changed':
- this.headphonesActive = (evt.detail.state != 'off');
- this.update.headphones.call(this);
- break;
- }
-
- break;
-
- case 'moznetworkupload':
- case 'moznetworkdownload':
- this.update.networkActivity.call(this);
- break;
- }
- },
-
- setActive: function sb_setActive(active) {
- this.active = active;
- if (active) {
- this.update.time.call(this);
-
- var battery = window.navigator.battery;
- if (battery) {
- battery.addEventListener('chargingchange', this);
- battery.addEventListener('levelchange', this);
- battery.addEventListener('statuschange', this);
- this.update.battery.call(this);
- }
-
- var conn = window.navigator.mozMobileConnection;
- if (conn) {
- conn.addEventListener('voicechange', this);
- conn.addEventListener('iccinfochange', this);
- conn.addEventListener('datachange', this);
- this.update.signal.call(this);
- this.update.data.call(this);
- }
-
- window.addEventListener('wifi-statuschange',
- this.update.wifi.bind(this));
- this.update.wifi.call(this);
-
- window.addEventListener('moznetworkupload', this);
- window.addEventListener('moznetworkdownload', this);
- } else {
- clearTimeout(this._clockTimer);
-
- var battery = window.navigator.battery;
- if (battery) {
- battery.removeEventListener('chargingchange', this);
- battery.removeEventListener('levelchange', this);
- battery.removeEventListener('statuschange', this);
- }
-
- var conn = window.navigator.mozMobileConnection;
- if (conn) {
- conn.removeEventListener('voicechange', this);
- conn.removeEventListener('iccinfochange', this);
- conn.removeEventListener('datachange', this);
- }
-
- window.removeEventListener('moznetworkupload', this);
- window.removeEventListener('moznetworkdownload', this);
- }
- },
-
- update: {
- label: function sb_updateLabel() {
- var conn = window.navigator.mozMobileConnection;
- var label = this.icons.label;
- var l10nArgs = JSON.parse(label.dataset.l10nArgs || '{}');
-
- if (!conn || !conn.voice || !conn.voice.connected ||
- conn.voice.emergencyCallsOnly) {
- delete l10nArgs.operator;
- label.dataset.l10nArgs = JSON.stringify(l10nArgs);
-
- label.dataset.l10nId = '';
- label.textContent = l10nArgs.date;
-
- return;
- }
-
- var operatorInfos = MobileOperator.userFacingInfo(conn);
- l10nArgs.operator = operatorInfos.operator;
-
- if (operatorInfos.region) {
- l10nArgs.operator += ' ' + operatorInfos.region;
- }
-
- label.dataset.l10nArgs = JSON.stringify(l10nArgs);
-
- label.dataset.l10nId = 'statusbarLabel';
- label.textContent = navigator.mozL10n.get('statusbarLabel', l10nArgs);
- },
-
- time: function sb_updateTime() {
- // Schedule another clock update when a new minute rolls around
- var _ = navigator.mozL10n.get;
- var f = new navigator.mozL10n.DateTimeFormat();
- var now = new Date();
- var sec = now.getSeconds();
- if (this._clockTimer)
- window.clearTimeout(this._clockTimer);
- this._clockTimer =
- window.setTimeout((this.update.time).bind(this), (59 - sec) * 1000);
-
- var formated = f.localeFormat(now, _('shortTimeFormat'));
- formated = formated.replace(/\s?(AM|PM)\s?/i, '<span>$1</span>');
- this.icons.time.innerHTML = formated;
-
- var label = this.icons.label;
- var l10nArgs = JSON.parse(label.dataset.l10nArgs || '{}');
- l10nArgs.date = f.localeFormat(now, _('statusbarDateFormat'));
- label.dataset.l10nArgs = JSON.stringify(l10nArgs);
- this.update.label.call(this);
- },
-
- battery: function sb_updateBattery() {
- var battery = window.navigator.battery;
- if (!battery)
- return;
-
- var icon = this.icons.battery;
-
- icon.hidden = false;
- icon.dataset.charging = battery.charging;
- icon.dataset.level = Math.floor(battery.level * 10) * 10;
- },
-
- networkActivity: function sb_updateNetworkActivity() {
- // Each time we receive an update, make network activity indicator
- // show up for 500ms.
-
- var icon = this.icons.networkActivity;
-
- clearTimeout(this._networkActivityTimer);
- icon.hidden = false;
-
- this._networkActivityTimer = setTimeout(function hideNetActivityIcon() {
- icon.hidden = true;
- }, 500);
- },
-
- signal: function sb_updateSignal() {
- var conn = window.navigator.mozMobileConnection;
- if (!conn || !conn.voice)
- return;
-
- var voice = conn.voice;
- var icon = this.icons.signal;
- var flightModeIcon = this.icons.flightMode;
- var _ = navigator.mozL10n.get;
-
- if (this.settingValues['ril.radio.disabled']) {
- // "Airplane Mode"
- icon.hidden = true;
- flightModeIcon.hidden = false;
- return;
- }
-
- flightModeIcon.hidden = true;
- icon.hidden = false;
-
- if (conn.cardState === 'absent') {
- // no SIM
- delete icon.dataset.level;
- delete icon.dataset.emergency;
- delete icon.dataset.searching;
- delete icon.dataset.roaming;
- } else if (voice.connected || this.hasActiveCall()) {
- // "Carrier" / "Carrier (Roaming)"
- icon.dataset.level = Math.ceil(voice.relSignalStrength / 20); // 0-5
- icon.dataset.roaming = voice.roaming;
-
- delete icon.dataset.emergency;
- delete icon.dataset.searching;
- } else {
- // "No Network" / "Emergency Calls Only (REASON)" / trying to connect
- icon.dataset.level = -1;
- // logically, we should have "&& !voice.connected" as well but we
- // already know this.
- icon.dataset.searching = (!voice.emergencyCallsOnly &&
- voice.state !== 'notSearching');
- icon.dataset.emergency = (voice.emergencyCallsOnly);
- delete icon.dataset.roaming;
- }
-
- if (voice.emergencyCallsOnly) {
- this.addCallListener();
- } else {
- this.removeCallListener();
- }
-
- },
-
- data: function sb_updateSignal() {
- var conn = window.navigator.mozMobileConnection;
- if (!conn || !conn.data)
- return;
-
- var data = conn.data;
- var icon = this.icons.data;
-
- if (this.settingValues['ril.radio.disabled'] ||
- !this.settingValues['ril.data.enabled'] ||
- !this.icons.wifi.hidden || !data.connected) {
- icon.hidden = true;
-
- return;
- }
-
- icon.hidden = false;
- icon.dataset.type =
- this.mobileDataIconTypes[data.type] || 'circle';
- },
-
-
- wifi: function sb_updateWifi() {
- var wifiManager = window.navigator.mozWifiManager;
- if (!wifiManager)
- return;
-
- var icon = this.icons.wifi;
- var wasHidden = icon.hidden;
-
- if (!this.settingValues['wifi.enabled']) {
- icon.hidden = true;
- if (!wasHidden)
- this.update.data.call(this);
-
- return;
- }
-
- switch (wifiManager.connection.status) {
- case 'disconnected':
- icon.hidden = true;
-
- break;
-
- case 'connecting':
- case 'associated':
- icon.hidden = false;
- icon.dataset.connecting = true;
- icon.dataset.level = 0;
-
- break;
-
- case 'connected':
- icon.hidden = false;
-
- var relSignalStrength =
- wifiManager.connectionInformation.relSignalStrength;
- icon.dataset.level = Math.floor(relSignalStrength / 25);
-
- break;
- }
-
- if (icon.hidden !== wasHidden)
- this.update.data.call(this);
- },
-
- tethering: function sb_updateTethering() {
- var icon = this.icons.tethering;
- icon.hidden = !(this.settingValues['tethering.usb.enabled'] ||
- this.settingValues['tethering.wifi.enabled']);
-
- icon.dataset.active =
- (this.settingValues['tethering.wifi.connectedClients'] !== 0) ||
- (this.settingValues['tethering.usb.connectedClients'] !== 0);
- },
-
- bluetooth: function sb_updateBluetooth() {
- var icon = this.icons.bluetooth;
-
- icon.hidden = !this.settingValues['bluetooth.enabled'];
- icon.dataset.active = Bluetooth.connected;
- },
-
- alarm: function sb_updateAlarm() {
- this.icons.alarm.hidden = !this.settingValues['alarm.enabled'];
- },
-
- mute: function sb_updateMute() {
- this.icons.mute.hidden =
- (this.settingValues['ring.enabled'] == true);
- },
-
- vibration: function sb_vibration() {
- var vibrate = (this.settingValues['vibration.enabled'] == true);
- if (vibrate) {
- this.icons.mute.classList.add('vibration');
- } else {
- this.icons.mute.classList.remove('vibration');
- }
- },
-
- recording: function sb_updateRecording() {
- window.clearTimeout(this.recordingTimer);
-
- var icon = this.icons.recording;
- icon.dataset.active = this.recordingActive;
-
- if (this.recordingActive) {
- // Geolocation is currently active, show the active icon.
- icon.hidden = false;
- return;
- }
-
- // Geolocation is currently inactive.
- // Show the inactive icon and hide it after kActiveIndicatorTimeout
- this.recordingTimer = window.setTimeout(function hideGeoIcon() {
- icon.hidden = true;
- }, this.kActiveIndicatorTimeout);
- },
-
- sms: function sb_updateSms() {
- // We are not going to show this for v1
-
- // this.icon.sms.hidden = ?
- // this.icon.sms.dataset.num = ?;
- },
-
- geolocation: function sb_updateGeolocation() {
- window.clearTimeout(this.geolocationTimer);
-
- var icon = this.icons.geolocation;
- icon.dataset.active = this.geolocationActive;
-
- if (this.geolocationActive) {
- // Geolocation is currently active, show the active icon.
- icon.hidden = false;
- return;
- }
-
- // Geolocation is currently inactive.
- // Show the inactive icon and hide it after kActiveIndicatorTimeout
- this.geolocationTimer = window.setTimeout(function hideGeoIcon() {
- icon.hidden = true;
- }, this.kActiveIndicatorTimeout);
- },
-
- usb: function sb_updateUsb() {
- var icon = this.icons.usb;
- icon.hidden = !this.umsActive;
- },
-
- headphones: function sb_updateHeadphones() {
- var icon = this.icons.headphones;
- icon.hidden = !this.headphonesActive;
- },
-
- systemDownloads: function sb_updatesystemDownloads() {
- var icon = this.icons.systemDownloads;
- icon.hidden = (this.systemDownloadsCount === 0);
- },
-
- callForwarding: function sb_updateCallForwarding() {
- var icon = this.icons.callForwarding;
- icon.hidden = !this.settingValues['ril.cf.enabled'];
- }
- },
-
- hasActiveCall: function sb_hasActiveCall() {
- var telephony = navigator.mozTelephony;
-
- // will return true as soon as we begin dialing
- return !!(telephony && telephony.active);
- },
-
- addCallListener: function sb_addCallListener() {
- var telephony = navigator.mozTelephony;
- if (telephony) {
- telephony.addEventListener('callschanged', this);
- }
- },
-
- removeCallListener: function sb_addCallListener() {
- var telephony = navigator.mozTelephony;
- if (telephony) {
- telephony.removeEventListener('callschanged', this);
- }
- },
-
- updateNotification: function sb_updateNotification(count) {
- var icon = this.icons.notification;
- if (!count) {
- icon.hidden = true;
- return;
- }
-
- icon.hidden = false;
- icon.dataset.num = count;
- },
-
- updateNotificationUnread: function sb_updateNotificationUnread(unread) {
- this.icons.notification.dataset.unread = unread;
- },
-
- incSystemDownloads: function sb_incSystemDownloads() {
- this.systemDownloadsCount++;
- this.update.systemDownloads.call(this);
- },
-
- decSystemDownloads: function sb_decSystemDownloads() {
- if (--this.systemDownloadsCount < 0) {
- this.systemDownloadsCount = 0;
- }
-
- this.update.systemDownloads.call(this);
- },
-
- getAllElements: function sb_getAllElements() {
- // ID of elements to create references
-
- var toCamelCase = function toCamelCase(str) {
- return str.replace(/\-(.)/g, function replacer(str, p1) {
- return p1.toUpperCase();
- });
- };
-
- this.ELEMENTS.forEach((function createElementRef(name) {
- this.icons[toCamelCase(name)] =
- document.getElementById('statusbar-' + name);
- }).bind(this));
-
- this.element = document.getElementById('statusbar');
- this.screen = document.getElementById('screen');
- this.attentionBar = document.getElementById('attention-bar');
- }
-};
-
-if (navigator.mozL10n.readyState == 'complete' ||
- navigator.mozL10n.readyState == 'interactive') {
- StatusBar.init();
-} else {
- window.addEventListener('localized', StatusBar.init.bind(StatusBar));
-}
-
-
diff --git a/apps/system/js/storage.js b/apps/system/js/storage.js
deleted file mode 100644
index ff7b10e..0000000
--- a/apps/system/js/storage.js
+++ /dev/null
@@ -1,60 +0,0 @@
-var Storage = {
-
- automounterDisable: 0,
- automounterEnable: 1,
- automounterDisableWhenUnplugged: 2,
-
- umsEnabled: 'ums.enabled',
- umsMode: 'ums.mode',
-
- init: function storageInit() {
- this.setMode(this.automounterDisable, 'init');
- window.addEventListener('lock', this);
- window.addEventListener('unlock', this);
-
- SettingsListener.observe(this.umsEnabled, false, function umsChanged(val) {
- if (LockScreen.locked) {
- // covers startup
- Storage.setMode(Storage.automounterDisable, 'screen locked');
- } else {
- Storage.setMode(Storage.modeFromBool(val), 'change in ums.enabled');
- }
- });
- },
-
- modeFromBool: function storageModeFromBool(val) {
- return val ? this.automounterEnable : this.automounterDisable;
- },
-
- setMode: function storageSetMode(val, reason) {
- if (!window.navigator.mozSettings)
- return;
-
- //console.info('Setting', this.umsMode, 'to', val, 'due to', reason);
- var param = {};
- param[this.umsMode] = val;
- SettingsListener.getSettingsLock().set(param);
- },
-
- handleEvent: function storageHandleEvent(e) {
- switch (e.type) {
- case 'lock':
- this.setMode(this.automounterDisableWhenUnplugged, 'screen locked');
- break;
- case 'unlock':
- if (!window.navigator.mozSettings)
- return;
-
- var req = SettingsListener.getSettingsLock().get(this.umsEnabled);
- req.onsuccess = function umsEnabledFetched() {
- var mode = Storage.modeFromBool(req.result[Storage.umsEnabled]);
- Storage.setMode(mode, 'screen unlocked');
- };
- break;
- default:
- return;
- }
- }
-};
-
-Storage.init();
diff --git a/apps/system/js/system_banner.js b/apps/system/js/system_banner.js
deleted file mode 100644
index 89028e2..0000000
--- a/apps/system/js/system_banner.js
+++ /dev/null
@@ -1,33 +0,0 @@
-'use strict';
-
-var SystemBanner = {
- banner: document.getElementById('system-banner'),
-
- // Shows a banner with a given message.
- // Optionally shows a button with a given label/callback.
- // buttonParams = { label: ..., callback: ... }
- show: function sb_show(message, buttonParams) {
- var banner = this.banner;
- banner.firstElementChild.textContent = message;
-
- var button = banner.querySelector('button');
- if (buttonParams) {
- banner.dataset.button = true;
- button.textContent = buttonParams.label;
- button.addEventListener('click', buttonParams.callback);
- }
-
- banner.addEventListener('animationend', function animationend() {
- banner.removeEventListener('animationend', animationend);
- banner.classList.remove('visible');
-
- if (buttonParams) {
- banner.dataset.button = false;
- button.removeEventListener('click', buttonParams.callback);
- button.classList.remove('visible');
- }
- });
-
- banner.classList.add('visible');
- }
-};
diff --git a/apps/system/js/system_dialog.js b/apps/system/js/system_dialog.js
deleted file mode 100644
index b0c32d8..0000000
--- a/apps/system/js/system_dialog.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-'use strict';
-
-/**
- * System app is made of a top-level `<div ="screen"></div>` DOM element
- * which contain all possible screens displayed by the app.
- * Multiple screens can be displayed at a time. We store the list of currently
- * visible screens into this DOM element class attribute.
- */
-var SystemScreen = {
- screen: document.getElementById('screen'),
-
- show: function ss_show(screenName) {
- this.screen.classList.add(screenName);
- },
-
- hide: function ss_show(screenName) {
- this.screen.classList.remove(screenName);
- },
-
- isVisible: function ss_isVisible(screenName) {
- return this.screen.classList.contains(screenName);
- }
-};
-
-/**
- * System app displays various kind of dialogs.
- * A dialog is a system app 'screen' that has a high z-index and is used to be
- * displayed on top of other apps. But it doesn't display over the status bar,
- * nor the eventually displayed keyboard.
- *
- * `SystemDialog` except the dialog DOM Element `id`.
- * This DOM Element has to have a DOM attribute 'role' set to 'dialog'.
- *
- * It also supports a second `options` object with following attributes:
- * `onHide`: function called when dialog is hidden, either when `hide()`
- * method is called, or when dialog is automatically hidden on
- * home button press
- */
-function SystemDialog(id, options) {
- var overlay = document.getElementById('dialog-overlay');
- var dialog = document.getElementById(id);
- var screenName = 'dialog';
-
- // Listen to keyboard visibility changes and window resizing
- // in order to resize the dialog accordingly
- function updateHeight(keyboardHeight) {
- if (SystemScreen.isVisible(screenName)) {
- var height = window.innerHeight -
- (keyboardHeight ? keyboardHeight : 0) -
- StatusBar.height;
- overlay.style.height = height + 'px';
- }
- };
- function handleEvent(evt) {
- switch (evt.type) {
- case 'resize':
- case 'keyboardhide':
- updateHeight();
- break;
- case 'keyboardchange':
- updateHeight(evt.detail.height);
- break;
- case 'home':
- case 'holdhome':
- // Automatically hide the dialog on home button press
- if (SystemScreen.isVisible(screenName)) {
- hide(evt.type);
- // Prevent WindowManager to shift homescreen to the first page
- // when the dialog is on top of the homescreen
- var displayedApp = WindowManager.getDisplayedApp();
- var displayedAppFrame = WindowManager.getAppFrame(displayedApp);
- if (evt.type == 'home' &&
- displayedAppFrame.classList.contains('homescreen'))
- evt.stopImmediatePropagation();
- }
- break;
- }
- };
- window.addEventListener('resize', handleEvent);
- window.addEventListener('keyboardchange', handleEvent);
- window.addEventListener('keyboardhide', handleEvent);
- window.addEventListener('home', handleEvent);
- window.addEventListener('holdhome', handleEvent);
-
- function show() {
- dialog.hidden = false;
- dialog.classList.add(id);
- SystemScreen.show(screenName);
- updateHeight();
- }
-
- function hide(reason) {
- dialog.hidden = true;
- dialog.classList.remove(id);
- SystemScreen.hide(screenName);
- if (typeof(options.onHide) == 'function')
- options.onHide(reason);
- }
-
- function isVisible() {
- return SystemScreen.isVisible(screenName) &&
- overlay.classList.contains(id);
- }
-
- return {
- show: show,
- hide: hide,
- isVisible: isVisible
- };
-}
-
diff --git a/apps/system/js/trusted_ui.js b/apps/system/js/trusted_ui.js
deleted file mode 100644
index 43bea21..0000000
--- a/apps/system/js/trusted_ui.js
+++ /dev/null
@@ -1,334 +0,0 @@
-/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil -*- */
-/* vim: set ft=javascript sw=2 ts=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var TrustedUIManager = {
-
- get currentStack() {
- if (!this._dialogStacks[this._lastDisplayedApp]) {
- this._dialogStacks[this._lastDisplayedApp] = [];
- }
- return this._dialogStacks[this._lastDisplayedApp];
- },
-
- _dialogStacks: {},
- _lastDisplayedApp: null,
-
- overlay: document.getElementById('dialog-overlay'),
-
- popupContainer: document.getElementById('trustedui-container'),
-
- popupContainerInner: document.getElementById('trustedui-inner'),
-
- container: document.getElementById('trustedui-frame-container'),
-
- dialogTitle: document.getElementById('trustedui-title'),
-
- screen: document.getElementById('screen'),
-
- loadingIcon: document.getElementById('statusbar-loading'),
-
- throbber: document.getElementById('trustedui-throbber'),
-
- closeButton: document.getElementById('trustedui-close'),
-
- hasTrustedUI: function trui_hasTrustedUI(origin) {
- return (this._dialogStacks[origin] && this._dialogStacks[origin].length);
- },
-
- getDialogFromOrigin: function trui_getDialogFromOrigin(origin) {
- if (!origin || !this.hasTrustedUI(origin))
- return false;
- var stack = this._dialogStacks[origin];
- return stack[stack.length - 1];
- },
-
- init: function trui_init() {
- window.addEventListener('home', this);
- window.addEventListener('holdhome', this);
- window.addEventListener('appwillopen', this);
- window.addEventListener('appopen', this);
- window.addEventListener('appwillclose', this);
- window.addEventListener('appterminated', this);
- window.addEventListener('keyboardhide', this);
- window.addEventListener('keyboardchange', this);
- window.addEventListener('mozbrowserloadstart', this);
- window.addEventListener('mozbrowserloadend', this);
- this.closeButton.addEventListener('click', this);
- },
-
- hideTrustedApp: function trui_hideTrustedApp() {
- var self = this;
- this.popupContainer.classList.add('closing');
- this.popupContainer.addEventListener('transitionend', function hide() {
- this.removeEventListener('transitionend', hide);
- self.hide();
- });
- },
-
- reopenTrustedApp: function trui_reopenTrustedApp() {
- this._hideAllFrames();
- var dialog = this._getTopDialog();
- this._makeDialogVisible(dialog);
- this.popupContainer.classList.add('closing');
- this.show();
- this.popupContainer.classList.remove('closing');
- },
-
- open: function trui_open(name, frame, chromeEventId, onCancelCB) {
- screen.mozLockOrientation('portrait');
- this._hideAllFrames();
- if (this.currentStack.length) {
- this._makeDialogHidden(this._getTopDialog());
- this._pushNewDialog(name, frame, chromeEventId, onCancelCB);
- } else {
- // first time, spin back to home screen first
- this.popupContainer.classList.add('up');
- this.popupContainer.classList.remove('closing');
- WindowManager.hideCurrentApp(function openTrustedUI() {
- this.popupContainer.classList.remove('up');
- this._pushNewDialog(name, frame, chromeEventId, onCancelCB);
- }.bind(this));
- }
- },
-
- close: function trui_close(chromeEventId, callback) {
- var stackSize = this.currentStack.length;
-
- this._restoreOrientation();
-
- if (callback)
- callback();
-
- if (stackSize === 0) {
- // nothing to close. what are you doing?
- return;
- } else if (stackSize === 1) {
- // only one dialog, so transition back to main app
- var self = this;
- var container = this.popupContainer;
- if (!CardsView.cardSwitcherIsShown()) {
- WindowManager.restoreCurrentApp();
- container.addEventListener('transitionend', function wait(event) {
- this.removeEventListener('transitionend', wait);
- self._closeDialog(chromeEventId);
- });
- } else {
- WindowManager.restoreCurrentApp(this._lastDisplayedApp);
- this._closeDialog(chromeEventId);
- }
-
- // The css transition caused by the removal of the trustedui
- // class by the hide() method will trigger a 'transitionend'
- // event ultimately to be fired.
- this.hide();
-
- window.focus();
- } else {
- this._closeDialog(chromeEventId);
- }
- },
-
- _dispatchCloseEvent: function dispatchCloseEvent(eventId) {
- var _ = navigator.mozL10n.get;
- if (!eventId)
- return;
- var event = document.createEvent('customEvent');
- var details = {
- id: eventId,
- type: 'cancel',
- errorMsg: _('dialog-closed')
- };
- event.initCustomEvent('mozContentEvent', true, true, details);
- window.dispatchEvent(event);
- },
-
- _getTopDialog: function trui_getTopDialog() {
- // get the topmost dialog for the _lastDisplayedApp or null
- return this.currentStack[this.currentStack.length - 1];
- },
-
- _pushNewDialog: function trui_PushNewDialog(name, frame, chromeEventId,
- onCancelCB) {
- // add some data attributes to the frame
- var dataset = frame.dataset;
- dataset.frameType = 'popup';
- dataset.frameName = frame.name;
- dataset.frameOrigin = this._lastDisplayedApp;
-
- // make a shiny new dialog object
- var dialog = {
- name: name,
- frame: frame,
- chromeEventId: chromeEventId,
- onCancelCB: onCancelCB
- };
-
- // push and show
- this.currentStack.push(dialog);
- this.dialogTitle.textContent = dialog.name;
- this.container.appendChild(dialog.frame);
- this._makeDialogVisible(dialog);
- },
-
- _makeDialogVisible: function trui_makeDialogVisible(dialog) {
- // make sure the trusty ui is visible
- this.popupContainer.classList.remove('closing');
- this.show();
-
- // ensure the frame is visible and the dialog title is correct.
- dialog.frame.classList.add('selected');
- this.dialogTitle.textContent = dialog.name;
- },
-
- _makeDialogHidden: function trui_makeDialogHidden(dialog) {
- if (!dialog)
- return;
- this._restoreOrientation();
- dialog.frame.classList.remove('selected');
- },
-
- _restoreOrientation: function trui_restoreOrientation() {
- var app = WindowManager.getDisplayedApp();
- WindowManager.setOrientationForApp(app);
- },
-
- /**
- * close the dialog identified by the chromeEventId
- */
- _closeDialog: function trui_closeDialog(chromeEventId) {
- if (this.currentStack.length === 0)
- return;
-
- var found = false;
- for (var i = 0; i < this.currentStack.length; i++) {
- if (this.currentStack[i].chromeEventId === chromeEventId) {
- var dialog = this.currentStack.splice(i, 1)[0];
- this.container.removeChild(dialog.frame);
- found = true;
- break;
- }
- }
-
- if (found && this.currentStack.length) {
- this._makeDialogVisible(this._getTopDialog());
- }
- },
-
- hide: function trui_hide() {
- this.screen.classList.remove('trustedui');
- },
-
- show: function trui_show() {
- this.screen.classList.add('trustedui');
- },
-
- isVisible: function trui_show() {
- return this.screen.classList.contains('trustedui');
- },
-
- setHeight: function trui_setHeight(height) {
- this.overlay.style.height = height + 'px';
- },
-
- /*
- * _destroyDialog: internal method called when the dialog is closed
- * by user action (canceled), or when 'appterminated' is received.
- * In either case, notify the caller.
- */
- _destroyDialog: function trui_destroyDialog(origin) {
- var stack = this.currentStack;
- if (origin)
- stack = this._dialogStacks[origin];
-
- if (stack.length === 0)
- return;
-
- // If the user closed a trusty UI dialog, they probably meant
- // to close every dialog.
- for (var i = 0, toClose = stack.length; i < toClose; i++) {
- var dialog = this._getTopDialog();
-
- // First, send a chrome event saying we've been canceled
- this._dispatchCloseEvent(dialog.chromeEventId);
-
- // Now close and fire the cancel callback, if it exists
- this.close(dialog.chromeEventId, dialog.onCancelCB);
- }
- this.hide();
- this.popupContainer.classList.remove('closing');
- },
-
- _hideAllFrames: function trui_hideAllFrames() {
- var selectedFrames = this.container.querySelectorAll('iframe.selected');
- for (var i = 0; i < selectedFrames.length; i++) {
- selectedFrames[i].classList.remove('selected');
- }
- },
-
- handleEvent: function trui_handleEvent(evt) {
- switch (evt.type) {
- case 'home':
- case 'holdhome':
- if (!this.isVisible())
- return;
-
- this.hideTrustedApp();
- break;
- case 'click':
- // Close-button clicked
- this._destroyDialog();
- break;
- case 'appterminated':
- this._destroyDialog(evt.detail.origin);
- break;
- case 'appwillopen':
- // Hiding trustedUI when coming from Activity
- if (this.isVisible())
- this.hideTrustedApp();
-
- // Ignore homescreen
- if (evt.target.classList.contains('homescreen'))
- return;
- this._lastDisplayedApp = evt.detail.origin;
- if (this.currentStack.length) {
- // Reopening an app with trustedUI
- this.popupContainer.classList.remove('up');
- this._makeDialogVisible(this._getTopDialog());
- WindowManager.hideCurrentApp();
- this.reopenTrustedApp();
- }
- break;
- case 'appopen':
- if (this.currentStack.length) {
- screen.mozLockOrientation('portrait');
- }
- break;
- case 'appwillclose':
- if (this.isVisible())
- return;
- var dialog = this._getTopDialog();
- this._makeDialogHidden(dialog);
- this.hide();
- break;
- case 'keyboardchange':
- this.setHeight(window.innerHeight -
- StatusBar.height - evt.detail.height);
- break;
- case 'keyboardhide':
- this.setHeight(window.innerHeight - StatusBar.height);
- break;
- case 'mozbrowserloadstart':
- this.throbber.classList.add('loading');
- break;
- case 'mozbrowserloadend':
- this.throbber.classList.remove('loading');
- break;
- }
- }
-
-};
-
-TrustedUIManager.init();
-
diff --git a/apps/system/js/ttlview.js b/apps/system/js/ttlview.js
deleted file mode 100644
index 81503af..0000000
--- a/apps/system/js/ttlview.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var TTLView = {
- element: null,
-
- get visible() {
- return this.element && this.element.style.display === 'block';
- },
-
- hide: function tv_hide() {
- if (this.element)
- this.element.style.visibility = 'hidden';
- },
-
- show: function tv_show() {
- var element = this.element;
- if (!element) {
- element = document.createElement('div');
- element.id = 'debug-ttl';
- element.innerHTML = '00000';
- element.dataset.zIndexLevel = 'debug-ttl';
-
- this.element = element;
- document.getElementById('screen').appendChild(element);
-
- // this is fired when the app launching is initialized
- window.addEventListener('appwillopen', function willopen(e) {
- element.innerHTML = '00000';
- });
-
- window.addEventListener('apploadtime', function apploadtime(e) {
- element.innerHTML = e.detail.time + ' [' + e.detail.type + ']';
- });
- }
-
- element.style.visibility = 'visible';
- },
-
- toggle: function tv_toggle() {
- this.visible ? this.hide() : this.show();
- }
-};
-
-SettingsListener.observe('debug.ttl.enabled', false, function(value) {
- !!value ? TTLView.show() : TTLView.hide();
-});
-
diff --git a/apps/system/js/updatable.js b/apps/system/js/updatable.js
deleted file mode 100644
index 57ce737..0000000
--- a/apps/system/js/updatable.js
+++ /dev/null
@@ -1,269 +0,0 @@
-'use strict';
-
-/*
- * An Updatable object represents an application *or* system update.
- * It takes care of the interaction with the UpdateManager and observes
- * the update itself to handle success/error cases.
- *
- * - name of the update
- * - size of the update
- * - download() to start the download
- * - cancelDownload() to cancel it
- */
-
-/* === App Updates === */
-function AppUpdatable(app) {
- this._mgmt = navigator.mozApps.mgmt;
- this.app = app;
-
- var manifest = app.manifest ? app.manifest : app.updateManifest;
- this.name = new ManifestHelper(manifest).name;
-
- this.size = app.downloadSize;
- this.progress = null;
-
- UpdateManager.addToUpdatableApps(this);
- app.ondownloadavailable = this.availableCallBack.bind(this);
- if (app.downloadAvailable) {
- this.availableCallBack();
- }
- if (app.readyToApplyDownload) {
- this.applyUpdate();
- }
-}
-
-AppUpdatable.prototype.download = function() {
- UpdateManager.addToDownloadsQueue(this);
- this.progress = 0;
-
- this.app.download();
-};
-
-AppUpdatable.prototype.cancelDownload = function() {
- this.app.cancelDownload();
-};
-
-AppUpdatable.prototype.uninit = function() {
- this.app.ondownloadavailable = null;
- this.clean();
-};
-
-AppUpdatable.prototype.clean = function() {
- this.app.ondownloaderror = null;
- this.app.ondownloadsuccess = null;
- this.app.ondownloadapplied = null;
- this.app.onprogress = null;
-
- this.progress = null;
-};
-
-AppUpdatable.prototype.availableCallBack = function() {
- this.size = this.app.downloadSize;
-
- if (this.app.installState === 'installed') {
- UpdateManager.addToUpdatesQueue(this);
-
- // we add these callbacks only now to prevent interfering
- // with other modules (especially the AppInstallManager)
- this.app.ondownloaderror = this.errorCallBack.bind(this);
- this.app.ondownloadsuccess = this.successCallBack.bind(this);
- this.app.ondownloadapplied = this.appliedCallBack.bind(this);
- this.app.onprogress = this.progressCallBack.bind(this);
- }
-};
-
-AppUpdatable.prototype.successCallBack = function() {
- var app = this.app;
- if (WindowManager.getDisplayedApp() !== app.origin) {
- this.applyUpdate();
- } else {
- var self = this;
- window.addEventListener('appwillclose', function waitClose() {
- window.removeEventListener('appwillclose', waitClose);
- self.applyUpdate();
- });
- }
-
- UpdateManager.removeFromDownloadsQueue(this);
- UpdateManager.removeFromUpdatesQueue(this);
-};
-
-AppUpdatable.prototype.applyUpdate = function() {
- WindowManager.kill(this.app.origin);
- this._mgmt.applyDownload(this.app);
-};
-
-AppUpdatable.prototype.appliedCallBack = function() {
- this.clean();
-};
-
-AppUpdatable.prototype.errorCallBack = function(e) {
- var errorName = e.application.downloadError.name;
- console.info('downloadError event, error code is', errorName);
- UpdateManager.requestErrorBanner();
- UpdateManager.removeFromDownloadsQueue(this);
- this.progress = null;
-};
-
-AppUpdatable.prototype.progressCallBack = function() {
- if (this.progress === null) {
- // this is the first progress
- UpdateManager.addToDownloadsQueue(this);
- this.progress = 0;
- }
-
- var delta = this.app.progress - this.progress;
-
- this.progress = this.app.progress;
- UpdateManager.downloadProgressed(delta);
-};
-
-/*
- * System Updates
- * Will be instanciated only once by the UpdateManager
- *
- */
-function SystemUpdatable() {
- var _ = navigator.mozL10n.get;
- this.name = _('systemUpdate');
- this.size = 0;
- this.downloading = false;
- this.paused = false;
-
- // XXX: this state should be kept on the platform side
- // https://bugzilla.mozilla.org/show_bug.cgi?id=827090
- this.checkKnownUpdate(UpdateManager.checkForUpdates.bind(UpdateManager));
-
- window.addEventListener('mozChromeEvent', this);
-}
-
-SystemUpdatable.KNOWN_UPDATE_FLAG = 'known-sysupdate';
-
-SystemUpdatable.prototype.download = function() {
- if (this.downloading) {
- return;
- }
-
- this.downloading = true;
- this.paused = false;
- this._dispatchEvent('update-available-result', 'download');
- UpdateManager.addToDownloadsQueue(this);
- this.progress = 0;
-};
-
-SystemUpdatable.prototype.cancelDownload = function() {
- this._dispatchEvent('update-download-cancel');
- this.downloading = false;
- this.paused = false;
-};
-
-SystemUpdatable.prototype.uninit = function() {
- window.removeEventListener('mozChromeEvent', this);
-};
-
-SystemUpdatable.prototype.handleEvent = function(evt) {
- if (evt.type !== 'mozChromeEvent')
- return;
-
- var detail = evt.detail;
- if (!detail.type)
- return;
-
- switch (detail.type) {
- case 'update-error':
- this.errorCallBack();
- break;
- case 'update-download-started':
- // TODO UpdateManager glue
- this.paused = false;
- break;
- case 'update-download-progress':
- var delta = detail.progress - this.progress;
- this.progress = detail.progress;
-
- UpdateManager.downloadProgressed(delta);
- break;
- case 'update-download-stopped':
- // TODO UpdateManager glue
- this.paused = detail.paused;
- if (!this.paused) {
- UpdateManager.startedUncompressing();
- }
- break;
- case 'update-downloaded':
- this.downloading = false;
- this.showApplyPrompt();
- break;
- case 'update-prompt-apply':
- this.showApplyPrompt();
- break;
- }
-};
-
-SystemUpdatable.prototype.errorCallBack = function() {
- UpdateManager.requestErrorBanner();
- UpdateManager.removeFromDownloadsQueue(this);
- this.downloading = false;
-};
-
-SystemUpdatable.prototype.showApplyPrompt = function() {
- var _ = navigator.mozL10n.get;
-
- // Update will be completed after restart
- this.forgetKnownUpdate();
-
- var cancel = {
- title: _('later'),
- callback: this.declineInstall.bind(this)
- };
-
- var confirm = {
- title: _('installNow'),
- callback: this.acceptInstall.bind(this)
- };
-
- UtilityTray.hide();
- CustomDialog.show(_('systemUpdateReady'), _('wantToInstall'),
- cancel, confirm);
-};
-
-SystemUpdatable.prototype.declineInstall = function() {
- CustomDialog.hide();
- this._dispatchEvent('update-prompt-apply-result', 'wait');
-
- UpdateManager.removeFromDownloadsQueue(this);
-};
-
-SystemUpdatable.prototype.acceptInstall = function() {
- CustomDialog.hide();
- this._dispatchEvent('update-prompt-apply-result', 'restart');
-};
-
-SystemUpdatable.prototype.rememberKnownUpdate = function() {
- asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
-};
-
-SystemUpdatable.prototype.checkKnownUpdate = function(callback) {
- if (typeof callback !== 'function') {
- return;
- }
-
- asyncStorage.getItem(SystemUpdatable.KNOWN_UPDATE_FLAG, function(value) {
- callback(!!value);
- });
-};
-
-SystemUpdatable.prototype.forgetKnownUpdate = function() {
- asyncStorage.removeItem(SystemUpdatable.KNOWN_UPDATE_FLAG);
-};
-
-SystemUpdatable.prototype._dispatchEvent = function(type, result) {
- var event = document.createEvent('CustomEvent');
- var data = { type: type };
- if (result) {
- data.result = result;
- }
-
- event.initCustomEvent('mozContentEvent', true, true, data);
- window.dispatchEvent(event);
-};
diff --git a/apps/system/js/update_manager.js b/apps/system/js/update_manager.js
deleted file mode 100644
index 8e37733..0000000
--- a/apps/system/js/update_manager.js
+++ /dev/null
@@ -1,623 +0,0 @@
-'use strict';
-
-/*
- * The UpdateManager is a central component for apps *and* system updates.
- * The user can start or cancel all downloads at once.
- * This component also makes sure of bothering the user to a minimum by
- * showing active notifications for new updates/errors only once.
- *
- * It maintains 2 queues of Updatable objects.
- * - updatesQueue for available updates
- * - downloadsQueue for active downloads
- */
-
-var UpdateManager = {
- _mgmt: null,
- _downloading: false,
- _uncompressing: false,
- _downloadedBytes: 0,
- _errorTimeout: null,
- _wifiLock: null,
- _systemUpdateDisplayed: false,
- _isDataConnectionWarningDialogEnabled: true,
- _settings: null,
- _conn: null,
- NOTIFICATION_BUFFERING_TIMEOUT: 30 * 1000,
- TOASTER_TIMEOUT: 1200,
-
- container: null,
- message: null,
- toaster: null,
- toasterMessage: null,
- laterButton: null,
- notnowButton: null,
- downloadButton: null,
- downloadViaDataConnectionButton: null,
- downloadDialog: null,
- downloadViaDataConnectionDialog: null,
- downloadDialogTitle: null,
- downloadDialogList: null,
- lastUpdatesAvailable: 0,
- _notificationTimeout: null,
-
- updatableApps: [],
- systemUpdatable: null,
- updatesQueue: [],
- downloadsQueue: [],
-
- init: function um_init() {
- if (!this._mgmt) {
- this._mgmt = navigator.mozApps.mgmt;
- }
-
- this._mgmt.getAll().onsuccess = (function gotAll(evt) {
- var apps = evt.target.result;
- apps.forEach(function appIterator(app) {
- new AppUpdatable(app);
- });
- }).bind(this);
-
- this._settings = navigator.mozSettings;
-
- this.systemUpdatable = new SystemUpdatable();
-
- this.container = document.getElementById('update-manager-container');
- this.message = this.container.querySelector('.message');
-
- this.toaster = document.getElementById('update-manager-toaster');
- this.toasterMessage = this.toaster.querySelector('.message');
-
- this.laterButton = document.getElementById('updates-later-button');
- this.notnowButton =
- document.getElementById('updates-viaDataConnection-notnow-button');
- this.downloadButton = document.getElementById('updates-download-button');
- this.downloadViaDataConnectionButton =
- document.getElementById('updates-viaDataConnection-download-button');
- this.downloadDialog = document.getElementById('updates-download-dialog');
- this.downloadDialogTitle = this.downloadDialog.querySelector('h1');
- this.downloadDialogList = this.downloadDialog.querySelector('ul');
- this.downloadViaDataConnectionDialog =
- document.getElementById('updates-viaDataConnection-dialog');
-
- this.container.onclick = this.containerClicked.bind(this);
- this.laterButton.onclick = this.cancelPrompt.bind(this);
- this.downloadButton.onclick = this.requestDownloads.bind(this);
- this.downloadDialogList.onchange = this.updateDownloadButton.bind(this);
- this.notnowButton.onclick =
- this.cancelDataConnectionUpdatesPrompt.bind(this);
- this.downloadViaDataConnectionButton.onclick =
- this.requestDownloads.bind(this);
-
- window.addEventListener('mozChromeEvent', this);
- window.addEventListener('applicationinstall', this);
- window.addEventListener('applicationuninstall', this);
- window.addEventListener('online', this);
- window.addEventListener('offline', this);
-
- SettingsListener.observe('gaia.system.checkForUpdates', false,
- this.checkForUpdates.bind(this));
-
- // We maintain the the edge and nowifi data attributes to show
- // a warning on the download dialog
- window.addEventListener('wifi-statuschange', this);
- this.updateWifiStatus();
- this.updateOnlineStatus();
-
- this._conn = window.navigator.mozMobileConnection;
- if (this._conn) {
- this._conn.addEventListener('datachange', this);
- this.updateDataStatus();
- }
-
- window.asyncStorage.
- getItem('gaia.system.isDataConnectionWarningDialogEnabled',
- (function(value) {
- value = value || true;
- this._isDataConnectionWarningDialogEnabled = true;
- this.downloadDialog.dataset.dataConnectionInlineWarning = !value;
- }).bind(this));
- },
-
- requestDownloads: function um_requestDownloads(evt) {
- evt.preventDefault();
-
- if (evt.target == this.downloadViaDataConnectionButton) {
- window.asyncStorage.
- setItem('gaia.system.isDataConnectionWarningDialogEnabled', false);
- this._isDataConnectionWarningDialogEnabled = false;
- this.downloadDialog.dataset.dataConnectionInlineWarning = true;
- this.startDownloads();
- } else {
- if (this._isDataConnectionWarningDialogEnabled &&
- this.downloadDialog.dataset.nowifi) {
- this.downloadViaDataConnectionDialog.classList.add('visible');
- } else {
- this.startDownloads();
- }
- }
- },
-
- startDownloads: function um_startDownloads() {
- this.downloadDialog.classList.remove('visible');
- this.downloadViaDataConnectionDialog.classList.remove('visible');
-
- UtilityTray.show();
-
- var checkValues = {};
- var dialog = this.downloadDialogList;
- var checkboxes = dialog.querySelectorAll('input[type="checkbox"]');
- for (var i = 0; i < checkboxes.length; i++) {
- var checkbox = checkboxes[i];
- checkValues[checkbox.dataset.position] = checkbox.checked;
- }
-
- this.updatesQueue.forEach(function(updatable, index) {
- // The user opted out of the download
- if (updatable.app && !checkValues[index]) {
- return;
- }
-
- updatable.download();
- });
-
- this._downloadedBytes = 0;
- this.render();
- },
-
- cancelAllDownloads: function um_cancelAllDownloads() {
- CustomDialog.hide();
-
- // We're emptying the array while iterating
- while (this.downloadsQueue.length) {
- var updatable = this.downloadsQueue[0];
- updatable.cancelDownload();
- this.removeFromDownloadsQueue(updatable);
- }
- },
-
- requestErrorBanner: function um_requestErrorBanner() {
- if (this._errorTimeout)
- return;
-
- var _ = navigator.mozL10n.get;
- var self = this;
- this._errorTimeout = setTimeout(function waitForMore() {
- SystemBanner.show(_('downloadError'));
- self._errorTimeout = null;
- }, this.NOTIFICATION_BUFFERING_TIMEOUT);
- },
-
- containerClicked: function um_containerClicker() {
- var _ = navigator.mozL10n.get;
-
- if (this._downloading) {
- var cancel = {
- title: _('no'),
- callback: this.cancelPrompt.bind(this)
- };
-
- var confirm = {
- title: _('yes'),
- callback: this.cancelAllDownloads.bind(this)
- };
-
- CustomDialog.show(_('cancelAllDownloads'), _('wantToCancelAll'),
- cancel, confirm);
- } else {
- this.showDownloadPrompt();
- }
-
- UtilityTray.hide();
- },
-
- showDownloadPrompt: function um_showDownloadPrompt() {
- var _ = navigator.mozL10n.get;
-
- this._systemUpdateDisplayed = false;
- this.downloadDialogTitle.textContent = _('numberOfUpdates', {
- n: this.updatesQueue.length
- });
-
- var updateList = '';
-
- // System update should always be on top
- this.updatesQueue.sort(function sortUpdates(updatable, otherUpdatable) {
- if (!updatable.app)
- return -1;
- if (!otherUpdatable.app)
- return 1;
-
- if (updatable.name < otherUpdatable.name)
- return -1;
- if (updatable.name > otherUpdatable.name)
- return 1;
- return 0;
- });
-
- this.downloadDialogList.innerHTML = '';
- this.updatesQueue.forEach(function updatableIterator(updatable, index) {
- var listItem = document.createElement('li');
-
- // The user can choose not to update an app
- var checkContainer = document.createElement('label');
- if (updatable instanceof SystemUpdatable) {
- checkContainer.textContent = _('required');
- checkContainer.classList.add('required');
- this._systemUpdateDisplayed = true;
- } else {
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.dataset.position = index;
- checkbox.checked = true;
-
- var span = document.createElement('span');
-
- checkContainer.appendChild(checkbox);
- checkContainer.appendChild(span);
- }
- listItem.appendChild(checkContainer);
-
- var name = document.createElement('div');
- name.classList.add('name');
- name.textContent = updatable.name;
- listItem.appendChild(name);
-
- if (updatable.size) {
- var sizeItem = document.createElement('div');
- sizeItem.textContent = this._humanizeSize(updatable.size);
- listItem.appendChild(sizeItem);
- } else {
- listItem.classList.add('nosize');
- }
-
- this.downloadDialogList.appendChild(listItem);
- }, this);
-
- this.downloadDialog.classList.add('visible');
- },
-
- updateDownloadButton: function() {
- if (this._systemUpdateDisplayed) {
- this.downloadButton.disabled = false;
- return;
- }
-
- var disabled = true;
-
- var dialog = this.downloadDialogList;
- var checkboxes = dialog.querySelectorAll('input[type="checkbox"]');
- for (var i = 0; i < checkboxes.length; i++) {
- if (checkboxes[i].checked) {
- disabled = false;
- break;
- }
- }
-
- this.downloadButton.disabled = disabled;
- },
-
- cancelPrompt: function um_cancelPrompt() {
- CustomDialog.hide();
- this.downloadDialog.classList.remove('visible');
- },
-
- cancelDataConnectionUpdatesPrompt: function um_cancelDCUpdatesPrompt() {
- CustomDialog.hide();
- this.downloadViaDataConnectionDialog.classList.remove('visible');
- this.downloadDialog.classList.remove('visible');
- },
-
- downloadProgressed: function um_downloadProgress(bytes) {
- if (bytes > 0) {
- this._downloadedBytes += bytes;
- this.render();
- }
- },
-
- startedUncompressing: function um_startedUncompressing() {
- this._uncompressing = true;
- this.render();
- },
-
- render: function um_render() {
- var _ = navigator.mozL10n.get;
-
- this.toasterMessage.innerHTML =
- _('updateAvailableInfo', {
- n: this.updatesQueue.length - this.lastUpdatesAvailable
- });
-
- var message = '';
- if (this._downloading) {
- if (this._uncompressing && this.downloadsQueue.length === 1) {
- message = _('uncompressingMessage');
- } else {
- var humanProgress = this._humanizeSize(this._downloadedBytes);
- message = _('downloadingUpdateMessage', {
- progress: humanProgress
- });
- }
- } else {
- message = _('updateAvailableInfo', {
- n: this.updatesQueue.length
- });
- }
-
- this.message.innerHTML = message;
- var css = this.container.classList;
- this._downloading ? css.add('downloading') : css.remove('downloading');
- },
-
- addToUpdatableApps: function um_addtoUpdatableapps(updatableApp) {
- this.updatableApps.push(updatableApp);
- },
-
- removeFromAll: function um_removeFromAll(updatableApp) {
- var removeIndex = this.updatableApps.indexOf(updatableApp);
- if (removeIndex === -1)
- return;
-
- var removedApp = this.updatableApps[removeIndex];
- this.removeFromUpdatesQueue(removedApp);
-
- removedApp.uninit();
- this.updatableApps.splice(removeIndex, 1);
- },
-
- addToUpdatesQueue: function um_addToUpdatesQueue(updatable) {
- if (this._downloading) {
- return;
- }
-
- if (updatable.app &&
- updatable.app.installState !== 'installed') {
- return;
- }
-
- if (updatable.app &&
- this.updatableApps.indexOf(updatable) === -1) {
- return;
- }
-
- var alreadyThere = this.updatesQueue.some(function lookup(u) {
- return (u.app === updatable.app);
- });
- if (alreadyThere) {
- return;
- }
-
- this.updatesQueue.push(updatable);
-
- if (this._notificationTimeout === null) {
- this._notificationTimeout = setTimeout(this.displayNotificationAndToaster.bind(this),
- this.NOTIFICATION_BUFFERING_TIMEOUT);
- }
- this.render();
- },
-
- displayNotificationAndToaster: function um_displayNotificationAndToaster() {
- this._notificationTimeout = null;
- if (this.updatesQueue.length && !this._downloading) {
- this.lastUpdatesAvailable = this.updatesQueue.length;
- StatusBar.updateNotificationUnread(true);
- this.displayNotificationIfHidden();
- this.toaster.classList.add('displayed');
- var self = this;
- setTimeout(function waitToHide() {
- self.toaster.classList.remove('displayed');
- }, this.TOASTER_TIMEOUT);
- }
- },
-
- removeFromUpdatesQueue: function um_removeFromUpdatesQueue(updatable) {
- var removeIndex = this.updatesQueue.indexOf(updatable);
- if (removeIndex === -1)
- return;
-
- this.updatesQueue.splice(removeIndex, 1);
- this.lastUpdatesAvailable = this.updatesQueue.length;
-
- if (this.updatesQueue.length === 0) {
- this.hideNotificationIfDisplayed();
- }
-
- this.render();
- },
-
- addToDownloadsQueue: function um_addToDownloadsQueue(updatable) {
- if (updatable.app &&
- this.updatableApps.indexOf(updatable) === -1) {
- return;
- }
-
- var alreadyThere = this.downloadsQueue.some(function lookup(u) {
- return (u.app === updatable.app);
- });
- if (alreadyThere) {
- return;
- }
-
- this.downloadsQueue.push(updatable);
-
- if (this.downloadsQueue.length === 1) {
- this._downloading = true;
- StatusBar.incSystemDownloads();
- this._wifiLock = navigator.requestWakeLock('wifi');
-
- this.displayNotificationIfHidden();
- this.render();
- }
- },
-
- removeFromDownloadsQueue: function um_removeFromDownloadsQueue(updatable) {
- var removeIndex = this.downloadsQueue.indexOf(updatable);
- if (removeIndex === -1)
- return;
-
- this.downloadsQueue.splice(removeIndex, 1);
-
- if (this.downloadsQueue.length === 0) {
- this._downloading = false;
- StatusBar.decSystemDownloads();
- this._downloadedBytes = 0;
- this.checkStatuses();
-
- if (this._wifiLock) {
- try {
- this._wifiLock.unlock();
- } catch (e) {
- // this can happen if the lock is already unlocked
- console.error('error during unlock', e);
- }
-
- this._wifiLock = null;
- }
-
- this.render();
- }
- },
-
- hideNotificationIfDisplayed: function() {
- if (this.container.classList.contains('displayed')) {
- this.container.classList.remove('displayed');
- NotificationScreen.decExternalNotifications();
- }
- },
-
- displayNotificationIfHidden: function() {
- if (!this.container.classList.contains('displayed')) {
- this.container.classList.add('displayed');
- NotificationScreen.incExternalNotifications();
- }
- },
-
- checkStatuses: function um_checkStatuses() {
- this.updatableApps.forEach(function(updatableApp) {
- var app = updatableApp.app;
- if (app.downloadAvailable) {
- this.addToUpdatesQueue(updatableApp);
- }
- }, this);
- },
-
- oninstall: function um_oninstall(evt) {
- var app = evt.application;
- var updatableApp = new AppUpdatable(app);
- },
-
- onuninstall: function um_onuninstall(evt) {
- this.updatableApps.some(function appIterator(updatableApp, index) {
- // The application object we get from the event
- // has only origin and manifestURL properties
- if (updatableApp.app.manifestURL === evt.application.manifestURL) {
- this.removeFromAll(updatableApp);
- return true;
- }
- return false;
- }, this);
- },
-
- handleEvent: function um_handleEvent(evt) {
- if (!evt.type)
- return;
-
- switch (evt.type) {
- case 'applicationinstall':
- this.oninstall(evt.detail);
- break;
- case 'applicationuninstall':
- this.onuninstall(evt.detail);
- break;
- case 'datachange':
- this.updateDataStatus();
- break;
- case 'offline':
- this.updateOnlineStatus();
- break;
- case 'online':
- this.updateOnlineStatus();
- break;
- case 'wifi-statuschange':
- this.updateWifiStatus();
- break;
- }
-
- if (evt.type !== 'mozChromeEvent')
- return;
-
- var detail = evt.detail;
-
- if (detail.type && detail.type === 'update-available') {
- this.systemUpdatable.size = detail.size;
- this.systemUpdatable.rememberKnownUpdate();
- this.addToUpdatesQueue(this.systemUpdatable);
- }
- },
-
- updateOnlineStatus: function su_updateOnlineStatus() {
- var online = (navigator && 'onLine' in navigator) ? navigator.onLine : true;
- this.downloadDialog.dataset.online = online;
-
- if (online) {
- this.laterButton.classList.remove('full');
- } else {
- this.laterButton.classList.add('full');
- }
- },
-
- updateWifiStatus: function su_updateWifiStatus() {
- var wifiManager = window.navigator.mozWifiManager;
- if (!wifiManager)
- return;
-
- this.downloadDialog.dataset.nowifi =
- (wifiManager.connection.status != 'connected');
- },
-
- checkForUpdates: function su_checkForUpdates(shouldCheck) {
- if (!shouldCheck) {
- return;
- }
-
- this._dispatchEvent('force-update-check');
-
- if (!this._settings) {
- return;
- }
-
- var lock = this._settings.createLock();
- lock.set({
- 'gaia.system.checkForUpdates': false
- });
- },
-
- _dispatchEvent: function um_dispatchEvent(type, result) {
- var event = document.createEvent('CustomEvent');
- var data = { type: type };
- if (result) {
- data.result = result;
- }
-
- event.initCustomEvent('mozContentEvent', true, true, data);
- window.dispatchEvent(event);
- },
-
- // This is going to be part of l10n.js
- _humanizeSize: function um_humanizeSize(bytes) {
- var _ = navigator.mozL10n.get;
- var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
-
- if (!bytes)
- return '0.00 ' + _(units[0]);
-
- var e = Math.floor(Math.log(bytes) / Math.log(1024));
- return (bytes / Math.pow(1024, Math.floor(e))).toFixed(2) + ' ' +
- _(units[e]);
- }
-};
-
-window.addEventListener('localized', function startup(evt) {
- window.removeEventListener('localized', startup);
-
- UpdateManager.init();
-});
diff --git a/apps/system/js/utility_tray.js b/apps/system/js/utility_tray.js
deleted file mode 100644
index 13f124d..0000000
--- a/apps/system/js/utility_tray.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var UtilityTray = {
- shown: false,
-
- active: false,
-
- overlay: document.getElementById('utility-tray'),
-
- statusbar: document.getElementById('statusbar'),
-
- screen: document.getElementById('screen'),
-
- init: function ut_init() {
- var touchEvents = ['touchstart', 'touchmove', 'touchend'];
-
- // XXX: Always use Mouse2Touch here.
- // We cannot reliably detect touch support normally
- // by evaluate (document instanceof DocumentTouch) on Desktop B2G.
- touchEvents.forEach(function bindEvents(name) {
- // window.addEventListener(name, this);
- Mouse2Touch.addEventHandler(window, name, this);
- }, this);
-
- window.addEventListener('screenchange', this);
- window.addEventListener('home', this);
-
- this.overlay.addEventListener('transitionend', this);
- },
-
- handleEvent: function ut_handleEvent(evt) {
- switch (evt.type) {
- case 'home':
- if (this.shown) {
- this.hide();
- }
- break;
-
- case 'screenchange':
- if (this.shown && !evt.detail.screenEnabled)
- this.hide(true);
-
- break;
-
- case 'touchstart':
- if (LockScreen.locked)
- return;
- if (evt.target !== this.overlay &&
- evt.target !== this.statusbar)
- return;
-
- this.active = true;
- // XXX: required for Mouse2Touch fake events to function
- evt.target.setCapture(true);
-
- this.onTouchStart(evt.touches[0]);
- break;
-
- case 'touchmove':
- if (!this.active)
- return;
-
- this.onTouchMove(evt.touches[0]);
- break;
-
- case 'touchend':
- if (!this.active)
- return;
-
- this.active = false;
- // XXX: required for Mouse2Touch fake events to function
- document.releaseCapture();
-
- this.onTouchEnd(evt.changedTouches[0]);
- break;
-
- case 'transitionend':
- if (!this.shown)
- this.screen.classList.remove('utility-tray');
- break;
- }
- },
-
- onTouchStart: function ut_onTouchStart(touch) {
- this.startX = touch.pageX;
- this.startY = touch.pageY;
- this.screen.classList.add('utility-tray');
- this.onTouchMove({ pageY: touch.pageY + this.statusbar.offsetHeight });
- },
-
- onTouchMove: function ut_onTouchMove(touch) {
- var screenHeight = this.overlay.getBoundingClientRect().height;
- var y = touch.pageY;
- if (y > this.lastY)
- this.opening = true;
- else if (y < this.lastY)
- this.opening = false;
- this.lastY = y;
- var dy = -(this.startY - y);
- if (this.shown)
- dy += screenHeight;
- dy = Math.min(screenHeight, dy);
-
- var style = this.overlay.style;
- style.MozTransition = '';
- style.MozTransform = 'translateY(' + dy + 'px)';
- },
-
- onTouchEnd: function ut_onTouchEnd(touch) {
- this.opening ? this.show() : this.hide();
- },
-
- hide: function ut_hide(instant) {
- var alreadyHidden = !this.shown;
- var style = this.overlay.style;
- style.MozTransition = instant ? '' : '-moz-transform 0.2s linear';
- style.MozTransform = 'translateY(0)';
- this.shown = false;
- if (instant)
- this.screen.classList.remove('utility-tray');
-
- if (!alreadyHidden) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('utilitytrayhide', true, true, null);
- window.dispatchEvent(evt);
- }
- },
-
- show: function ut_show(dy) {
- var alreadyShown = this.shown;
- var style = this.overlay.style;
- style.MozTransition = '-moz-transform 0.2s linear';
- style.MozTransform = 'translateY(100%)';
- this.shown = true;
- this.screen.classList.add('utility-tray');
-
- if (!alreadyShown) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('utilitytrayshow', true, true, null);
- window.dispatchEvent(evt);
- }
- }
-};
-
-UtilityTray.init();
diff --git a/apps/system/js/value_selector/date_picker.js b/apps/system/js/value_selector/date_picker.js
deleted file mode 100644
index 9cdd484..0000000
--- a/apps/system/js/value_selector/date_picker.js
+++ /dev/null
@@ -1,568 +0,0 @@
-/**
- * DatePicker is a html/js "widget" which will display
- * all the days of a given month and allow selection of
- * one specific day. It also implements controls to travel
- * between months and jump into arbitrary time.
- *
- * The DatePicker itself contains no UI for the controls.
- *
- * Example usage:
- *
- * // the container will have elements for the month
- * // added and removed from it.
- * var picker = new DatePicker(container);
- *
- * // EVENTS:
- *
- * // called when the user clicks a day in the calendar.
- * picker.onvaluechange = function(date) {}
- *
- * // called when the month of the calendar changes.
- * // NOTE: at this time this can only happen programmatically
- * // so there is only for control flow.
- * picker.onmonthchange = function(date) {}
- *
- * // display a given year/month/date on the calendar the month
- * // is zero based just like the JS date constructor.
- * picker.display(2012, 0, 2);
- *
- * // move to the next month.
- * picker.next();
- *
- * // move to the previous month
- * picker.previous();
- *
- */
-var DatePicker = (function() {
- 'use strict';
-
- const SELECTED = 'selected';
-
- var Calc = {
-
- NEXT_MONTH: 'next-month',
-
- OTHER_MONTH: 'other-month',
-
- PRESENT: 'present',
-
- FUTURE: 'future',
-
- PAST: 'past',
-
- get today() {
- return new Date();
- },
-
- daysInWeek: function() {
- //XXX: We need to localize this...
- return 7;
- },
-
- /**
- * Checks is given date is today.
- *
- * @param {Date} date compare.
- * @return {Boolean} true when today.
- */
- isToday: function(date) {
- return Calc.isSameDate(date, Calc.today);
- },
-
- /**
- * Checks if two date objects occur
- * on the same date (in the same month, year, day).
- * Disregards time.
- *
- * @param {Date} first date.
- * @param {Date} second date.
- * @return {Boolean} true when they are the same date.
- */
- isSameDate: function(first, second) {
- return first.getMonth() == second.getMonth() &&
- first.getDate() == second.getDate() &&
- first.getFullYear() == second.getFullYear();
- },
-
- /**
- * Returns an identifier for a specific
- * date in time for a given date
- *
- * @param {Date} date to get id for.
- * @return {String} identifier.
- */
- getDayId: function(date) {
- return [
- date.getFullYear(),
- date.getMonth(),
- date.getDate()
- ].join('-');
- },
-
- /**
- * Returns a date object from
- * a string id for a date.
- *
- * @param {String} id identifier for date.
- * @return {Date} date output.
- */
- dateFromId: function(id) {
- var parts = id.split('-');
- return new Date(parts[0], parts[1], parts[2]);
- },
-
- createDay: function(date, day, month, year) {
- return new Date(
- typeof year !== 'undefined' ? year : date.getFullYear(),
- typeof month !== 'undefined' ? month : date.getMonth(),
- typeof day !== 'undefined' ? day : date.getDate()
- );
- },
-
- /**
- * Finds localized week start date of given date.
- *
- * @param {Date} date any day the week.
- * @return {Date} first date in the week of given date.
- */
- getWeekStartDate: function(date) {
- var currentDay = date.getDay();
- var startDay = date.getDate() - currentDay;
-
- return Calc.createDay(date, startDay);
- },
-
- getWeekEndDate: function(date) {
- // TODO: There are localization problems
- // with this approach as we assume a 7 day week.
- var start = Calc.getWeekStartDate(date);
- start.setDate(start.getDate() + 7);
- start.setMilliseconds(-1);
-
- return start;
- },
-
- /**
- * Returns an array of dates objects.
- * Inclusive. First and last are
- * the given instances.
- *
- * @param {Date} start starting day.
- * @param {Date} end ending day.
- * @param {Boolean} includeTime include times start/end ?
- */
- daysBetween: function(start, end, includeTime) {
- if (!(start instanceof Date)) {
- throw new Error('start date must be an instanceof Date');
- }
-
- if (!(end instanceof Date)) {
- throw new Error('end date must be an instanceof Date');
- }
-
- if (start > end) {
- var tmp = end;
- end = start;
- start = tmp;
- tmp = null;
- }
-
- var list = [];
- var last = start.getDate();
- var cur;
-
- // for infinite loop protection.
- var max = 500;
- var macInc = 0;
-
- while (macInc++ < max) {
- var next = new Date(
- start.getFullYear(),
- start.getMonth(),
- ++last
- );
-
- if (next > end) {
- throw new Error(
- 'sanity fails next is greater then end'
- );
- }
-
- if (!Calc.isSameDate(next, end)) {
- list.push(next);
- continue;
- }
-
- break;
- }
-
- if (includeTime) {
- list.unshift(start);
- list.push(end);
- } else {
- list.unshift(this.createDay(start));
- list.push(this.createDay(end));
- }
-
- return list;
- },
-
- /**
- * Checks if date is in the past
- *
- * @param {Date} date to check.
- * @return {Boolean} true when date is in the past.
- */
- isPast: function(date) {
- return (date.valueOf() < Calc.today.valueOf());
- },
-
- /**
- * Checks if date is in the future
- *
- * @param {Date} date to check.
- * @return {Boolean} true when date is in the future.
- */
- isFuture: function(date) {
- return !Calc.isPast(date);
- },
-
- /**
- * Based on the input date
- * will return one of the following states
- *
- * past, present, future
- *
- * @param {Date} day for compare.
- * @param {Date} month comparison month.
- * @return {String} state.
- */
- relativeState: function(day, month) {
- var states;
- //var today = Calc.today;
-
- // 1. the date is today (real time)
- if (Calc.isToday(day)) {
- return Calc.PRESENT;
- }
-
- // 2. the date is in the past (real time)
- if (Calc.isPast(day)) {
- states = Calc.PAST;
- // 3. the date is in the future (real time)
- } else {
- states = Calc.FUTURE;
- }
-
- // 4. the date is not in the current month (relative time)
- if (day.getMonth() !== month.getMonth()) {
- states += ' ' + Calc.OTHER_MONTH;
- }
-
- return states;
- }
-
- };
-
- /* expose calc */
- DatePicker.Calc = Calc;
-
- /**
- * Initialize a date picker widget.
- *
- * @param {HTMLELement} element target of widget creation.
- */
- function DatePicker(element) {
- this.element = element;
- // default time is set so next/previous work
- // but we do not render the initial display here.
- this._position = new Date();
-
- // register events
- element.addEventListener('click', this);
-
- //XXX: When the document is localized again
- // we must also re-render the month because
- // the week days may have changed?
- // This will only happen when we change timezones
- // unless we add this information to the locales.
- }
-
- DatePicker.prototype = {
-
- /**
- * Internal value not exposed so we can fire events
- * when the getter/setter's are used.
- *
- * @type Date
- */
- _value: null,
-
- SELECTED: 'selected',
-
- /**
- * Gets current value
- *
- * @return {Null|Date} date or null.
- */
- get value() {
- return this._value;
- },
-
- /**
- * Sets the current value of the date picker.
- * When value differs from the currently set the
- * `onvaluechange` event will be fired with the new/old value.
- */
- set value(value) {
- var old = this._value;
- if (old !== value) {
- this._value = value;
- this._clearSelectedDay(value);
- this.onvaluechange(value, old);
- }
- },
-
- /**
- * Clears the currently selected date of its 'selected' class.
- * @private
- */
- _clearSelectedDay: function(value) {
- var target = this.element.querySelector('.' + SELECTED);
- if (target) {
- target.classList.remove(SELECTED);
- }
- },
-
- handleEvent: function(e) {
- switch (e.type) {
- case 'click':
- var target = e.target;
- //XXX: if the html of the date elements changes
- // this may also need to be altered as it
- // assumes that there is no nesting of elements.
- if (target.dataset.date) {
- var date = Calc.dateFromId(target.dataset.date);
- // order here is important as setting value will
- // clear all the past selected dates...
- this.value = date;
- this._position = date;
- // must come after setting selected date
- target.classList.add(SELECTED);
- }
- break;
- }
- },
-
- /**
- * Getter is used for date normalization.
- */
- get year() {
- return this._position.getFullYear();
- },
-
- /**
- * Getter is used for date normalization.
- */
- get month() {
- return this._position.getMonth();
- },
-
- get date() {
- return this._position.getDate();
- },
-
- /**
- * Find the number of days in the given month/year.
- * Month is zero based like the JS date constructor.
- *
- * @param {Numeric} year year value.
- * @param {Numeric} month month value.
- * @return {Numeric} number of days in month.
- */
- _daysInMonth: function(year, month) {
- var end = new Date(year, month + 1);
- end.setMilliseconds(-1);
- return end.getDate();
- },
-
- /**
- * Build the container for a day element.
- * Each element has classes added to it based
- * on what date it is created for.
- *
- * _today_ is based on today's actual date.
- * Each date element also contains a data-date attribute
- * with its current date as a string represented in
- * the following format: "yyyy-mm-dd".
- *
- * Possible classes:
- * - past
- * - present (today)
- * - future
- * - other-month (day of another month but falls within same week)
- *
- * @param {Date} date date desired.
- * @return {HTMLElement} dom element for day.
- */
- _renderDay: function(date) {
- var dayContainer = document.createElement('li');
- var dayEl = document.createElement('span');
-
- dayContainer.className = Calc.relativeState(
- date,
- this._position
- );
-
- dayEl.dataset.date = Calc.getDayId(date);
- dayEl.textContent = date.getDate();
-
- dayContainer.appendChild(dayEl);
-
- return dayContainer;
- },
-
- /**
- * Renders a set of dates and returns an ol element
- * containing each date.
- *
- * @private
- * @param {Array[Date]} dates array of dates.
- * @return {HTMLELement} container for week.
- */
- _renderWeek: function(dates) {
- var container = document.createElement('ol');
- var i = 0;
- var len = dates.length;
-
- for (; i < len; i++) {
- container.appendChild(
- this._renderDay(dates[i])
- );
- }
-
- return container;
- },
-
- /**
- * Finds all dates in a given month by week.
- * Includes leading and trailing days that occur
- * outside the given year/month combination.
- *
- * @private
- * @param {Numeric} year target year.
- * @param {Numeric} month target month.
- * @return {Array[Date]} array of dates.
- */
- _getMonthDays: function(year, month) {
- var date = new Date(year, month);
- var dateEnd = new Date(year, month + 1);
- dateEnd.setMilliseconds(-1);
-
- var start = Calc.getWeekStartDate(date);
- var end = Calc.getWeekEndDate(dateEnd);
- return Calc.daysBetween(start, end);
- },
-
- /**
- * Returns a section element with all
- * the days of the given month/year pair.
- *
- * Each month has a class for the number of weeks
- * it contains.
- *
- * Possible values:
- * - weeks-4
- * - weeks-5
- * - weeks-6
- *
- * @private
- */
- _renderMonth: function(year, month) {
- var container = document.createElement('section');
- var days = this._getMonthDays(year, month);
- var daysInWeek = Calc.daysInWeek();
- var weeks = days.length / daysInWeek;
- var i = 0;
-
- container.classList.add('weeks-' + weeks);
-
- for (; i < weeks; i++) {
- container.appendChild(this._renderWeek(
- days.splice(0, daysInWeek)
- ));
- }
-
- return container;
- },
-
- /**
- * Moves calendar one month into the future.
- */
- next: function() {
- this.display(this.year, this.month + 1, this.date);
- },
-
- /**
- * Moves calendar one month into the past.
- */
- previous: function() {
- this.display(this.year, this.month - 1, this.date);
- },
-
- /**
- * Primary method to display given month.
- * Will remove the current display and replace
- * it with the given month.
- *
- * @param {Numeric} year year to display.
- * @param {Numeric} month month to display.
- * @param {Numeric} date date to display.
- */
- display: function(year, month, date) {
-
- // reset the date to the last date if overflow
- var lastDate = new Date(year, month + 1, 0).getDate();
- if (lastDate < date)
- date = lastDate;
-
- // Should come before render month
- this._position = new Date(year, month, date);
-
- var element = this._renderMonth(year, month);
-
- if (this.monthDisplay) {
- this.monthDisplay.parentNode.removeChild(
- this.monthDisplay
- );
- }
-
- this.monthDisplay = element;
- this.element.appendChild(this.monthDisplay);
-
- this.onmonthchange(this._position);
-
- // Set the date as selected if presented
- this._clearSelectedDay();
- if (date) {
- var dayId = Calc.getDayId(this._position);
- this.value = this._position;
- var selector = '[data-date="' + dayId + '"]';
- var dateElement = document.querySelector(selector);
- dateElement.classList.add(SELECTED);
- }
- },
-
- /**
- * Called when the month is changed.
- */
- onmonthchange: function(month, year) {},
-
- /**
- * Called when the selected day changes.
- */
- onvaluechange: function(date) {}
- };
-
- return DatePicker;
-}());
diff --git a/apps/system/js/value_selector/input_parser.js b/apps/system/js/value_selector/input_parser.js
deleted file mode 100644
index 5eef320..0000000
--- a/apps/system/js/value_selector/input_parser.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Stateless object for input parser functions..
- * The intent is the methods here will only relate to the parsing
- * of input[type="date|time"]
- */
-
-ValueSelector.InputParser = (function() {
-
- var InputParser = {
- _dateParts: ['year', 'month', 'date'],
- _timeParts: ['hours', 'minutes', 'seconds'],
-
- /**
- * Import HTML5 input[type="time"] string value
- *
- * @param {String} value 23:20:50.52, 17:39:57.
- * @return {Object} { hours: 23, minutes: 20, seconds: 50 }.
- */
- importTime: function(value) {
- var result = {
- hours: 0,
- minutes: 0,
- seconds: 0
- };
-
- var parts = value.split(':');
- var part;
- var partName;
-
- var i = 0;
- var len = InputParser._timeParts.length;
-
- for (; i < len; i++) {
- partName = InputParser._timeParts[i];
- part = parts[i];
- if (part) {
- result[partName] = parseInt(part.slice(0, 2), 10) || 0;
- }
- }
-
- return result;
- },
-
- /**
- * Export date to HTML5 input[type="time"]
- *
- * @param {Date} value export value.
- * @return {String} 17:39:57.
- */
- exportTime: function(value) {
- var hour = value.getHours();
- var minute = value.getMinutes();
- var second = value.getSeconds();
-
- var result = '';
-
- result += InputParser.padNumber(hour) + ':';
- result += InputParser.padNumber(minute) + ':';
- result += InputParser.padNumber(second);
-
- return result;
- },
-
- /**
- * Import HTML5 input[type="time"] to object.
- *
- * @param {String} value 1997-12-19.
- * @return {Object} { year: 1997, month: 12, date: 19 }.
- */
- importDate: function(value) {
- var result = {
- year: 0,
- month: 0,
- date: 0
- };
-
- var parts = value.split('-');
- var part;
- var partName;
-
- var i = 0;
- var len = InputParser._dateParts.length;
-
- for (; i < len; i++) {
- partName = InputParser._dateParts[i];
- part = parts[i];
- if (part) {
- result[partName] = parseInt(part, 10);
- }
- }
-
- if (result.month > 0) {
- result.month = result.month - 1;
- }
-
- result.date = result.date || 1;
-
- return result;
- },
-
- /**
- * Export js date to HTML5 input[type="date"]
- *
- * @param {Date} value export value.
- * @return {String} date string (1997-12-19).
- */
- exportDate: function(value) {
- var year = value.getFullYear();
- var month = value.getMonth() + 1;
- var date = value.getDate();
-
- var result = '';
-
- result += InputParser.padNumber(year) + '-';
- result += InputParser.padNumber(month) + '-';
- result += InputParser.padNumber(date);
-
- return result;
- },
-
- /**
- * Designed to take a date & time value from
- * html5 input types and returns a JS Date.
- *
- * @param {String} date input date.
- * @param {String} time input time.
- *
- * @return {Date} full date object from date/time.
- */
- formatInputDate: function(date, time) {
- time = InputParser.importTime(time);
- date = InputParser.importDate(date);
-
- return new Date(
- date.year,
- date.month,
- date.date,
- time.hours,
- time.minutes,
- time.seconds
- );
- },
-
- /**
- * @param {Numeric} numeric value.
- * @return {String} Pad the numeric with a leading zero if < 10.
- */
- padNumber: function(numeric) {
- var value = String(numeric);
- if (numeric < 10) {
- return '0' + value;
- }
-
- return value;
- }
- };
-
- return InputParser;
-
-}());
diff --git a/apps/system/js/value_selector/spin_date_picker.js b/apps/system/js/value_selector/spin_date_picker.js
deleted file mode 100644
index feb0602..0000000
--- a/apps/system/js/value_selector/spin_date_picker.js
+++ /dev/null
@@ -1,341 +0,0 @@
-/**
- * SpinDatePicker is a html/js "widget" which enables users
- * pick a specific date. It display the date in the way based
- * on the language setting.
- *
- * The SpinDatePicker itself contains no UI for the controls.
- *
- * Example usage:
- *
- * // All necessary UI elements are contained in the root element.
- * var picker = new SpinDatePicker(root);
- * picker.value = new Date();
- * // after users pick a date
- * var newDate = picker.value;
- */
-var SpinDatePicker = (function SpinDatePicker() {
- 'use strict';
-
- var FIRST_YEAR = 1900;
- var LAST_YEAR = 2099;
-
- function getYearText() {
- var yearText = [];
- var dateTimeFormat = navigator.mozL10n.DateTimeFormat();
-
- for (var i = FIRST_YEAR; i <= LAST_YEAR; i++) {
- var date = new Date(i, 0, 1);
- yearText.push(dateTimeFormat.localeFormat(date, '%Y'));
- }
-
- return yearText;
- }
-
- function getMonthText() {
- var monthText = [];
- var date = new Date(0);
- var dateTimeFormat = navigator.mozL10n.DateTimeFormat();
-
- for (var i = 0; i < 12; i++) {
- date.setMonth(i);
- monthText.push(dateTimeFormat.localeFormat(date, '%B'));
- }
-
- return monthText;
- }
-
- function getDateText(days) {
- var dateText = [];
- var date = new Date(0);
- var dateTimeFormat = navigator.mozL10n.DateTimeFormat();
-
- for (var i = 1; i <= days; i++) {
- date.setDate(i);
- dateText.push(dateTimeFormat.localeFormat(date, '%d'));
- }
-
- return dateText;
- }
-
- function getDaysInMonth(year, month) {
- var date = new Date(year, month + 1, 0);
- return date.getDate();
- }
-
- /**
- * Get the order of date components.
- *
- * @param {String} date format.
- */
- function getDateComponentOrder(format) {
- var format = navigator.mozL10n.get('dateTimeFormat_%x');
- var order = '';
- var tokens = format.match(/(%E.|%O.|%.)/g);
-
- if (tokens) {
- tokens.forEach(function(token) {
- switch (token) {
- case '%Y':
- case '%y':
- case '%Oy':
- case 'Ey':
- case 'EY':
- order += 'Y';
- break;
- case '%B':
- case '%b':
- case '%m':
- case '%Om':
- order += 'M';
- break;
- case '%d':
- case '%e':
- case '%Od':
- case '%Oe':
- order += 'D';
- break;
- }
- });
- }
-
- if (order.length != 3)
- order = 'DMY';
-
- return order;
- }
-
- /**
- * Initialize a date picker widget.
- *
- * @param {HTMLELement} element target of widget creation.
- */
- function SpinDatePicker(element) {
- this.element = element;
-
- this.yearPicker = null;
- this.monthPicker = null;
- this.datePickers = {
- '28': null,
- '29': null,
- '30': null,
- '31': null
- };
-
- //XXX: When the document is localized again
- // we must also re-render the month because
- // the week days may have changed?
- // This will only happen when we change timezones
- // unless we add this information to the locales.
-
- var pickerContainer =
- element.querySelector('.picker-container');
- var yearPickerContainer =
- element.querySelector('.value-picker-year');
- var monthPickerContainer =
- element.querySelector('.value-picker-month');
- var tmpDatePickerContainers =
- element.querySelectorAll('.value-picker-date');
- var datePickerContainers = {
- '28': tmpDatePickerContainers[0],
- '29': tmpDatePickerContainers[1],
- '30': tmpDatePickerContainers[2],
- '31': tmpDatePickerContainers[3]
- };
-
- var updateCurrentValue = function spd_updateCurrentValue() {
- var selectedYear = this.yearPicker.getSelectedIndex() + FIRST_YEAR;
- var selectedMonth = this.monthPicker.getSelectedIndex();
- var days = getDaysInMonth(selectedYear, selectedMonth);
- var datePicker = this.datePickers[days];
- var selectedDate = datePicker.getSelectedIndex() + 1;
-
- this._value = new Date(selectedYear, selectedMonth, selectedDate);
- };
-
- var updateDatePickerVisibility =
- function spd_updateDatePickerVisibility() {
- var days = getDaysInMonth(this.yearPicker.getSelectedIndex() +
- FIRST_YEAR, this.monthPicker.getSelectedIndex());
- for (var i = 28; i <= 31; i++) {
- datePickerContainers[i].hidden = true;
- this.datePickers[i].setSelectedIndex(this._currentSelectedDateIndex);
- }
- datePickerContainers[days].hidden = false;
- };
-
- var onvaluechangeInternal =
- function spd_onvaluechangeInternal(newDateValue) {
- this.yearPicker.setSelectedIndex(newDateValue.getFullYear() - FIRST_YEAR);
- this.monthPicker.setSelectedIndex(newDateValue.getMonth());
- for (var i = 28; i <= 31; i++) {
- this.datePickers[i].setSelectedIndex(newDateValue.getDate() - 1);
- }
- updateDatePickerVisibility.apply(this);
- updateCurrentValue.apply(this);
- };
-
- var onSelectedYearChanged =
- function spd_onSelectedYearChanged(selectedYear) {
- updateDatePickerVisibility.apply(this);
- updateCurrentValue.apply(this);
- };
-
- var onSelectedMonthChanged =
- function spd_onSelectedMonthChanged(selectedMonth) {
- updateDatePickerVisibility.apply(this);
- updateCurrentValue.apply(this);
- };
-
- var onSelectedDateChanged =
- function spd_onSelectedDateChanged(selectedDate) {
- this._currentSelectedDateIndex = selectedDate;
- updateCurrentValue.apply(this);
- };
-
- var unitClassName = 'picker-unit';
-
- // year value picker
- var yearUnitStyle = {
- valueDisplayedText: getYearText(),
- className: unitClassName
- };
- if (this.yearPicker)
- this.yearPicker.uninit();
- this.yearPicker = new ValuePicker(yearPickerContainer, yearUnitStyle);
- this.yearPicker.onselectedindexchange = onSelectedYearChanged.bind(this);
-
- // month value picker
- var monthUnitStyle = {
- valueDisplayedText: getMonthText(),
- className: unitClassName
- };
- if (this.monthPicker)
- this.monthPicker.uninit();
- this.monthPicker =
- new ValuePicker(monthPickerContainer, monthUnitStyle);
- this.monthPicker.onselectedindexchange = onSelectedMonthChanged.bind(this);
-
- // date value picker
- for (var i = 28; i <= 31; i++) {
- var datePickerContainer = datePickerContainers[i];
- var dateUnitStyle = {
- valueDisplayedText: getDateText(i),
- className: unitClassName
- };
- var datePicker = this.datePickers[i];
-
- if (datePicker)
- datePicker.uninit();
- datePickerContainer.hidden = false;
- this.datePickers[i] = new ValuePicker(datePickerContainer, dateUnitStyle);
- this.datePickers[i].onselectedindexchange =
- onSelectedDateChanged.bind(this);
- }
-
- // set component order
- var dateComponentOrder = getDateComponentOrder();
- var pickerClassList = pickerContainer.classList;
- pickerClassList.remove('YMD');
- pickerClassList.remove('DMY');
- pickerClassList.remove('MDY');
- pickerClassList.add(dateComponentOrder);
-
- // Prevent focus being taken away by us for time picker.
- // The event listener on outer box will not be triggered cause
- // there is a evt.stopPropagation() in value_picker.js
- this.pickerElements = [monthPickerContainer, yearPickerContainer];
- for (var i = 28; i <= 31; i++) {
- this.pickerElements.push(datePickerContainers[i]);
- }
-
- this.pickerElements.forEach((function pickerElements_forEach(picker) {
- picker.addEventListener('mousedown', this);
- }).bind(this));
-
- this.onvaluechangeInternal = onvaluechangeInternal.bind(this);
- }
-
- SpinDatePicker.prototype = {
-
- /**
- * Internal value not exposed so we can fire events
- * when the getter/setter's are used.
- *
- * @type Date
- */
- _value: null,
-
- /**
- * Gets current value
- *
- * @return {Null|Date} date or null.
- */
- get value() {
- return this._value;
- },
-
- /**
- * Sets the current value of the date picker.
- * When value differs from the currently set the
- * `onvaluechange` event will be fired with the new/old value.
- */
- set value(value) {
- var old = this._value;
- if (old !== value) {
- this._value = value;
- this.onvaluechangeInternal(value);
- }
- },
-
- /**
- * Getter is used for date normalization.
- */
- get year() {
- return this._value.getFullYear();
- },
-
- /**
- * Getter is used for date normalization.
- */
- get month() {
- return this._value.getMonth();
- },
-
- get date() {
- return this._value.getDate();
- },
-
- handleEvent: function vs_handleEvent(evt) {
- switch (evt.type) {
- case 'mousedown':
- // Prevent focus being taken away by us.
- evt.preventDefault();
- break;
- }
- },
-
- uninit: function() {
- if (this.yearPicker)
- this.yearPicker.uninit();
- if (this.monthPicker)
- this.monthPicker.uninit();
- if (this.datePickers) {
- for (var i = 28; i <= 31; i++) {
- var datePicker = this.datePickers[i];
- datePicker.uninit();
- }
- }
-
- this.pickerElements.forEach((function pickerElements_forEach(picker) {
- picker.removeEventListener('mousedown', this);
- }).bind(this));
- },
-
- /**
- * Called when the selected date changes.
- */
- onvaluechangeInternal: function(date) {}
- };
-
- return SpinDatePicker;
-}());
diff --git a/apps/system/js/value_selector/value_picker.js b/apps/system/js/value_selector/value_picker.js
deleted file mode 100644
index 34e686f..0000000
--- a/apps/system/js/value_selector/value_picker.js
+++ /dev/null
@@ -1,222 +0,0 @@
-var ValuePicker = (function() {
- //
- // Constructor
- //
- function VP(e, unitStyle) {
- this.element = e;
- this._valueDisplayedText = unitStyle.valueDisplayedText;
- this._unitClassName = unitStyle.className;
- this._lower = 0;
- this._upper = unitStyle.valueDisplayedText.length - 1;
- this._range = unitStyle.valueDisplayedText.length;
- this._currentIndex = 0;
- this.init();
- }
-
- //
- // Public methods
- //
- VP.prototype.getSelectedIndex = function() {
- var selectedIndex = this._currentIndex;
- return selectedIndex;
- };
-
- VP.prototype.getSelectedDisplayedText = function() {
- var displayedText = this._valueDisplayedText[this._currentIndex];
- return displayedText;
- };
-
- VP.prototype.setSelectedIndex = function(tunedIndex, ignorePicker) {
- if ((tunedIndex % 1) > 0.5) {
- tunedIndex = Math.floor(tunedIndex) + 1;
- } else {
- tunedIndex = Math.floor(tunedIndex);
- }
-
- if (tunedIndex < this._lower) {
- tunedIndex = this._lower;
- }
-
- if (tunedIndex > this._upper) {
- tunedIndex = this._upper;
- }
-
- if (this._currentIndex != tunedIndex) {
- this._currentIndex = tunedIndex;
- this.onselectedindexchange(this._currentIndex);
- }
- this.updateUI(tunedIndex, ignorePicker);
-
- return tunedIndex;
- };
-
- VP.prototype.setSelectedIndexByDisplayedText = function(displayedText) {
- var newIndex = this._valueDisplayedText.indexOf(displayedText);
- if (newIndex != -1) {
- if (this._currentIndex != newIndex) {
- this._currentIndex = newIndex;
- this.onselectedindexchange(this._currentIndex);
- }
- this.updateUI(newIndex);
- }
- };
-
- //
- // Internal methods
- //
- VP.prototype.init = function() {
- this.initUI();
- this.setSelectedIndex(0); // Default Index is zero
- this.mousedonwHandler = vp_mousedown.bind(this);
- this.mousemoveHandler = vp_mousemove.bind(this);
- this.mouseupHandler = vp_mouseup.bind(this);
- this.addEventListeners();
- };
-
- VP.prototype.initUI = function() {
- var lower = this._lower;
- var upper = this._upper;
- var unitCount = this._valueDisplayedText.length;
- for (var i = 0; i < unitCount; ++i) {
- this.addPickerUnit(i);
- }
- // cache the size of picker
- this._pickerUnits = this.element.children;
- this._pickerUnitsHeight = this._pickerUnits[0].clientHeight;
- this._pickerHeight = this._pickerUnits[0].clientHeight *
- this._pickerUnits.length;
- this._space = this._pickerHeight / this._range;
- };
-
- VP.prototype.addPickerUnit = function(index) {
- var html = this._valueDisplayedText[index];
- var unit = document.createElement('div');
- unit.className = this._unitClassName;
- unit.innerHTML = html;
- this.element.appendChild(unit);
- };
-
- VP.prototype.updateUI = function(index, ignorePicker) {
- if (true !== ignorePicker) {
- this.element.style.top =
- (this._lower - index) * this._space + 'px';
- }
- };
-
- VP.prototype.addEventListeners = function() {
- this.element.addEventListener('mousedown', this.mousedonwHandler, false);
- };
-
- VP.prototype.removeEventListeners = function() {
- this.element.removeEventListener('mouseup', this.mouseupHandler, false);
- this.element.removeEventListener('mousemove', this.mousemoveHandler, false);
- };
-
- VP.prototype.uninit = function() {
- this.element.removeEventListener('mousedown', this.mousedonwHandler, false);
- this.element.removeEventListener('mouseup', this.mouseupHandler, false);
- this.element.removeEventListener('mousemove', this.mousemoveHandler, false);
- this.element.style.top = '0px';
- this.onselectedindexchange = null;
- empty(this.element);
- };
-
- VP.prototype.onselectedindexchange = function(index) {};
-
- function cloneEvent(evt) {
- if ('touches' in evt) {
- evt = evt.touches[0];
- }
- return { x: evt.pageX, y: evt.pageY, timestamp: evt.timeStamp };
- }
-
- function empty(element) {
- while (element.hasChildNodes())
- element.removeChild(element.lastChild);
- element.innerHTML = '';
- }
-
- //
- // Tuneable parameters
- //
- var SPEED_THRESHOLD = 0.1;
- var currentEvent, startEvent, currentSpeed;
- var tunedIndex = 0;
-
- function toFixed(value) {
- return parseFloat(value.toFixed(1));
- }
-
- function calcSpeed() {
- var movingSpace = startEvent.y - currentEvent.y;
- var deltaTime = currentEvent.timestamp - startEvent.timestamp;
- var speed = movingSpace / deltaTime;
- currentSpeed = parseFloat(speed.toFixed(2));
- }
-
- function calcTargetIndex(space) {
- return tunedIndex - getMovingSpace() / space;
- }
-
- // If the user swap really slow, narrow down the moving space
- // So the user can fine tune value.
- function getMovingSpace() {
- var movingSpace = currentEvent.y - startEvent.y;
- var reValue = Math.abs(currentSpeed) > SPEED_THRESHOLD ?
- movingSpace : movingSpace / 4;
- return reValue;
- }
-
- function vp_mousemove(event) {
- event.stopPropagation();
- event.target.setCapture(true);
- currentEvent = cloneEvent(event);
-
- calcSpeed();
-
- // move selected index
- this.element.style.top = parseFloat(this.element.style.top) +
- getMovingSpace() + 'px';
-
- tunedIndex = calcTargetIndex(this._space);
- var roundedIndex = Math.round(tunedIndex * 10) / 10;
-
- if (roundedIndex != this._currentIndex) {
- this.setSelectedIndex(toFixed(roundedIndex), true);
- }
-
- startEvent = currentEvent;
- }
-
- function vp_mouseup(event) {
- event.stopPropagation();
- this.removeEventListeners();
-
- // Add animation back
- this.element.classList.add('animation-on');
-
- // Add momentum if speed is higher than a given threshold.
- if (Math.abs(currentSpeed) > SPEED_THRESHOLD) {
- var direction = currentSpeed > 0 ? 1 : -1;
- tunedIndex += Math.min(Math.abs(currentSpeed) * 5, 5) * direction;
- }
- tunedIndex = this.setSelectedIndex(toFixed(tunedIndex));
- currentSpeed = 0;
- }
-
- function vp_mousedown(event) {
- event.stopPropagation();
-
- // Stop animation
- this.element.classList.remove('animation-on');
-
- startEvent = currentEvent = cloneEvent(event);
- tunedIndex = this._currentIndex;
-
- this.removeEventListeners();
- this.element.addEventListener('mousemove', this.mousemoveHandler, false);
- this.element.addEventListener('mouseup', this.mouseupHandler, false);
- }
-
- return VP;
-}());
diff --git a/apps/system/js/value_selector/value_selector.js b/apps/system/js/value_selector/value_selector.js
deleted file mode 100644
index b3381b3..0000000
--- a/apps/system/js/value_selector/value_selector.js
+++ /dev/null
@@ -1,526 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var ValueSelector = {
-
- _containers: {},
- _popups: {},
- _buttons: {},
- _datePicker: null,
-
- debug: function(msg) {
- var debugFlag = false;
- if (debugFlag) {
- console.log('[ValueSelector] ', msg);
- }
- },
-
- init: function vs_init() {
-
- var self = this;
-
- window.navigator.mozKeyboard.onfocuschange = function onfocuschange(evt) {
- var typeToHandle = ['select-one', 'select-multiple', 'date',
- 'time', 'datetime', 'datetime-local', 'blur'];
-
- var type = evt.detail.type;
- // handle the <select> element and inputs with type of date/time
- // in system app for now
- if (typeToHandle.indexOf(type) == -1)
- return;
-
- var currentValue = evt.detail.value;
-
- switch (evt.detail.type) {
- case 'select-one':
- case 'select-multiple':
- self.debug('select triggered' + JSON.stringify(evt.detail));
- self._currentPickerType = evt.detail.type;
- self.showOptions(evt.detail);
- break;
-
- case 'date':
- self.showDatePicker(currentValue);
- break;
-
- case 'time':
- self.showTimePicker(currentValue);
- break;
-
- case 'datetime':
- case 'datetime-local':
- // TODO
- break;
- case 'blur':
- self.hide();
- break;
- }
- };
-
- this._element = document.getElementById('value-selector');
- this._element.addEventListener('mousedown', this);
- this._containers['select'] =
- document.getElementById('value-selector-container');
- this._containers['select'].addEventListener('click', this);
- ActiveEffectHelper.enableActive(this._containers['select']);
-
- this._popups['select'] =
- document.getElementById('select-option-popup');
- this._popups['select'].addEventListener('submit', this);
- this._popups['time'] =
- document.getElementById('time-picker-popup');
- this._popups['date'] =
- document.getElementById('spin-date-picker-popup');
-
- this._buttons['select'] = document.getElementById('select-options-buttons');
- this._buttons['select'].addEventListener('click', this);
-
- this._buttons['time'] = document.getElementById('time-picker-buttons');
- this._buttons['time'].addEventListener('click', this);
- this._buttons['date'] = document.getElementById('spin-date-picker-buttons');
-
- this._buttons['date'].addEventListener('click', this);
-
- this._containers['time'] = document.getElementById('picker-bar');
- this._containers['date'] = document.getElementById('spin-date-picker');
-
- ActiveEffectHelper.enableActive(this._buttons['select']);
- ActiveEffectHelper.enableActive(this._buttons['time']);
- ActiveEffectHelper.enableActive(this._buttons['date']);
-
- // Prevent focus being taken away by us for time picker.
- // The event listener on outer box will not be triggered cause
- // there is a evt.stopPropagation() in value_picker.js
- var pickerElements = ['value-picker-hours', 'value-picker-minutes',
- 'value-picker-hour24-state'];
-
- pickerElements.forEach((function pickerElements_forEach(id) {
- var element = document.getElementById(id);
- element.addEventListener('mousedown', this);
- }).bind(this));
-
- window.addEventListener('appopen', this);
- window.addEventListener('appwillclose', this);
-
- // invalidate the current spin date picker when language setting changes
- navigator.mozSettings.addObserver('language.current',
- (function language_change(e) {
- if (this._datePicker) {
- this._datePicker.uninit();
- this._datePicker = null;
- }}).bind(this));
- },
-
- handleEvent: function vs_handleEvent(evt) {
- switch (evt.type) {
- case 'appopen':
- case 'appwillclose':
- this.hide();
- break;
-
- case 'click':
- var currentTarget = evt.currentTarget;
- switch (currentTarget) {
- case this._buttons['select']:
- case this._buttons['time']:
- case this._buttons['date']:
- var target = evt.target;
- if (target.dataset.type == 'cancel') {
- this.cancel();
- } else if (target.dataset.type == 'ok') {
- this.confirm();
- }
- break;
-
- case this._containers['select']:
- this.handleSelect(evt.target);
- break;
- }
- break;
-
- case 'submit':
- // Prevent the form from submit.
- case 'mousedown':
- // Prevent focus being taken away by us.
- evt.preventDefault();
- break;
-
- default:
- this.debug('no event handler defined for' + evt.type);
- break;
- }
- },
-
- handleSelect: function vs_handleSelect(target) {
-
- if (target.dataset === undefined ||
- (target.dataset.optionIndex === undefined &&
- target.dataset.optionValue === undefined))
- return;
-
- if (this._currentPickerType === 'select-one') {
- var selectee = this._containers['select'].
- querySelectorAll('[aria-checked="true"]');
- for (var i = 0; i < selectee.length; i++) {
- selectee[i].removeAttribute('aria-checked');
- }
-
- target.setAttribute('aria-checked', 'true');
- } else if (target.getAttribute('aria-checked') === 'true') {
- target.removeAttribute('aria-checked');
- } else {
- target.setAttribute('aria-checked', 'true');
- }
-
- // setValue here to trigger change event
- var singleOptionIndex;
- var optionIndices = [];
-
- var selectee = this._containers['select'].
- querySelectorAll('[aria-checked="true"]');
-
- if (this._currentPickerType === 'select-one') {
-
- if (selectee.length > 0)
- singleOptionIndex = selectee[0].dataset.optionIndex;
-
- window.navigator.mozKeyboard.setSelectedOption(singleOptionIndex);
-
- } else if (this._currentPickerType === 'select-multiple') {
- // Multiple select case
- for (var i = 0; i < selectee.length; i++) {
-
- var index = parseInt(selectee[i].dataset.optionIndex);
- optionIndices.push(index);
- }
-
- window.navigator.mozKeyboard.setSelectedOptions(optionIndices);
- }
-
- },
-
- show: function vs_show(detail) {
- this._element.hidden = false;
- },
-
- showPanel: function vs_showPanel(type) {
- for (var p in this._containers) {
- if (p === type) {
- this._popups[p].hidden = false;
- } else {
- this._popups[p].hidden = true;
- }
- }
- },
-
- hide: function vs_hide() {
- this._element.hidden = true;
- },
-
- cancel: function vs_cancel() {
- this.debug('cancel invoked');
- window.navigator.mozKeyboard.removeFocus();
- this.hide();
- },
-
- confirm: function vs_confirm() {
-
- if (this._currentPickerType === 'time') {
-
- var timeValue = TimePicker.getTimeValue();
- this.debug('output value: ' + timeValue);
-
- window.navigator.mozKeyboard.setValue(timeValue);
- } else if (this._currentPickerType === 'date') {
- var dateValue = this._datePicker.value;
- // The format should be 2012-09-19
- dateValue = dateValue.toLocaleFormat('%Y-%m-%d');
- this.debug('output value: ' + dateValue);
- window.navigator.mozKeyboard.setValue(dateValue);
- }
-
- window.navigator.mozKeyboard.removeFocus();
- this.hide();
- },
-
- showOptions: function vs_showOptions(detail) {
-
- var options = null;
- if (detail.choices && detail.choices.choices)
- options = detail.choices.choices;
-
- if (options)
- this.buildOptions(options);
-
- this.show();
- this.showPanel('select');
- },
-
- buildOptions: function(options) {
-
- var optionHTML = '';
-
- function escapeHTML(str) {
- var span = document.createElement('span');
- span.textContent = str;
- return span.innerHTML;
- }
-
- for (var i = 0, n = options.length; i < n; i++) {
-
- var checked = options[i].selected ? ' aria-checked="true"' : '';
-
- // This for attribute is created only to avoid applying
- // a general rule in building block
- var forAttribute = ' for="gaia-option-' + options[i].optionIndex + '"';
-
- optionHTML += '<li data-option-index="' + options[i].optionIndex + '"' +
- checked + '>' +
- '<label' + forAttribute + '> <span>' +
- escapeHTML(options[i].text) +
- '</span></label>' +
- '</li>';
- }
-
- var optionsContainer = document.querySelector(
- '#value-selector-container ol');
- if (!optionsContainer)
- return;
-
- optionsContainer.innerHTML = optionHTML;
-
-
- // Apply different style when the options are more than 1 page
- if (options.length > 5) {
- this._containers['select'].classList.add('scrollable');
- } else {
- this._containers['select'].classList.remove('scrollable');
- }
-
- // Change the title for multiple select
- var titleL10nId = 'choose-options';
- if (this._currentPickerType === 'select-one')
- titleL10nId = 'choose-option';
-
- var optionsTitle = document.querySelector(
- '#value-selector-container h1');
-
- if (optionsTitle) {
- optionsTitle.dataset.l10nId = titleL10nId;
- optionsTitle.textContent = navigator.mozL10n.get(titleL10nId);
- }
- },
-
- showTimePicker: function vs_showTimePicker(currentValue) {
- this._currentPickerType = 'time';
- this.show();
- this.showPanel('time');
-
- if (!this._timePickerInitialized) {
- TimePicker.initTimePicker();
- this._timePickerInitialized = true;
- }
-
- var time;
- if (!currentValue) {
- var now = new Date();
- time = {
- hours: now.getHours(),
- minutes: now.getMinutes()
- };
- } else {
- var inputParser = ValueSelector.InputParser;
- if (!inputParser)
- console.error('Cannot get input parser for value selector');
-
- time = inputParser.importTime(currentValue);
- }
-
- var timePicker = TimePicker.timePicker;
- // Set the value of time picker according to the current value
- if (timePicker.is12hFormat) {
- var hour = (time.hours % 12);
- hour = (hour == 0) ? 12 : hour;
- // 24-hour state value selector: AM = 0, PM = 1
- var hour24State = (time.hours >= 12) ? 1 : 0;
- timePicker.hour.setSelectedIndexByDisplayedText(hour);
- timePicker.hour24State.setSelectedIndex(hour24State);
- } else {
- timePicker.hour.setSelectedIndex(time.hours);
- }
-
- timePicker.minute.setSelectedIndex(time.minutes);
- },
-
- showDatePicker: function vs_showDatePicker(currentValue) {
- this._currentPickerType = 'date';
- this.show();
- this.showPanel('date');
-
- if (!this._datePicker) {
- this._datePicker = new SpinDatePicker(this._containers['date']);
- }
-
- // Show current date as default value
- var date = new Date();
- if (currentValue) {
- var inputParser = ValueSelector.InputParser;
- if (!inputParser)
- console.error('Cannot get input parser for value selector');
-
- date = inputParser.formatInputDate(currentValue, '');
- }
- this._datePicker.value = date;
- }
-
-};
-
-var TimePicker = {
- timePicker: {
- hour: null,
- minute: null,
- hour24State: null,
- is12hFormat: false
- },
-
- get hourSelector() {
- delete this.hourSelector;
- return this.hourSelector =
- document.getElementById('value-picker-hours');
- },
-
- get minuteSelector() {
- delete this.minuteSelector;
- return this.minuteSelector =
- document.getElementById('value-picker-minutes');
- },
-
- get hour24StateSelector() {
- delete this.hour24StateSelector;
- return this.hour24StateSelector =
- document.getElementById('value-picker-hour24-state');
- },
-
- initTimePicker: function tp_initTimePicker() {
- var localeTimeFormat = navigator.mozL10n.get('dateTimeFormat_%X');
- var is12hFormat = (localeTimeFormat.indexOf('%p') >= 0);
- this.timePicker.is12hFormat = is12hFormat;
- this.setTimePickerStyle();
- var startHour = is12hFormat ? 1 : 0;
- var endHour = is12hFormat ? (startHour + 12) : (startHour + 12 * 2);
- var unitClassName = 'picker-unit';
- var hourDisplayedText = [];
- for (var i = startHour; i < endHour; i++) {
- var value = i;
- hourDisplayedText.push(value);
- }
- var hourUnitStyle = {
- valueDisplayedText: hourDisplayedText,
- className: unitClassName
- };
- this.timePicker.hour = new ValuePicker(this.hourSelector, hourUnitStyle);
-
- var minuteDisplayedText = [];
- for (var i = 0; i < 60; i++) {
- var value = (i < 10) ? '0' + i : i;
- minuteDisplayedText.push(value);
- }
- var minuteUnitStyle = {
- valueDisplayedText: minuteDisplayedText,
- className: unitClassName
- };
- this.timePicker.minute =
- new ValuePicker(this.minuteSelector, minuteUnitStyle);
-
- if (is12hFormat) {
- var hour24StateUnitStyle = {
- valueDisplayedText: ['AM', 'PM'],
- className: unitClassName
- };
- this.timePicker.hour24State =
- new ValuePicker(this.hour24StateSelector, hour24StateUnitStyle);
- }
- },
-
- setTimePickerStyle: function tp_setTimePickerStyle() {
- var style = (this.timePicker.is12hFormat) ? 'format12h' : 'format24h';
- document.getElementById('picker-bar').classList.add(style);
- },
-
- // return a string for the time value, format: "16:37"
- getTimeValue: function tp_getTimeValue() {
- var hour = 0;
- if (this.timePicker.is12hFormat) {
- var hour24Offset = 12 * this.timePicker.hour24State.getSelectedIndex();
- hour = this.timePicker.hour.getSelectedDisplayedText();
- hour = (hour == 12) ? 0 : hour;
- hour = hour + hour24Offset;
- } else {
- hour = this.timePicker.hour.getSelectedIndex();
- }
- var minute = this.timePicker.minute.getSelectedDisplayedText();
-
- return hour + ':' + minute;
- }
-};
-
-var ActiveEffectHelper = (function() {
-
- var lastActiveElement = null;
-
- function _setActive(element, isActive) {
- if (isActive) {
- element.classList.add('active');
- lastActiveElement = element;
- } else {
- element.classList.remove('active');
- if (lastActiveElement) {
- lastActiveElement.classList.remove('active');
- lastActiveElement = null;
- }
- }
- }
-
- function _onMouseDown(evt) {
- var target = evt.target;
-
- _setActive(target, true);
- target.addEventListener('mouseleave', _onMouseLeave);
- }
-
- function _onMouseUp(evt) {
- var target = evt.target;
-
- _setActive(target, false);
- target.removeEventListener('mouseleave', _onMouseLeave);
- }
-
- function _onMouseLeave(evt) {
- var target = evt.target;
- _setActive(target, false);
- target.removeEventListener('mouseleave', _onMouseLeave);
- }
-
- var _events = {
- 'mousedown': _onMouseDown,
- 'mouseup': _onMouseUp
- };
-
- function _enableActive(element) {
- // Attach event listeners
- for (var event in _events) {
- var callback = _events[event] || null;
- if (callback)
- element.addEventListener(event, callback);
- }
- }
-
- return {
- enableActive: _enableActive
- };
-
-})();
-
-ValueSelector.init();
diff --git a/apps/system/js/voicemail.js b/apps/system/js/voicemail.js
deleted file mode 100644
index dea5116..0000000
--- a/apps/system/js/voicemail.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-// Custom voicemail notification -- This can be removed once DesktopNotification
-// supports removing notifications via API
-var Voicemail = {
-
- icon: null,
- notification: null,
- // A random starting point that is unlikely to be used by other notifications
- notificationId: 3000 + Math.floor(Math.random() * 999),
-
- init: function vm_init() {
- var voicemail = window.navigator.mozVoicemail;
- if (!voicemail)
- return;
-
- voicemail.addEventListener('statuschanged', this);
-
- this.icon = window.location.protocol + '//' +
- window.location.hostname + '/style/icons/voicemail.png';
- },
-
- handleEvent: function vm_handleEvent(evt) {
- var voicemail = window.navigator.mozVoicemail;
- if (!voicemail.status)
- return;
-
- this.updateNotification(voicemail.status);
- },
-
- updateNotification: function vm_updateNotification(status) {
- var _ = window.navigator.mozL10n.get;
- var title = status.returnMessage;
- var showCount = status.hasMessages && status.messageCount > 0;
-
- if (!title) {
- title = showCount ? _('newVoicemails', { n: status.messageCount }) :
- _('newVoicemailsUnknown');
- }
-
- var text = title;
- var voicemailNumber = navigator.mozVoicemail.number;
- if (voicemailNumber) {
- text = _('dialNumber', { number: voicemailNumber });
- }
-
- this.hideNotification();
- if (status.hasMessages) {
- this.showNotification(title, text, voicemailNumber);
- }
- },
-
- showNotification: function vm_showNotification(title, text, voicemailNumber) {
- this.notificationId++;
- this.notification = NotificationScreen.addNotification({
- id: this.notificationId, title: title, text: text, icon: this.icon
- });
-
- if (!voicemailNumber) {
- return;
- }
-
- var self = this;
- function vmNotification_onTap(event) {
- self.notification.removeEventListener('tap', vmNotification_onTap);
-
- var telephony = window.navigator.mozTelephony;
- if (!telephony) {
- return;
- }
-
- telephony.dial(voicemailNumber);
- }
-
- this.notification.addEventListener('tap', vmNotification_onTap);
- },
-
- hideNotification: function vm_hideNotification() {
- if (!this.notification) {
- return;
- }
-
- if (this.notification.parentNode) {
- NotificationScreen.removeNotification(this.notificationId);
- }
-
- this.notification = null;
- this.notificationId = 0;
- }
-};
-
-Voicemail.init();
diff --git a/apps/system/js/wifi.js b/apps/system/js/wifi.js
deleted file mode 100644
index 3456fdf..0000000
--- a/apps/system/js/wifi.js
+++ /dev/null
@@ -1,223 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var Wifi = {
- wifiWakeLocked: false,
-
- wifiEnabled: true,
-
- wifiDisabledByWakelock: false,
-
- // Without wake lock, wait for kOffTime milliseconds and turn wifi off
- // after the conditions are met.
- kOffTime: 60 * 1000,
-
- // if Wifi is enabled but disconnected, try to scan for networks every
- // kScanInterval ms.
- kScanInterval: 20 * 1000,
-
- _scanTimer: null,
-
- init: function wf_init() {
- window.addEventListener('screenchange', this);
-
- var battery = window.navigator.battery;
- battery.addEventListener('chargingchange', this);
-
- if (!window.navigator.mozSettings)
- return;
-
- // If wifi is turned off by us and phone got rebooted,
- // bring wifi back.
- var name = 'wifi.disabled_by_wakelock';
- var req = SettingsListener.getSettingsLock().get(name);
- req.onsuccess = function gotWifiDisabledByWakelock() {
- if (!req.result[name])
- return;
-
- // Re-enable wifi and reset wifi.disabled_by_wakelock
- // SettingsListener.getSettingsLock() always return invalid lock
- // in our usage here.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=793239
- var lock = navigator.mozSettings.createLock();
- lock.set({ 'wifi.enabled': true });
- lock.set({ 'wifi.disabled_by_wakelock': false });
- };
-
- var self = this;
- var wifiManager = window.navigator.mozWifiManager;
- // when wifi is really enabled, emit event to notify QuickSettings
- wifiManager.onenabled = function onWifiEnabled() {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('wifi-enabled',
- /* canBubble */ true, /* cancelable */ false, null);
- window.dispatchEvent(evt);
- };
-
- // when wifi is really disabled, emit event to notify QuickSettings
- wifiManager.ondisabled = function onWifiDisabled() {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('wifi-disabled',
- /* canBubble */ true, /* cancelable */ false, null);
- window.dispatchEvent(evt);
- };
-
- // when wifi status change, emit event to notify StatusBar/UpdateManager
- wifiManager.onstatuschange = function onWifiDisabled() {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('wifi-statuschange',
- /* canBubble */ true, /* cancelable */ false, null);
- window.dispatchEvent(evt);
- };
-
- // Track the wifi.enabled mozSettings value
- SettingsListener.observe('wifi.enabled', true, function(value) {
- if (!wifiManager && value) {
- self.wifiEnabled = false;
-
- // roll back the setting value to notify the UIs
- // that wifi interface is not available
- if (value) {
- SettingsListener.getSettingsLock().set({
- 'wifi.enabled': false
- });
- }
-
- return;
- }
-
- self.wifiEnabled = value;
-
- clearTimeout(self._scanTimer);
- if (!value)
- return;
-
- // If wifi is enabled but disconnected.
- // we would need to call getNetworks() continuously
- // so we could join known wifi network
- self._scanTimer = setInterval(function wifi_scan() {
- if (wifiManager.connection.status == 'disconnected')
- wifiManager.getNetworks();
- });
- });
-
- var power = navigator.mozPower;
- power.addWakeLockListener(function wifi_handleWakeLock(topic, state) {
- if (topic !== 'wifi')
- return;
-
- self.wifiWakeLocked = (state == 'locked-foreground' ||
- state == 'locked-background');
-
- self.maybeToggleWifi();
- });
- },
-
- handleEvent: function wifi_handleEvent(evt) {
- this.maybeToggleWifi();
- },
-
- // Check the status of screen, wifi wake lock and power source
- // and turn on/off wifi accordingly
- maybeToggleWifi: function wifi_maybeToggleWifi() {
- var battery = window.navigator.battery;
- var wifiManager = window.navigator.mozWifiManager;
- if (!battery || !wifiManager ||
- (!this.wifiEnabled && !this.wifiDisabledByWakelock))
- return;
-
-
- // Let's quietly turn off wifi if there is no wake lock and
- // the screen is off and we are not on a power source.
- if (!ScreenManager.screenEnabled &&
- !this.wifiWakeLocked && !battery.charging) {
- // We don't need to do anything if wifi is not enabled currently
- if (!this.wifiEnabled)
- return;
-
- // We still need to turn of wifi even if there is no Alarm API
- if (!navigator.mozAlarms) {
- console.warn('Turning off wifi without sleep timer because' +
- ' Alarm API is not available');
- this.sleep();
-
- return;
- }
-
- // Set System Message Handler, so we will be notified when alarm goes off.
- this.setSystemMessageHandler();
-
- // Start with a timer, only turn off wifi till timeout.
- var date = new Date(Date.now() + this.kOffTime);
- var self = this;
- var req = navigator.mozAlarms.add(date, 'ignoreTimezone', 'wifi-off');
- req.onsuccess = function wifi_offAlarmSet() {
- self._alarmId = req.result;
- };
- req.onerror = function wifi_offAlarmSetFailed() {
- console.warn('Fail to set wifi sleep timer on Alarm API. ' +
- 'Turn off wifi immediately.');
- self.sleep();
- };
- }
- // ... and quietly turn it back on or cancel the timer otherwise
- else {
- if (this._alarmId) {
- navigator.mozAlarms.remove(this._alarmId);
- this._alarmId = null;
- }
-
- // If wifi is enabled but disconnected.
- // we would need to call getNetworks() so we could join known wifi network
- if (this.wifiEnabled && wifiManager.connection.status == 'disconnected') {
- wifiManager.getNetworks();
- }
-
- // We don't need to do anything if we didn't disable wifi at first place.
- if (!this.wifiDisabledByWakelock)
- return;
-
- var lock = SettingsListener.getSettingsLock();
- // turn wifi back on.
- lock.set({ 'wifi.enabled': true });
-
- this.wifiDisabledByWakelock = false;
- lock.set({ 'wifi.disabled_by_wakelock': false });
- }
- },
-
- // Quietly turn off wifi for real, set wifiDisabledByWakelock to true
- // so we will turn it back on.
- sleep: function wifi_sleep() {
- var lock = SettingsListener.getSettingsLock();
- // Actually turn off the wifi
- lock.set({ 'wifi.enabled': false });
-
- // Remember that it was turned off by us.
- this.wifiDisabledByWakelock = true;
-
- // Keep this value in disk so if the phone reboots we'll
- // be able to turn the wifi back on.
- lock.set({ 'wifi.disabled_by_wakelock': true });
- },
-
- // Register for handling system message,
- // this cannot be done during |init()| because of bug 797803
- setSystemMessageHandler: function wifi_setSystemMessageHandler() {
- if (this._systemMessageHandlerRegistered)
- return;
-
- this._systemMessageHandlerRegistered = true;
- var self = this;
- navigator.mozSetMessageHandler('alarm', function gotAlarm(message) {
- if (message.data !== 'wifi-off')
- return;
-
- self.sleep();
- });
- }
-};
-
-Wifi.init();
diff --git a/apps/system/js/window.js b/apps/system/js/window.js
deleted file mode 100644
index a9109dd..0000000
--- a/apps/system/js/window.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-(function(window){
-
- var _ = navigator.mozL10n.get;
-
- var ENABLE_LOG = false;
-
- // Use mutation observer to monitor appWindow status change
- window.AppLog = function AppLog(app) {
- // select the target node
- var target = app.frame;
-
- // create an observer instance
- var observer = new MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- console.log(mutation.target.id,
- mutation.target.className,
- mutation.attributeName);
- });
- });
-
- // configuration of the observer:
- var config = { attributes: true };
-
- // pass in the target node, as well as the observer options
- observer.observe(target, config);
- }
-
- window.AppError = function AppError(app) {
- var self = this;
- this.app = app;
- this.app.frame.addEventListener('mozbrowsererror', function (evt) {
- if (evt.detail.type != 'other')
- return;
-
- console.warn('app of [' + self.app.origin + '] got a mozbrowsererror event.');
-
- if (self.injected) {
- self.update();
- } else {
- self.render();
- }
- self.show();
- self.injected = true;
- });
- return this;
- };
-
- AppError.className = 'appError';
-
- AppError.prototype.hide = function() {
- this.element.classList.remove('visible');
- }
-
- AppError.prototype.show = function() {
- this.element.classList.add('visible');
- }
-
- AppError.prototype.render = function() {
- this.app.frame.insertAdjacentHTML('beforeend', this.view());
- this.closeButton = this.app.frame.querySelector('.' + AppError.className + ' .close');
- this.reloadButton = this.app.frame.querySelector('.' + AppError.className + ' .reload');
- this.titleElement = this.app.frame.querySelector('.' + AppError.className + ' .title');
- this.messageElement = this.app.frame.querySelector('.' + AppError.className + ' .message');
- this.element = this.app.frame.querySelector('.' + AppError.className);
- var self = this;
- this.closeButton.onclick = function() {
- self.app.kill();
- }
-
- this.reloadButton.onclick = function() {
- self.hide();
- self.app.reload();
- }
- }
-
- AppError.prototype.update = function() {
- this.titleElement.textContent = this.getTitle();
- this.messageElement.textContent = this.getMessage();
- }
-
- AppError.prototype.id = function() {
- return AppError.className + '-' + this.app.frame.id;
- }
-
- AppError.prototype.getTitle = function() {
- if (AirplaneMode.enabled) {
- return _('airplane-is-on');
- } else if (!navigator.onLine) {
- return _('network-connection-unavailable');
- } else {
- return _('error-title', { name: this.app.name });
- }
- }
-
- AppError.prototype.getMessage = function() {
- if (AirplaneMode.enabled) {
- return _('airplane-is-turned-on', { name: this.app.name });
- } else if (!navigator.onLine) {
- return _('network-error', { name: this.app.name });
- } else {
- return _('error-message', { name: this.app.name });
- }
- }
-
- AppError.prototype.view = function() {
- return '<div id="' + this.id() + '" class="' + AppError.className + ' visible" role="dialog">' +
- '<div class="modal-dialog-message-container inner">' +
- '<h3 data-l10n-id="error-title" class="title">' + this.getTitle() + '</h3>' +
- '<p>' +
- '<span data-l10n-id="error-message" class="message">' + this.getMessage() + '</span>' +
- '</p>' +
- '</div>' +
- '<menu data-items="2">' +
- '<button class="close" data-l10n-id="try-again">' + _('close') + '</button>' +
- '<button class="reload" data-l10n-id="try-again">' + _('try-again') + '</button>' +
- '</menu>' +
- '</div>';
- }
-
- window.AppWindow = function AppWindow(configuration) {
- for (var key in configuration) {
- this[key] = configuration[key];
- }
-
- // We keep the appError object here for the purpose that
- // we may need to export the error state of AppWindow instance to the other module
- // in the future.
- this.appError = new AppError(this);
- if (ENABLE_LOG)
- this.appLog = new AppLog(this);
-
- return this;
- };
-
- AppWindow.prototype.reload = function() {
- this.iframe.reload(true);
- }
-
- AppWindow.prototype.kill = function() {
- // XXX: A workaround because a AppWindow instance shouldn't reference Window Manager directly here.
- // In the future we should make every app maintain and execute the events in itself.
- // Like resize, setVisibility...
- // And Window Manager is in charge of cross app management.
- WindowManager.kill(this.origin);
- }
-
-}(this));
diff --git a/apps/system/js/window_manager.js b/apps/system/js/window_manager.js
deleted file mode 100644
index e53605e..0000000
--- a/apps/system/js/window_manager.js
+++ /dev/null
@@ -1,2011 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-//
-// This file calls getElementById without waiting for an onload event, so it
-// must have a defer attribute or be included at the end of the <body>.
-//
-// This module is responsible for launching apps and for allowing
-// the user to switch among apps and kill apps. Specifically, it handles:
-// launching apps,
-// killing apps
-// keeping track of the set of running apps (which we call tasks here)
-// keeping track of which task is displayed (the foreground task)
-// changing the foreground task
-// hiding all apps to display the homescreen
-// displaying the app switcher to allow the user to switch and kill apps
-// performing appropriate transition animations between:
-// the homescreen and an app
-// the homescreen and the switcher
-// an app and the homescreen
-// the switcher and the homescreen
-// the switcher and the current foreground task
-// the switcher and a different task
-// Handling Home key events to switch to the homescreen and the switcher
-//
-// The public API of the module is small. It defines an WindowManager object
-// with these methods:
-//
-// launch(origin): switch to the specified running app
-// kill(origin, callback): stop specified app
-// reload(origin): reload the given app
-// getDisplayedApp(): return the origin of the currently displayed app
-// setOrientationForApp(origin): set the phone to orientation to a given app
-// getAppFrame(origin): returns the iframe element for the specified origin
-// which is assumed to be running. This is only currently used
-// for tests and chrome stuff: see the end of the file
-// getRunningApps(): get the app references of the running apps.
-//
-// TODO
-// The "origin" does not actually refer to app's origin but rather a identifier
-// of the app reference that one gets from |getDisplayedApp()| or
-// iterates |getRunningApps|. The string is make up of the specified
-// launching entry point, origin, or the website url launched by wrapper.
-// It would be ideal if the variable get correctly named and it's rule is being
-// properly documented.
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=796629
-//
-
-var WindowManager = (function() {
- 'use strict';
-
- function debug(str) {
- dump('WindowManager: ' + str + '\n');
- }
-
- // Holds the origin of the home screen, which should be the first
- // app we launch through web activity during boot
- var homescreen = null;
- var homescreenURL = '';
- var homescreenManifestURL = '';
- var ftu = null;
- var ftuManifestURL = '';
- var ftuURL = '';
- var isRunningFirstRunApp = false;
- // keep the reference of inline activity frame here
- var inlineActivityFrames = [];
- var activityCallerOrigin = '';
-
- // Some document elements we use
- var windows = document.getElementById('windows');
- var screenElement = document.getElementById('screen');
- var wrapperHeader = document.querySelector('#wrapper-activity-indicator');
- var wrapperFooter = document.querySelector('#wrapper-footer');
- var kTransitionTimeout = 1000;
-
- // Set this to true to debugging the transitions and state change
- var slowTransition = false;
- if (slowTransition) {
- windows.classList.add('slow-transition');
- }
-
- //
- // The set of running apps.
- // This is a map from app origin to an object like this:
- // {
- // name: the app's name
- // manifest: the app's manifest object
- // frame: the iframe element that the app is displayed in
- // launchTime: last time when app gets active
- // }
- //
- var runningApps = {};
- var numRunningApps = 0; // appendFrame() and removeFrame() maintain this count
- var nextAppId = 0; // to give each app's iframe a unique id attribute
-
- // The origin of the currently displayed app, or null if there isn't one
- var displayedApp = null;
-
- // Function to hide init starting logo
- function handleInitlogo(callback) {
- var initlogo = document.getElementById('initlogo');
- initlogo.classList.add('hide');
- initlogo.addEventListener('transitionend', function delInitlogo() {
- initlogo.removeEventListener('transitionend', delInitlogo);
- initlogo.parentNode.removeChild(initlogo);
- if (callback) {
- callback();
- }
- });
- };
-
- // Public function. Return the origin of the currently displayed app
- // or null if there is none.
- function getDisplayedApp() {
- return displayedApp || null;
- }
-
- function requireFullscreen(origin) {
- var app = runningApps[origin];
- if (!app)
- return false;
-
- var manifest = app.manifest;
- if (manifest.entry_points && manifest.type == 'certified') {
- var entryPoint = manifest.entry_points[origin.split('/')[3]];
- if (entryPoint)
- return entryPoint.fullscreen;
- return false;
- } else {
- return manifest.fullscreen;
- }
- }
-
- // Make the specified app the displayed app.
- // Public function. Pass null to make the homescreen visible
- function launch(origin) {
- // If the origin is indeed valid we make that app as the displayed app.
- if (isRunning(origin)) {
- setDisplayedApp(origin);
- return;
- }
-
- // If the origin is null, make the homescreen visible.
- if (origin == null) {
- setDisplayedApp(homescreen);
- return;
- }
-
- // At this point, we have no choice but to show the homescreen.
- // We cannot launch/relaunch a given app based on the "origin" because
- // we would need the manifest URL and the specific entry point.
- console.warn('No running app is being identified as "' + origin + '". ' +
- 'Showing home screen instead.');
- setDisplayedApp(homescreen);
- }
-
- function isRunning(origin) {
- return runningApps.hasOwnProperty(origin);
- }
-
- function getAppFrame(origin) {
- if (isRunning(origin))
- return runningApps[origin].frame;
- else
- return null;
- }
-
- // Set the size of the app's iframe to match the size of the screen.
- // We have to call this on resize events (which happen when the
- // phone orientation is changed). And also when an app is launched
- // and each time an app is brought to the front, since the
- // orientation could have changed since it was last displayed
- function setAppSize(origin, changeActivityFrame) {
- var app = runningApps[origin];
- if (!app)
- return;
-
- var frame = app.frame;
- var manifest = app.manifest;
-
- var cssWidth = window.innerWidth + 'px';
- var cssHeight = window.innerHeight - StatusBar.height;
- if ('wrapper' in frame.dataset) {
- cssHeight -= 10;
- }
- cssHeight += 'px';
-
- if (!screenElement.classList.contains('attention') &&
- requireFullscreen(origin)) {
- cssHeight = window.innerHeight + 'px';
- }
-
- frame.style.width = cssWidth;
- frame.style.height = cssHeight;
-
- // We will call setInlineActivityFrameSize()
- // if changeActivityFrame is not explicitly set to false.
- if (changeActivityFrame !== false)
- setInlineActivityFrameSize();
- }
-
- // App's height is relevant to keyboard height
- function setAppHeight(keyboardHeight) {
- var app = runningApps[displayedApp];
- if (!app)
- return;
-
- var frame = app.frame;
- var manifest = app.manifest;
-
- var cssHeight =
- window.innerHeight - StatusBar.height - keyboardHeight + 'px';
-
- if (!screenElement.classList.contains('attention') &&
- requireFullscreen(displayedApp)) {
- cssHeight = window.innerHeight - keyboardHeight + 'px';
- }
-
- frame.style.height = cssHeight;
-
- setInlineActivityFrameSize();
- }
-
- // Copy the dimension of the currently displayed app
- function setInlineActivityFrameSize() {
- if (!inlineActivityFrames.length)
- return;
-
- var app = runningApps[displayedApp];
- var appFrame = app.frame;
- var frame = inlineActivityFrames[inlineActivityFrames.length - 1];
-
- frame.style.width = appFrame.style.width;
-
- if (document.mozFullScreen) {
- frame.style.height = window.innerHeight + 'px';
- frame.style.top = '0px';
- } else {
- if ('wrapper' in appFrame.dataset) {
- frame.style.height = window.innerHeight - StatusBar.height + 'px';
- } else {
- frame.style.height = appFrame.style.height;
- }
- frame.style.top = appFrame.offsetTop + 'px';
- }
- }
-
- function setFrameBackgroundBlob(frame, blob, transparent) {
- URL.revokeObjectURL(frame.dataset.bgObjectURL);
- delete frame.dataset.bgObjectURL;
-
- var objectURL = URL.createObjectURL(blob);
- frame.dataset.bgObjectURL = objectURL;
- var backgroundCSS =
- '-moz-linear-gradient(top, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.5) 100%),' +
- 'url(' + objectURL + '),' +
- ((transparent) ? 'transparent' : '#fff');
-
- frame.style.background = backgroundCSS;
- }
-
- function clearFrameBackground(frame) {
- if (!('bgObjectURL' in frame.dataset))
- return;
-
- URL.revokeObjectURL(frame.dataset.bgObjectURL);
- delete frame.dataset.bgObjectURL;
- frame.style.background = '';
- }
-
- var openFrame = null;
- var closeFrame = null;
- var openCallback = null;
- var closeCallback = null;
- var transitionOpenCallback = null;
- var transitionCloseCallback = null;
-
- // Use setOpenFrame() to reset the CSS classes set
- // to the current openFrame (before overwriting the reference)
- function setOpenFrame(frame) {
- if (openFrame) {
- removeFrameClasses(openFrame);
- }
-
- openFrame = frame;
- }
-
- // Use setCloseFrame() to reset the CSS classes set
- // to the current closeFrame (before overwriting the reference)
- function setCloseFrame(frame) {
- if (closeFrame) {
- removeFrameClasses(closeFrame);
- // closeFrame should not be set to active
- closeFrame.classList.remove('active');
- }
-
- closeFrame = frame;
- }
-
- // Remove these visible className from frame so we will not ended
- // up having a frozen frame in the middle of the transition
- function removeFrameClasses(frame) {
- var classNames = ['opening', 'closing', 'opening-switching',
- 'opening-card', 'closing-card'];
-
- var classList = frame.classList;
-
- classNames.forEach(function removeClass(className) {
- classList.remove(className);
- });
- }
-
- windows.addEventListener('transitionend', function frameTransitionend(evt) {
- var prop = evt.propertyName;
- var frame = evt.target;
- if (prop !== 'transform')
- return;
-
- var classList = frame.classList;
-
- if (classList.contains('inlineActivity')) {
- if (classList.contains('active')) {
- if (openFrame)
- openFrame.firstChild.focus();
-
- setOpenFrame(null);
- } else {
- windows.removeChild(frame);
- }
-
- return;
- }
-
- if (screenElement.classList.contains('switch-app')) {
- if (classList.contains('closing')) {
- classList.remove('closing');
- classList.add('closing-card');
-
- if (openFrame) {
- if (openFrame.classList.contains('opening-card')) {
- openFrame.classList.remove('opening-card');
- openFrame.classList.add('opening-switching');
- } else {
- // Skip the opening-card and opening-switching transition
- // because the closing-card transition had already finished here.
- if (openFrame.classList.contains('fullscreen-app')) {
- screenElement.classList.add('fullscreen-app');
- }
- openFrame.classList.add('opening');
- }
- }
- } else if (classList.contains('closing-card')) {
- windowClosed(frame);
- setTimeout(closeCallback);
- closeCallback = null;
-
- } else if (classList.contains('opening-switching')) {
- // If the opening app need to be full screen, switch to full screen
- if (classList.contains('fullscreen-app')) {
- screenElement.classList.add('fullscreen-app');
- }
-
- classList.remove('opening-switching');
- classList.add('opening');
- } else if (classList.contains('opening')) {
- windowOpened(frame);
-
- setTimeout(openCallback);
- openCallback = null;
-
- setCloseFrame(null);
- setOpenFrame(null);
- screenElement.classList.remove('switch-app');
- }
-
- return;
- }
-
- if (classList.contains('opening')) {
- windowOpened(frame);
-
- setTimeout(openCallback);
- openCallback = null;
-
- setOpenFrame(null);
- } else if (classList.contains('closing')) {
- windowClosed(frame);
-
- setTimeout(closeCallback);
- closeCallback = null;
-
- setCloseFrame(null);
- }
- });
-
- // Executes when the opening transition scale the app
- // to full size.
- function windowOpened(frame) {
- var iframe = frame.firstChild;
-
- frame.classList.add('active');
- windows.classList.add('active');
-
- if ('wrapper' in frame.dataset) {
- wrapperFooter.classList.add('visible');
- }
-
- // Take the focus away from the currently displayed app
- var app = runningApps[displayedApp];
- if (app && app.iframe)
- app.iframe.blur();
-
- // Give the focus to the frame
- iframe.focus();
-
- if (!TrustedUIManager.isVisible() && !isRunningFirstRunApp) {
- // Set homescreen visibility to false
- toggleHomescreen(false);
- }
-
- // Set displayedApp to the new value
- displayedApp = iframe.dataset.frameOrigin;
-
- // Set orientation for the new app
- setOrientationForApp(displayedApp);
-
- // Dispatch an 'appopen' event.
- var manifestURL = runningApps[displayedApp].manifestURL;
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('appopen', true, false, {
- manifestURL: manifestURL,
- origin: displayedApp
- });
- frame.dispatchEvent(evt);
- }
-
- // Executes when app closing transition finishes.
- function windowClosed(frame) {
- var iframe = frame.firstChild;
-
- // If the FTU is closing, make sure we save this state
- if (iframe.src == ftuURL) {
- isRunningFirstRunApp = false;
- document.getElementById('screen').classList.remove('ftu');
- window.asyncStorage.setItem('ftu.enabled', false);
- // Done with FTU, letting everyone know
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('ftudone',
- /* canBubble */ true, /* cancelable */ false, {});
- window.dispatchEvent(evt);
- }
-
- frame.classList.remove('active');
- windows.classList.remove('active');
-
- // set the closed frame visibility to false
- if ('setVisible' in iframe)
- iframe.setVisible(false);
-
- screenElement.classList.remove('fullscreen-app');
- }
-
- // The following things needs to happen when firstpaint happens.
- // We centralize all that here but not all of them applies.
- windows.addEventListener('mozbrowserfirstpaint', function firstpaint(evt) {
- var iframe = evt.target;
- var frame = iframe.parentNode;
-
- // remove the unpainted flag
- delete iframe.dataset.unpainted;
-
- setTimeout(function firstpainted() {
- // Save the screenshot
- // Remove the background only until we actually got the screenshot,
- // because the getScreenshot() call will be pushed back by
- // painting/loading in the child process; when we got the screenshot,
- // that means the app is mostly loaded.
- // (as opposed to plain white firstpaint)
- saveAppScreenshot(frame, function screenshotTaken() {
- // Remove the default background
- frame.classList.remove('default-background');
-
- // Remove the screenshot from frame
- clearFrameBackground(frame);
- });
- });
- });
-
- // setFrameBackground() will attach the screenshot background to
- // the given frame.
- // The callback could be sync or async (depend on whether we need
- // the screenshot from database or not)
- function setFrameBackground(frame, callback, transparent) {
- var iframe = frame.firstChild;
- // If the frame is painted, or there is already background image present
- // start the transition right away.
- if (!('unpainted' in iframe.dataset) ||
- ('bgObjectURL' in frame.dataset)) {
- callback();
- return;
- }
-
- // Get the screenshot from the database
- getAppScreenshotFromDatabase(iframe.src || iframe.dataset.frameOrigin,
- function(screenshot) {
- // If firstpaint is faster than database, we will not transition
- // with screenshot.
- if (!('unpainted' in iframe.dataset)) {
- callback();
- return;
- }
-
- if (!screenshot) {
- // put a default background
- frame.classList.add('default-background');
- callback();
- return;
- }
-
- // set the screenshot as the background of the frame itself.
- // we are safe to do so since there is nothing on it yet.
- setFrameBackgroundBlob(frame, screenshot, transparent);
-
- // start the transition
- callback();
- });
- }
-
- // On-disk database for window manager.
- // It's only for app screenshots right now.
- var database = null;
- var DB_SCREENSHOT_OBJSTORE = 'screenshots';
-
- (function openDatabase() {
- var DB_VERSION = 2;
- var DB_NAME = 'window_manager';
-
- var req = window.indexedDB.open(DB_NAME, DB_VERSION);
- req.onerror = function() {
- console.error('Window Manager: opening database failed.');
- };
- req.onupgradeneeded = function databaseUpgradeneeded() {
- database = req.result;
-
- if (database.objectStoreNames.contains(DB_SCREENSHOT_OBJSTORE))
- database.deleteObjectStore(DB_SCREENSHOT_OBJSTORE);
-
- var store = database.createObjectStore(
- DB_SCREENSHOT_OBJSTORE, { keyPath: 'url' });
- };
-
- req.onsuccess = function databaseSuccess() {
- database = req.result;
- };
- })();
-
- function putAppScreenshotToDatabase(url, data) {
- if (!database)
- return;
-
- var txn = database.transaction(DB_SCREENSHOT_OBJSTORE, 'readwrite');
- txn.onerror = function() {
- console.warn(
- 'Window Manager: transaction error while trying to save screenshot.');
- };
- var store = txn.objectStore(DB_SCREENSHOT_OBJSTORE);
- var req = store.put({
- url: url,
- screenshot: data
- });
- req.onerror = function(evt) {
- console.warn(
- 'Window Manager: put error while trying to save screenshot.');
- };
- }
-
- function getAppScreenshotFromDatabase(url, callback) {
- if (!database) {
- console.warn(
- 'Window Manager: Neither database nor app frame is ' +
- 'ready for getting screenshot.');
-
- callback();
- return;
- }
-
- var req = database.transaction(DB_SCREENSHOT_OBJSTORE)
- .objectStore(DB_SCREENSHOT_OBJSTORE).get(url);
- req.onsuccess = function() {
- if (!req.result) {
- console.log('Window Manager: No screenshot in database. ' +
- 'This is expected from a fresh installed app.');
- callback();
-
- return;
- }
-
- callback(req.result.screenshot, true);
- }
- req.onerror = function(evt) {
- console.warn('Window Manager: get screenshot from database failed.');
- callback();
- };
- }
-
- function deleteAppScreenshotFromDatabase(url) {
- var txn = database.transaction(DB_SCREENSHOT_OBJSTORE);
- var store = txn.objectStore(DB_SCREENSHOT_OBJSTORE);
-
- store.delete(url);
- }
-
- function getAppScreenshotFromFrame(frame, callback) {
- if (!frame) {
- callback();
- return;
- }
-
- var iframe = frame.firstChild;
- var req = iframe.getScreenshot(iframe.offsetWidth, iframe.offsetHeight);
-
- req.onsuccess = function gotScreenshotFromFrame(evt) {
- var result = evt.target.result;
- callback(result, false);
- };
-
- req.onerror = function gotScreenshotFromFrameError(evt) {
- console.warn('Window Manager: getScreenshot failed.');
- callback();
- };
- }
-
- // Meta method for get the screenshot from the app frame,
- // and save it to database.
- function saveAppScreenshot(frame, callback) {
- getAppScreenshotFromFrame(frame, function gotScreenshot(screenshot) {
- if (callback)
- callback(screenshot);
-
- if (!screenshot)
- return;
-
- var iframe = frame.firstChild;
- putAppScreenshotToDatabase(iframe.src || iframe.dataset.frameOrigin,
- screenshot);
- });
- }
-
- // Perform an "open" animation for the app's iframe
- function openWindow(origin, callback) {
- var app = runningApps[origin];
- setOpenFrame(app.frame);
-
- openCallback = callback || function() {};
-
- // set the size of the opening app
- setAppSize(origin);
-
- if (origin === homescreen) {
- // We cannot apply background screenshot to home screen app since
- // the screenshot is encoded in JPEG and the alpha channel is
- // not perserved. See
- // https://bugzilla.mozilla.org/show_bug.cgi?id=801676#c33
- // If that resolves,
- // setFrameBackground(openFrame, gotBackground, true);
- // will simply work here.
-
- // Call the openCallback only once. We have to use tmp var as
- // openCallback can be a method calling the callback
- // (like the `removeFrame` callback in `kill()` ).
- var tmpCallback = openCallback;
- openCallback = null;
- tmpCallback();
-
- windows.classList.add('active');
- openFrame.classList.add('homescreen');
- openFrame.firstChild.focus();
- setOpenFrame(null);
- displayedApp = origin;
-
- return;
- }
-
- if (requireFullscreen(origin))
- screenElement.classList.add('fullscreen-app');
-
- transitionOpenCallback = function startOpeningTransition() {
- // We have been canceled by another transition.
- if (!openFrame || transitionOpenCallback != startOpeningTransition)
- return;
-
- // Make sure we're not called twice.
- transitionOpenCallback = null;
-
- if (!screenElement.classList.contains('switch-app')) {
- openFrame.classList.add('opening');
- } else if (!openFrame.classList.contains('opening')) {
- openFrame.classList.add('opening-card');
- }
- };
-
- if ('unpainted' in openFrame.firstChild.dataset) {
- waitForNextPaintOrBackground(openFrame, transitionOpenCallback);
- } else {
- waitForNextPaint(openFrame, transitionOpenCallback);
- }
-
- // Set the frame to be visible.
- if ('setVisible' in openFrame.firstChild) {
- if (!AttentionScreen.isFullyVisible()) {
- openFrame.firstChild.setVisible(true);
- } else {
- // If attention screen is fully visible now,
- // don't give the open frame visible.
- // This is the case that homescreen is restarted behind attention screen
- openFrame.firstChild.setVisible(false);
- }
- }
- }
-
- function waitForNextPaintOrBackground(frame, callback) {
- var waiting = true;
- function proceed() {
- if (waiting) {
- waiting = false;
- callback();
- }
- }
-
- waitForNextPaint(frame, proceed);
- setFrameBackground(frame, proceed);
- }
-
- function waitForNextPaint(frame, callback) {
- function onNextPaint() {
- clearTimeout(timeout);
- callback();
- }
-
- var iframe = frame.firstChild;
-
- // Register a timeout in case we don't receive
- // nextpaint in an acceptable time frame.
- var timeout = setTimeout(function() {
- if ('removeNextPaintListener' in iframe)
- iframe.removeNextPaintListener(onNextPaint);
- callback();
- }, kTransitionTimeout);
-
- if ('addNextPaintListener' in iframe)
- iframe.addNextPaintListener(onNextPaint);
- }
-
- // Perform a "close" animation for the app's iframe
- function closeWindow(origin, callback) {
- var app = runningApps[origin];
- setCloseFrame(app.frame);
- closeCallback = callback || function() {};
-
- // Animate the window close. Ensure the homescreen is in the
- // foreground since it will be shown during the animation.
- var homescreenFrame = ensureHomescreen();
-
- // invoke openWindow to show homescreen here
- openWindow(homescreen, null);
-
- // Take keyboard focus away from the closing window
- closeFrame.firstChild.blur();
-
- // set orientation for homescreen app
- setOrientationForApp(homescreen);
-
- // Set the size of both homescreen app and the closing app
- // since the orientation had changed.
- setAppSize(homescreen);
- setAppSize(origin);
-
- // Send a synthentic 'appwillclose' event.
- // The keyboard uses this and the appclose event to know when to close
- // See https://github.com/andreasgal/gaia/issues/832
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('appwillclose', true, false, { origin: origin });
- closeFrame.dispatchEvent(evt);
-
- if ('wrapper' in closeFrame.dataset) {
- wrapperHeader.classList.remove('visible');
- wrapperFooter.classList.remove('visible');
- }
-
- transitionCloseCallback = function startClosingTransition() {
- // We have been canceled by another transition.
- if (!closeFrame || transitionCloseCallback != startClosingTransition)
- return;
-
- // Make sure we're not called twice.
- transitionCloseCallback = null;
-
- // Start the transition
- closeFrame.classList.add('closing');
- closeFrame.classList.remove('active');
- };
-
- waitForNextPaint(homescreenFrame, transitionCloseCallback);
- }
-
- // Perform a "switching" animation for the closing frame and the opening frame
- function switchWindow(origin, callback) {
- // This will trigger different transition to both openWindow()
- // and closeWindow() transition.
- screenElement.classList.add('switch-app');
-
- // Ask closeWindow() to start closing the displayedApp
- closeWindow(displayedApp, callback);
-
- // Ask openWindow() to show a card on the right waiting to be opened
- openWindow(origin);
- }
-
- // Ensure the homescreen is loaded and return its frame. Restarts
- // the homescreen app if it was killed in the background.
- // Note: this function would not invoke openWindow(homescreen),
- // which should be handled in setDisplayedApp and in closeWindow()
- function ensureHomescreen(reset) {
- // If the url of the homescreen is not known at this point do nothing.
- if (!homescreen || !homescreenManifestURL) {
- return null;
- }
-
- if (!isRunning(homescreen)) {
- var app = Applications.getByManifestURL(homescreenManifestURL);
- appendFrame(null, homescreen, homescreenURL,
- app.manifest.name, app.manifest, app.manifestURL);
- runningApps[homescreen].iframe.dataset.start = Date.now();
- setAppSize(homescreen);
- } else if (reset) {
- runningApps[homescreen].iframe.src = homescreenURL;
- setAppSize(homescreen);
- }
-
- return runningApps[homescreen].frame;
- }
-
- function retrieveHomescreen(callback) {
- var lock = navigator.mozSettings.createLock();
- var setting = lock.get('homescreen.manifestURL');
- setting.onsuccess = function() {
- var app =
- Applications.getByManifestURL(this.result['homescreen.manifestURL']);
-
- // XXX This is a one-day workaround to not break everybody and make sure
- // work can continue.
- if (!app) {
- var tmpURL = document.location.toString()
- .replace('system', 'homescreen')
- .replace('index.html', 'manifest.webapp');
- app = Applications.getByManifestURL(tmpURL);
- }
-
- if (app) {
- homescreenManifestURL = app.manifestURL;
- homescreen = app.origin;
- homescreenURL = app.origin + '/index.html#root';
-
- callback(app);
- }
- }
- }
-
- function skipFTU() {
- document.getElementById('screen').classList.remove('ftuStarting');
- handleInitlogo();
- setDisplayedApp(homescreen);
- }
-
- // Check if the FTU was executed or not, if not, get a
- // reference to the app and launch it.
- function retrieveFTU() {
- window.asyncStorage.getItem('ftu.enabled', function getItem(launchFTU) {
- document.getElementById('screen').classList.add('ftuStarting');
- if (launchFTU === false) {
- skipFTU();
- return;
- }
- var lock = navigator.mozSettings.createLock();
- var req = lock.get('ftu.manifestURL');
- req.onsuccess = function() {
- ftuManifestURL = this.result['ftu.manifestURL'];
- if (!ftuManifestURL) {
- dump('FTU manifest cannot be found skipping.\n');
- skipFTU();
- return;
- }
- ftu = Applications.getByManifestURL(ftuManifestURL);
- if (!ftu) {
- dump('Opps, bogus FTU manifest.\n');
- skipFTU();
- return;
- }
- ftuURL = ftu.origin + ftu.manifest.entry_points['ftu'].launch_path;
- ftu.launch('ftu');
- };
- req.onerror = function() {
- dump('Couldn\'t get the ftu manifestURL.\n');
- skipFTU();
- };
- });
- }
-
- // Hide current app
- function hideCurrentApp(callback) {
- if (displayedApp == null || displayedApp == homescreen)
- return;
-
- toggleHomescreen(true);
- var frame = getAppFrame(displayedApp);
- frame.classList.add('back');
- frame.classList.remove('restored');
- if (callback) {
- frame.addEventListener('transitionend', function execCallback() {
- frame.style.visibility = 'hidden';
- frame.removeEventListener('transitionend', execCallback);
- callback();
- });
- }
- }
-
- // If app parameter is passed,
- // it means there's a specific app needs to be restored
- // instead of current app
- function restoreCurrentApp(app) {
- if (app) {
- // Restore app visibility immediately but don't open it.
- var frame = getAppFrame(app);
- frame.style.visibility = 'visible';
- frame.classList.remove('back');
- } else {
- app = displayedApp;
- toggleHomescreen(false);
- var frame = getAppFrame(app);
- frame.style.visibility = 'visible';
- frame.classList.remove('back');
- frame.classList.add('restored');
- frame.addEventListener('transitionend', function removeRestored() {
- frame.removeEventListener('transitionend', removeRestored);
- frame.classList.remove('restored');
- });
- }
- }
-
- function toggleHomescreen(visible) {
- var homescreenFrame = ensureHomescreen();
- if (homescreenFrame && 'setVisible' in homescreenFrame.firstChild)
- homescreenFrame.firstChild.setVisible(visible);
- }
-
- // Switch to a different app
- function setDisplayedApp(origin, callback) {
- var currentApp = displayedApp, newApp = origin || homescreen;
- var isFirstRunApplication = !currentApp && (origin == ftuURL);
-
- var homescreenFrame = null;
- if (!isFirstRunApplication) {
- // Returns the frame reference of the home screen app.
- // Restarts the homescreen app if it was killed in the background.
- homescreenFrame = ensureHomescreen();
- }
-
- // Cancel transitions waiting to be started.
- transitionOpenCallback = null;
- transitionCloseCallback = null;
-
- // Discard any existing activity
- stopInlineActivity(true);
-
- // Before starting a new transition, let's make sure current transitions
- // are stopped and the state classes are cleaned up.
- // visibility status should also be reset.
- if (openFrame && 'setVisible' in openFrame.firstChild)
- openFrame.firstChild.setVisible(false);
- if (closeFrame && 'setVisible' in closeFrame.firstChild)
- closeFrame.firstChild.setVisible(false);
-
- if (!isFirstRunApplication && newApp == homescreen && !AttentionScreen.isFullyVisible()) {
- toggleHomescreen(true);
- }
-
- setOpenFrame(null);
- setCloseFrame(null);
- screenElement.classList.remove('switch-app');
- screenElement.classList.remove('fullscreen-app');
-
- // Dispatch an appwillopen event only when we open an app
- if (newApp != currentApp) {
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('appwillopen', true, true, { origin: newApp });
-
- var app = runningApps[newApp];
- // Allows listeners to cancel app opening and so stay on homescreen
- if (!app.frame.dispatchEvent(evt)) {
- if (typeof(callback) == 'function')
- callback();
- return;
- }
-
- var iframe = app.iframe;
-
- // unpainted means that the app is cold booting
- // if it is, we're going to listen for Browser API's loadend event
- // which indicates that the iframe's document load is complete
- //
- // if the app is not cold booting (is in memory) we will listen
- // to appopen event, which is fired when the transition to the
- // app window is complete.
- //
- // [w] - warm boot (app is in memory, just transition to it)
- // [c] - cold boot (app has to be booted, we show it's document load
- // time)
- var type;
- if ('unpainted' in iframe.dataset) {
- type = 'mozbrowserloadend';
- } else {
- iframe.dataset.start = Date.now();
- type = 'appopen';
- }
-
- app.frame.addEventListener(type, function apploaded(e) {
- e.target.removeEventListener(e.type, apploaded);
-
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('apploadtime', true, false, {
- time: parseInt(Date.now() - iframe.dataset.start),
- type: (e.type == 'appopen') ? 'w' : 'c'
- });
- iframe.dispatchEvent(evt);
- });
- }
-
- // Case 1: the app is already displayed
- if (currentApp && currentApp == newApp) {
- if (newApp == homescreen) {
- // relaunch homescreen
- openWindow(homescreen, callback);
- } else if (callback) {
- // Just run the callback right away if it is not homescreen
- callback();
- }
- }
- // Case 2: null --> app
- else if (isFirstRunApplication) {
- isRunningFirstRunApp = true;
- openWindow(newApp, function windowOpened() {
- handleInitlogo(function() {
- var mainScreen = document.getElementById('screen');
- mainScreen.classList.add('ftu');
- mainScreen.classList.remove('ftuStarting');
- });
- });
- }
- // Case 3: null->homescreen || homescreen->app
- else if ((!currentApp && newApp == homescreen) ||
- (currentApp == homescreen && newApp)) {
- openWindow(newApp, callback);
- }
- // Case 4: app->homescreen
- else if (currentApp && currentApp != homescreen && newApp == homescreen) {
- // For screenshot to catch current window size
- closeWindow(currentApp, callback);
- }
- // Case 5: app-to-app transition
- else {
- switchWindow(newApp, callback);
- }
- // Set homescreen as active,
- // to control the z-index between homescreen & keyboard iframe
- if ((newApp == homescreen) && homescreenFrame) {
- homescreenFrame.classList.add('active');
- } else {
- homescreenFrame.classList.remove('active');
- }
-
- // Record the time when app was launched,
- // need this to display apps in proper order on CardsView.
- // We would also need this to determined the freshness of the frame
- // for making screenshots.
- if (newApp)
- runningApps[newApp].launchTime = Date.now();
-
- // If the app has a attention screen open, displaying it
- AttentionScreen.showForOrigin(newApp);
- }
-
- function setOrientationForApp(origin) {
- if (origin == null) { // No app is currently running.
- screen.mozLockOrientation('portrait-primary');
- return;
- }
-
- var app = runningApps[origin];
- if (!app)
- return;
- var manifest = app.manifest;
-
- if (manifest.orientation) {
- var rv = screen.mozLockOrientation(manifest.orientation);
- if (rv === false) {
- console.warn('screen.mozLockOrientation() returned false for',
- origin, 'orientation', manifest.orientation);
- }
- }
- else { // If no orientation was requested, then let it rotate
- screen.mozUnlockOrientation();
- }
- }
-
- var isOutOfProcessDisabled = false;
- SettingsListener.observe('debug.oop.disabled', false, function(value) {
- isOutOfProcessDisabled = value;
- });
-
- function createFrame(origFrame, origin, url, name, manifest, manifestURL) {
- var iframe = origFrame || document.createElement('iframe');
- iframe.setAttribute('mozallowfullscreen', 'true');
-
- var frame = document.createElement('div');
- frame.appendChild(iframe);
- frame.className = 'appWindow';
-
- iframe.dataset.frameOrigin = origin;
- // Save original frame URL in order to restore it on frame load error
- iframe.dataset.frameURL = url;
-
- // Note that we don't set the frame size here. That will happen
- // when we display the app in setDisplayedApp()
-
- // frames are began unpainted.
- iframe.dataset.unpainted = true;
-
- if (!manifestURL) {
- frame.setAttribute('data-wrapper', 'true');
- return frame;
- }
-
- // Most apps currently need to be hosted in a special 'mozbrowser' iframe.
- // They also need to be marked as 'mozapp' to be recognized as apps by the
- // platform.
- iframe.setAttribute('mozbrowser', 'true');
-
- // These apps currently have bugs preventing them from being
- // run out of process. All other apps will be run OOP.
- //
- var outOfProcessBlackList = [
- 'Browser'
- // Requires nested content processes (bug 761935). This is not
- // on the schedule for v1.
- ];
-
- if (!isOutOfProcessDisabled &&
- outOfProcessBlackList.indexOf(name) === -1) {
- // FIXME: content shouldn't control this directly
- iframe.setAttribute('remote', 'true');
- }
-
- iframe.setAttribute('mozapp', manifestURL);
- iframe.src = url;
- return frame;
- }
-
- function appendFrame(origFrame, origin, url, name, manifest, manifestURL) {
- // Create the <iframe mozbrowser mozapp> that hosts the app
- var frame =
- createFrame(origFrame, origin, url, name, manifest, manifestURL);
- var iframe = frame.firstChild;
- frame.id = 'appframe' + nextAppId++;
- iframe.dataset.frameType = 'window';
-
- // Give a name to the frame for differentiating between main frame and
- // inline frame. With the name we can get frames of the same app using the
- // window.open method.
- iframe.name = 'main';
-
- // If this frame corresponds to the homescreen, set mozapptype=homescreen
- // so we're less likely to kill this frame's process when we're running low
- // on memory.
- //
- // We must do this before we the appendChild() call below. Once
- // we add this frame to the document, we can't change its app type.
- if (origin === homescreen) {
- iframe.setAttribute('mozapptype', 'homescreen');
- }
-
- // Add the iframe to the document
- windows.appendChild(frame);
-
- // And map the app origin to the info we need for the app
- var app = new AppWindow({
- origin: origin,
- name: name,
- manifest: manifest,
- manifestURL: manifestURL,
- frame: frame,
- iframe: iframe,
- launchTime: 0
- });
- runningApps[origin] = app;
-
- if (requireFullscreen(origin)) {
- frame.classList.add('fullscreen-app');
- }
- if (origin === ftuURL) {
- // Add a way to identify ftu app
- // (Used by SimLock)
- frame.classList.add('ftu');
- }
-
- // A frame should start with visible false
- if ('setVisible' in iframe)
- iframe.setVisible(false);
-
- numRunningApps++;
-
- return app;
- }
-
- function startInlineActivity(origin, url, name, manifest, manifestURL) {
- // Create the <iframe mozbrowser mozapp> that hosts the app
- var frame = createFrame(null, origin, url, name, manifest, manifestURL);
- var iframe = frame.firstChild;
- frame.classList.add('inlineActivity');
- iframe.dataset.frameType = 'inline-activity';
-
- // Give a name to the frame for differentiating between main frame and
- // inline frame. With the name we can get frames of the same app using the
- // window.open method.
- iframe.name = 'inline';
-
- // Save the reference
- inlineActivityFrames.push(frame);
-
- // Set the size
- setInlineActivityFrameSize();
-
- // Add the iframe to the document
- windows.appendChild(frame);
-
- // Open the frame, first, store the reference
- openFrame = frame;
-
- // set the frame to visible state
- if ('setVisible' in iframe)
- iframe.setVisible(true);
-
- setFrameBackground(openFrame, function gotBackground() {
- // Start the transition when this async/sync callback is called.
- openFrame.classList.add('active');
- if (inlineActivityFrames.length == 1)
- activityCallerOrigin = displayedApp;
- if ('wrapper' in runningApps[displayedApp].frame.dataset) {
- wrapperFooter.classList.remove('visible');
- wrapperHeader.classList.remove('visible');
- }
- });
- }
-
- function removeFrame(origin) {
- var app = runningApps[origin];
- var frame = app.frame;
-
- if (frame) {
- windows.removeChild(frame);
- clearFrameBackground(frame);
- }
-
- if (openFrame == frame) {
- setOpenFrame(null);
- setTimeout(openCallback);
- openCallback = null;
- }
- if (closeFrame == frame) {
- setCloseFrame(null);
- setTimeout(closeCallback);
- closeCallback = null;
- }
-
- delete runningApps[origin];
- numRunningApps--;
- }
-
- function removeInlineFrame(frame) {
- // If frame is transitioning we should remove the reference
- if (openFrame == frame)
- setOpenFrame(null);
-
- // If frame is never set visible, we can remove the frame directly
- // without closing transition
- if (!frame.classList.contains('active')) {
- windows.removeChild(frame);
- return;
- }
- // Take keyboard focus away from the closing window
- frame.firstChild.blur();
- // Remove the active class and start the closing transition
- frame.classList.remove('active');
- }
-
- // If all is not specified,
- // remove the top most frame
- function stopInlineActivity(all) {
- if (!inlineActivityFrames.length)
- return;
-
- if (!all) {
- var frame = inlineActivityFrames.pop();
- removeInlineFrame(frame);
- } else {
- // stop all activity frames
- // Remore the inlineActivityFrame reference
- for (var frame of inlineActivityFrames) {
- removeInlineFrame(frame);
- }
- inlineActivityFrames = [];
- }
-
- if (!inlineActivityFrames.length) {
- // Give back focus to the displayed app
- var app = runningApps[displayedApp];
- if (app && app.iframe) {
- app.iframe.focus();
- if ('wrapper' in app.frame.dataset) {
- wrapperFooter.classList.add('visible');
- }
- }
- screenElement.classList.remove('inline-activity');
- }
- }
-
- // Watch activity completion here instead of activity.js
- // Because we know when and who to re-launch when activity ends.
- window.addEventListener('mozChromeEvent', function(e) {
- if (e.detail.type == 'activity-done') {
- // Remove the top most frame every time we get an 'activity-done' event.
- stopInlineActivity();
- if (!inlineActivityFrames.length) {
- setDisplayedApp(activityCallerOrigin);
- activityCallerOrigin = '';
- }
- }
- });
-
- // There are two types of mozChromeEvent we need to handle
- // in order to launch the app for Gecko
- window.addEventListener('mozChromeEvent', function(e) {
- var startTime = Date.now();
-
- var manifestURL = e.detail.manifestURL;
- if (!manifestURL)
- return;
-
- var app = Applications.getByManifestURL(manifestURL);
- if (!app)
- return;
-
- var manifest = app.manifest;
- var name = new ManifestHelper(manifest).name;
- var origin = app.origin;
-
- // Check if it's a virtual app from a entry point.
- // If so, change the app name and origin to the
- // entry point.
- var entryPoints = manifest.entry_points;
- if (entryPoints && manifest.type == 'certified') {
- var givenPath = e.detail.url.substr(origin.length);
-
- // Workaround here until the bug (to be filed) is fixed
- // Basicly, gecko is sending the URL without launch_path sometimes
- for (var ep in entryPoints) {
- var currentEp = entryPoints[ep];
- var path = givenPath;
- if (path.indexOf('?') != -1) {
- path = path.substr(0, path.indexOf('?'));
- }
-
- //Remove the origin and / to find if if the url is the entry point
- if (path.indexOf('/' + ep) == 0 &&
- (currentEp.launch_path == path)) {
- origin = origin + currentEp.launch_path;
- name = new ManifestHelper(currentEp).name;
- }
- }
- }
- switch (e.detail.type) {
- // mozApps API is asking us to launch the app
- // We will launch it in foreground
- case 'webapps-launch':
- if (origin == homescreen) {
- // No need to append a frame if is homescreen
- setDisplayedApp();
- } else {
- if (!isRunning(origin)) {
- appendFrame(null, origin, e.detail.url,
- name, app.manifest, app.manifestURL);
- }
- runningApps[origin].iframe.dataset.start = startTime;
- setDisplayedApp(origin, null, 'window');
- }
- break;
- // System Message Handler API is asking us to open the specific URL
- // that handles the pending system message.
- // We will launch it in background if it's not handling an activity.
- case 'open-app':
- // If the system message goes to System app,
- // we should not be launching that in a frame.
- if (e.detail.url === window.location.href)
- return;
-
- if (e.detail.isActivity && e.detail.target.disposition &&
- e.detail.target.disposition == 'inline') {
- // Inline activities behaves more like a dialog,
- // let's deal them here.
-
- startInlineActivity(origin, e.detail.url,
- name, manifest, app.manifestURL);
-
- return;
- }
-
- if (isRunning(origin)) {
- // If the app is in foreground, it's too risky to change it's
- // URL. We'll ignore this request.
- if (displayedApp !== origin) {
- var iframe = getAppFrame(origin).firstChild;
-
- // If the app is opened and it is loaded to the correct page,
- // then there is nothing to do.
- if (iframe.src !== e.detail.url) {
- // Rewrite the URL of the app frame to the requested URL.
- // XXX: We could ended opening URls not for the app frame
- // in the app frame. But we don't care.
- iframe.src = e.detail.url;
- }
- }
- } else if (origin !== homescreen) {
- // XXX: We could ended opening URls not for the app frame
- // in the app frame. But we don't care.
- appendFrame(null, origin, e.detail.url,
- name, manifest, app.manifestURL);
-
- // set the size of the iframe
- // so Cards View will get a correct screenshot of the frame
- if (!e.detail.isActivity)
- setAppSize(origin, false);
- } else {
- ensureHomescreen();
- }
-
- // We will only bring web activity handling apps to the foreground
- if (!e.detail.isActivity)
- return;
-
- // XXX: the correct way would be for UtilityTray to close itself
- // when there is a appwillopen/appopen event.
- UtilityTray.hide();
-
- setDisplayedApp(origin);
-
- break;
- }
- });
-
- // If the application tried to close themselves by calling window.close()
- // we will handle that here.
- // XXX: this event is fired twice:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=814583
- window.addEventListener('mozbrowserclose', function(e) {
- if (!'frameType' in e.target.dataset)
- return;
-
- switch (e.target.dataset.frameType) {
- case 'window':
- kill(e.target.dataset.frameOrigin);
- break;
-
- case 'inline-activity':
- stopInlineActivity(true);
- break;
- }
- });
-
- // Deal with locationchange
- window.addEventListener('mozbrowserlocationchange', function(e) {
- if (!'frameType' in e.target.dataset)
- return;
-
- e.target.dataset.url = e.detail;
- });
-
- // Deal with application uninstall event
- // if the application is being uninstalled, we ensure it stop running here.
- window.addEventListener('applicationuninstall', function(e) {
- kill(e.detail.application.origin);
-
- deleteAppScreenshotFromDatabase(e.detail.application.origin);
- });
-
- // When an UI layer is overlapping the current app,
- // WindowManager should set the visibility of app iframe to false
- // And reset to true when the layer is gone.
- // We may need to handle windowclosing, windowopened in the future.
- var attentionScreenTimer = null;
-
- var overlayEvents = [
- 'lock',
- 'will-unlock',
- 'attentionscreenshow',
- 'attentionscreenhide',
- 'status-active',
- 'status-inactive'
- ];
-
- function overlayEventHandler(evt) {
- if (attentionScreenTimer)
- clearTimeout(attentionScreenTimer);
- switch (evt.type) {
- case 'status-active':
- case 'attentionscreenhide':
- case 'will-unlock':
- if (LockScreen.locked)
- return;
- if (inlineActivityFrames.length) {
- setVisibilityForInlineActivity(true);
- } else {
- setVisibilityForCurrentApp(true);
- }
- break;
- case 'lock':
- setVisibilityForCurrentApp(false);
- break;
-
- /*
- * Because in-transition is needed in attention screen,
- * We set a timer here to deal with visibility change
- */
- case 'status-inactive':
- if (!AttentionScreen.isVisible())
- return;
- case 'attentionscreenshow':
- if (evt.detail && evt.detail.origin &&
- evt.detail.origin != displayedApp) {
- attentionScreenTimer = setTimeout(function setVisibility() {
- if (inlineActivityFrames.length) {
- setVisibilityForInlineActivity(false);
- } else {
- setVisibilityForCurrentApp(false);
- }
- }, 3000);
-
- // Immediatly blur the frame in order to ensure hiding the keyboard
- var app = runningApps[displayedApp];
- if (app)
- app.iframe.blur();
- }
- break;
- }
- }
-
- overlayEvents.forEach(function overlayEventIterator(event) {
- window.addEventListener(event, overlayEventHandler);
- });
-
- function setVisibilityForInlineActivity(visible) {
- if (!inlineActivityFrames.length)
- return;
-
- var topFrame = inlineActivityFrames[inlineActivityFrames.length - 1].firstChild;
- if ('setVisible' in topFrame) {
- topFrame.setVisible(visible);
- }
-
- // Restore/give away focus on visiblity change
- // so that the app can take back its focus
- if (visible) {
- topFrame.focus();
- } else {
- topFrame.blur();
- }
- }
-
- function setVisibilityForCurrentApp(visible) {
- var app = runningApps[displayedApp];
- if (!app)
- return;
- if ('setVisible' in app.iframe)
- app.iframe.setVisible(visible);
-
- // Restore/give away focus on visiblity change
- // so that the app can take back its focus
- if (visible)
- app.iframe.focus();
- else
- app.iframe.blur();
- }
-
- function handleAppCrash(origin, manifestURL) {
- if (origin && manifestURL) {
- // When inline activity frame crashes,
- // query the localized name from manifest
- var app = Applications.getByManifestURL(manifestURL);
- CrashReporter.setAppName(getAppName(origin, app.manifest));
- } else {
- var app = runningApps[displayedApp];
- CrashReporter.setAppName(app.name);
- }
- }
-
- function getAppName(origin, manifest) {
- if (!manifest)
- return '';
-
- if (manifest.entry_points && manifest.type == 'certified') {
- var entryPoint = manifest.entry_points[origin.split('/')[3]];
- return new ManifestHelper(entryPoint).name;
- }
- return new ManifestHelper(manifest).name;
- }
-
- // Deal with crashed apps
- window.addEventListener('mozbrowsererror', function(e) {
- if (!'frameType' in e.target.dataset)
- return;
-
- var origin = e.target.dataset.frameOrigin;
- var manifestURL = e.target.getAttribute('mozapp');
-
- if (e.target.dataset.frameType == 'inline-activity') {
- stopInlineActivity(true);
- handleAppCrash(origin, manifestURL);
- return;
- }
-
- if (e.target.dataset.frameType !== 'window')
- return;
-
- /*
- detail.type = error (Server Not Found case)
- is handled in Modal Dialog
- */
- if (e.detail.type !== 'fatal')
- return;
-
- // If the crashing app is currently displayed, we will present
- // the user with a banner notification.
- if (displayedApp == origin)
- handleAppCrash();
-
- // If the crashing app is the home screen app and it is the displaying app
- // we will need to relaunch it right away.
- // Alternatively, if home screen is not the displaying app,
- // we will not relaunch it until the foreground app is closed.
- // (to be dealt in setDisplayedApp(), not here)
- if (displayedApp == homescreen) {
- kill(origin, function relaunchHomescreen() {
- setDisplayedApp(homescreen);
- });
- return;
- }
-
- // Actually remove the frame, and trigger the closing transition
- // if the app is currently displaying
- kill(origin);
- });
-
-
- function hasPermission(app, permission) {
- var mozPerms = navigator.mozPermissionSettings;
- if (!mozPerms)
- return false;
-
- var value = mozPerms.get(permission, app.manifestURL, app.origin, false);
-
- return (value === 'allow');
- }
-
- // Use a setting in order to be "called" by settings app
- navigator.mozSettings.addObserver(
- 'clear.remote-windows.data',
- function clearRemoteWindowsData(setting) {
- var shouldClear = setting.settingValue;
- if (!shouldClear)
- return;
-
- // Delete all storage and cookies from our content processes
- var request = navigator.mozApps.getSelf();
- request.onsuccess = function() {
- request.result.clearBrowserData();
- };
-
- // Reset the setting value to false
- var lock = navigator.mozSettings.createLock();
- lock.set({'clear.remote-windows.data': false});
- });
-
- // Watch for window.open usages in order to open wrapper frames
- window.addEventListener('mozbrowseropenwindow', function handleWrapper(evt) {
- var detail = evt.detail;
- var features;
- try {
- features = JSON.parse(detail.features);
- } catch (e) {
- features = {};
- }
-
- // Handles only call to window.open with `{remote: true}` feature.
- if (!features.remote)
- return;
-
- // XXX bug 819882: for now, only allows homescreen to open oop windows
- var callerIframe = evt.target;
- var callerFrame = callerIframe.parentNode;
- var manifestURL = callerIframe.getAttribute('mozapp');
- var callerApp = Applications.getByManifestURL(manifestURL);
- if (!callerApp || !callerFrame.classList.contains('homescreen'))
- return;
- var callerOrigin = callerApp.origin;
-
- // So, we are going to open a remote window.
- // Now, avoid PopupManager listener to be fired.
- evt.stopImmediatePropagation();
-
- var name = detail.name;
- var url = detail.url;
-
- // Use fake origin for named windows in order to be able to reuse them,
- // otherwise always open a new window for '_blank'.
- var origin = null;
- var app = null;
- if (name == '_blank') {
- origin = url;
-
- // Just bring on top if a wrapper window is already running with this url
- if (origin in runningApps &&
- runningApps[origin].windowName == '_blank') {
- setDisplayedApp(origin);
- return;
- }
- } else {
- origin = 'window:' + name + ',source:' + callerOrigin;
-
- var runningApp = runningApps[origin];
- if (runningApp && runningApp.windowName === name) {
- if (runningApp.iframe.src === url) {
- // If the url is already loaded, just display the app
- setDisplayedApp(origin);
- return;
- } else {
- // Wrapper context shouldn't be shared between two apps -> killing
- kill(origin);
- }
- }
- }
-
- var title = '', icon = '', remote = false, useAsyncPanZoom = false;
- var originName, originURL, searchName, searchURL;
-
- try {
- var features = JSON.parse(detail.features);
- var regExp = new RegExp('&nbsp;', 'g');
-
- title = features.name.replace(regExp, ' ') || url;
- icon = features.icon || '';
-
- if (features.origin) {
- originName = features.origin.name.replace(regExp, ' ');
- originURL = decodeURIComponent(features.origin.url);
- }
-
- if (features.search) {
- searchName = features.search.name.replace(regExp, ' ');
- searchURL = decodeURIComponent(features.search.url);
- }
-
- if (features.useAsyncPanZoom)
- useAsyncPanZoom = true;
- } catch (ex) { }
-
- // If we don't reuse an existing app, open a brand new one
- var iframe;
- if (!app) {
- // Bug 807438: Move new window document OOP
- // Ignore `event.detail.frameElement` for now in order
- // to create a remote system app frame.
- // So that new window documents are going to share
- // system app content processes data jar.
- iframe = document.createElement('iframe');
- iframe.setAttribute('mozbrowser', 'true');
- iframe.setAttribute('remote', 'true');
-
- iframe.addEventListener('mozbrowserloadstart', function start() {
- iframe.dataset.loading = true;
- wrapperHeader.classList.add('visible');
- });
-
- iframe.addEventListener('mozbrowserloadend', function end() {
- delete iframe.dataset.loading;
- wrapperHeader.classList.remove('visible');
- });
-
- // `mozasyncpanzoom` only works when added before attaching the iframe
- // node to the document.
- if (useAsyncPanZoom) {
- iframe.dataset.useAsyncPanZoom = true;
- iframe.setAttribute('mozasyncpanzoom', 'true');
- }
-
- var app = appendFrame(iframe, origin, url, title, {
- 'name': title
- }, null);
-
- // Set the window name in order to reuse this app if we try to open
- // a new window with same name
- app.windowName = name;
- } else {
- iframe = app.iframe;
-
- // Update app name for the card view
- app.manifest.name = title;
- }
-
- iframe.dataset.name = title;
- iframe.dataset.icon = icon;
-
- if (originName)
- iframe.dataset.originName = originName;
- if (originURL)
- iframe.dataset.originURL = originURL;
-
- if (searchName)
- iframe.dataset.searchName = searchName;
- if (searchURL)
- iframe.dataset.searchURL = searchURL;
-
- // First load blank page in order to hide previous website
- iframe.src = url;
-
- setDisplayedApp(origin);
- }, true); // Use capture in order to catch the event before PopupManager does
-
-
- // Stop running the app with the specified origin
- function kill(origin, callback) {
- if (!isRunning(origin))
- return;
-
- // As we can't immediatly remove runningApps entry,
- // we flag it as being killed in order to avoid trying to remove it twice.
- // (Check required because of bug 814583)
- if (runningApps[origin].killed)
- return;
- runningApps[origin].killed = true;
-
- // If the app is the currently displayed app, switch to the homescreen
- if (origin === displayedApp) {
- // when the homescreen is displayed and being
- // killed we need to forcibly restart it...
- if (origin === homescreen) {
- removeFrame(origin);
-
- // XXX workaround bug 810431.
- // we need this here and not in other situations
- // as it is expected that homescreen frame is available.
- setTimeout(function() {
- setDisplayedApp();
-
- if (callback) {
- callback();
- }
- });
- } else {
- setDisplayedApp(homescreen, function() {
- removeFrame(origin);
- if (callback)
- setTimeout(callback);
- });
- }
-
- } else {
- removeFrame(origin);
- }
-
- // Send a synthentic 'appterminated' event.
- // Let other system app module know an app is
- // being killed, removed or crashed.
- var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('appterminated', true, false, { origin: origin });
- window.dispatchEvent(evt);
- }
-
- // Reload the frame of the running app
- function reload(origin) {
- if (!isRunning(origin))
- return;
-
- var app = runningApps[origin];
- app.reload();
- }
-
- // When a resize event occurs, resize the running app, if there is one
- // When the status bar is active it doubles in height so we need a resize
- var appResizeEvents = ['resize', 'status-active', 'status-inactive',
- 'keyboardchange', 'keyboardhide',
- 'attentionscreenhide'];
- appResizeEvents.forEach(function eventIterator(event) {
- window.addEventListener(event, function on(evt) {
- if (event == 'keyboardchange') {
- // Cancel fullscreen if keyboard pops
- if (document.mozFullScreen)
- document.mozCancelFullScreen();
-
- setAppHeight(evt.detail.height);
- } else if (displayedApp) {
- setAppSize(displayedApp);
- }
- });
- });
-
- window.addEventListener('home', function(e) {
- // If the lockscreen is active, it will stop propagation on this event
- // and we'll never see it here. Similarly, other overlays may use this
- // event to hide themselves and may prevent the event from getting here.
- // Note that for this to work, the lockscreen and other overlays must
- // be included in index.html before this one, so they can register their
- // event handlers before we do.
-
- // If we are currently transitioning, the user would like to cancel
- // it instead of toggling homescreen panels.
- var inTransition = !!(openFrame || closeFrame);
-
- if (document.mozFullScreen) {
- document.mozCancelFullScreen();
- }
-
- if (displayedApp !== homescreen || inTransition) {
- if (displayedApp != ftuURL) {
- setDisplayedApp(homescreen);
- } else {
- e.preventDefault();
- }
- } else {
- stopInlineActivity(true);
- ensureHomescreen(true);
- }
- });
-
- // Cancel dragstart event to workaround
- // https://bugzilla.mozilla.org/show_bug.cgi?id=783076
- // which stops OOP home screen pannable with left mouse button on
- // B2G/Desktop.
- windows.addEventListener('dragstart', function(evt) {
- evt.preventDefault();
- }, true);
-
- // With all important event handlers in place, we can now notify
- // Gecko that we're ready for certain system services to send us
- // messages (e.g. the radio).
- // Note that shell.js starts listen for the mozContentEvent event at
- // mozbrowserloadstart, which sometimes does not happen till window.onload.
- window.addEventListener('load', function wm_loaded() {
- window.removeEventListener('load', wm_loaded);
-
- var evt = new CustomEvent('mozContentEvent',
- { bubbles: true, cancelable: false,
- detail: { type: 'system-message-listener-ready' } });
- window.dispatchEvent(evt);
- });
-
- // This is code copied from
- // http://dl.dropbox.com/u/8727858/physical-events/index.html
- // It appears to workaround the Nexus S bug where we're not
- // getting orientation data. See:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=753245
- // It seems it needs to be in both window_manager.js and bootstrap.js.
- function dumbListener2(event) {}
- window.addEventListener('devicemotion', dumbListener2);
-
- window.setTimeout(function() {
- window.removeEventListener('devicemotion', dumbListener2);
- }, 2000);
-
- // Return the object that holds the public API
- return {
- isFtuRunning: function() {
- return isRunningFirstRunApp;
- },
- launch: launch,
- kill: kill,
- reload: reload,
- getDisplayedApp: getDisplayedApp,
- setOrientationForApp: setOrientationForApp,
- getAppFrame: getAppFrame,
- getRunningApps: function() {
- return runningApps;
- },
- setDisplayedApp: setDisplayedApp,
- getCurrentDisplayedApp: function() {
- return runningApps[displayedApp];
- },
- hideCurrentApp: hideCurrentApp,
- restoreCurrentApp: restoreCurrentApp,
- retrieveHomescreen: retrieveHomescreen,
- retrieveFTU: retrieveFTU
- };
-}());
-
diff --git a/apps/system/js/wrapper.js b/apps/system/js/wrapper.js
deleted file mode 100644
index 160d70b..0000000
--- a/apps/system/js/wrapper.js
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-
-'use strict';
-
-var Launcher = (function() {
- function log(str) {
- dump(' -+- Launcher -+-: ' + str + '\n');
- }
-
- function currentAppFrame() {
- return WindowManager.getAppFrame(WindowManager.getDisplayedApp());
- }
-
-
- function currentAppIframe() {
- return currentAppFrame().firstChild;
- }
-
- var _ = navigator.mozL10n.get;
-
- var BUTTONBAR_TIMEOUT = 5000;
- var BUTTONBAR_INITIAL_OPEN_TIMEOUT = 1500;
-
- var footer = document.querySelector('#wrapper-footer');
- window.addEventListener('appopen', function onAppOpen(e) {
- if ('wrapper' in currentAppFrame().dataset) {
- window.addEventListener('mozbrowserlocationchange', onLocationChange);
- onLocationChange();
- onDisplayedApplicationChange();
- }
- });
-
- window.addEventListener('appwillclose', function onAppClose(e) {
- if ('wrapper' in currentAppFrame().dataset) {
- window.removeEventListener('mozbrowserlocationchange', onLocationChange);
- clearTimeout(buttonBarTimeout);
- footer.classList.add('closed');
- isButtonBarDisplayed = false;
- }
- });
-
- window.addEventListener('keyboardchange', function onKeyboardChange(e) {
- if ('wrapper' in currentAppFrame().dataset) {
- if (footer.classList.contains('visible')) {
- footer.classList.remove('visible');
- }
- }
- });
-
- window.addEventListener('keyboardhide', function onKeyboardChange(e) {
- if ('wrapper' in currentAppFrame().dataset) {
- if (!footer.classList.contains('visible')) {
- footer.classList.add('visible');
- }
- }
- });
-
- var buttonBarTimeout;
-
- var isButtonBarDisplayed = false;
- function toggleButtonBar(time) {
- clearTimeout(buttonBarTimeout);
- footer.classList.toggle('closed');
- isButtonBarDisplayed = !isButtonBarDisplayed;
- if (isButtonBarDisplayed) {
- buttonBarTimeout = setTimeout(toggleButtonBar, time || BUTTONBAR_TIMEOUT);
- }
- }
-
- function clearButtonBarTimeout() {
- clearTimeout(buttonBarTimeout);
- buttonBarTimeout = setTimeout(toggleButtonBar, BUTTONBAR_TIMEOUT);
- }
-
- document.getElementById('handler').
- addEventListener('mousedown', function open() { toggleButtonBar() });
-
- document.getElementById('close-button').
- addEventListener('mousedown', function close() { toggleButtonBar() });
-
- var reload = document.getElementById('reload-button');
- reload.addEventListener('click', function doReload(evt) {
- clearButtonBarTimeout();
- currentAppIframe().reload(true);
- });
-
- var back = document.getElementById('back-button');
- back.addEventListener('click', function goBack() {
- clearButtonBarTimeout();
- currentAppIframe().goBack();
- });
-
- var forward = document.getElementById('forward-button');
- forward.addEventListener('click', function goForward() {
- clearButtonBarTimeout();
- currentAppIframe().goForward();
- });
-
- function onLocationChange() {
- currentAppIframe().getCanGoForward().onsuccess = function forwardSuccess(e) {
- if (e.target.result === true) {
- delete forward.dataset.disabled;
- } else {
- forward.dataset.disabled = true;
- }
- }
-
- currentAppIframe().getCanGoBack().onsuccess = function backSuccess(e) {
- if (e.target.result === true) {
- delete back.dataset.disabled;
- } else {
- back.dataset.disabled = true;
- }
- }
- }
-
- window.addEventListener('mozbrowserlocationchange', onLocationChange);
-
- var bookmarkButton = document.getElementById('bookmark-button');
- function onDisplayedApplicationChange() {
- toggleButtonBar(BUTTONBAR_INITIAL_OPEN_TIMEOUT);
-
- var dataset = currentAppIframe().dataset;
- if (dataset.originURL || dataset.searchURL) {
- delete bookmarkButton.dataset.disabled;
- return;
- }
-
- bookmarkButton.dataset.disabled = true;
- }
-
- bookmarkButton.addEventListener('click', function doBookmark(evt) {
- if (bookmarkButton.dataset.disabled)
- return;
-
- clearButtonBarTimeout();
- var dataset = currentAppIframe().dataset;
-
- function selected(value) {
- if (!value)
- return;
-
- var name, url;
- if (value === 'origin') {
- name = dataset.originName;
- url = dataset.originURL;
- }
-
- if (value === 'search') {
- name = dataset.searchName;
- url = dataset.searchURL;
- }
-
- var activity = new MozActivity({
- name: 'save-bookmark',
- data: {
- type: 'url',
- url: url,
- name: name,
- icon: dataset.icon,
- useAsyncPanZoom: dataset.useAsyncPanZoom,
- iconable: false
- }
- });
-
- activity.onsuccess = function onsuccess() {
- if (value === 'origin') {
- delete currentAppIframe().dataset.originURL;
- }
-
- if (value === 'search') {
- delete currentAppIframe().dataset.searchURL;
- }
-
- if (!currentAppIframe().dataset.originURL &&
- !currentAppIframe().dataset.searchURL) {
- bookmarkButton.dataset.disabled = true;
- }
- }
- }
-
- var data = {
- title: _('add-to-home-screen'),
- options: []
- };
-
- if (dataset.originURL) {
- data.options.push({ id: 'origin', text: dataset.originName });
- }
-
- if (dataset.searchURL) {
- data.options.push({ id: 'search', text: dataset.searchName });
- }
-
- ModalDialog.selectOne(data, selected);
- });
-}());