Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
20
assets/webapps/uitest.gaiamobile.org/js/API/audiotag.js
Normal file
20
assets/webapps/uitest.gaiamobile.org/js/API/audiotag.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
var clickHandlers = {
|
||||
'play': function play() {
|
||||
var src = this.dataset.src;
|
||||
var ringtonePlayer = new Audio();
|
||||
ringtonePlayer.loop = true;
|
||||
var selectedSound = '../../data/ringtones/' + src;
|
||||
ringtonePlayer.src = selectedSound;
|
||||
ringtonePlayer.play();
|
||||
window.setTimeout(function _pauseRingtone() {
|
||||
ringtonePlayer.pause();
|
||||
}, 20000);
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', function(evt) {
|
||||
if (clickHandlers[evt.target.id || evt.target.dataset.fn])
|
||||
clickHandlers[evt.target.id || evt.target.dataset.fn].call(evt.target, evt);
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
var clickHandlers = {
|
||||
'go': function _go() {
|
||||
var URL = document.getElementById('URL').value;
|
||||
var a = new MozActivity({ name: 'view', data: {type: 'url', url: URL }});
|
||||
a.onsuccess = function() { alert('Success!'); };
|
||||
a.onerror = function() { alert('Failure going to URL'); };
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', function(evt) {
|
||||
if (clickHandlers[evt.target.id || evt.target.dataset.fn])
|
||||
clickHandlers[evt.target.id || evt.target.dataset.fn].call(this, evt);
|
||||
});
|
||||
12
assets/webapps/uitest.gaiamobile.org/js/API/composeemail.js
Normal file
12
assets/webapps/uitest.gaiamobile.org/js/API/composeemail.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
var composeEmail = document.querySelector('#compose-email');
|
||||
if (composeEmail) {
|
||||
composeEmail.onclick = function() {
|
||||
var createEmail = new MozActivity({
|
||||
name: 'new', // Possibly compose-mail in future versions
|
||||
data: {
|
||||
type: 'mail',
|
||||
url: 'mailto:example@example.org'
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
370
assets/webapps/uitest.gaiamobile.org/js/API/contacts.js
Normal file
370
assets/webapps/uitest.gaiamobile.org/js/API/contacts.js
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
'use stricts';
|
||||
|
||||
/**
|
||||
* Just a couple of testing tools for the Contacts app.
|
||||
*
|
||||
* Right now, it just allows you to insert a large number of fake contacts
|
||||
* into the database, and then clear the database.
|
||||
*/
|
||||
|
||||
var ContactsTest = {
|
||||
get loadButton() {
|
||||
delete this.loadButton;
|
||||
return this.loadButton = document.getElementById('insert-contacts');
|
||||
},
|
||||
|
||||
get clearButton() {
|
||||
delete this.clearButton;
|
||||
return this.clearButton = document.getElementById('clear-contacts');
|
||||
},
|
||||
|
||||
get getButton() {
|
||||
delete this.getButton;
|
||||
return this.getButton = document.getElementById('get-contacts');
|
||||
},
|
||||
|
||||
get pickActivityButton() {
|
||||
delete this.pickActivityButton;
|
||||
return this.pickActivityButton = document.getElementById('activities-pick');
|
||||
},
|
||||
|
||||
get newActivityButton() {
|
||||
delete this.newActivityButton;
|
||||
return this.newActivityButton = document.getElementById('activities-new');
|
||||
},
|
||||
get updateExistingActivityButton() {
|
||||
delete this.updateExistingActivityButton;
|
||||
return this.updateExistingActivityButton =
|
||||
document.getElementById('activities-update');
|
||||
},
|
||||
|
||||
get updateExistingActivityEmailButton() {
|
||||
delete this.updateExistingActivityEmailButton;
|
||||
return this.updateExistingActivityEmailButton =
|
||||
document.getElementById('activities-update-email');
|
||||
},
|
||||
|
||||
get updateExistingActivityEmailPhoneButton() {
|
||||
delete this.updateExistingActivityEmailPhoneButton;
|
||||
return this.updateExistingActivityEmailPhoneButton =
|
||||
document.getElementById('activities-update-email-phone');
|
||||
},
|
||||
|
||||
get newWithDataActivityButton() {
|
||||
delete this.newWithDataActivityButton;
|
||||
return this.newWithDataActivityButton =
|
||||
document.getElementById('activities-new-data');
|
||||
},
|
||||
|
||||
get insertSocialContacts() {
|
||||
delete this.insertSocialContacts;
|
||||
return this.insertSocialContacts =
|
||||
document.getElementById('insert-social-contacts');
|
||||
},
|
||||
|
||||
|
||||
init: function ct_init() {
|
||||
this.loadButton.addEventListener('click', this.loadContacts.bind(this));
|
||||
this.clearButton.addEventListener('click', this.clearContacts.bind(this));
|
||||
this.getButton.addEventListener('click', this.getContacts.bind(this));
|
||||
this.pickActivityButton.addEventListener('click',
|
||||
this.pickActivity.bind(this));
|
||||
this.newActivityButton.addEventListener('click',
|
||||
this.newActivity.bind(this));
|
||||
this.updateExistingActivityButton.addEventListener('click',
|
||||
this.updateExistingActivity.bind(this));
|
||||
this.updateExistingActivityEmailButton.addEventListener('click',
|
||||
this.updateExistingActivityEmail.bind(this));
|
||||
|
||||
this.updateExistingActivityEmailPhoneButton.addEventListener('click',
|
||||
this.updateExistingActivityEmailPhone.bind(this));
|
||||
|
||||
this.newWithDataActivityButton.addEventListener('click',
|
||||
this.newWithDataActivity.bind(this));
|
||||
|
||||
this.insertSocialContacts.addEventListener('click',
|
||||
this.finsertSocialContacts.bind(this));
|
||||
},
|
||||
|
||||
uninit: function ct_uninit() {
|
||||
this.loadButton.removeEventListener('click', this.loadContacts.bind(this));
|
||||
this.clearButton.removeEventListener('click',
|
||||
this.clearContacts.bind(this));
|
||||
this.getButton.removeEventListener('click', this.getContacts.bind(this));
|
||||
this.newActivityButton.removeEventListener('click',
|
||||
this.newActivity.bind(this));
|
||||
this.updateExistingActivityButton.removeEventListener('click',
|
||||
this.updateExistingActivity.bind(this));
|
||||
},
|
||||
|
||||
clearContacts: function ct_clearContacts() {
|
||||
if (!confirm('This will wipe out ALL of the contacts in the database. ' +
|
||||
'Are you sure?'))
|
||||
return;
|
||||
|
||||
// Ok, we're really doing this.
|
||||
var req = window.navigator.mozContacts.clear();
|
||||
req.onsuccess = function() {
|
||||
alert('Contacts deleted.');
|
||||
};
|
||||
req.onerror = function() {
|
||||
alert('Problem deleting contacts');
|
||||
};
|
||||
},
|
||||
|
||||
getContacts: function ct_getContacts() {
|
||||
var options = {
|
||||
sortBy: 'familyName',
|
||||
sortOrder: 'ascending'
|
||||
};
|
||||
var start = new Date();
|
||||
var req = window.navigator.mozContacts.find(options);
|
||||
req.onsuccess = function() {
|
||||
var duration = new Date() - start;
|
||||
alert('Contacts received: ' + duration + 'msec');
|
||||
};
|
||||
req.onerror = function() {
|
||||
alert('Problem receiving contacts');
|
||||
};
|
||||
},
|
||||
|
||||
setContactId: function ct_setContactId(id) {
|
||||
this.contactId = id;
|
||||
},
|
||||
|
||||
getContactId: function ct_getContactId() {
|
||||
return this.contactId;
|
||||
},
|
||||
|
||||
pickActivity: function ct_pickActivity() {
|
||||
var activity = new MozActivity({
|
||||
name: 'pick',
|
||||
data: {
|
||||
type: 'webcontacts/contact'
|
||||
}
|
||||
});
|
||||
|
||||
var self = this;
|
||||
activity.onsuccess = function() {
|
||||
var number = this.result.number;
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Picked contact with number: ' + number;
|
||||
};
|
||||
|
||||
activity.onerror = function() {
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Activity canceled';
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
newActivity: function ct_newActivity() {
|
||||
var activity = new MozActivity({
|
||||
name: 'new',
|
||||
data: {
|
||||
type: 'webcontacts/contact'
|
||||
}
|
||||
});
|
||||
|
||||
var self = this;
|
||||
activity.onsuccess = function() {
|
||||
var contact = this.result.contact;
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'New contact' + ' create with id: ' + contact.id;
|
||||
self.setContactId(contact.id);
|
||||
};
|
||||
|
||||
activity.onerror = function() {
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Activity canceled';
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
updateExistingActivityEmail: function ct_updateExistingActivityEmail() {
|
||||
var activity = new MozActivity({
|
||||
name: 'update',
|
||||
data: {
|
||||
type: 'webcontacts/contact',
|
||||
params: {
|
||||
'email': 'test@test.com'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var self = this;
|
||||
activity.onsuccess = function() {
|
||||
var contact = this.result.contact;
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'updated contact' + ' update with id: ' + contact.id;
|
||||
self.setContactId(contact.id);
|
||||
};
|
||||
|
||||
activity.onerror = function() {
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Activity canceled';
|
||||
};
|
||||
},
|
||||
|
||||
updateExistingActivityEmailPhone: function() {
|
||||
var activity = new MozActivity({
|
||||
name: 'update',
|
||||
data: {
|
||||
type: 'webcontacts/contact',
|
||||
params: {
|
||||
'email': 'test@test.com',
|
||||
'tel': '21312132'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var self = this;
|
||||
activity.onsuccess = function() {
|
||||
var contact = this.result.contact;
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'updated contact' + ' update with id: ' + contact.id;
|
||||
self.setContactId(contact.id);
|
||||
};
|
||||
|
||||
activity.onerror = function() {
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Activity canceled';
|
||||
};
|
||||
},
|
||||
|
||||
updateExistingActivity: function ct_updateExistingActivity() {
|
||||
var activity = new MozActivity({
|
||||
name: 'update',
|
||||
data: {
|
||||
type: 'webcontacts/contact',
|
||||
params: {
|
||||
'tel': '4087469720'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var self = this;
|
||||
activity.onsuccess = function() {
|
||||
var contact = this.result.contact;
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'updated contact' + ' update with id: ' + contact.id;
|
||||
self.setContactId(contact.id);
|
||||
};
|
||||
|
||||
activity.onerror = function() {
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Activity canceled';
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
newWithDataActivity: function ct_newActivity() {
|
||||
var activity = new MozActivity({
|
||||
name: 'new',
|
||||
data: {
|
||||
type: 'webcontacts/contact',
|
||||
params: {
|
||||
'tel': '555-555-555',
|
||||
'email': 'cool-hunter@telefonica.es',
|
||||
'address': 'San Francisco',
|
||||
'note': 'This is a note',
|
||||
'giveName': 'John',
|
||||
'familyName': 'Orlock',
|
||||
'company': 'Lost Industries'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var self = this;
|
||||
activity.onsuccess = function() {
|
||||
var contact = this.result.contact;
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'New contact' + ' create with id: ' + contact.id;
|
||||
self.setContactId(contact.id);
|
||||
};
|
||||
|
||||
activity.onerror = function() {
|
||||
document.getElementById('activities-result').innerHTML =
|
||||
'Activity canceled';
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
loadContacts: function ct_loadContacts() {
|
||||
var req = new XMLHttpRequest();
|
||||
req.overrideMimeType('application/json');
|
||||
req.open('GET', '../../data/fakecontacts/fakecontacts.json', true);
|
||||
req.onreadystatechange = function() {
|
||||
// We will get a 0 status if the app is in app://
|
||||
if (req.readyState === 4 && (req.status === 200 ||
|
||||
req.status === 0)) {
|
||||
var contacts = JSON.parse(req.responseText);
|
||||
this._insertContacts(contacts);
|
||||
}
|
||||
};
|
||||
req.onreadystatechange = req.onreadystatechange.bind(this);
|
||||
|
||||
this.loadButton.disabled = true;
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
_insertContacts: function ct_insertContacts(aContacts) {
|
||||
var self = this;
|
||||
|
||||
var cs = new ContactsSaver(aContacts);
|
||||
cs.start();
|
||||
|
||||
cs.onsuccess = function() {
|
||||
self.loadButton.disabled = false;
|
||||
};
|
||||
cs.onsaved = function(n) {
|
||||
self._setInsertionCount(n, aContacts.length);
|
||||
};
|
||||
cs.onerror = function(c, e) {
|
||||
Components.utils.reportError('Could not add contact with name: ' +
|
||||
c.familyName[0]);
|
||||
};
|
||||
},
|
||||
|
||||
_setInsertionCount: function ct__setInsertionCount(aSoFar, aTotal) {
|
||||
var insertionEl = document.getElementById('insertion-count');
|
||||
insertionEl.textContent = aSoFar + ' / ' + aTotal;
|
||||
},
|
||||
|
||||
_error: function ct__error(c) {
|
||||
Components.utils.reportError('Could not add contact with name: ' +
|
||||
c.familyName[0]);
|
||||
},
|
||||
|
||||
finsertSocialContacts: function ct_finsertSocialContacts() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.overrideMimeType('application/json');
|
||||
xhr.open('GET', '../../data/fakesocialcontacts/contacts_social.json', true);
|
||||
xhr.onload = function(e) {
|
||||
// We will get a 0 status if the app is in app://
|
||||
if (xhr.status === 200 || xhr.status === 0) {
|
||||
var cdata = JSON.parse(xhr.responseText);
|
||||
this._insertSocialContacts(cdata.data);
|
||||
}
|
||||
};
|
||||
xhr.onload = xhr.onload.bind(this);
|
||||
|
||||
xhr.send(null);
|
||||
},
|
||||
|
||||
_insertSocialContacts: function ct__insertSocialContacts(contacts) {
|
||||
var cs = new ContactsSaver(contacts);
|
||||
|
||||
cs.start();
|
||||
|
||||
var self = this;
|
||||
|
||||
cs.onsuccess = function() { window.alert('Added!'); };
|
||||
cs.onerror = function(e, c) {
|
||||
self._error(c);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('load', ContactsTest.init.bind(ContactsTest));
|
||||
window.addEventListener('unload', ContactsTest.uninit.bind(ContactsTest));
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
function ContactsSaver(data) {
|
||||
this.data = data;
|
||||
var next = 0;
|
||||
var self = this;
|
||||
|
||||
this.start = function() {
|
||||
saveContact(data[0]);
|
||||
};
|
||||
|
||||
function saveContact(cdata) {
|
||||
if (cdata.bday) {
|
||||
cdata.bday = new Date(cdata.bday);
|
||||
}
|
||||
if (cdata.anniversary) {
|
||||
cdata.anniversary = new Date(cdata.anniversary);
|
||||
}
|
||||
var contact = new mozContact(cdata);
|
||||
var req = navigator.mozContacts.save(contact);
|
||||
req.onsuccess = function(e) {
|
||||
if (typeof self.onsaved === 'function') {
|
||||
self.onsaved(next + 1);
|
||||
}
|
||||
continuee();
|
||||
};
|
||||
|
||||
req.onerror = function(e) {
|
||||
if (typeof self.onerror === 'function') {
|
||||
self.onerror(self.data[next], e.target.error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function continuee() {
|
||||
next++;
|
||||
if (next < self.data.length) {
|
||||
saveContact(self.data[next]);
|
||||
}
|
||||
else {
|
||||
// End has been reached
|
||||
if (typeof self.onsuccess === 'function') {
|
||||
self.onsuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
assets/webapps/uitest.gaiamobile.org/js/API/dialnumber.js
Normal file
11
assets/webapps/uitest.gaiamobile.org/js/API/dialnumber.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
var dial = document.querySelector('#dial');
|
||||
if (dial) {
|
||||
dial.onclick = function() {
|
||||
var call = new MozActivity({
|
||||
name: 'dial',
|
||||
data: {
|
||||
number: '+46777888999'
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
84
assets/webapps/uitest.gaiamobile.org/js/API/downloads.js
Normal file
84
assets/webapps/uitest.gaiamobile.org/js/API/downloads.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
var Downloads = function Downloads() {
|
||||
|
||||
var deleteButton, statusButton;
|
||||
|
||||
var download = null;
|
||||
|
||||
var init = function init() {
|
||||
deleteButton = document.getElementById('downloadDelete');
|
||||
deleteButton.addEventListener('click', onDelete);
|
||||
statusButton = document.getElementById('downloadStatus');
|
||||
statusButton.addEventListener('click', onStatus);
|
||||
|
||||
listen();
|
||||
};
|
||||
|
||||
var onDelete = function onDelete(evt) {
|
||||
LazyLoader.load(['/shared/js/download/download_helper.js'],
|
||||
function helperLoaded() {
|
||||
var request = DownloadHelper.remove(download);
|
||||
request.onsuccess = function() {
|
||||
alert('Download removed succesfully');
|
||||
download = null;
|
||||
deleteButton.disabled = true;
|
||||
statusButton.disabled = true;
|
||||
};
|
||||
|
||||
request.onerror = function(msg) {
|
||||
alert('Error : ' + msg.message);
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var onStatus = function onStatus(evt) {
|
||||
if (download === null) {
|
||||
alert('No download initiated');
|
||||
} else {
|
||||
var msg = 'Current download:\n';
|
||||
msg += 'Total bytes: ' + download.totalBytes + '\n';
|
||||
msg += 'Current bytes: ' + download.currentBytes + '\n';
|
||||
msg += 'Url: ' + download.url + '\n';
|
||||
msg += 'Path: ' + download.path + '\n';
|
||||
try {
|
||||
msg += 'Start time: ' + download.startTime + '\n';
|
||||
} catch (e) {
|
||||
msg += 'Start: unknown\n';
|
||||
}
|
||||
msg += 'Id: ' + download.id + '\n';
|
||||
alert('Current download: ' + JSON.stringify(msg));
|
||||
console.log(msg);
|
||||
}
|
||||
};
|
||||
|
||||
var listen = function listen() {
|
||||
navigator.mozDownloadManager.ondownloadstart = downloadStartedListener;
|
||||
};
|
||||
|
||||
var downloadStartedListener = function downloadStartedListener(evt) {
|
||||
download = evt.download;
|
||||
download.onstatechange = downloadChangeListener;
|
||||
|
||||
statusButton.disabled = false;
|
||||
statusButton.textContent = 'Status: ' + download.state;
|
||||
//console.log('State new download: ' + download.state);
|
||||
};
|
||||
|
||||
var downloadChangeListener = function downloadChangeListener(evt) {
|
||||
statusButton.textContent = 'Status: ' + download.state;
|
||||
console.log('State change: ' + download.state);
|
||||
|
||||
if (download.state === 'succeeded') {
|
||||
console.log('Download finished');
|
||||
deleteButton.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
'init': init
|
||||
};
|
||||
}();
|
||||
|
||||
window.addEventListener('load', Downloads.init.bind(Downloads));
|
||||
118
assets/webapps/uitest.gaiamobile.org/js/API/fxa.js
Normal file
118
assets/webapps/uitest.gaiamobile.org/js/API/fxa.js
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* Tests for Firefox Accounts observer API
|
||||
*
|
||||
* navigator.mozId.watch(), .request(), and .logout().
|
||||
*/
|
||||
|
||||
function unpackAssertion(assertion) {
|
||||
var parts = assertion.split('.');
|
||||
return {
|
||||
header: atob(parts[0]),
|
||||
claim: atob(parts[1]),
|
||||
payload: atob(parts[3])
|
||||
};
|
||||
}
|
||||
|
||||
function FXATests() {
|
||||
this._eventNum = 1;
|
||||
}
|
||||
|
||||
FXATests.prototype = {
|
||||
_setupCallbacks: function() {
|
||||
if (this._running) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
try {
|
||||
navigator.mozId.watch({
|
||||
wantIssuer: 'firefox-accounts',
|
||||
|
||||
onlogin: function(assertion) {
|
||||
var unpacked = JSON.stringify(unpackAssertion(assertion), null, 2);
|
||||
self.recordEvent('login', 'login',
|
||||
{assertion: assertion, unpacked: unpacked});
|
||||
},
|
||||
|
||||
onlogout: function() {
|
||||
self.recordEvent('logout', 'logout');
|
||||
},
|
||||
|
||||
onready: function() {
|
||||
self.recordEvent('ready', 'ready');
|
||||
},
|
||||
|
||||
onerror: function(error) {
|
||||
self.recordEvent('error: ' + JSON.stringify(error), 'error');
|
||||
}
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
this.recordEvent('error: ' + JSON.stringify(error), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Bind UI components
|
||||
*/
|
||||
_bindEvents: function() {
|
||||
if (this._running) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var testElementHandlers = {
|
||||
'request': function() {
|
||||
navigator.mozId.request({
|
||||
oncancel: function() {
|
||||
self.recordEvent('cancel', 'cancel');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
'logout': function() {
|
||||
navigator.mozId.logout();
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(testElementHandlers).forEach(function(selector) {
|
||||
document.getElementById(selector).addEventListener(
|
||||
'click', testElementHandlers[selector]);
|
||||
});
|
||||
},
|
||||
|
||||
recordEvent: function(message, cklass, params) {
|
||||
var li = document.createElement('li');
|
||||
if (cklass) {
|
||||
li.classList.add(cklass);
|
||||
}
|
||||
|
||||
var events = document.getElementById('event-stream');
|
||||
var html = message;
|
||||
|
||||
if (typeof params === 'object') {
|
||||
Object.keys(params).forEach(function(key) {
|
||||
html += '<div>' + key + ':</div>';
|
||||
html += '<div class="' + key + '">' + params[key] + '</div>';
|
||||
});
|
||||
}
|
||||
|
||||
li.innerHTML = html;
|
||||
events.appendChild(li);
|
||||
this._eventNum += 1;
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this._setupCallbacks();
|
||||
this._bindEvents();
|
||||
this._running = true;
|
||||
|
||||
this.recordEvent('Starting. Wait for "ready" message.');
|
||||
},
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var fxaTests = new FXATests();
|
||||
fxaTests.init();
|
||||
}, false);
|
||||
|
||||
22
assets/webapps/uitest.gaiamobile.org/js/API/geolocation.js
Normal file
22
assets/webapps/uitest.gaiamobile.org/js/API/geolocation.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
function Location(position)//location function is defining with parameter
|
||||
{
|
||||
//Specifies the longitude estimate in decimal degrees.
|
||||
//The value range is [-180.00, +180.00].
|
||||
var latitude = position.coords.latitude;
|
||||
var longitude = position.coords.longitude;
|
||||
//latitude value is defining in label element where id is lati
|
||||
document.getElementById('lati').innerHTML = latitude;
|
||||
document.getElementById('longi').innerHTML = longitude;
|
||||
}
|
||||
|
||||
document.getElementById('submit').addEventListener('click',
|
||||
function findLocation() {
|
||||
//checking browser compatibility
|
||||
if (navigator.geolocation)
|
||||
{
|
||||
//getCurrentPosition method retrieve
|
||||
//the current geographic location of the user
|
||||
navigator.geolocation.getCurrentPosition(Location);
|
||||
}
|
||||
}
|
||||
);
|
||||
220
assets/webapps/uitest.gaiamobile.org/js/API/getusermedia.js
Normal file
220
assets/webapps/uitest.gaiamobile.org/js/API/getusermedia.js
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
'use stricts';
|
||||
|
||||
// This is an indivisual gUM test item, may be audio, video, or both
|
||||
function gUMItem() {
|
||||
var video_status = false;
|
||||
var audio_status = false;
|
||||
var capturing = false;
|
||||
var constrain;
|
||||
|
||||
var media;
|
||||
var video_frame;
|
||||
var video;
|
||||
var snapshots_frames;
|
||||
var audio;
|
||||
var startButtons;
|
||||
var stopButtons;
|
||||
var snapshotButton;
|
||||
var message;
|
||||
|
||||
var snapshots = [];
|
||||
var saved_stream;
|
||||
|
||||
this.init = function(content, i) {
|
||||
media = content.querySelector('[data-type="media"]');
|
||||
video_frame = content.querySelector('[data-type="video-frame"]');
|
||||
video = content.querySelector('video');
|
||||
snapshots_frames = content.querySelector('[data-type="snapshots-frames"]');
|
||||
audio = content.querySelector('audio');
|
||||
startButtons = content.querySelector('[data-type="startbuttons"]');
|
||||
stopButtons = content.querySelector('[data-type="stopbuttons"]');
|
||||
snapshotButton = content.querySelector('[data-type="snapshotButton"]');
|
||||
message = content.querySelector('[data-type="message"]');
|
||||
|
||||
// remove them first, we will add them back when we need them
|
||||
media.removeChild(video_frame);
|
||||
media.removeChild(audio);
|
||||
|
||||
// label button with index
|
||||
content.querySelector('[data-type="startVideoButton"]').textContent += i;
|
||||
content.querySelector('[data-type="startAudioButton"]').textContent += i;
|
||||
content.querySelector('[data-type="startAudioVideoButton"]').
|
||||
textContent += i;
|
||||
|
||||
content.querySelector('[data-type="startVideoButton"]').
|
||||
addEventListener('click', startVideo);
|
||||
content.querySelector('[data-type="startAudioButton"]').
|
||||
addEventListener('click', startAudio);
|
||||
content.querySelector('[data-type="startAudioVideoButton"]').
|
||||
addEventListener('click', startAudioVideo);
|
||||
content.querySelector('[data-type="startDoubleRequest"]').
|
||||
addEventListener('click', startDoubleRequest);
|
||||
content.querySelector('[data-type="stopButton"]').
|
||||
addEventListener('click', stopMedia);
|
||||
content.querySelector('[data-type="pauseButton"]').
|
||||
addEventListener('click', pauseMedia);
|
||||
content.querySelector('[data-type="snapshotButton"]').
|
||||
addEventListener('click', startSnapshot);
|
||||
};
|
||||
|
||||
function startVideo() {
|
||||
startMedia({video: true});
|
||||
}
|
||||
|
||||
function startAudioVideo() {
|
||||
startMedia({video: true, audio: true});
|
||||
}
|
||||
|
||||
function startAudio() {
|
||||
startMedia({audio: true});
|
||||
}
|
||||
|
||||
function startDoubleRequest() {
|
||||
// empty request, just for prompt
|
||||
function empty() {}
|
||||
function success(stream) {
|
||||
message.innerHTML = '<p class="success">Double prompt!</p>';
|
||||
}
|
||||
function error(err) {
|
||||
message.innerHTML = '<p class="error">' + err + '</p>';
|
||||
}
|
||||
window.navigator.mozGetUserMedia({audio: true}, empty, error);
|
||||
window.navigator.mozGetUserMedia({audio: true}, success, error);
|
||||
}
|
||||
|
||||
function startMedia(param) {
|
||||
constrain = param;
|
||||
function success(stream) {
|
||||
message.innerHTML = '<p class="success">Success!</p>';
|
||||
stopButtons.style.display = 'block';
|
||||
startButtons.style.display = 'none';
|
||||
|
||||
if ('video' in constrain) {
|
||||
video_status = true;
|
||||
media.appendChild(video_frame);
|
||||
video.mozSrcObject = stream;
|
||||
video.play();
|
||||
snapshots_frames.innerHTML = '';
|
||||
stopButtons.appendChild(snapshotButton);
|
||||
}
|
||||
if ('audio' in constrain) {
|
||||
audio_status = true;
|
||||
media.appendChild(audio);
|
||||
audio.mozSrcObject = stream;
|
||||
audio.play();
|
||||
}
|
||||
}
|
||||
|
||||
function error(err) {
|
||||
if (video_status)
|
||||
video_status = false;
|
||||
message.innerHTML = '<p class="error">' + err + '</p>';
|
||||
}
|
||||
window.navigator.mozGetUserMedia(param, success, error);
|
||||
}
|
||||
|
||||
function pauseMedia() {
|
||||
if (saved_stream) {
|
||||
if (video_status) {
|
||||
video.mozSrcObject = saved_stream;
|
||||
video.play();
|
||||
} else if (audio_status) {
|
||||
audio.mozSrcObject = saved_stream;
|
||||
audio.play();
|
||||
}
|
||||
saved_stream = null;
|
||||
} else {
|
||||
if (video_status) {
|
||||
video.pause();
|
||||
saved_stream = video.mozSrcObject;
|
||||
video.mozSrcObject = null;
|
||||
} else if (audio_status) {
|
||||
audio.pause();
|
||||
saved_stream = audio.mozSrcObject;
|
||||
audio.mozSrcObject = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stopMedia() {
|
||||
message.innerHTML = '';
|
||||
if (video_status) {
|
||||
video.mozSrcObject.stop();
|
||||
video.mozSrcObject = null;
|
||||
snapshots = [];
|
||||
snapshots_frames.innerHTML = '';
|
||||
media.removeChild(video_frame);
|
||||
|
||||
stopButtons.removeChild(snapshotButton);
|
||||
snapshotButton.textContent = 'Snapshot';
|
||||
|
||||
capturing = false;
|
||||
video_status = false;
|
||||
}
|
||||
if (audio_status) {
|
||||
audio.mozSrcObject.stop();
|
||||
audio.mozSrcObject = null;
|
||||
media.removeChild(audio);
|
||||
|
||||
audio_status = false;
|
||||
}
|
||||
saved_stream = null;
|
||||
|
||||
stopButtons.style.display = 'none';
|
||||
startButtons.style.display = 'block';
|
||||
}
|
||||
|
||||
function startSnapshot() {
|
||||
capturing = !capturing;
|
||||
if (capturing) {
|
||||
captureImage();
|
||||
snapshotButton.textContent = 'Stop Snapshot';
|
||||
} else {
|
||||
snapshotButton.textContent = 'Snapshot';
|
||||
}
|
||||
}
|
||||
|
||||
function captureImage() {
|
||||
if (video_status && capturing) {
|
||||
//dump('Capturing len ' + snapshots.length + '\n');
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = video.videoWidth / 4;
|
||||
canvas.height = video.videoHeight / 4;
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
if (snapshots.unshift(canvas) > 4)
|
||||
snapshots.length = 4;
|
||||
snapshots_frames.innerHTML = '';
|
||||
for (var j = 0; j < snapshots.length; j++) {
|
||||
snapshots_frames.appendChild(snapshots[j]);
|
||||
}
|
||||
|
||||
setTimeout(captureImage, 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// You can modify max_instances to test more than one gUM instance
|
||||
function gUMTest() {
|
||||
var max_instances = 2;
|
||||
var gUMItems = [];
|
||||
|
||||
(function init() {
|
||||
var contents = document.getElementById('contents');
|
||||
for (var i = 0; i < max_instances; i++) {
|
||||
gUMItems[i] = new gUMItem;
|
||||
|
||||
// display elements
|
||||
// first copy one from template then modify it.
|
||||
var template = document.getElementById('content_template');
|
||||
var content = template.cloneNode(true);
|
||||
content.id = 'content' + (i + 1);
|
||||
content.classList.remove('hidden');
|
||||
gUMItems[i].init(content, (i + 1));
|
||||
contents.appendChild(content);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
window.addEventListener('load', gUMTest);
|
||||
111
assets/webapps/uitest.gaiamobile.org/js/API/identity-get.js
Normal file
111
assets/webapps/uitest.gaiamobile.org/js/API/identity-get.js
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* In these tests, we exercise the native navigator.mozId.get method.
|
||||
*/
|
||||
|
||||
function getUnverifiedOk() {
|
||||
return document.getElementById('unverified-ok').checked;
|
||||
}
|
||||
|
||||
function getIssuerName() {
|
||||
return document.getElementById('issuer-name').value.trim();
|
||||
}
|
||||
|
||||
function unpackAssertion(assertion) {
|
||||
var parts = assertion.split('.');
|
||||
return {
|
||||
header: atob(parts[0]),
|
||||
claim: atob(parts[1]),
|
||||
payload: atob(parts[3])
|
||||
};
|
||||
}
|
||||
|
||||
function IdentityTests() {
|
||||
|
||||
/**
|
||||
* recordEvent: make a note in the event stream
|
||||
*
|
||||
* message is the main text of the note
|
||||
* cklass is the css class to apply to the enclosing li
|
||||
* params is an optional dictionary of strings to append as divs
|
||||
*/
|
||||
this._eventNum = 1;
|
||||
this.recordEvent = function id_recordEvent(message, cklass, params) {
|
||||
var li = document.createElement('li');
|
||||
if (cklass) {
|
||||
li.classList.add(cklass);
|
||||
}
|
||||
|
||||
var events = document.getElementById('event-stream');
|
||||
var html = message;
|
||||
|
||||
if (typeof params === 'object') {
|
||||
Object.keys(params).forEach(function(key) {
|
||||
html += '<div>' + key + ':</div>';
|
||||
html += "<div class='" + key + "'>" + params[key] + '</div>';
|
||||
});
|
||||
}
|
||||
|
||||
li.innerHTML = html;
|
||||
events.appendChild(li);
|
||||
this._eventNum += 1;
|
||||
};
|
||||
|
||||
this.gotAssertion = function id_gotAssertion(assertion) {
|
||||
var result = {assertion: assertion};
|
||||
if (assertion) {
|
||||
result.unpacked = JSON.stringify(unpackAssertion(assertion), null, 2);
|
||||
}
|
||||
this.recordEvent('Assertion', 'assertion', result);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind UI components
|
||||
*/
|
||||
this._bindEvents = function id__bindEvents() {
|
||||
if (this._running) return;
|
||||
var gotAssertion = this.gotAssertion.bind(this);
|
||||
var self = this;
|
||||
var testElementHandlers = {
|
||||
't-get': function() {
|
||||
navigator.mozId.get(gotAssertion);
|
||||
},
|
||||
|
||||
't-get-allowUnverified': function() {
|
||||
navigator.mozId.get(gotAssertion, {
|
||||
allowUnverified: getUnverifiedOk()
|
||||
});
|
||||
},
|
||||
|
||||
't-get-forceIssuer': function() {
|
||||
navigator.mozId.get(gotAssertion, {
|
||||
forceIssuer: getIssuerName()
|
||||
});
|
||||
},
|
||||
|
||||
't-get-forceIssuer-allowUnverified': function() {
|
||||
navigator.mozId.get(gotAssertion, {
|
||||
allowUnverified: getUnverifiedOk(),
|
||||
forceIssuer: getIssuerName()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(testElementHandlers).forEach(function(selector) {
|
||||
document.getElementById(selector).addEventListener(
|
||||
'click', testElementHandlers[selector]);
|
||||
});
|
||||
};
|
||||
|
||||
this.init = function id_init() {
|
||||
this._bindEvents();
|
||||
this._running = true;
|
||||
|
||||
this.recordEvent('Tests are ready');
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var identityTests = new IdentityTests();
|
||||
identityTests.init();
|
||||
}, false);
|
||||
|
||||
143
assets/webapps/uitest.gaiamobile.org/js/API/identity.js
Normal file
143
assets/webapps/uitest.gaiamobile.org/js/API/identity.js
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* The IdentityTests are meant to be exercised from marionette as part of the
|
||||
* gaia-ui-tests suites.
|
||||
*
|
||||
* In these tests, we exercise the native navigator.mozId directly.
|
||||
*/
|
||||
|
||||
function getUnverifiedOk() {
|
||||
return document.getElementById('unverified-ok').checked;
|
||||
}
|
||||
|
||||
function getIssuerName() {
|
||||
return document.getElementById('issuer-name').value.trim();
|
||||
}
|
||||
|
||||
function unpackAssertion(assertion) {
|
||||
var parts = assertion.split('.');
|
||||
return {
|
||||
header: atob(parts[0]),
|
||||
claim: atob(parts[1]),
|
||||
payload: atob(parts[3])
|
||||
};
|
||||
}
|
||||
|
||||
function IdentityTests() {
|
||||
|
||||
/**
|
||||
* recordEvent: make a note in the event stream
|
||||
*
|
||||
* message is the main text of the note
|
||||
* cklass is the css class to apply to the enclosing li
|
||||
* params is an optional dictionary of strings to append as divs
|
||||
*/
|
||||
this._eventNum = 1;
|
||||
this.recordEvent = function id_recordEvent(message, cklass, params) {
|
||||
var li = document.createElement('li');
|
||||
if (cklass) {
|
||||
li.classList.add(cklass);
|
||||
}
|
||||
|
||||
var events = document.getElementById('event-stream');
|
||||
var html = message;
|
||||
|
||||
if (typeof params === 'object') {
|
||||
Object.keys(params).forEach(function(key) {
|
||||
html += '<div>' + key + ':</div>';
|
||||
html += "<div class='" + key + "'>" + params[key] + '</div>';
|
||||
});
|
||||
}
|
||||
|
||||
li.innerHTML = html;
|
||||
events.appendChild(li);
|
||||
this._eventNum += 1;
|
||||
};
|
||||
|
||||
this._setupCallbacks = function id__setupCallbacks() {
|
||||
if (this._running) return;
|
||||
var self = this;
|
||||
try {
|
||||
navigator.mozId.watch({
|
||||
|
||||
onlogin: function(assertion) {
|
||||
var unpacked = JSON.stringify(unpackAssertion(assertion), null, 2);
|
||||
self.recordEvent('login', 'login',
|
||||
{assertion: assertion, unpacked: unpacked});
|
||||
},
|
||||
|
||||
onlogout: function() {
|
||||
self.recordEvent('logout', 'logout');
|
||||
},
|
||||
|
||||
onready: function() {
|
||||
self.recordEvent('ready', 'ready');
|
||||
}
|
||||
|
||||
});
|
||||
} catch (err) {
|
||||
this.recordEvent('Error: ' + err, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind UI components
|
||||
*/
|
||||
this._bindEvents = function id__bindEvents() {
|
||||
if (this._running) return;
|
||||
var self = this;
|
||||
var testElementHandlers = {
|
||||
't-request': function() {
|
||||
navigator.mozId.request();
|
||||
},
|
||||
|
||||
't-request-withOnCancel': function() {
|
||||
navigator.mozId.request({oncancel: function() {
|
||||
self.recordEvent('cancel', 'cancel');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
't-request-allowUnverified': function() {
|
||||
navigator.mozId.request({
|
||||
allowUnverified: getUnverifiedOk()
|
||||
});
|
||||
},
|
||||
|
||||
't-request-forceIssuer': function() {
|
||||
navigator.mozId.request({
|
||||
forceIssuer: getIssuerName()
|
||||
});
|
||||
},
|
||||
|
||||
't-request-forceIssuer-allowUnverified': function() {
|
||||
navigator.mozId.request({
|
||||
allowUnverified: getUnverifiedOk(),
|
||||
forceIssuer: getIssuerName()
|
||||
});
|
||||
},
|
||||
|
||||
't-logout': function() {
|
||||
navigator.mozId.logout();
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(testElementHandlers).forEach(function(selector) {
|
||||
document.getElementById(selector).addEventListener(
|
||||
'click', testElementHandlers[selector]);
|
||||
});
|
||||
};
|
||||
|
||||
this.init = function id_init() {
|
||||
this._setupCallbacks();
|
||||
this._bindEvents();
|
||||
this._running = true;
|
||||
|
||||
this.recordEvent('Ready to rock');
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var identityTests = new IdentityTests();
|
||||
identityTests.init();
|
||||
}, false);
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
document.getElementById('go').onclick = function _go() {
|
||||
var a = new MozActivity(
|
||||
{
|
||||
name: 'test-inline',
|
||||
data: {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
a.onsuccess = function() {
|
||||
document.getElementById('result').textContent = this.result.text;
|
||||
};
|
||||
|
||||
a.onerror = function() {
|
||||
document.getElementById('result').textContent = '(canceled)';
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
document.getElementById('go').onclick = function _go() {
|
||||
var a = new MozActivity({ name: 'test', data: {type: 'text'}});
|
||||
a.onsuccess = function() { alert('Success!'); };
|
||||
a.onerror = function() { alert('Failure.'); };
|
||||
};
|
||||
82
assets/webapps/uitest.gaiamobile.org/js/API/openaudio.js
Normal file
82
assets/webapps/uitest.gaiamobile.org/js/API/openaudio.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
var open = document.getElementById('open');
|
||||
var opensavefile = document.getElementById('opensavefile');
|
||||
var opensaveblob = document.getElementById('opensaveblob');
|
||||
open.hidden = true;
|
||||
opensavefile.hidden = true;
|
||||
opensaveblob.hidden = true;
|
||||
|
||||
open.onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'audio/ogg',
|
||||
blob: localblob,
|
||||
title: 'jonobacon-freesoftwaresong2.ogg'
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
opensavefile.onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'audio/ogg',
|
||||
blob: localblob,
|
||||
allowSave: true,
|
||||
filename: 'downloads/uitest/jonobacon-freesoftwaresong2.ogg'
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
opensaveblob.onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'audio/ogg',
|
||||
blob: remoteblob,
|
||||
allowSave: true,
|
||||
filename: 'downloads/uitest/Back_In_Black-sample.ogg'
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
// The audio we want to open
|
||||
var localblob;
|
||||
var remoteblob;
|
||||
var localURL = '../../data/audio/jonobacon-freesoftwaresong2.ogg';
|
||||
var remoteURL = 'http://upload.wikimedia.org/wikipedia/en/4/45/' +
|
||||
'ACDC_-_Back_In_Black-sample.ogg';
|
||||
|
||||
var localxhr = new XMLHttpRequest();
|
||||
localxhr.open('GET', localURL);
|
||||
localxhr.responseType = 'blob';
|
||||
localxhr.send();
|
||||
localxhr.onload = function() {
|
||||
localblob = new Blob([localxhr.response], { type: 'audio/ogg' });
|
||||
open.hidden = false;
|
||||
opensavefile.hidden = false;
|
||||
};
|
||||
localxhr.onerror = function() {
|
||||
console.log('Error loading test audio', localxhr.error.name);
|
||||
};
|
||||
|
||||
var remotexhr = new XMLHttpRequest();
|
||||
remotexhr.open('GET', remoteURL);
|
||||
remotexhr.responseType = 'blob';
|
||||
remotexhr.send();
|
||||
remotexhr.onload = function() {
|
||||
remoteblob = new Blob([remotexhr.response], { type: 'audio/ogg' });
|
||||
opensaveblob.hidden = false;
|
||||
};
|
||||
remotexhr.onerror = function() {
|
||||
console.log('Error loading test audio from network', remotexhr.error.name);
|
||||
};
|
||||
49
assets/webapps/uitest.gaiamobile.org/js/API/openvideo.js
Normal file
49
assets/webapps/uitest.gaiamobile.org/js/API/openvideo.js
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
var open = document.getElementById('open');
|
||||
var opensave = document.getElementById('opensave');
|
||||
open.hidden = true;
|
||||
opensave.hidden = true;
|
||||
|
||||
open.onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'video/3gpp',
|
||||
blob: videoblob,
|
||||
title: 'Stapler'
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
opensave.onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'video/3gpp',
|
||||
blob: videoblob,
|
||||
allowSave: true,
|
||||
filename: 'downloads/uitest/stapler.3gp'
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
// The image we want to view
|
||||
var videoblob;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '../../data/video/stapler.3gp');
|
||||
xhr.responseType = 'blob';
|
||||
xhr.send();
|
||||
xhr.onload = function() {
|
||||
videoblob = new Blob([xhr.response], { type: 'video/3gpp' });
|
||||
open.hidden = false;
|
||||
opensave.hidden = false;
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
console.log('Error loading test video', xhr.error.name);
|
||||
};
|
||||
56
assets/webapps/uitest.gaiamobile.org/js/API/orientation.js
Normal file
56
assets/webapps/uitest.gaiamobile.org/js/API/orientation.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
function orientationTest(evt) {
|
||||
switch (evt.target.id) {
|
||||
case 'lock1':
|
||||
screen.mozLockOrientation(['portrait']);
|
||||
break;
|
||||
case 'lock2':
|
||||
screen.mozLockOrientation(['landscape']);
|
||||
break;
|
||||
case 'lock3':
|
||||
screen.mozLockOrientation(['portrait-primary']);
|
||||
break;
|
||||
case 'lock4':
|
||||
screen.mozLockOrientation(['portrait-secondary']);
|
||||
break;
|
||||
case 'lock5':
|
||||
screen.mozLockOrientation(['landscape-primary']);
|
||||
break;
|
||||
case 'lock6':
|
||||
screen.mozLockOrientation(['landscape-secondary']);
|
||||
break;
|
||||
case 'lock7':
|
||||
screen.mozLockOrientation(['portrait', 'landscape-primary']);
|
||||
break;
|
||||
case 'lock8':
|
||||
screen.mozLockOrientation(['portrait', 'landscape-secondary']);
|
||||
break;
|
||||
case 'lock9':
|
||||
screen.mozLockOrientation(['landscape', 'portrait-primary']);
|
||||
break;
|
||||
case 'lock10':
|
||||
screen.mozLockOrientation(['landscape', 'portrait-secondary']);
|
||||
break;
|
||||
case 'lock11':
|
||||
screen.mozLockOrientation(['portrait-primary', 'landscape-primary']);
|
||||
break;
|
||||
case 'lock12':
|
||||
screen.mozLockOrientation(['portrait-secondary', 'landscape-primary']);
|
||||
break;
|
||||
case 'lock13':
|
||||
screen.mozLockOrientation(['portrait-primary', 'landscape-secondary']);
|
||||
break;
|
||||
case 'lock14':
|
||||
screen.mozLockOrientation(['portrait-secondary', 'landscape-secondary']);
|
||||
break;
|
||||
case 'unlock':
|
||||
screen.mozUnlockOrientation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
var buttons = document.getElementsByTagName('button');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
buttons[i].addEventListener('click', orientationTest);
|
||||
}
|
||||
});
|
||||
63
assets/webapps/uitest.gaiamobile.org/js/API/pay.js
Normal file
63
assets/webapps/uitest.gaiamobile.org/js/API/pay.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
/* vim: set ft=javascript sw=2 ts=2 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
Mock payment provider JWT
|
||||
|
||||
{ "iss": "323d34dc-b5cf-4822-8e47-6a4515dc74db",
|
||||
"request": {
|
||||
"description": "The forbidden fruit",
|
||||
"id": "af1f960a-3f90-4e2d-a20f-d5170aee49f2",
|
||||
"postbackURL": "https://inapp-pay-test.paas.allizom.org/mozpay/postback",
|
||||
"productData": "localTransID=6fc8f207-da3f-440f-9977-eb613aae0a00",
|
||||
"chargebackURL": "https://inapp-pay-test.paas.allizom.org/mozpay/chargeback",
|
||||
"name": "Virtual Kiwi"
|
||||
},
|
||||
"typ": "tests/payments/pay/v1",
|
||||
"aud": "ferjm.github.io/gaia-mock-payment-provider"
|
||||
}
|
||||
|
||||
*/
|
||||
const mockJWT = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzMjNkMzRkYy1iNWNmLTQ4MjItOGU0Ny02YTQ1MTVkYzc0ZGIiLCJhdWQiOiJmZXJqbS5naXRodWIuaW8vZ2FpYS1tb2NrLXBheW1lbnQtcHJvdmlkZXIiLCJ0eXAiOiJ0ZXN0cy9wYXltZW50cy9wYXkvdjEiLCJyZXF1ZXN0Ijp7ImlkIjoiYWYxZjk2MGEtM2Y5MC00ZTJkLWEyMGYtZDUxNzBhZWU0OWYyIiwibmFtZSI6IlZpcnR1YWwgS2l3aSIsImRlc2NyaXB0aW9uIjoiVGhlIGZvcmJpZGRlbiBmcnVpdCIsInByb2R1Y3REYXRhIjoibG9jYWxUcmFuc0lEPTZmYzhmMjA3LWRhM2YtNDQwZi05OTc3LWViNjEzYWFlMGEwMCIsInBvc3RiYWNrVVJMIjoiaHR0cHM6Ly9pbmFwcC1wYXktdGVzdC5wYWFzLmFsbGl6b20ub3JnL21venBheS9wb3N0YmFjayIsImNoYXJnZWJhY2tVUkwiOiJodHRwczovL2luYXBwLXBheS10ZXN0LnBhYXMuYWxsaXpvbS5vcmcvbW96cGF5L2NoYXJnZWJhY2sifX0.DlHejmKRlVPLYO-HVAYDzqOcv5eXMsVlpnozcADpnh4';
|
||||
|
||||
// Invalid typ JWT
|
||||
const invalidJWT = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.IntcImF1ZFwiOiBcImNvbm5lY3QucWEtb3BlbnRlbC0wNC5oaS5pbmV0XCIsIFwiaXNzXCI6IFwiMzRYVjM3QkRSQkJGNEtaQ1M5UVVcIiwgXCJyZXF1ZXN0XCI6IHtcIm5hbWVcIjogXCJQaWNlIG9mIENha2VcIiwgXCJwcmljZVwiOiAxMC41LCBcInByaWNlVGllclwiOiAxLCBcInByb2R1Y3RkYXRhXCI6IFwidHJhbnNhY3Rpb25faWQ9MTJcIiwgXCJjdXJyZW5jeUNvZGVcIjogXCJVU0RcIiwgXCJkZXNjcmlwdGlvblwiOiBcIlZpcnR1YWwgY2hvY29sYXRlIGNha2UgdG8gZmlsbCB5b3VyIHZpcnR1YWwgdHVtbXlcIn0sIFwiZXhwXCI6IDEzNDIwMDMwNzA1MTMsIFwiaWF0XCI6IDEzNDIwMDMwNzQxMTMsIFwidHlwXCI6IFwicGF5bWVudHMvaW5hcHAvdjFcIn0i.I5rFwoBtgyTltMJ_11rHOgcto-HdFbYlIOgVOVSlJe0';
|
||||
|
||||
var PayTests = {
|
||||
|
||||
init: function pt_init() {
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var jwts = {
|
||||
'test-pmpp': [mockJWT],
|
||||
'test-invalid': [invalidJWT],
|
||||
'test-nojwt': undefined,
|
||||
'test-repeated': [mockJWT, mockJWT]
|
||||
};
|
||||
|
||||
['test-pmpp',
|
||||
'test-invalid',
|
||||
'test-nojwt',
|
||||
'test-repeated'].forEach(function(id) {
|
||||
document.getElementById(id).addEventListener('click', function() {
|
||||
PayTests.pay(jwts[id]);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
pay: function pt_pay(JWTs) {
|
||||
var request = navigator.mozPay(JWTs);
|
||||
request.onsuccess = function onsuccess() {
|
||||
document.getElementById('result').innerHTML = 'Payment success';
|
||||
};
|
||||
request.onerror = function onerror() {
|
||||
console.log("Error " + request.error.name);
|
||||
document.getElementById('result').innerHTML = 'Payment error ' +
|
||||
request.error.name;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
PayTests.init();
|
||||
13
assets/webapps/uitest.gaiamobile.org/js/API/pickdownload.js
Normal file
13
assets/webapps/uitest.gaiamobile.org/js/API/pickdownload.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
function pick(type) {
|
||||
var data = {type: type};
|
||||
var a = new MozActivity({ name: 'pick', data: data});
|
||||
a.onsuccess = function(e) {
|
||||
var result = document.getElementById('result');
|
||||
result.textContent = a.result.name + ' ' + a.result.type + ' (' +
|
||||
a.result.size + ')';
|
||||
};
|
||||
}
|
||||
|
||||
document.getElementById('b1').onclick = function() {
|
||||
pick('application/*');
|
||||
};
|
||||
25
assets/webapps/uitest.gaiamobile.org/js/API/pickphoto.js
Normal file
25
assets/webapps/uitest.gaiamobile.org/js/API/pickphoto.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
function pick(type, nocrop, width, height) {
|
||||
var data = {type: type};
|
||||
if (nocrop) data.nocrop = true;
|
||||
if (width) data.width = width;
|
||||
if (height) data.height = height;
|
||||
var a = new MozActivity({ name: 'pick', data: data});
|
||||
a.onsuccess = function(e) {
|
||||
console.log('got blob of type', a.result.blob.type);
|
||||
var url = URL.createObjectURL(a.result.blob);
|
||||
var img = document.getElementById('result');
|
||||
img.src = url;
|
||||
img.onload = function() { URL.revokeObjectURL(url); };
|
||||
};
|
||||
a.onerror = function() { alert('Failure picking photo'); };
|
||||
}
|
||||
|
||||
document.getElementById('b1').onclick = function() { pick('image/jpeg'); };
|
||||
document.getElementById('b2').onclick = function() { pick('image/png'); };
|
||||
document.getElementById('b3').onclick = function() {
|
||||
pick(['image/jpeg', 'image/png']);
|
||||
};
|
||||
document.getElementById('b4').onclick = function() { pick('image/*'); };
|
||||
document.getElementById('b5').onclick = function() { pick('image/*', true); };
|
||||
document.getElementById('b6').onclick = function() { pick('image/*', false,
|
||||
100, 100); };
|
||||
32
assets/webapps/uitest.gaiamobile.org/js/API/picktype.js
Normal file
32
assets/webapps/uitest.gaiamobile.org/js/API/picktype.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
function pick(type, nocrop, width, height) {
|
||||
var data = {type: type};
|
||||
if (nocrop) data.nocrop = true;
|
||||
if (width) data.width = width;
|
||||
if (height) data.height = height;
|
||||
var a = new MozActivity({ name: 'pick', data: data});
|
||||
a.onsuccess = function(e) {
|
||||
console.log('got blob of type', a.result.blob.type);
|
||||
var url = URL.createObjectURL(a.result.blob);
|
||||
var img = document.getElementById('result');
|
||||
img.src = url;
|
||||
img.onload = function() { URL.revokeObjectURL(url); };
|
||||
};
|
||||
a.onerror = function() { alert('Failure picking'); };
|
||||
}
|
||||
|
||||
document.getElementById('b1').onclick = function() {
|
||||
pick(['video/*', 'image/*']);
|
||||
};
|
||||
document.getElementById('b2').onclick = function() {
|
||||
pick(['image/*', 'video/*']);
|
||||
};
|
||||
document.getElementById('b3').onclick = function() {
|
||||
pick(['video/*', 'image/jpg']);
|
||||
};
|
||||
document.getElementById('b4').onclick = function() {
|
||||
pick(['video/*', 'image/png']);
|
||||
};
|
||||
document.getElementById('b5').onclick = function() {
|
||||
pick(['video/3gpp', 'image/jpg']);
|
||||
};
|
||||
|
||||
18
assets/webapps/uitest.gaiamobile.org/js/API/pickvideo.js
Normal file
18
assets/webapps/uitest.gaiamobile.org/js/API/pickvideo.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
function pick(type, nocrop, width, height) {
|
||||
var data = {type: type};
|
||||
if (nocrop) data.nocrop = true;
|
||||
if (width) data.width = width;
|
||||
if (height) data.height = height;
|
||||
var a = new MozActivity({ name: 'pick', data: data});
|
||||
a.onsuccess = function(e) {
|
||||
console.log('got blob of type', a.result.blob.type);
|
||||
var url = URL.createObjectURL(a.result.blob);
|
||||
var img = document.getElementById('result');
|
||||
img.src = url;
|
||||
img.onload = function() { URL.revokeObjectURL(url); };
|
||||
};
|
||||
a.onerror = function() { alert('Failure picking video'); };
|
||||
}
|
||||
|
||||
document.getElementById('b1').onclick = function() { pick('video/3gpp'); };
|
||||
document.getElementById('b2').onclick = function() { pick('video/*'); };
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
'use strict';
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
function log(aMsg) {
|
||||
console.log('-*- mdns.js : ' + aMsg + '\n');
|
||||
}
|
||||
|
||||
if (typeof navigator.mozPresentationDeviceInfo !== 'undefined') {
|
||||
navigator.mozPresentationDeviceInfo.addEventListener('devicechange',
|
||||
function(e) {
|
||||
log('device changed');
|
||||
getAll();
|
||||
});
|
||||
|
||||
document.getElementById('discovery').onclick = function _discovery() {
|
||||
log('discovery');
|
||||
navigator.mozPresentationDeviceInfo.forceDiscovery();
|
||||
getAll();
|
||||
};
|
||||
|
||||
getAll();
|
||||
}
|
||||
|
||||
function appendDevice(device) {
|
||||
var node = document.createElement('li');
|
||||
var textnode = document.createTextNode(device.name);
|
||||
node.appendChild(textnode);
|
||||
document.getElementById('devices').appendChild(node);
|
||||
}
|
||||
|
||||
function clearDevices() {
|
||||
var devNode = document.getElementById('devices');
|
||||
while (devNode.firstChild) {
|
||||
devNode.removeChild(devNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
function getAll() {
|
||||
log('getAll');
|
||||
navigator.mozPresentationDeviceInfo.getAll().then(function(devices) {
|
||||
log('devices found: ' + devices.length);
|
||||
clearDevices();
|
||||
for (var device of devices) {
|
||||
appendDevice(device);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
13
assets/webapps/uitest.gaiamobile.org/js/API/savebookmark.js
Normal file
13
assets/webapps/uitest.gaiamobile.org/js/API/savebookmark.js
Normal file
File diff suppressed because one or more lines are too long
14
assets/webapps/uitest.gaiamobile.org/js/API/search.js
Normal file
14
assets/webapps/uitest.gaiamobile.org/js/API/search.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
var search = document.querySelector('#search');
|
||||
if (search) {
|
||||
search.onclick = function() {
|
||||
var search_area = document.querySelector('#search_area');
|
||||
console.log('Search:' + search_area.value);
|
||||
var searching = new MozActivity({
|
||||
name: 'search',
|
||||
data: {
|
||||
type: 'text/plain',
|
||||
keyword: search_area.value
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
179
assets/webapps/uitest.gaiamobile.org/js/API/secure_element.js
Normal file
179
assets/webapps/uitest.gaiamobile.org/js/API/secure_element.js
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
'use strict';
|
||||
|
||||
/* globals Utils, AID, APDU */
|
||||
|
||||
var SIMAccessManager = {
|
||||
ERROR_MSG: {
|
||||
NOT_IDLE: 'WRONG SIM ACCESS STATE',
|
||||
ACCESS_FAILED: 'FAILED TO ENABLE SIM ACCESS',
|
||||
APPLETS_FAILED: 'FAILED TO GET APPLETS DATA'
|
||||
},
|
||||
|
||||
SIM_ACCESS_STATES: {
|
||||
DISABLED: 'disabled',
|
||||
IDLE: 'idle',
|
||||
BUSY: 'busy'
|
||||
},
|
||||
|
||||
_simState: null,
|
||||
_seSession: null,
|
||||
|
||||
start: function start() {
|
||||
if(!navigator.seManager) {
|
||||
return Promise.reject('Securel Element API not present');
|
||||
}
|
||||
|
||||
return navigator.seManager.getSEReaders()
|
||||
.then((readers) => {
|
||||
return readers[0].openSession();
|
||||
})
|
||||
.then((session) => {
|
||||
this._seSession = session;
|
||||
this._simState = this.SIM_ACCESS_STATES.IDLE;
|
||||
})
|
||||
.catch(() => {
|
||||
this._simState = this.SIM_ACCESS_STATES.DISABLED;
|
||||
return Promise.reject(this.ERROR_MSG.ACCESS_FAILED);
|
||||
});
|
||||
},
|
||||
|
||||
stop: function stop() {
|
||||
return this._seSession.closeAll()
|
||||
.then(() => {
|
||||
this._seSession = null;
|
||||
this._simState = this.SIM_ACCESS_STATES.DISABLED;
|
||||
});
|
||||
},
|
||||
|
||||
getAppletsData: function getAppletsData() {
|
||||
if(this._simState !== this.SIM_ACCESS_STATES.IDLE) {
|
||||
return Promise.reject(this.ERROR_MSG.NOT_IDLE);
|
||||
}
|
||||
|
||||
this._simState = this.SIM_ACCESS_STATES.BUSY;
|
||||
return this._seSession.openLogicalChannel(AID.CRS)
|
||||
.then((channel) => {
|
||||
return channel.transmit(APDU.CRS.getStatusAll1st);
|
||||
})
|
||||
.then((resp) => {
|
||||
var receivedData = new Uint8Array();
|
||||
|
||||
// we can get different responses, also propriatary
|
||||
// using counter to not allow to try to query the SIM indifinately
|
||||
var count = 0;
|
||||
var condition = (resp) =>
|
||||
(count++ > 10 || resp.sw1 === 0x90 && resp.sw2 === 0x00);
|
||||
var action = (resp) => {
|
||||
receivedData = Utils.joinUint8Arrays(receivedData, resp.data);
|
||||
return resp.channel.transmit(APDU.CRS.getStatusAllNext)
|
||||
};
|
||||
|
||||
return Utils.whilePromise(condition, action, resp)
|
||||
.then((lastResp) => {
|
||||
lastResp.channel.close();
|
||||
this._simState = this.SIM_ACCESS_STATES.IDLE;
|
||||
|
||||
return Utils.joinUint8Arrays(receivedData, lastResp.data);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
return this._cleanup(this.ERROR_MSG.APPLETS_FAILED);
|
||||
});
|
||||
},
|
||||
|
||||
toggleApplet: function toggleApplet(on, aid) {
|
||||
if(this._simState !== this.SIM_ACCESS_STATES.IDLE) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
this._simState = this.SIM_ACCESS_STATES.BUSY;
|
||||
var apdu = on ? APDU.CRS.activateCLF(aid) : APDU.CRS.deactivateCLF(aid);
|
||||
return this._seSession.openLogicalChannel(AID.CRS)
|
||||
.then((channel) => channel.transmit(apdu))
|
||||
.then((resp) => {
|
||||
return resp.channel.close()
|
||||
.then(() => {
|
||||
this._simState = this.SIM_ACCESS_STATES.IDLE;
|
||||
return resp.sw1 === 0x90 && resp.sw2 === 0x00;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_cleanup: function cleanup(message) {
|
||||
this._simState = this.SIM_ACCESS_STATES.IDLE;
|
||||
return Promise.reject(message);
|
||||
}
|
||||
};
|
||||
|
||||
var WalletDemo = {
|
||||
init: function init() {
|
||||
if(!navigator.seManager) {
|
||||
this._updateStatus('Secure Element API not available.');
|
||||
return;
|
||||
}
|
||||
|
||||
SIMAccessManager.start()
|
||||
.then(() => {
|
||||
this._updateStatus('Init SIM access, getting applets from CRS');
|
||||
return this._readDataRefreshUI();
|
||||
})
|
||||
.catch((error) => {
|
||||
this._updateStatus('Init failed.', error);
|
||||
SIMAccessManager.stop();
|
||||
});
|
||||
},
|
||||
|
||||
_readDataRefreshUI: function readDataRefreshUI() {
|
||||
return SIMAccessManager.getAppletsData()
|
||||
.then((appletsData) => {
|
||||
// parsing and filtering to get payment enabled applets
|
||||
var list = Utils.parseAppletsData(appletsData).filter((applet) => {
|
||||
return applet.state === '1F01' || applet.state === '1F00';
|
||||
});
|
||||
this._updateStatus(list.length + ' applets read from SIM');
|
||||
this._updateUI(list);
|
||||
});
|
||||
},
|
||||
|
||||
_updateUI: function updateUI(parsedApplets) {
|
||||
var div = document.querySelector('#applets-view div');
|
||||
div.innerHTML = '';
|
||||
parsedApplets.forEach((applet) => {
|
||||
var button = document.createElement('button');
|
||||
var state = (applet.state === '1F01') ? 'active' : 'not active' ;
|
||||
button.innerHTML = '<p>' + applet.aid + '</p>' +
|
||||
'<p> contactless state: ' + state + '</p>';
|
||||
|
||||
button.addEventListener('click',
|
||||
() => this._toggleApplet(applet.state === '1F00', applet.aid));
|
||||
div.appendChild(button);
|
||||
});
|
||||
},
|
||||
|
||||
_toggleApplet: function toggleApplet(activate, aid) {
|
||||
SIMAccessManager.toggleApplet(activate, aid)
|
||||
.then((success) => {
|
||||
if(success) {
|
||||
this._updateStatus(aid + ' ' + ((activate) ? 'active' : 'not active'));
|
||||
return this._readDataRefreshUI();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this._updateStatus('Failed to toggle applets', error);
|
||||
});
|
||||
},
|
||||
|
||||
_updateStatus: function showStatus(status, error) {
|
||||
console.log(status);
|
||||
var selector = '.success';
|
||||
if(error) {
|
||||
console.log(error);
|
||||
selector = '.error';
|
||||
status += ', error: ' + error;
|
||||
}
|
||||
document.querySelector(selector).textContent = status;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
window.addEventListener('load', () => WalletDemo.init());
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
'use strict';
|
||||
|
||||
/* exported Utils, APDU, AID */
|
||||
|
||||
const Utils = {
|
||||
byteToHexString: function byteToHexString(uint8arr) {
|
||||
if (!uint8arr) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var hexStr = '';
|
||||
for (var i = 0; i < uint8arr.length; i++) {
|
||||
var hex = (uint8arr[i] & 0xff).toString(16);
|
||||
hex = (hex.length === 1) ? '0' + hex : hex;
|
||||
hexStr += hex;
|
||||
}
|
||||
return hexStr.toUpperCase();
|
||||
},
|
||||
|
||||
hexStringToByte: function hexStringToByte(str) {
|
||||
var a = [];
|
||||
for(var i = 0, len = str.length; i < len; i+=2) {
|
||||
a.push(parseInt(str.substr(i,2),16));
|
||||
}
|
||||
return new Uint8Array(a);
|
||||
},
|
||||
|
||||
joinUint8Arrays: function joinUint8Arrays() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var length = args.reduce(function(a, b) { return a + b.length; }, 0);
|
||||
var out = new Uint8Array(length);
|
||||
|
||||
args.reduce(function(previousLen, buffer) {
|
||||
out.set(buffer, previousLen);
|
||||
return previousLen + buffer.length;
|
||||
}, 0);
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
whilePromise: function whilePromise(condition, action, init) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var loop = (value) => {
|
||||
if (condition(value)) {
|
||||
return resolve(value);
|
||||
}
|
||||
|
||||
return action(value).then(loop).catch(reject);
|
||||
};
|
||||
loop(init);
|
||||
});
|
||||
},
|
||||
|
||||
parseAppletsData: function parseAppletsData(data) {
|
||||
var list = [];
|
||||
for(var i = 0, len = data.length; i < len;) {
|
||||
if(data[i] === 0x61) {
|
||||
var end = i+2 + data[i+1];
|
||||
var appletData = data.subarray(i+2, end);
|
||||
var applet = this._parseSingleApplet(appletData);
|
||||
|
||||
if(applet) {
|
||||
list.push(applet);
|
||||
}
|
||||
i = end;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
},
|
||||
|
||||
_parseSingleApplet: function _parseSingleApplet(data) {
|
||||
// checking for AID tag
|
||||
if (data[0] === 0x4F) {
|
||||
var applet = {
|
||||
aid: this.byteToHexString(data.subarray(2, 2 + data[1])),
|
||||
state: this.byteToHexString(data.subarray(data[1] + 5))
|
||||
};
|
||||
return applet;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
CRS AID, TAGS and APDUs based on:
|
||||
GlobalPlatform Card Technology Contactless Services Card Specification v2.2
|
||||
- Amendment C Version 1.1.1
|
||||
*/
|
||||
|
||||
const AID = {
|
||||
CRS: Utils.hexStringToByte('A00000015143525300')
|
||||
};
|
||||
|
||||
const APDU = {
|
||||
CRS: {
|
||||
getStatusAll1st: { cla: 0x80, ins: 0xF2, p1: 0x40, p2: 0x00,
|
||||
data: new Uint8Array([
|
||||
0x4F, 0x00, // applet AID, empty here
|
||||
0x5C, 0x03, // tag list to be returned
|
||||
0x4F, // AID
|
||||
0x9F, 0x70 // applet life cycle state - first byte;
|
||||
// contactless activation state - second byte
|
||||
])
|
||||
},
|
||||
|
||||
getStatusAllNext: { cla: 0x80, ins: 0xF2, p1: 0x40, p2: 0x01,
|
||||
data: new Uint8Array([0x4F, 0x00, 0x5C, 0x03, 0x4F, 0x9F, 0x70])
|
||||
},
|
||||
|
||||
activateCLF: (aid) => {
|
||||
return { cla: 0x80, ins: 0xF0, p1: 0x01, p2: 0x01, data:
|
||||
Utils.joinUint8Arrays([0x4F, 0x0F], Utils.hexStringToByte(aid))
|
||||
};
|
||||
},
|
||||
|
||||
deactivateCLF: (aid) => {
|
||||
return { cla: 0x80, ins: 0xF0, p1: 0x01, p2: 0x00, data:
|
||||
Utils.joinUint8Arrays([0x4F, 0x0F], Utils.hexStringToByte(aid))
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
12
assets/webapps/uitest.gaiamobile.org/js/API/sendsms.js
Normal file
12
assets/webapps/uitest.gaiamobile.org/js/API/sendsms.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
var sendSMS = document.querySelector('#send-sms');
|
||||
if (sendSMS) {
|
||||
sendSMS.onclick = function() {
|
||||
var sms = new MozActivity({
|
||||
name: 'new', // Possible compose-sms in future versions
|
||||
data: {
|
||||
type: 'websms/sms',
|
||||
number: '+46777888999'
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
31
assets/webapps/uitest.gaiamobile.org/js/API/shareimage.js
Normal file
31
assets/webapps/uitest.gaiamobile.org/js/API/shareimage.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
var shareImage = document.querySelector("#share-image"),
|
||||
imgToShare = document.querySelector("#image-to-share");
|
||||
if (shareImage && imgToShare) {
|
||||
shareImage.onclick = function () {
|
||||
if(imgToShare.naturalWidth > 0) {
|
||||
// Create dummy canvas
|
||||
var blobCanvas = document.createElement("canvas");
|
||||
blobCanvas.width = imgToShare.width;
|
||||
blobCanvas.height = imgToShare.height;
|
||||
|
||||
// Get context and draw image
|
||||
var blobCanvasContext = blobCanvas.getContext("2d");
|
||||
blobCanvasContext.drawImage(imgToShare, 0, 0);
|
||||
|
||||
// Export to blob and share through a Web Activitiy
|
||||
blobCanvas.toBlob(function (blob) {
|
||||
var sharingImage = new MozActivity({
|
||||
name: "share",
|
||||
data: {
|
||||
type: "image/*",
|
||||
number: 1,
|
||||
blobs: [blob]
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
alert("Image failed to load, can't be shared");
|
||||
}
|
||||
}
|
||||
}
|
||||
13
assets/webapps/uitest.gaiamobile.org/js/API/shareurl.js
Normal file
13
assets/webapps/uitest.gaiamobile.org/js/API/shareurl.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
var share = document.querySelector('#share');
|
||||
if (share) {
|
||||
share.onclick = function() {
|
||||
var sharing = new MozActivity({
|
||||
name: 'share',
|
||||
data: {
|
||||
type: 'url', // Possibly text/html in future versions,
|
||||
number: 1,
|
||||
url: 'http://www.mozilla.org'
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
59
assets/webapps/uitest.gaiamobile.org/js/API/viewphoto.js
Normal file
59
assets/webapps/uitest.gaiamobile.org/js/API/viewphoto.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// The image we want to view
|
||||
var imageblob;
|
||||
|
||||
// Create an image from a canvas
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 600;
|
||||
canvas.height = 800;
|
||||
var context = canvas.getContext('2d');
|
||||
context.font = '20pt Arial';
|
||||
context.fillStyle = 'red';
|
||||
context.fillText('Hello World', 100, 100);
|
||||
context.strokeStyle = 'blue';
|
||||
context.lineWidth = 4;
|
||||
context.strokeRect(0, 0, 600, 800);
|
||||
|
||||
canvas.toBlob(function(blob) {
|
||||
imageblob = blob;
|
||||
}, 'image/png');
|
||||
|
||||
document.getElementById('view').onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'image/png',
|
||||
blob: imageblob
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
document.getElementById('viewsave').onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'image/png',
|
||||
blob: imageblob,
|
||||
allowSave: true,
|
||||
filename: 'downloads/uitests/helloworldhello.png'
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
|
||||
document.getElementById('viewError').onclick = function() {
|
||||
var a = new MozActivity({
|
||||
name: 'open',
|
||||
data: {
|
||||
type: 'image/jpeg',
|
||||
blob: new Blob(['empty-image'], {'type': 'image/jpeg'})
|
||||
}
|
||||
});
|
||||
a.onsuccess = function() {
|
||||
console.log('activity returns', JSON.stringify(a.result));
|
||||
};
|
||||
};
|
||||
Loading…
Reference in a new issue