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.
BIN
gaia/dev_apps/uitest/data/audio/jonobacon-freesoftwaresong2.ogg
Executable file
5
gaia/dev_apps/uitest/data/fakecontacts/LICENSE
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
The contents of these fake contacts are licensed under the Creative Commons Attribution-Share Alike 3.0 United States License.
|
||||
|
||||
Original source attributed to: Fake Name Generator (http://www.fakenamegenerator.com/)
|
||||
|
||||
For more information, please see http://creativecommons.org/licenses/by-sa/3.0/us/.
|
||||
19237
gaia/dev_apps/uitest/data/fakecontacts/fakecontacts.json
Executable file
33
gaia/dev_apps/uitest/data/fakesocialcontacts/contacts_social.json
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"data": [
|
||||
{
|
||||
"name": ["DJ Trasto"],
|
||||
"givenName": ["DJ"],
|
||||
"familyName": ["Trasto"],
|
||||
"category": ["twitter"],
|
||||
"bday": "1979-11-02"
|
||||
},
|
||||
{
|
||||
"name": ["Armin van Beer"],
|
||||
"givenName": ["Armin"],
|
||||
"familyName": ["van Beer"],
|
||||
"category": ["facebook","twitter"],
|
||||
"org": ["State of Web"],
|
||||
"bday": "1974-03-15"
|
||||
},
|
||||
{
|
||||
"name": ["Spaniard Web Mafia"],
|
||||
"givenName": ["Spaniard"],
|
||||
"familyName": ["Web Mafia"],
|
||||
"category": ["twitter"],
|
||||
"org": ["Libraries.JS"]
|
||||
},
|
||||
{
|
||||
"name": ["David Siestta"],
|
||||
"givenName": ["David"],
|
||||
"familyName": ["Siestta"],
|
||||
"category": ["facebook"],
|
||||
"bday": "1980-04-20"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
gaia/dev_apps/uitest/data/ringtones/AC_prgrssv__Retro_Alarm_Clock_v02_SOFT.ogg
Executable file
BIN
gaia/dev_apps/uitest/data/ringtones/AC_progressive_dapple10.ogg
Executable file
BIN
gaia/dev_apps/uitest/data/ringtones/AC_progressive_shimmer07.ogg
Executable file
BIN
gaia/dev_apps/uitest/data/ringtones/ALARM_progressive2_dapple.mp3
Executable file
BIN
gaia/dev_apps/uitest/data/ringtones/ALARM_progressive_dapple.mp3
Executable file
BIN
gaia/dev_apps/uitest/data/ringtones/classic.ogg
Executable file
BIN
gaia/dev_apps/uitest/data/video/meetthecubs.webm
Executable file
BIN
gaia/dev_apps/uitest/data/video/stapler.3gp
Executable file
150
gaia/dev_apps/uitest/index.html
Executable file
|
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>UI tests</title>
|
||||
<!-- We don't need localization in this app -->
|
||||
<link rel="stylesheet" type="text/css" href="style/uitest.css">
|
||||
<link rel="stylesheet" type="text/css" href="style/tabs.css" >
|
||||
<link rel="stylesheet" type="text/css" href="style/lists.css" >
|
||||
<link rel="stylesheet" type="text/css" href="shared/style/lists.css">
|
||||
|
||||
<!-- Gaia Components -->
|
||||
<link rel="stylesheet" href="app://theme.gaiamobile.org/shared/elements/gaia-theme/style.css">
|
||||
<link rel="stylesheet" href="shared/elements/gaia-icons/gaia-icons.css">
|
||||
|
||||
<!-- Gaia Components -->
|
||||
<script src="shared/elements/config.js"></script>
|
||||
<script src="shared/elements/gaia-header/dist/gaia-header.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/uitest.js"></script>
|
||||
<!-- <script src="shared/js/mime_mapper.js"></script> -->
|
||||
<!-- <script src="shared/js/settings_listener.js"></script> -->
|
||||
<!-- <script src="shared/js/download/download_formatter.js"></script> -->
|
||||
<!-- <script src="shared/js/download/download_helper.js"></script> -->
|
||||
<!-- <script src="shared/js/download/download_store.js"></script> -->
|
||||
<script defer src="shared/js/lazy_loader.js"></script>
|
||||
<script defer src="shared/js/accessibility_helper.js"></script>
|
||||
</head>
|
||||
<body class="theme-productivity">
|
||||
<div class="panel list-panel">
|
||||
<div id="UI-tests" class="page">
|
||||
<section role="region">
|
||||
<gaia-header>
|
||||
<h1>UI Tests</h1>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<section data-type="list">
|
||||
<ul class="sublist">
|
||||
<li><a href="#test=UI/alert">Alert/Prompt</a></li>
|
||||
<li><a href="#test=UI/canvas">Canvas Tag</a></li>
|
||||
<li><a href="#test=UI/contextmenu">Contextmenu</a></li>
|
||||
<li><a href="#test=UI/css_dimension">CSS dimension</a></li>
|
||||
<li><a href="#test=UI/empty">Empty</a></li>
|
||||
<li><a href="#test=UI/fullscreen">mozRequestFullScreen</a></li>
|
||||
<li><a href="#test=UI/fullscreen_controls">Fullscreen Ctr</a></li>
|
||||
<li><a href="#test=UI/keyboard">Keyboard</a></li>
|
||||
<li><a href="#test=UI/newnotification">new Notification()</a></li>
|
||||
<li><a href="#test=UI/notification">mozNotification</a></li>
|
||||
<li><a href="#test=UI/open">window.open</a></li>
|
||||
<li><a href="#test=UI/scrollbar">Scroll bar</a></li>
|
||||
<li><a href="#test=UI/select">Select</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<div id="API-tests" class="page invisible">
|
||||
<section role="region">
|
||||
<gaia-header>
|
||||
<h1>API Tests</h1>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<section data-type="list">
|
||||
<ul class="sublist">
|
||||
<li><a href="#test=API/audiotag">audio tag</a></li>
|
||||
<li><a href="#test=API/browseractivities">Browser Activities</a></li>
|
||||
<li><a href="#test=API/composeemail">Compose Email</a></li>
|
||||
<li><a href="#test=API/contacts">Contacts</a></li>
|
||||
<li><a href="#test=API/copypaste">Copy Paste</a></li>
|
||||
<li><a href="#test=API/csp">CSP Warning</a></li>
|
||||
<li><a href="#test=API/dialnumber">Dial Number</a></li>
|
||||
<li><a href="#test=API/downloads">Downloads</a></li>
|
||||
<li><a href="#test=API/geolocation">Geolocation</a></li>
|
||||
<li><a href="#test=API/getusermedia">getUserMedia</a></li>
|
||||
<li><a href="#test=API/httpauthentication">HTTP Auth</a></li>
|
||||
<li><a href="#test=API/fxa" id="mozId-fxa">Firefox Accounts mozId</a></li>
|
||||
<li><a href="#test=API/identity" id="mozId-persona">Persona mozId</a></li>
|
||||
<li><a href="#test=API/identity-get" id="mozId-persona-get">Persona mozId.get</a></li>
|
||||
<li><a href="#test=API/inlineactivities">Inline Activities</a></li>
|
||||
<li><a href="#test=API/multiactivities">Multi Activities</a></li>
|
||||
<li><a href="#test=API/openaudio">Open Audio</a></li>
|
||||
<li><a href="#test=API/openvideo">Open Video</a></li>
|
||||
<li><a href="#test=API/orientation">mozLockOrientation</a></li>
|
||||
<li><a href="#test=API/pay">navigator.mozPay</a></li>
|
||||
<li><a href="#test=API/pickphoto">Pick Photo</a></li>
|
||||
<li><a href="#test=API/picktype">Pick Photo/Video</a></li>
|
||||
<li><a href="#test=API/pickvideo">Pick Video</a></li>
|
||||
<li><a href="#test=API/pickdownload">Pick Download</a></li>
|
||||
<li><a href="#test=API/presentation_api">Presentation API</a></li>
|
||||
<li><a href="#test=API/savebookmark">Save bookmark</a></li>
|
||||
<li><a href="#test=API/sendsms">Send SMS</a></li>
|
||||
<li><a href="#test=API/shareimage">Share Image</a></li>
|
||||
<li><a href="#test=API/shareurl">Share URL</a></li>
|
||||
<li><a href="#test=API/viewphoto">View Photo</a></li>
|
||||
<li><a href="#test=API/search">Search keyword</a></li>
|
||||
<li><a href="#test=API/secure_element">Secure Element (Wallet)</a><li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<div id="HW-tests" class="page invisible">
|
||||
<section role="region">
|
||||
<gaia-header>
|
||||
<h1 class="header-title">HW Tests</h1>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<section data-type="list">
|
||||
<ul class="sublist">
|
||||
<li><a href="#test=HW/battery">Battery</a></li>
|
||||
<li><a href="#test=HW/bluetooth">Bluetooth</a></li>
|
||||
<li><a href="#test=HW/camera">Camera</a></li>
|
||||
<li><a href="#test=HW/fmradio">FM radio</a></li>
|
||||
<li><a href="#test=HW/headphone">Headphone</a></li>
|
||||
<li><a href="#test=HW/lcd">LCD</a></li>
|
||||
<li><a href="#test=HW/physicalkeys">Physical keys</a></li>
|
||||
<li><a href="#test=HW/radio">Radio information</a></li>
|
||||
<li><a href="#test=HW/ringer">Ringer</a></li>
|
||||
<li><a href="#test=HW/sdcards">SD cards</a></li>
|
||||
<li><a href="#test=HW/sensors">Sensors</a></li>
|
||||
<li><a href="#test=HW/touchscreen">Touch screen</a></li>
|
||||
<li><a href="#test=HW/vibrator">Vibrator</a></li>
|
||||
<li><a href="#test=HW/wifi">Wi-Fi</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<div id="tabs" class="tabs">
|
||||
<ul role="tablist" class="bb-tablist" data-items="3">
|
||||
<li id="panel1" role="presentation">
|
||||
<a href="#UI" id="UI" role="tab" aria-controls="UIpanel">UI</a>
|
||||
<div id="UIpanel" class="bb-tabpanel" role="tabpanel" aria-labelledby="UI"></div>
|
||||
</li>
|
||||
<li id="panel2" role="presentation">
|
||||
<a href="#API" id="API" role="tab" aria-controls="APIpanel">API</a>
|
||||
<div id="APIpanel" class="bb-tabpanel" role="tabpanel" aria-labelledby="API"></div>
|
||||
</li>
|
||||
<li id="panel3" role="presentation">
|
||||
<a href="#HW" id="HW" role="tab" aria-controls="HWpanel">HW</a>
|
||||
<div id="HWpanel" class="bb-tabpanel" role="tabpanel" aria-labelledby="HW"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="test-panel" class="panel test-panel">
|
||||
<section role="region">
|
||||
<gaia-header id="test-panel-header" action="back">
|
||||
<h1 id="test-panel-title" class="header-title"></h1>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<iframe id="test-iframe" mozallowfullscreen="true"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
20
gaia/dev_apps/uitest/js/API/audiotag.js
Executable 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);
|
||||
});
|
||||
15
gaia/dev_apps/uitest/js/API/browseractivities.js
Executable file
|
|
@ -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
gaia/dev_apps/uitest/js/API/composeemail.js
Executable 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
gaia/dev_apps/uitest/js/API/contacts.js
Executable 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));
|
||||
47
gaia/dev_apps/uitest/js/API/contacts_saver.js
Executable file
|
|
@ -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
gaia/dev_apps/uitest/js/API/dialnumber.js
Executable 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
gaia/dev_apps/uitest/js/API/downloads.js
Executable 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
gaia/dev_apps/uitest/js/API/fxa.js
Executable 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
gaia/dev_apps/uitest/js/API/geolocation.js
Executable 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
gaia/dev_apps/uitest/js/API/getusermedia.js
Executable 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
gaia/dev_apps/uitest/js/API/identity-get.js
Executable 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
gaia/dev_apps/uitest/js/API/identity.js
Executable 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);
|
||||
|
||||
17
gaia/dev_apps/uitest/js/API/inlineactivities.js
Executable file
|
|
@ -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)';
|
||||
};
|
||||
};
|
||||
5
gaia/dev_apps/uitest/js/API/multiactivities.js
Executable file
|
|
@ -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
gaia/dev_apps/uitest/js/API/openaudio.js
Executable 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
gaia/dev_apps/uitest/js/API/openvideo.js
Executable 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
gaia/dev_apps/uitest/js/API/orientation.js
Executable 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
gaia/dev_apps/uitest/js/API/pay.js
Executable 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
gaia/dev_apps/uitest/js/API/pickdownload.js
Executable 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
gaia/dev_apps/uitest/js/API/pickphoto.js
Executable 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
gaia/dev_apps/uitest/js/API/picktype.js
Executable 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
gaia/dev_apps/uitest/js/API/pickvideo.js
Executable 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/*'); };
|
||||
48
gaia/dev_apps/uitest/js/API/presentation_api.js
Executable file
|
|
@ -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
gaia/dev_apps/uitest/js/API/savebookmark.js
Executable file
14
gaia/dev_apps/uitest/js/API/search.js
Executable 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
gaia/dev_apps/uitest/js/API/secure_element.js
Executable 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());
|
||||
122
gaia/dev_apps/uitest/js/API/secure_element_utils.js
Executable file
|
|
@ -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
gaia/dev_apps/uitest/js/API/sendsms.js
Executable 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
gaia/dev_apps/uitest/js/API/shareimage.js
Executable 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
gaia/dev_apps/uitest/js/API/shareurl.js
Executable 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
gaia/dev_apps/uitest/js/API/viewphoto.js
Executable 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));
|
||||
};
|
||||
};
|
||||
25
gaia/dev_apps/uitest/js/HW/battery.js
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
'use strict';
|
||||
|
||||
function batteryTest() {
|
||||
var battery = window.navigator.battery;
|
||||
var charging = document.getElementById('charging');
|
||||
var level = document.getElementById('level');
|
||||
var chargingTime = document.getElementById('charging-time');
|
||||
var disChargingTime = document.getElementById('discharging-time');
|
||||
|
||||
function update(evt) {
|
||||
charging.textContent = battery.charging;
|
||||
level.textContent = battery.level * 100;
|
||||
chargingTime.textContent = battery.chargingTime;
|
||||
disChargingTime.textContent = battery.dischargingTime;
|
||||
}
|
||||
|
||||
battery.addEventListener('chargingchange', update);
|
||||
battery.addEventListener('levelchange', update);
|
||||
battery.addEventListener('onchargingtimechange', update);
|
||||
battery.addEventListener('ondischargingtimechange', update);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
window.addEventListener('load', batteryTest);
|
||||
99
gaia/dev_apps/uitest/js/HW/bluetooth.js
Executable file
|
|
@ -0,0 +1,99 @@
|
|||
'use strict';
|
||||
|
||||
function bluetoothTest() {
|
||||
var bluetooth = window.navigator.mozBluetooth;
|
||||
var settings = window.navigator.mozSettings;
|
||||
var switchButton = document.getElementById('switch');
|
||||
var state = document.getElementById('state');
|
||||
var address = document.getElementById('address');
|
||||
var version = document.getElementById('version');
|
||||
var btHelper = new BluetoothHelper();
|
||||
|
||||
function update() {
|
||||
var req = settings.createLock().get('bluetooth.enabled');
|
||||
req.onsuccess = function() {
|
||||
var isBluetoothEnabled = req.result['bluetooth.enabled'];
|
||||
switchButton.checked = isBluetoothEnabled;
|
||||
if (!isBluetoothEnabled) {
|
||||
state.innerHTML = 'Off';
|
||||
address.innerHTML = 'unknown';
|
||||
}
|
||||
else {
|
||||
state.innerHTML = 'On';
|
||||
if (!btHelper.v2) {
|
||||
btHelper.getAddress(function bt_gotAddress(addr) {
|
||||
if (isBluetoothEnabled) {
|
||||
address.innerHTML = addr;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Click on switch will only update settings and
|
||||
// it takes some time for bluetooth hardware to turns on.
|
||||
// That's why we should listen to 'enabled' event of bluetooth
|
||||
function bluetoothSwitch() {
|
||||
settings.createLock().set({'bluetooth.enabled': switchButton.checked});
|
||||
// set enabled stat for BT APIv2
|
||||
if (switchButton.checked) {
|
||||
btHelper.enable();
|
||||
} else {
|
||||
btHelper.disable();
|
||||
}
|
||||
}
|
||||
|
||||
if (btHelper.v2) {
|
||||
version.textContent = "v2";
|
||||
bluetooth.addEventListener('attributechanged', (evt) => {
|
||||
for (var i in evt.attrs) {
|
||||
switch (evt.attrs[i]) {
|
||||
case 'defaultAdapter':
|
||||
var adapter = bluetooth.defaultAdapter;
|
||||
if (adapter.address) { // for default On case
|
||||
address.innerHTML = adapter.address;
|
||||
}
|
||||
adapter.addEventListener('attributechanged', (evt) => {
|
||||
for (var i in evt.attrs) {
|
||||
switch (evt.attrs[i]) {
|
||||
case 'state':
|
||||
if (adapter.state === 'enabled') {
|
||||
switchButton.checked = true;
|
||||
state.innerHTML = 'On';
|
||||
} else if (adapter.state === 'disabled') {
|
||||
switchButton.checked = false;
|
||||
state.innerHTML = 'Off';
|
||||
address.innerHTML = 'unknown';
|
||||
}
|
||||
break;
|
||||
case 'address':
|
||||
address.innerHTML = adapter.address;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
version.textContent = "v1";
|
||||
bluetooth.addEventListener('adapteradded', update);
|
||||
bluetooth.addEventListener('enabled', update);
|
||||
bluetooth.addEventListener('disabled', update);
|
||||
}
|
||||
|
||||
// init
|
||||
switchButton.addEventListener('click', bluetoothSwitch);
|
||||
|
||||
// Update bluetooth information in the first load
|
||||
update();
|
||||
}
|
||||
|
||||
window.addEventListener('load', bluetoothTest);
|
||||
|
||||
19
gaia/dev_apps/uitest/js/HW/camera.js
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
var clickHandlers = {
|
||||
'camera': function() {
|
||||
var activity = new MozActivity({
|
||||
name: 'record',
|
||||
data: {
|
||||
type: 'photos'
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', function(evt) {
|
||||
if (clickHandlers[evt.target.id]) {
|
||||
clickHandlers[evt.target.id].call(this, evt);
|
||||
}
|
||||
});
|
||||
|
||||
154
gaia/dev_apps/uitest/js/HW/fmradio.js
Executable file
|
|
@ -0,0 +1,154 @@
|
|||
'use strict';
|
||||
|
||||
function FMRadioTest() {
|
||||
var messageText = document.getElementById('message');
|
||||
var frequencyMin = document.getElementById('frequency-min');
|
||||
var frequencyMax = document.getElementById('frequency-max');
|
||||
|
||||
var container = document.getElementById('container');
|
||||
var controlPanel = document.getElementById('controlPanel');
|
||||
|
||||
var frequencyInput = document.getElementById('frequency');
|
||||
var switchBtn = document.getElementById('switch');
|
||||
var seekUpBtn = document.getElementById('seekUp');
|
||||
var seekDownBtn = document.getElementById('seekDown');
|
||||
var seekAndCancelBtn = document.getElementById('seekAndCancel');
|
||||
|
||||
if (!navigator.mozFMRadio) {
|
||||
console.log('mozFMRadio not support');
|
||||
container.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var radio = navigator.mozFMRadio;
|
||||
var prevFreq = radio.frequencyLowerBound;
|
||||
var lock = false;
|
||||
if (radio.enabled) {
|
||||
prevFreq = radio.frequency;
|
||||
}
|
||||
|
||||
switchBtn.textContent = radio.enabled;
|
||||
frequencyMin.textContent = radio.frequencyLowerBound;
|
||||
frequencyMax.textContent = radio.frequencyUpperBound;
|
||||
controlPanel.hidden = !radio.enabled;
|
||||
frequencyInput.value = prevFreq;
|
||||
|
||||
togglePanel();
|
||||
toggleControlPanel();
|
||||
|
||||
radio.addEventListener('antennaavailablechange', togglePanel);
|
||||
radio.addEventListener('frequencychange', frequencyChanged);
|
||||
|
||||
frequencyInput.addEventListener('change', setFrequency);
|
||||
switchBtn.addEventListener('click', onclick_radioSwitch);
|
||||
seekUpBtn.addEventListener('click', seek);
|
||||
seekDownBtn.addEventListener('click', seek);
|
||||
seekAndCancelBtn.addEventListener('click', seekAndCancel);
|
||||
window.addEventListener('unload', uninit);
|
||||
|
||||
function logError() {
|
||||
messageText.textContent = this.error.name;
|
||||
}
|
||||
|
||||
// show/hide panels
|
||||
function togglePanel() {
|
||||
if (radio && radio.antennaAvailable) {
|
||||
container.hidden = false;
|
||||
messageText.textContent = '';
|
||||
}
|
||||
else {
|
||||
container.hidden = true;
|
||||
messageText.textContent = 'Headphone is required for FMRadio';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleControlPanel() {
|
||||
lock = false;
|
||||
controlPanel.hidden = !radio.enabled;
|
||||
if (radio.enabled) {
|
||||
switchBtn.textContent = 'Stop';
|
||||
}
|
||||
else {
|
||||
switchBtn.textContent = 'Start';
|
||||
}
|
||||
switchBtn.disabled = false;
|
||||
}
|
||||
|
||||
function onclick_radioSwitch() {
|
||||
if (lock) {
|
||||
return;
|
||||
}
|
||||
|
||||
// lock button until request is finished
|
||||
lock = true;
|
||||
switchBtn.disabled = true;
|
||||
|
||||
var req;
|
||||
if (!radio.enabled) {
|
||||
messageText.textContent = 'turning on FM, please wait...';
|
||||
req = radio.enable(prevFreq);
|
||||
}
|
||||
else {
|
||||
req = radio.disable();
|
||||
}
|
||||
req.onsuccess = req.onerror = function() {
|
||||
toggleControlPanel();
|
||||
if (this.error) {
|
||||
messageText.textContent = this.error.name;
|
||||
}
|
||||
else {
|
||||
messageText.textContent = '';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function frequencyChanged() {
|
||||
console.log('freq changed');
|
||||
frequencyInput.value = radio.frequency;
|
||||
prevFreq = radio.frequency;
|
||||
}
|
||||
|
||||
function setFrequency() {
|
||||
var req = radio.setFrequency(frequencyInput.value);
|
||||
req.onerror = logError;
|
||||
}
|
||||
|
||||
function seek(evt) {
|
||||
var req;
|
||||
if (evt.target.id == 'seekUp') {
|
||||
req = radio.seekUp();
|
||||
}
|
||||
else {
|
||||
req = radio.seekDown();
|
||||
}
|
||||
req.onerror = logError;
|
||||
}
|
||||
|
||||
function seekAndCancel(evt) {
|
||||
var req = radio.seekUp();
|
||||
console.log('seekUP()');
|
||||
req.onsuccess = function() {
|
||||
console.log('seekUP().onsuccess');
|
||||
};
|
||||
req.onerror = function() {
|
||||
console.log('seekUP().onerror:' + this.error.name);
|
||||
};
|
||||
|
||||
var cancel = radio.cancelSeek();
|
||||
console.log('cancel()');
|
||||
cancel.onsuccess = function() {
|
||||
console.log('canelSeek().onsuccess');
|
||||
};
|
||||
cancel.onerror = function() {
|
||||
console.log('cancelSeek().onerror:' + this.error.name);
|
||||
};
|
||||
}
|
||||
|
||||
function uninit() {
|
||||
if (radio.enabled) {
|
||||
radio.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', FMRadioTest);
|
||||
23
gaia/dev_apps/uitest/js/HW/headphone.js
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
function headphoneTest() {
|
||||
var status_display = document.getElementById('status');
|
||||
var acm = navigator.mozAudioChannelManager;
|
||||
if (acm) {
|
||||
acm.addEventListener('headphoneschange', update.bind(this));
|
||||
}
|
||||
else {
|
||||
status_display.textContent = 'mozAudioChannelManager not found';
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (acm.headphones) {
|
||||
status_display.textContent = 'plugged';
|
||||
}
|
||||
else {
|
||||
status_display.textContent = 'unpluged';
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
window.addEventListener('load', headphoneTest);
|
||||
71
gaia/dev_apps/uitest/js/HW/lcd.js
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
'use strict';
|
||||
|
||||
var LCDTest = {
|
||||
get fullscreenDiv() {
|
||||
delete this.fullScreenDiv;
|
||||
return this.fullScreenDiv = document.getElementById('fullscreen-div');
|
||||
},
|
||||
firstTimeHint: null,
|
||||
init: function() {
|
||||
document.body.addEventListener('click', this);
|
||||
this.fullscreenDiv.addEventListener('click',
|
||||
this.exitFullscreen.bind(this));
|
||||
this.firstTimeHint = true;
|
||||
},
|
||||
enterFullscreen: function(color) {
|
||||
this.fullscreenDiv.mozRequestFullScreen();
|
||||
this.fullscreenDiv.classList.remove('invisible');
|
||||
this.fullscreenDiv.classList.remove('red');
|
||||
this.fullscreenDiv.classList.remove('green');
|
||||
this.fullscreenDiv.classList.remove('blue');
|
||||
this.fullscreenDiv.classList.remove('white');
|
||||
this.fullscreenDiv.classList.remove('black');
|
||||
this.fullscreenDiv.classList.add(color);
|
||||
if (this.firstTimeHint) {
|
||||
this.firstTimeHint = false;
|
||||
alert('Tap screen again to exit fullscreen mode');
|
||||
}
|
||||
},
|
||||
exitFullscreen: function() {
|
||||
document.mozCancelFullScreen();
|
||||
this.fullscreenDiv.classList.add('invisible');
|
||||
},
|
||||
turnOn: function() {
|
||||
navigator.mozPower.screenEnabled = true;
|
||||
|
||||
// no longer need the lock
|
||||
this.wakeLock.unlock();
|
||||
},
|
||||
// Only handle clicks on button, clicks on div is handled by exitFullscreen
|
||||
handleEvent: function(evt) {
|
||||
switch (evt.target.id) {
|
||||
case 'red':
|
||||
this.enterFullscreen('red');
|
||||
break;
|
||||
case 'green':
|
||||
this.enterFullscreen('green');
|
||||
break;
|
||||
case 'blue':
|
||||
this.enterFullscreen('blue');
|
||||
break;
|
||||
case 'white':
|
||||
this.enterFullscreen('white');
|
||||
break;
|
||||
case 'black':
|
||||
this.enterFullscreen('black');
|
||||
break;
|
||||
case 'off':
|
||||
// We are going to shutdown the screen, this may lead to
|
||||
// the sleep of CPU. Use wake lock to prevent from sleeping
|
||||
// which cause setTimeout stop working.
|
||||
this.wakeLock = window.navigator.requestWakeLock('screen');
|
||||
|
||||
setTimeout(this.turnOn.bind(this), 3000);
|
||||
navigator.mozPower.screenEnabled = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
wakeLock: null
|
||||
};
|
||||
|
||||
window.addEventListener('load', LCDTest.init.bind(LCDTest));
|
||||
26
gaia/dev_apps/uitest/js/HW/physicalkeys.js
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
'use strict';
|
||||
|
||||
/*
|
||||
var ringer = function callsHandler() {
|
||||
var phoneSoundURL = new SettingsURL();
|
||||
SettingsListener.observe('dialer.ringtone', '', function(value) {
|
||||
ringtonePlayer.pause();
|
||||
ringtonePlayer.src = phoneSoundURL.set(value);
|
||||
});
|
||||
var ringtonePlayer = ringtonePlayer;
|
||||
ringtonePlayer = new Audio();
|
||||
ringtonePlayer.mozAudioChannelType = 'ringer';
|
||||
ringtonePlayer.src = phoneSoundURL.get();
|
||||
ringtonePlayer.loop = false;
|
||||
|
||||
window.addEventListener('home', function (evt) {
|
||||
evt.preventDefault();
|
||||
ringtonePlayer.play();
|
||||
});
|
||||
window.addEventListener('click', function (evt) {
|
||||
evt.stopPropagation();
|
||||
ringtonePlayer.play();
|
||||
});
|
||||
}();
|
||||
|
||||
*/
|
||||
173
gaia/dev_apps/uitest/js/HW/radio.js
Executable file
|
|
@ -0,0 +1,173 @@
|
|||
'use strict';
|
||||
|
||||
function IMEI(serviceId) {
|
||||
var IMEIText = document.getElementById('IMEI');
|
||||
|
||||
navigator.mozTelephony.dial('*#06#', serviceId).then(function(call) {
|
||||
return call.result.then(function getIMEI(message) {
|
||||
if (message && (message.serviceCode === 'scImei') &&
|
||||
message.statusMessage) {
|
||||
IMEIText.textContent = message.statusMessage;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// SIM card information such as ICCID, MSISDN
|
||||
function iccInfo(mozIcc, parentContainer)
|
||||
{
|
||||
var messageText = parentContainer.querySelector('[data-type="icc-message"]');
|
||||
var ICCIDText = parentContainer.querySelector('[data-type="ICCID"]');
|
||||
var MSISDNText = parentContainer.querySelector('[data-type="MSISDN"]');
|
||||
var container = parentContainer.querySelector('[data-type="icc-container"]');
|
||||
|
||||
mozIcc.addEventListener('cardstatechange', update_icc);
|
||||
update_icc();
|
||||
|
||||
function update_icc() {
|
||||
if (mozIcc.cardState == null ||
|
||||
!mozIcc.iccInfo) {
|
||||
container.hidden = true;
|
||||
messageText.textContent = 'Airplane mode on';
|
||||
}
|
||||
else {
|
||||
ICCIDText.textContent = mozIcc.iccInfo.iccid;
|
||||
MSISDNText.textContent = mozIcc.iccInfo.msisdn || 'Unknown';
|
||||
container.hidden = false;
|
||||
messageText.textContent = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// data & voice network information
|
||||
function mobileConnectionInfo(conn, parentContainer)
|
||||
{
|
||||
conn.addEventListener('datachange', update_data_network);
|
||||
conn.addEventListener('voicechange', update_voice_network);
|
||||
update_data_network();
|
||||
update_voice_network();
|
||||
|
||||
function update_data_network() {
|
||||
var container = parentContainer.
|
||||
querySelector('[data-type="data-container"]');
|
||||
var message = parentContainer.
|
||||
querySelector('[data-type="data-message"]');
|
||||
var result = update_network(conn.data, container, message);
|
||||
}
|
||||
function update_voice_network() {
|
||||
var container = parentContainer.
|
||||
querySelector('[data-type="voice-container"]');
|
||||
var message = parentContainer.
|
||||
querySelector('[data-type="voice-message"]');
|
||||
var result = update_network(conn.voice, container, message);
|
||||
}
|
||||
function update_network(network, container, message) {
|
||||
if (!conn || conn.radioState != 'enabled' ||
|
||||
!network || !network.connected || network.emergencyCallsOnly) {
|
||||
container.hidden = true;
|
||||
message.textContent = 'Disconnect';
|
||||
}
|
||||
else {
|
||||
container.querySelector('[data-type="network"]').textContent =
|
||||
network.network.shortName;
|
||||
container.querySelector('[data-type="LAC"]').textContent =
|
||||
network.cell.gsmCellId;
|
||||
container.querySelector('[data-type="CID"]').textContent =
|
||||
network.cell.gsmLocationAreaCode;
|
||||
container.querySelector('[data-type="strength"]').textContent =
|
||||
network.relSignalStrength;
|
||||
container.querySelector('[data-type="type"]').textContent =
|
||||
network.type;
|
||||
container.querySelector('[data-type="roaming"]').textContent =
|
||||
network.roaming;
|
||||
container.hidden = false;
|
||||
message.textContent = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function radioTest() {
|
||||
var iccIdIndex = [];
|
||||
var icc_num = 0;
|
||||
|
||||
if (('mozIccManager' in navigator) &&
|
||||
navigator.mozIccManager &&
|
||||
('mozMobileConnections' in navigator) &&
|
||||
navigator.mozMobileConnections.length > 0) {
|
||||
var iccManager = navigator.mozIccManager;
|
||||
|
||||
// IMEI should be the same no matter which connection is used
|
||||
IMEI(0);
|
||||
|
||||
var template = document.getElementById('connection-template');
|
||||
template.hidden = true;
|
||||
|
||||
if (iccManager.iccIds.length > 0) {
|
||||
for (var i = 0; i < iccManager.iccIds.length; i++) {
|
||||
addIcc(iccManager.iccIds[i], i);
|
||||
showInfo(iccManager.iccIds[i]);
|
||||
}
|
||||
} else {
|
||||
document.getElementById('global-message').textContent =
|
||||
'SIM card not found, insert SIM and turn off airplane mode';
|
||||
}
|
||||
|
||||
iccManager.addEventListener('iccdetected', function(evt) {
|
||||
document.getElementById('global-message').textContent = '';
|
||||
addIcc(evt.iccId);
|
||||
showInfo(evt.iccId);
|
||||
});
|
||||
iccManager.addEventListener('iccundetected', function(evt) {
|
||||
removeIcc(evt.iccId);
|
||||
});
|
||||
}
|
||||
else {
|
||||
alert('navigator.mozIccManager or navigator.mozMobileConnections ' +
|
||||
'not supported');
|
||||
}
|
||||
|
||||
function showInfo(iccId) {
|
||||
var i = iccIdIndex[iccId];
|
||||
var connectionContainer = document.getElementById('connection#' + i);
|
||||
|
||||
// show ICC#
|
||||
connectionContainer.querySelector('[data-type="SIM-number"]')
|
||||
.textContent = i;
|
||||
|
||||
iccInfo(navigator.mozIccManager.getIccById(iccId), connectionContainer);
|
||||
|
||||
mobileConnectionInfo(navigator.mozMobileConnections[i],
|
||||
connectionContainer);
|
||||
}
|
||||
|
||||
function addIcc(iccId) {
|
||||
var connectionContainer = document.getElementById('connection#' + icc_num);
|
||||
if (!connectionContainer) {
|
||||
// copy connection-template then modify it.
|
||||
connectionContainer = template.cloneNode(true);
|
||||
connectionContainer.id = 'connection#' + icc_num;
|
||||
connectionContainer.hidden = false;
|
||||
|
||||
document.getElementById('content').appendChild(connectionContainer);
|
||||
}
|
||||
|
||||
iccIdIndex[iccId] = icc_num;
|
||||
icc_num++;
|
||||
}
|
||||
|
||||
function removeIcc(iccId) {
|
||||
var i = iccIdIndex[iccId];
|
||||
if (i != null) {
|
||||
iccIdIndex[iccId] = null;
|
||||
// re-organize index
|
||||
for (var key in iccIdIndex) {
|
||||
if (iccIdIndex[key] >= i) {
|
||||
iccIdIndex[key]--;
|
||||
}
|
||||
}
|
||||
icc_num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', radioTest);
|
||||
17
gaia/dev_apps/uitest/js/HW/ringer.js
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
'use strict';
|
||||
|
||||
var ringtonePlayer = new Audio();
|
||||
|
||||
// Get ringer file path from settings
|
||||
var phoneSoundURL = new SettingsURL();
|
||||
SettingsListener.observe('dialer.ringtone', '', function(value) {
|
||||
ringtonePlayer.pause();
|
||||
ringtonePlayer.src = phoneSoundURL.set(value);
|
||||
});
|
||||
|
||||
document.body.addEventListener('click', function(evt) {
|
||||
if (evt.target.id == 'ring') {
|
||||
ringtonePlayer.play();
|
||||
}
|
||||
});
|
||||
|
||||
85
gaia/dev_apps/uitest/js/HW/sdcards.js
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
'use strict';
|
||||
|
||||
// Whenever the check button is clicked,
|
||||
// we delete previously displayed result (if any) then show new result
|
||||
function checkSDCards() {
|
||||
var sdcards = navigator.getDeviceStorages('sdcard');
|
||||
document.getElementById('numOfCards').textContent = sdcards.length;
|
||||
|
||||
// cardInfo collection
|
||||
var cardsInfo = document.getElementById('cardsInfo');
|
||||
|
||||
// Clear last result
|
||||
while (cardsInfo.firstChild) {
|
||||
cardsInfo.removeChild(cardsInfo.firstChild);
|
||||
}
|
||||
|
||||
// Show new result
|
||||
sdcards.forEach(function showCards(card, index, cards) {
|
||||
// To add a new SD cardInfo,
|
||||
// first copy one from card_template then modify it.
|
||||
var template = document.getElementById('card_template');
|
||||
var cardInfo = template.cloneNode(true);
|
||||
cardInfo.id = 'card' + index;
|
||||
cardInfo.classList.remove('invisible');
|
||||
|
||||
var cardNo =
|
||||
cardInfo.querySelector('#card' + index + ' > .no > span');
|
||||
var cardStatus =
|
||||
cardInfo.querySelector('#card' + index + ' > .status > span');
|
||||
var cardSpace =
|
||||
cardInfo.querySelector('#card' + index + ' > .space');
|
||||
var cardSpaceTotal =
|
||||
cardInfo.querySelector('#card' + index + ' > .space > .totalSpace');
|
||||
var cardSpaceFree =
|
||||
cardInfo.querySelector('#card' + index + ' > .space > .freeSpace');
|
||||
var cardSpaceUsed =
|
||||
cardInfo.querySelector('#card' + index + ' > .space > .usedSpace');
|
||||
cardNo.textContent = index;
|
||||
|
||||
// Show availability and hide other infomation if not available
|
||||
var reqAvailable = card.available();
|
||||
reqAvailable.onsuccess = function() {
|
||||
cardStatus.textContent = this.result;
|
||||
if (this.result == 'shared' || this.result == 'unavailable') {
|
||||
cardSpace.classList.add('invisible');
|
||||
}
|
||||
};
|
||||
reqAvailable.onerror = function() {
|
||||
cardStatus.textContent = 'Unable to get sdcard status' + this.error.name;
|
||||
};
|
||||
|
||||
// Show space info.
|
||||
// If the other space info is already updated, show total space
|
||||
var reqFree = card.freeSpace();
|
||||
reqFree.onsuccess = function() {
|
||||
var spaceGB = this.result / Math.pow(10, 9);
|
||||
cardSpaceFree.textContent = spaceGB;
|
||||
if (cardSpaceTotal.textContent == '') {
|
||||
cardSpaceTotal.textContent = spaceGB;
|
||||
}
|
||||
else {
|
||||
cardSpaceTotal.textContent =
|
||||
parseFloat(cardSpaceTotal.textContent) + spaceGB;
|
||||
}
|
||||
};
|
||||
var reqUsed = card.usedSpace();
|
||||
reqUsed.onsuccess = function() {
|
||||
var spaceGB = this.result / Math.pow(10, 9);
|
||||
cardSpaceUsed.textContent = spaceGB;
|
||||
if (cardSpaceTotal.textContent == '') {
|
||||
cardSpaceTotal.textContent = spaceGB;
|
||||
}
|
||||
else {
|
||||
cardSpaceTotal.textContent =
|
||||
parseFloat(cardSpaceTotal.textContent) + spaceGB;
|
||||
}
|
||||
};
|
||||
|
||||
cardsInfo.appendChild(cardInfo);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
document.getElementById('check').addEventListener('click', checkSDCards);
|
||||
});
|
||||
67
gaia/dev_apps/uitest/js/HW/sensors.js
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
'use strict';
|
||||
|
||||
function sensorTest() {
|
||||
var interval = document.getElementById('interval');
|
||||
var accelerationX = document.getElementById('acceleration-x');
|
||||
var accelerationY = document.getElementById('acceleration-y');
|
||||
var accelerationZ = document.getElementById('acceleration-z');
|
||||
var accelerationGX = document.getElementById('acceleration-gravity-x');
|
||||
var accelerationGY = document.getElementById('acceleration-gravity-y');
|
||||
var accelerationGZ = document.getElementById('acceleration-gravity-z');
|
||||
var rotAlpha = document.getElementById('rot-rate-alpha');
|
||||
var rotBeta = document.getElementById('rot-rate-beta');
|
||||
var rotGamma = document.getElementById('rot-rate-gamma');
|
||||
var orientationAlpha = document.getElementById('orientation-alpha');
|
||||
var orientationBeta = document.getElementById('orientation-beta');
|
||||
var orientationGamma = document.getElementById('orientation-gamma');
|
||||
var proximityMin = document.getElementById('proximity-min');
|
||||
var proximityMax = document.getElementById('proximity-max');
|
||||
var proximityValue = document.getElementById('proximity-value');
|
||||
var compassCalibration = document.getElementById('compassneedscalibration');
|
||||
|
||||
window.addEventListener('devicemotion', function(e) {
|
||||
interval.textContent = e.interval;
|
||||
|
||||
if (e.acceleration) {
|
||||
accelerationX.textContent = e.acceleration.x;
|
||||
accelerationY.textContent = e.acceleration.y;
|
||||
accelerationZ.textContent = e.acceleration.z;
|
||||
}
|
||||
|
||||
if (e.accelerationIncludingGravity) {
|
||||
accelerationGX.textContent = e.accelerationIncludingGravity.x;
|
||||
accelerationGY.textContent = e.accelerationIncludingGravity.y;
|
||||
accelerationGZ.textContent = e.accelerationIncludingGravity.z;
|
||||
}
|
||||
|
||||
if (e.rotationRate) {
|
||||
rotAlpha.textContent = e.rotationRate.alpha;
|
||||
rotBeta.textContent = e.rotationRate.beta;
|
||||
rotGamma.textContent = e.rotationRate.gamma;
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.addEventListener('deviceorientation', function(e) {
|
||||
if (e) {
|
||||
orientationAlpha.textContent = e.alpha;
|
||||
orientationBeta.textContent = e.beta;
|
||||
orientationGamma.textContent = e.gamma;
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.addEventListener('devicelight', function(event) {
|
||||
document.getElementById('light').textContent = event.value;
|
||||
});
|
||||
|
||||
window.addEventListener('deviceproximity', function(event) {
|
||||
proximityMin.textContent = event.min;
|
||||
proximityMax.textContent = event.max;
|
||||
proximityValue.textContent = event.value;
|
||||
});
|
||||
|
||||
window.addEventListener('compassneedscalibration', function(e) {
|
||||
compassCalibration.textContent = 'true';
|
||||
}, false);
|
||||
}
|
||||
|
||||
window.addEventListener('load', sensorTest);
|
||||
448
gaia/dev_apps/uitest/js/HW/touchscreen.js
Executable file
|
|
@ -0,0 +1,448 @@
|
|||
'use strict';
|
||||
|
||||
// test result indicator
|
||||
var Status = {
|
||||
NOT_FINISHED: 1,
|
||||
FINISHED: 2,
|
||||
ABORT: 3
|
||||
};
|
||||
|
||||
// UTILS
|
||||
var util = {
|
||||
// Use this function to get correct click position on canvas
|
||||
relMouseCoords: function(canvas, evt) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var eventX = evt.clientX - rect.left;
|
||||
var eventY = evt.clientY - rect.top;
|
||||
return {x: eventX, y: eventY};
|
||||
},
|
||||
|
||||
clearScreen: function(ctx) {
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
},
|
||||
|
||||
drawRectFromCoord: function(ctx, x1, y1, x2, y2) {
|
||||
ctx.translate(0.5, 0.5);
|
||||
ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
|
||||
ctx.translate(-0.5, -0.5);
|
||||
},
|
||||
|
||||
// Fill rect without overlapping border,
|
||||
fillRectFromCoord: function(ctx, x1, y1, x2, y2) {
|
||||
ctx.fillRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1);
|
||||
},
|
||||
|
||||
drawCircle: function(ctx, x, y, radius, width, color) {
|
||||
ctx.lineWidth = width;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.beginPath();
|
||||
ctx.translate(0.5, 0.5);
|
||||
ctx.arc(x, y, radius, 0, 2 * Math.PI);
|
||||
ctx.translate(-0.5, -0.5);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
},
|
||||
|
||||
distance_sqr: function(x1, y1, x2, y2) {
|
||||
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
|
||||
},
|
||||
|
||||
// Return the index less or equal to num
|
||||
binary_search: function(arr, num) {
|
||||
var begin = 0;
|
||||
var end = arr.length - 1;
|
||||
while (begin < end) {
|
||||
var pivot = Math.round((begin + end) / 2);
|
||||
if (num < arr[pivot]) {
|
||||
end = pivot - 1;
|
||||
}
|
||||
else if (num > arr[pivot]) {
|
||||
begin = pivot + 1;
|
||||
}
|
||||
else {
|
||||
return pivot;
|
||||
}
|
||||
}
|
||||
if (num < arr[begin]) {
|
||||
return begin - 1;
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
};
|
||||
|
||||
// TEST 1
|
||||
// Draw 4 circles on the corners and 1 circle in the center
|
||||
var test1 = function(canvas) {
|
||||
var ctx = canvas.getContext('2d');
|
||||
var circle_radius = Math.min(canvas.width, canvas.height) * 0.1;
|
||||
var circles_coord =
|
||||
[[circle_radius, circle_radius],
|
||||
[circle_radius, canvas.height - circle_radius],
|
||||
[canvas.width - circle_radius, circle_radius],
|
||||
[canvas.width - circle_radius, canvas.height - circle_radius],
|
||||
[canvas.width / 2, canvas.height / 2]];
|
||||
var lineWidth = 2;
|
||||
var lineColor = 'red';
|
||||
var lineColorClicked = 'lime';
|
||||
var is_clicked = [];
|
||||
|
||||
var exitIconPositionX;
|
||||
var exitIconPositionY;
|
||||
var exitIconWidth;
|
||||
var exitIconHeight;
|
||||
|
||||
(function init() {
|
||||
util.clearScreen(ctx);
|
||||
|
||||
// Draw not-clicked circle
|
||||
for (var i = 0; i < circles_coord.length; i++) {
|
||||
util.drawCircle(ctx, circles_coord[i][0], circles_coord[i][1],
|
||||
circle_radius, lineWidth, lineColor);
|
||||
is_clicked[i] = false;
|
||||
}
|
||||
// Draw exit icon
|
||||
var image = document.getElementById('icon-exit');
|
||||
exitIconWidth = image.width;
|
||||
exitIconHeight = image.height;
|
||||
// Draw icon below center
|
||||
exitIconPositionX = (canvas.width - exitIconWidth) / 2;
|
||||
exitIconPositionY = canvas.height * 0.65;
|
||||
ctx.drawImage(image, exitIconPositionX, exitIconPositionY);
|
||||
})();
|
||||
|
||||
// Touch test, change circle color if touch point is in the circle.
|
||||
// Test ends if all circles are touched
|
||||
this.test = function(x, y) {
|
||||
// Clicked on exit button
|
||||
if (x > exitIconPositionX && x <= exitIconPositionX + exitIconWidth &&
|
||||
y > exitIconPositionY && y <= exitIconPositionY + exitIconHeight) {
|
||||
return Status.ABORT;
|
||||
}
|
||||
for (var i = 0; i < circles_coord.length; i++) {
|
||||
if (!is_clicked[i] &&
|
||||
util.distance_sqr(x, y, circles_coord[i][0], circles_coord[i][1]) <
|
||||
circle_radius * circle_radius) {
|
||||
// Clear red circle by covering a bigger white circle on it
|
||||
util.drawCircle(ctx, circles_coord[i][0], circles_coord[i][1],
|
||||
circle_radius, lineWidth + 2, 'white');
|
||||
// Draw new circle
|
||||
util.drawCircle(ctx, circles_coord[i][0], circles_coord[i][1],
|
||||
circle_radius, lineWidth, lineColorClicked);
|
||||
|
||||
is_clicked[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < circles_coord.length; i++) {
|
||||
if (!is_clicked[i]) {
|
||||
return Status.NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
// Test over
|
||||
return Status.FINISHED;
|
||||
};
|
||||
};
|
||||
|
||||
// TEST 2
|
||||
// Draw several cubes on the edge of screen
|
||||
var test2 = function(canvas) {
|
||||
var ctx = canvas.getContext('2d');
|
||||
var aspect = canvas.width / canvas.height;
|
||||
var cubes_num_vertical = 20;
|
||||
var cubes_num_horizontal = Math.round(cubes_num_vertical * aspect);
|
||||
var cube_width = canvas.width / cubes_num_horizontal;
|
||||
var cube_height = canvas.height / cubes_num_vertical;
|
||||
|
||||
var cube_coord_x = [];
|
||||
var cube_coord_y = [];
|
||||
var is_clicked_top = [];
|
||||
var is_clicked_bottom = [];
|
||||
var is_clicked_left = [];
|
||||
var is_clicked_right = [];
|
||||
var total_clicked = 0;
|
||||
|
||||
var exitIconPositionX;
|
||||
var exitIconPositionY;
|
||||
var exitIconWidth;
|
||||
var exitIconHeight;
|
||||
|
||||
(function init() {
|
||||
util.clearScreen(ctx);
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.fillStyle = 'lime';
|
||||
ctx.lineWidth = 1;
|
||||
|
||||
// Because width/height of screen can not be divided evenly
|
||||
// So we precaculate the grid (coordination) of cubes for future use
|
||||
for (var i = 0; i < cubes_num_horizontal; i++) {
|
||||
cube_coord_x[i] = Math.round(cube_width * i);
|
||||
}
|
||||
cube_coord_x[cubes_num_horizontal] = canvas.width - 1;
|
||||
for (var i = 0; i < cubes_num_vertical; i++) {
|
||||
cube_coord_y[i] = Math.round(cube_height * i);
|
||||
}
|
||||
cube_coord_y[cubes_num_vertical] = canvas.height - 1;
|
||||
|
||||
// Draw Top/Bottom/Left/Right cubes
|
||||
for (var i = 0; i < cubes_num_horizontal; i++) {
|
||||
util.drawRectFromCoord(ctx, cube_coord_x[i], cube_coord_y[0],
|
||||
cube_coord_x[i + 1], cube_coord_y[1]);
|
||||
is_clicked_top[i] = false;
|
||||
}
|
||||
for (var i = 0; i < cubes_num_horizontal; i++) {
|
||||
util.drawRectFromCoord(ctx,
|
||||
cube_coord_x[i],
|
||||
cube_coord_y[cubes_num_vertical - 1],
|
||||
cube_coord_x[i + 1],
|
||||
cube_coord_y[cubes_num_vertical]);
|
||||
is_clicked_bottom[i] = false;
|
||||
}
|
||||
for (var i = 0; i < cubes_num_vertical; i++) {
|
||||
util.drawRectFromCoord(ctx,
|
||||
cube_coord_x[0],
|
||||
cube_coord_y[i],
|
||||
cube_coord_x[1],
|
||||
cube_coord_y[i + 1]);
|
||||
is_clicked_left[i] = false;
|
||||
}
|
||||
for (var i = 0; i < cubes_num_vertical; i++) {
|
||||
util.drawRectFromCoord(ctx,
|
||||
cube_coord_x[cubes_num_horizontal - 1],
|
||||
cube_coord_y[i],
|
||||
cube_coord_x[cubes_num_horizontal],
|
||||
cube_coord_y[i + 1]);
|
||||
is_clicked_right[i] = false;
|
||||
}
|
||||
|
||||
// Draw exit icon
|
||||
var image = document.getElementById('icon-exit');
|
||||
exitIconWidth = image.width;
|
||||
exitIconHeight = image.height;
|
||||
exitIconPositionX = (canvas.width - exitIconWidth) / 2;
|
||||
exitIconPositionY = (canvas.height - exitIconHeight) / 2;
|
||||
ctx.drawImage(image, exitIconPositionX, exitIconPositionY);
|
||||
}
|
||||
)();
|
||||
|
||||
// Touch test, fill cubes if touch point is in the cube.
|
||||
// Test ends if all cubes are touched
|
||||
this.test = function(x, y) {
|
||||
// Clicked on exit button
|
||||
if (x > exitIconPositionX && x <= exitIconPositionX + exitIconWidth &&
|
||||
y > exitIconPositionY && y <= exitIconPositionY + exitIconHeight) {
|
||||
return Status.ABORT;
|
||||
}
|
||||
|
||||
if (cube_coord_x[1] <= x && x <= cube_coord_x[cubes_num_horizontal - 1] &&
|
||||
cube_coord_y[1] <= y && y <= cube_coord_y[cubes_num_vertical - 1]) {
|
||||
return Status.NOT_FINISHED;
|
||||
}
|
||||
|
||||
var startXi = util.binary_search(cube_coord_x, x);
|
||||
var startYi = util.binary_search(cube_coord_y, y);
|
||||
util.fillRectFromCoord(ctx,
|
||||
cube_coord_x[startXi],
|
||||
cube_coord_y[startYi],
|
||||
cube_coord_x[startXi + 1],
|
||||
cube_coord_y[startYi + 1]);
|
||||
if (startYi == 0 && !is_clicked_top[startXi]) {
|
||||
is_clicked_top[startXi] = true;
|
||||
}
|
||||
if (startYi == cubes_num_vertical - 1 && !is_clicked_bottom[startXi]) {
|
||||
is_clicked_bottom[startXi] = true;
|
||||
}
|
||||
if (startXi == 0 && !is_clicked_left[startYi]) {
|
||||
is_clicked_left[startYi] = true;
|
||||
}
|
||||
if (startXi == cubes_num_horizontal - 1 && !is_clicked_right[startYi]) {
|
||||
is_clicked_right[startYi] = true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < cubes_num_vertical; i++) {
|
||||
if (!is_clicked_left[i] || !is_clicked_right[i]) {
|
||||
return Status.NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < cubes_num_horizontal; i++) {
|
||||
if (!is_clicked_top[i] || !is_clicked_bottom[i]) {
|
||||
return Status.NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
// Test over
|
||||
return Status.FINISHED;
|
||||
};
|
||||
};
|
||||
|
||||
var test_driver = function() {
|
||||
var current_test = null;
|
||||
var canvas = document.getElementById('canvas');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
canvas.style.width = canvas.width + 'px';
|
||||
canvas.style.height = canvas.height + 'px';
|
||||
|
||||
// returns true if no other tests
|
||||
function proceed() {
|
||||
if (current_test == null) {
|
||||
current_test = new test1(canvas);
|
||||
return false;
|
||||
}
|
||||
else if (current_test instanceof test1) {
|
||||
current_test = new test2(canvas);
|
||||
return false;
|
||||
}
|
||||
else if (current_test instanceof test2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
proceed();
|
||||
|
||||
// returns whether all tests are finished
|
||||
this.touch = function(x, y) {
|
||||
var touchResult = current_test.test(x, y);
|
||||
if (touchResult == Status.ABORT) {
|
||||
return Status.ABORT;
|
||||
}
|
||||
// one test finished, go on next test
|
||||
if (touchResult == Status.FINISHED) {
|
||||
var isAllFinished = proceed();
|
||||
if (isAllFinished) {
|
||||
return Status.FINISHED;
|
||||
}
|
||||
}
|
||||
return Status.NOT_FINISHED;
|
||||
};
|
||||
};
|
||||
|
||||
// Handle touch input, Codes modified from
|
||||
// https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Events/Touch_events
|
||||
var touchTest = function() {
|
||||
var ongoingTouches = [];
|
||||
var driver = null;
|
||||
var canvas = null;
|
||||
|
||||
function copyTouch(touch) {
|
||||
return { identifier: touch.identifier,
|
||||
pageX: touch.pageX,
|
||||
pageY: touch.pageY };
|
||||
}
|
||||
|
||||
function ongoingTouchIndexById(idToFind) {
|
||||
for (var i = 0; i < ongoingTouches.length; i++) {
|
||||
var id = ongoingTouches[i].identifier;
|
||||
|
||||
if (id == idToFind) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
function handleEvent(evt) {
|
||||
var touches = evt.changedTouches;
|
||||
var result;
|
||||
evt.preventDefault();
|
||||
|
||||
switch (evt.type) {
|
||||
case 'touchstart':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
ongoingTouches.push(copyTouch(touches[i]));
|
||||
var coord = util.relMouseCoords(canvas, touches[i]);
|
||||
result = driver.touch(coord.x, coord.y);
|
||||
}
|
||||
break;
|
||||
case 'touchmove':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
var coord = util.relMouseCoords(canvas, touches[i]);
|
||||
var idx = ongoingTouchIndexById(touches[i].identifier);
|
||||
|
||||
if (idx >= 0) {
|
||||
var coord_last = util.relMouseCoords(canvas, ongoingTouches[idx]);
|
||||
result = driver.touch(coord.x, coord.y);
|
||||
// swap in the new touch record
|
||||
ongoingTouches.splice(idx, 1, copyTouch(touches[i]));
|
||||
} else {
|
||||
console.log('can\'t figure out which touch to continue');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'touchend':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
var coord = util.relMouseCoords(canvas, touches[i]);
|
||||
var idx = ongoingTouchIndexById(touches[i].identifier);
|
||||
|
||||
if (idx >= 0) {
|
||||
ongoingTouches.splice(i, 1); // remove it; we're done
|
||||
} else {
|
||||
console.log('can\'t figure out which touch to end');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'touchcancel':
|
||||
for (var i = 0; i < touches.length; i++) {
|
||||
ongoingTouches.splice(i, 1); // remove it; we're done
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// All tests over
|
||||
if (result == Status.FINISHED || result == Status.ABORT) {
|
||||
// Clear remaining touches
|
||||
touches = null;
|
||||
canvas.removeEventListener('touchstart', handleEvent, false);
|
||||
canvas.removeEventListener('touchend', handleEvent, false);
|
||||
canvas.removeEventListener('touchcancel', handleEvent, false);
|
||||
canvas.removeEventListener('touchleave', handleEvent, false);
|
||||
canvas.removeEventListener('touchmove', handleEvent, false);
|
||||
console.log('uninitialized.');
|
||||
|
||||
if (result == Status.ABORT) {
|
||||
alert('Test terminated by user');
|
||||
} else {
|
||||
alert('Test Success!');
|
||||
}
|
||||
document.mozCancelFullScreen();
|
||||
// This is a hack to close touch test, uitest.js will close this iframe
|
||||
window.parent.window.location.hash = '';
|
||||
}
|
||||
}
|
||||
|
||||
this.init = function() {
|
||||
driver = new test_driver();
|
||||
|
||||
if (canvas == null) {
|
||||
canvas = document.getElementsByTagName('canvas')[0];
|
||||
canvas.addEventListener('touchstart', handleEvent, false);
|
||||
canvas.addEventListener('touchend', handleEvent, false);
|
||||
canvas.addEventListener('touchcancel', handleEvent, false);
|
||||
canvas.addEventListener('touchleave', handleEvent, false);
|
||||
canvas.addEventListener('touchmove', handleEvent, false);
|
||||
console.log('initialized.');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// XXX: There is a problem of getting into fullscreen
|
||||
// When we called mozRequestFullscreen, it actually resized two times.
|
||||
// We get almost fullscreen (except status bar) after first event, and truely
|
||||
// fullscreen after second event. So we need to wait for the second event.
|
||||
var resizedTimes = 0;
|
||||
window.addEventListener('resize', function startTest() {
|
||||
if (resizedTimes < 1) {
|
||||
resizedTimes++;
|
||||
}
|
||||
else {
|
||||
window.removeEventListener('resize', startTest);
|
||||
var test = new touchTest;
|
||||
test.init();
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
document.getElementById('canvas').classList.remove('invisible');
|
||||
var exitButton = document.getElementById('fullscreen-exit');
|
||||
document.body.mozRequestFullScreen();
|
||||
});
|
||||
54
gaia/dev_apps/uitest/js/HW/vibrator.js
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
'use strict';
|
||||
|
||||
function vibratorTest() {
|
||||
var durationText = document.getElementById('duration-text');
|
||||
var duration = document.getElementById('duration');
|
||||
var timesText = document.getElementById('times-text');
|
||||
var times = document.getElementById('times');
|
||||
|
||||
var clickHandlers = {
|
||||
'off': function() {
|
||||
window.navigator.vibrate(0);
|
||||
},
|
||||
'one-short': function() {
|
||||
window.navigator.vibrate(200);
|
||||
},
|
||||
'two-short': function() {
|
||||
window.navigator.vibrate([200, 100, 200, 100]);
|
||||
},
|
||||
'one-long': function() {
|
||||
window.navigator.vibrate(10000);
|
||||
},
|
||||
'custom-pattern': function() {
|
||||
var timesNum = parseInt(times.value);
|
||||
var pattern = [];
|
||||
for (var i = 0; i < timesNum * 2; i++) {
|
||||
pattern.push(parseInt(duration.value));
|
||||
}
|
||||
window.navigator.vibrate(pattern);
|
||||
}
|
||||
};
|
||||
|
||||
// Update text when sliding bar is changed
|
||||
var changeHandlers = {
|
||||
'duration': function() {
|
||||
durationText.textContent = duration.value;
|
||||
},
|
||||
'times': function() {
|
||||
timesText.textContent = times.value;
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', function(evt) {
|
||||
if (clickHandlers[evt.target.id]) {
|
||||
clickHandlers[evt.target.id].call(this, evt);
|
||||
}
|
||||
});
|
||||
document.body.addEventListener('input', function(evt) {
|
||||
if (changeHandlers[evt.target.id]) {
|
||||
changeHandlers[evt.target.id].call(this, evt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', vibratorTest);
|
||||
37
gaia/dev_apps/uitest/js/HW/wifi.js
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
function wifiTest() {
|
||||
var WiFiMACText = document.getElementById('address');
|
||||
var WiFiStateText = document.getElementById('state');
|
||||
var switchButton = document.getElementById('switch');
|
||||
|
||||
var settings = window.navigator.mozSettings;
|
||||
var wifiManager;
|
||||
function update() {
|
||||
switchButton.checked = wifiManager.enabled;
|
||||
if (wifiManager.enabled) {
|
||||
WiFiStateText.textContent = 'On';
|
||||
WiFiMACText.textContent = wifiManager.macAddress;
|
||||
}
|
||||
else {
|
||||
WiFiStateText.textContent = 'Off';
|
||||
WiFiMACText.textContent = 'Not available';
|
||||
}
|
||||
}
|
||||
if ('mozWifiManager' in navigator) {
|
||||
wifiManager = navigator.mozWifiManager;
|
||||
// navigator.mozWifiManager does not have addEventListener()
|
||||
wifiManager.onenabled = update.bind(this);
|
||||
wifiManager.ondisabled = update.bind(this);
|
||||
update();
|
||||
}
|
||||
// Click on switch will only update settings and
|
||||
// it takes some time for hardware to turns on.
|
||||
// That's why we should listen to enabled/disabled event of wifi
|
||||
function wifiSwitch() {
|
||||
settings.createLock().set({'wifi.enabled': switchButton.checked});
|
||||
}
|
||||
switchButton.addEventListener('click', wifiSwitch);
|
||||
}
|
||||
|
||||
window.addEventListener('load', wifiTest);
|
||||
42
gaia/dev_apps/uitest/js/UI/alert.js
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
'use strict';
|
||||
|
||||
var clickHandlers = {
|
||||
'button1': function() {
|
||||
window.parent.alert('Hello world!');
|
||||
},
|
||||
'button2': function() {
|
||||
window.parent.alert(window.parent.confirm('Hello world?'));
|
||||
},
|
||||
'button3': function() {
|
||||
window.parent.alert(window.parent.prompt('Hello world:', 'initial value'));
|
||||
},
|
||||
'button21': function() {
|
||||
alert('Hello world!');
|
||||
},
|
||||
'button22': function() {
|
||||
alert(confirm('Hello world?'));
|
||||
},
|
||||
'button23': function() {
|
||||
alert(prompt('Hello world:', 'initial value'));
|
||||
},
|
||||
'button31': function() {
|
||||
var msg = 'Hello world!1\n2\n3\n4\n5\n6\n7\n8\n9';
|
||||
msg += '\n10\n11\n12\n13\n14\n15\n16\n17\n18\n';
|
||||
alert(msg);
|
||||
},
|
||||
'button32': function() {
|
||||
var msg = 'Hello world!1\n2\n3\n4\n5\n6\n7\n8\n9';
|
||||
msg += '\n10\n11\n12\n13\n14\n15\n16\n17\n18\n';
|
||||
alert(confirm(msg));
|
||||
},
|
||||
'button33': function() {
|
||||
var msg = 'Hello world!1\n2\n3\n4\n5\n6\n7\n8\n9';
|
||||
msg += '\n10\n11\n12\n13\n14\n15\n16\n17\n18\n';
|
||||
alert(prompt(msg));
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', function(evt) {
|
||||
if (clickHandlers[evt.target.id])
|
||||
clickHandlers[evt.target.id].call(this, evt);
|
||||
});
|
||||
59
gaia/dev_apps/uitest/js/UI/canvas.js
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
'use strict';
|
||||
|
||||
var CanvasTests = {
|
||||
|
||||
get drawButton() {
|
||||
delete this.drawButton;
|
||||
return this.drawButton = document.getElementById('button-draw');
|
||||
},
|
||||
|
||||
get toggleHiddenButton() {
|
||||
delete this.toggleHiddenButton;
|
||||
return this.toggleHiddenButton =
|
||||
document.getElementById('button-toggle-hidden');
|
||||
},
|
||||
|
||||
get canvas() {
|
||||
delete this.canvas;
|
||||
return this.canvas = document.getElementById('canvas');
|
||||
},
|
||||
|
||||
get hiddenStatus() {
|
||||
delete this.hiddenStatus;
|
||||
return this.hiddenStatus = document.getElementById('hidden-status');
|
||||
},
|
||||
|
||||
init: function ct_init() {
|
||||
this.hiddenStatus.innerHTML =
|
||||
'hidden = ' +
|
||||
this.canvas.classList.contains('hidden');
|
||||
|
||||
this.drawButton.addEventListener('click', this.draw.bind(this));
|
||||
this.toggleHiddenButton.addEventListener('click',
|
||||
this.toggleShowHide.bind(this));
|
||||
},
|
||||
|
||||
draw: function ct_draw() {
|
||||
// var element = document.getElementById('canvas');
|
||||
var context = this.canvas.getContext('2d');
|
||||
var image = new Image();
|
||||
var path = '../../style/images/canardpc.jpg';
|
||||
image.src = path;
|
||||
var self = this;
|
||||
image.onload = function() {
|
||||
var w = image.width;
|
||||
var h = image.height;
|
||||
context.drawImage(image, 0, 0, w, h, 0, 0, w, h);
|
||||
};
|
||||
},
|
||||
|
||||
toggleShowHide: function ct_toggleShowHide() {
|
||||
this.canvas.classList.toggle('hidden');
|
||||
var status = this.canvas.classList.contains('hidden');
|
||||
this.hiddenStatus.innerHTML = 'hidden = ' + status;
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
CanvasTests.init();
|
||||
});
|
||||
24
gaia/dev_apps/uitest/js/UI/contextmenu.js
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
var clickHandlers = {
|
||||
'reload': function() {
|
||||
window.location.reload();
|
||||
},
|
||||
'comments': function() {
|
||||
window.location = '#comments';
|
||||
alert(window.location.href);
|
||||
},
|
||||
'twitter': function() {
|
||||
window.open('http://twitter.com/intent/tweet?text=' +
|
||||
document.title + ': ' + window.location.href, 'shareWindow');
|
||||
},
|
||||
'facebook': function() {
|
||||
window.open('http://facebook.com/sharer/sharer.php?u=' +
|
||||
window.location.href, 'shareWindow');
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
});
|
||||
19
gaia/dev_apps/uitest/js/UI/css_dimension.js
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
function css_dimension_test() {
|
||||
var bar_inch = document.getElementById('bar_inch');
|
||||
var bar_mm = document.getElementById('bar_mm');
|
||||
var bar_px = document.getElementById('bar_px');
|
||||
var bar_mozmm = document.getElementById('bar_mozmm');
|
||||
|
||||
bar_inch.style.width = '1in';
|
||||
bar_inch.style.backgroundColor = '#00FF00';
|
||||
bar_mm.style.width = '25.4mm';
|
||||
bar_mm.style.backgroundColor = '#00DD44';
|
||||
bar_px.style.width = '96px';
|
||||
bar_px.style.backgroundColor = '#00BB88';
|
||||
bar_mozmm.style.width = '25.4mozmm';
|
||||
bar_mozmm.style.backgroundColor = '#0099CC';
|
||||
}
|
||||
|
||||
window.addEventListener('load', css_dimension_test);
|
||||
13
gaia/dev_apps/uitest/js/UI/empty.js
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
var clickHandlers = {
|
||||
/*
|
||||
'id': function () {
|
||||
alert('event triggered!');
|
||||
}, */
|
||||
};
|
||||
|
||||
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);
|
||||
});
|
||||
45
gaia/dev_apps/uitest/js/UI/fullscreen.js
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
function fullscreenTest() {
|
||||
var fullscreenDiv = document.getElementById('fullscreen-div');
|
||||
|
||||
var testBtnDiv = document.getElementById('testBtn-div');
|
||||
var testBtn = document.getElementById('testBtn');
|
||||
var isFullscreenDiv = false;
|
||||
var isFullscreen = false;
|
||||
var displayMode;
|
||||
|
||||
function clickHandlers(evt) {
|
||||
switch (evt.target.id) {
|
||||
case 'testBtn':
|
||||
if (!isFullscreen) {
|
||||
window.parent.document.getElementById('test-iframe')
|
||||
.mozRequestFullScreen();
|
||||
testBtn.textContent = 'Cancel fullscreen';
|
||||
} else {
|
||||
window.parent.document.mozCancelFullScreen();
|
||||
testBtn.textContent = 'Test';
|
||||
}
|
||||
isFullscreen = !isFullscreen;
|
||||
break;
|
||||
case 'testBtn-div':
|
||||
if (!isFullscreenDiv) {
|
||||
fullscreenDiv.mozRequestFullScreen();
|
||||
testBtnDiv.textContent = 'Cancel fullscreen';
|
||||
} else {
|
||||
document.mozCancelFullScreen();
|
||||
testBtnDiv.textContent = 'Test';
|
||||
|
||||
// Also cancels fullscreen of caused by another button (if any)
|
||||
isFullscreen = false;
|
||||
testBtn.textContent = 'Test';
|
||||
}
|
||||
isFullscreenDiv = !isFullscreenDiv;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
document.body.addEventListener('click', clickHandlers.bind(this));
|
||||
}
|
||||
|
||||
window.addEventListener('load', fullscreenTest);
|
||||
29
gaia/dev_apps/uitest/js/UI/keyboard.js
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
function keyboardTest() {
|
||||
(function designmode(id) {
|
||||
var iframe = document.querySelector('#' + id);
|
||||
iframe.contentDocument.designMode = 'on';
|
||||
iframe.contentDocument.body.textContent = 'Hola supermercado';
|
||||
})('iframe-designmode');
|
||||
|
||||
(function contentEditable(id) {
|
||||
var iframe = document.querySelector('#' + id);
|
||||
iframe.contentDocument.body.setAttribute('contenteditable', true);
|
||||
iframe.contentDocument.body.textContent = 'Telebancos por aqui';
|
||||
})('iframe-contenteditable');
|
||||
|
||||
var readme = document.getElementById('readme');
|
||||
var readmeBtn = document.getElementById('readme_button');
|
||||
readme.hidden = true;
|
||||
|
||||
readmeBtn.addEventListener('click',
|
||||
function toggle_readme() {
|
||||
readme.hidden = !readme.hidden;
|
||||
if (readme.hidden) {
|
||||
readmeBtn.textContent = 'Show README';
|
||||
} else {
|
||||
readmeBtn.textContent = 'Hide README';
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
window.addEventListener('load', keyboardTest);
|
||||
64
gaia/dev_apps/uitest/js/UI/newnotification.js
Executable file
64
gaia/dev_apps/uitest/js/UI/notification.js
Executable file
19
gaia/dev_apps/uitest/js/UI/popup.js
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
document.getElementById('close').onclick = function() {
|
||||
window.close();
|
||||
};
|
||||
|
||||
document.getElementById('open').onclick = function() {
|
||||
window.open('/tests_html/UI/popup.html', '', 'dialog');
|
||||
};
|
||||
|
||||
window.addEventListener('resize', function() {
|
||||
if (window.innerHeight > 60) {
|
||||
document.body.style.backgroundColor = 'white';
|
||||
document.body.style.fontSize = '20px';
|
||||
document.body.style.color = 'black';
|
||||
} else {
|
||||
document.body.style.backgroundColor = 'green';
|
||||
document.body.style.fontSize = '10px';
|
||||
document.body.style.color = 'white';
|
||||
}
|
||||
});
|
||||
6
gaia/dev_apps/uitest/js/UI/scrollbar.js
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
window.addEventListener('load', function() {
|
||||
var p = document.getElementById('probe');
|
||||
document.getElementById('report').textContent =
|
||||
'Scroll bar width calculated from Javascript: ' +
|
||||
(p.offsetWidth - p.scrollWidth - 2) + 'px'; // 2 = border width * 2
|
||||
});
|
||||
16
gaia/dev_apps/uitest/js/UI/select.js
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
function changeTest(evt) {
|
||||
console.log('++select++ onchange: ' + this.selectedIndex);
|
||||
}
|
||||
|
||||
function blurTest(evt) {
|
||||
console.log('++select++ onblur: ' + this.id);
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
var elementList = ['singleSel', 'multiSel', 'sizeSel'];
|
||||
elementList.forEach(function(elementId) {
|
||||
console.log('elementId: ' + elementId);
|
||||
document.getElementById(elementId).onchange = changeTest;
|
||||
document.getElementById(elementId).addEventListener('blur', blurTest);
|
||||
});
|
||||
});
|
||||
35
gaia/dev_apps/uitest/js/UI/window_open.js
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
'use strict';
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
var popup = null;
|
||||
var buttons = document.querySelectorAll('button');
|
||||
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var button = buttons[i];
|
||||
button.addEventListener('click', function(e) {
|
||||
var target = e.target;
|
||||
var actualWindow = window;
|
||||
if (target.classList.contains('mozbrowser')) {
|
||||
actualWindow = window.parent;
|
||||
}
|
||||
|
||||
switch (target.dataset.action) {
|
||||
case 'open':
|
||||
var param1 = null,
|
||||
param2 = null;
|
||||
var hash = target.dataset.url.split('#');
|
||||
if (hash.length > 1) {
|
||||
param1 = hash[1];
|
||||
param2 = hash[1];
|
||||
}
|
||||
popup = actualWindow.open(target.dataset.url, param1, param2);
|
||||
break;
|
||||
case 'close':
|
||||
popup.close();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
184
gaia/dev_apps/uitest/js/uitest.js
Executable file
|
|
@ -0,0 +1,184 @@
|
|||
'use stricts';
|
||||
|
||||
var UITest = {
|
||||
get UItests() {
|
||||
delete this.UItests;
|
||||
return this.UItests = document.getElementById('UI-tests');
|
||||
},
|
||||
get APItests() {
|
||||
delete this.APItests;
|
||||
return this.APItests = document.getElementById('API-tests');
|
||||
},
|
||||
get HWtests() {
|
||||
delete this.HWtests;
|
||||
return this.HWtests = document.getElementById('HW-tests');
|
||||
},
|
||||
get iframe() {
|
||||
delete this.iframe;
|
||||
return this.iframe = document.getElementById('test-iframe');
|
||||
},
|
||||
get backHeader() {
|
||||
delete this.backHeader;
|
||||
return this.backHeader = document.getElementById('test-panel-header');
|
||||
},
|
||||
get panelTitle() {
|
||||
delete this.panelTitle;
|
||||
return this.panelTitle = document.getElementById('test-panel-title');
|
||||
},
|
||||
get tabs() {
|
||||
delete this.tabs;
|
||||
return this.tabs = document.querySelectorAll('[role="tab"]');
|
||||
},
|
||||
get UITab() {
|
||||
delete this.UITab;
|
||||
return this.UITab = document.getElementById('UI');
|
||||
},
|
||||
get APITab() {
|
||||
delete this.APITab;
|
||||
return this.APITab = document.getElementById('API');
|
||||
},
|
||||
get HWTab() {
|
||||
delete this.HWTab;
|
||||
return this.HWTab = document.getElementById('HW');
|
||||
},
|
||||
currentTab: 'UI',
|
||||
handleNotificationMessage: function(message) {
|
||||
if (!message.clicked) {
|
||||
return;
|
||||
}
|
||||
this.bringSelfToForeground();
|
||||
},
|
||||
bringSelfToForeground: function() {
|
||||
navigator.mozApps.getSelf().onsuccess = function gotSelf(evt) {
|
||||
var app = evt.target.result;
|
||||
app.launch();
|
||||
};
|
||||
},
|
||||
handleActivity: function(activity) {
|
||||
if (activity.source.name != 'internal-system-engineering-mode') {
|
||||
return;
|
||||
}
|
||||
//TODO use mozEngineeringMode API to do something
|
||||
},
|
||||
init: function ut_init() {
|
||||
this.iframe.addEventListener('load', this);
|
||||
this.iframe.addEventListener('unload', this);
|
||||
document.body.addEventListener('transitionend', this);
|
||||
window.addEventListener('keyup', this);
|
||||
window.addEventListener('hashchange', this);
|
||||
this.backHeader.addEventListener('action', this);
|
||||
|
||||
navigator.mozSetMessageHandler('notification', function(msg) {
|
||||
this.handleNotificationMessage(msg);
|
||||
}.bind(this));
|
||||
|
||||
navigator.mozSetMessageHandler('activity', function(activity) {
|
||||
this.handleActivity(activity);
|
||||
}.bind(this));
|
||||
|
||||
var name = this.getNameFromHash();
|
||||
if (name) {
|
||||
this.openTest(name);
|
||||
}
|
||||
else {
|
||||
// if no test is specified, load UI tests list (select UI tab)
|
||||
window.location.hash = 'UI';
|
||||
}
|
||||
},
|
||||
uninit: function ut_uninit() {
|
||||
this.iframe.removeEventListener('load', this);
|
||||
this.iframe.removeEventListener('unload', this);
|
||||
document.body.removeEventListener('transitionend', this);
|
||||
window.removeEventListener('keyup', this);
|
||||
window.removeEventListener('hashchange', this);
|
||||
this.backHeader.removeEventListener('action', this);
|
||||
},
|
||||
getNameFromHash: function ut_getNameFromHash() {
|
||||
return (/\btest=(.+)(&|$)/.exec(window.location.hash) || [])[1];
|
||||
},
|
||||
handleEvent: function ut_handleEvent(ev) {
|
||||
switch (ev.type) {
|
||||
case 'action':
|
||||
if (ev.target != this.backHeader) {
|
||||
return;
|
||||
}
|
||||
if (window.location.hash) {
|
||||
window.location.hash = '';
|
||||
}
|
||||
break;
|
||||
case 'load':
|
||||
this.iframe.contentWindow.addEventListener('keyup', this);
|
||||
break;
|
||||
case 'unload':
|
||||
this.iframe.contentWindow.removeEventListener('keyup', this);
|
||||
break;
|
||||
case 'hashchange':
|
||||
if (window.location.hash == '#UI')
|
||||
{
|
||||
this.UItests.classList.remove('invisible');
|
||||
AccessibilityHelper.setAriaSelected(this.UITab, this.tabs);
|
||||
if (!this.HWtests.classList.contains('invisible'))
|
||||
this.HWtests.classList.add('invisible');
|
||||
if (!this.APItests.classList.contains('invisible'))
|
||||
this.APItests.classList.add('invisible');
|
||||
}
|
||||
else if (window.location.hash == '#API')
|
||||
{
|
||||
this.APItests.classList.remove('invisible');
|
||||
AccessibilityHelper.setAriaSelected(this.APITab, this.tabs);
|
||||
if (!this.UItests.classList.contains('invisible'))
|
||||
this.UItests.classList.add('invisible');
|
||||
if (!this.HWtests.classList.contains('invisible'))
|
||||
this.HWtests.classList.add('invisible');
|
||||
}
|
||||
else if (window.location.hash == '#HW')
|
||||
{
|
||||
this.HWtests.classList.remove('invisible');
|
||||
AccessibilityHelper.setAriaSelected(this.HWTab, this.tabs);
|
||||
if (!this.UItests.classList.contains('invisible'))
|
||||
this.UItests.classList.add('invisible');
|
||||
if (!this.APItests.classList.contains('invisible'))
|
||||
this.APItests.classList.add('invisible');
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = this.getNameFromHash();
|
||||
if (!name) {
|
||||
this.closeTest();
|
||||
return;
|
||||
}
|
||||
this.panelTitle.textContent = name;
|
||||
this.openTest(name);
|
||||
}
|
||||
break;
|
||||
case 'transitionend':
|
||||
var name = this.getNameFromHash();
|
||||
if (!name)
|
||||
this.iframe.src = 'about:blank';
|
||||
break;
|
||||
}
|
||||
},
|
||||
openTest: function ut_openTest(name) {
|
||||
// save tab name from URL
|
||||
// e.g. '#test=UI/empty' => 'UI'
|
||||
this.currentTab = (/=\b(.+)\//.exec(window.location.hash) || [])[1];
|
||||
document.body.classList.add('test');
|
||||
|
||||
var self = this;
|
||||
window.setTimeout(function openTestPage() {
|
||||
self.iframe.src = './tests_html/' + name + '.html';
|
||||
}, 200);
|
||||
},
|
||||
closeTest: function ut_closeTest() {
|
||||
var isOpened = document.body.classList.contains('test');
|
||||
if (!isOpened)
|
||||
return false;
|
||||
document.body.classList.remove('test');
|
||||
|
||||
// select tab after close test iframe
|
||||
window.location.hash = this.currentTab;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('load', UITest.init.bind(UITest));
|
||||
51
gaia/dev_apps/uitest/manifest.webapp
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"name": "UI tests",
|
||||
"launch_path": "/index.html",
|
||||
"type": "certified",
|
||||
"developer": {
|
||||
"name": "The Gaia Team",
|
||||
"url": "https://github.com/mozilla-b2g/gaia"
|
||||
},
|
||||
"messages": [
|
||||
{ "notification": "/index.html" }
|
||||
],
|
||||
"activities": {
|
||||
"internal-system-engineering-mode": {
|
||||
"filters": {},
|
||||
"href": "/index.html",
|
||||
"disposition": "window"
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"84": "/style/icons/ui-test_84.png",
|
||||
"126": "/style/icons/ui-test_126.png",
|
||||
"142": "/style/icons/ui-test_142.png",
|
||||
"189": "/style/icons/ui-test_189.png",
|
||||
"284": "/style/icons/ui-test_284.png"
|
||||
},
|
||||
"permissions": {
|
||||
"fmradio":{},
|
||||
"browser":{},
|
||||
"geolocation":{},
|
||||
"wifi-manage":{},
|
||||
"mobilenetwork":{},
|
||||
"mobileconnection":{},
|
||||
"power":{},
|
||||
"backgroundservice":{},
|
||||
"attention":{},
|
||||
"contacts":{ "access": "readwrite" },
|
||||
"settings":{ "access": "readwrite" },
|
||||
"desktop-notification":{},
|
||||
"device-storage:sdcard":{ "access": "readwrite" },
|
||||
"settings":{ "access": "readwrite" },
|
||||
"audio-capture":{},
|
||||
"video-capture":{},
|
||||
"bluetooth":{},
|
||||
"downloads":{},
|
||||
"firefox-accounts": {},
|
||||
"engineering-mode": {},
|
||||
"secureelement-manage": {},
|
||||
"presentation-device-manage": {},
|
||||
"moz-extremely-unstable-and-will-change-webcomponents": {}
|
||||
}
|
||||
}
|
||||
31
gaia/dev_apps/uitest/style/API.css
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
.center {
|
||||
display: block;
|
||||
margin: 0px auto;
|
||||
text-align: center;
|
||||
}
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
p.success {
|
||||
color: green;
|
||||
}
|
||||
p.error {
|
||||
color: red;
|
||||
}
|
||||
input {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
button {
|
||||
/* overwrite building blocks settings to display 2-lines button */
|
||||
line-height: normal !important;
|
||||
text-align: center;
|
||||
}
|
||||
input[type='button'] {
|
||||
font-size: 2rem;
|
||||
}
|
||||
21
gaia/dev_apps/uitest/style/API/identity.css
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
button {
|
||||
font-size: 1rem;
|
||||
height: 3rem;
|
||||
margin-bottom: 0.3rem;
|
||||
text-overflow: clip;
|
||||
}
|
||||
ol {
|
||||
padding-left: 1rem;
|
||||
padding-right:0rem;
|
||||
}
|
||||
|
||||
.textfield {
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
.panel {
|
||||
display:inline-block;
|
||||
width: 49%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
4
gaia/dev_apps/uitest/style/API/openaudio.css
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
button {
|
||||
height: 7rem;
|
||||
}
|
||||
|
||||
5
gaia/dev_apps/uitest/style/API/orientation.css
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
button {
|
||||
font-size: 1.2rem;
|
||||
height: 3rem;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
39
gaia/dev_apps/uitest/style/HW.css
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
button {
|
||||
font-size: 3rem;
|
||||
}
|
||||
button[size='small'] {
|
||||
font-size: 2rem;
|
||||
}
|
||||
input[type='number'] {
|
||||
font-size: 3rem;
|
||||
width: 100%;
|
||||
}
|
||||
input[type='range'] {
|
||||
height: 2rem;
|
||||
}
|
||||
input[type='range']::-moz-range-thumb {
|
||||
background: orange;
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
}
|
||||
.invisible {
|
||||
display: none;
|
||||
}
|
||||
.red {
|
||||
background: red;
|
||||
}
|
||||
.green {
|
||||
background: green;
|
||||
}
|
||||
.blue {
|
||||
background: blue;
|
||||
}
|
||||
.white {
|
||||
background: white;
|
||||
}
|
||||
.black {
|
||||
background: black;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
77
gaia/dev_apps/uitest/style/UI.css
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
textarea, input, select, [contenteditable] {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
input, textarea, iframe {
|
||||
width: 100%;
|
||||
}
|
||||
button {
|
||||
/* overwrite building blocks settings to display 2-lines button */
|
||||
line-height: normal !important;
|
||||
text-align: center;
|
||||
}
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
canvas.hidden {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* keyboard */
|
||||
.table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.row {
|
||||
display: table-row;
|
||||
border-top: 1px dashed rgba(150,150,150,1);
|
||||
}
|
||||
.column_left,
|
||||
.column_middle,
|
||||
.column_right {
|
||||
display: table-cell;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
.column_left {
|
||||
width: 20%;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
.column_middle {
|
||||
width: 20%;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
.column_right {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid red;
|
||||
overflow: auto;
|
||||
background-color: #fcc;
|
||||
margin: 20px;
|
||||
}
|
||||
.sbox {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #ccc;
|
||||
float: left;
|
||||
}
|
||||
.sbox:nth-child(2n) {
|
||||
background-color: #fff;
|
||||
}
|
||||
.bar {
|
||||
font-size: 1.5rem
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
#fullscreen-div {
|
||||
background-color: #ccf;
|
||||
}
|
||||
#contextMenu {
|
||||
background: #eee;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
}
|
||||
BIN
gaia/dev_apps/uitest/style/icons/ui-test_126.png
Executable file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
gaia/dev_apps/uitest/style/icons/ui-test_142.png
Executable file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
gaia/dev_apps/uitest/style/icons/ui-test_189.png
Executable file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
gaia/dev_apps/uitest/style/icons/ui-test_284.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
gaia/dev_apps/uitest/style/icons/ui-test_84.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
gaia/dev_apps/uitest/style/images/canardpc.jpg
Executable file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
gaia/dev_apps/uitest/style/images/fullscreen_exit.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
47
gaia/dev_apps/uitest/style/lists.css
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
.sublist {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
position: absolute;
|
||||
top: 5rem;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow-y: scroll !important;
|
||||
-moz-user-select: none;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.sublist > li {
|
||||
-moz-box-sizing: border-box;
|
||||
|
||||
padding: 0px 16px;
|
||||
border-top: 1px solid hsla(207,22%,92%,1) !important;
|
||||
border-bottom: 1px solid hsla(223,7%,81%,1) !important;
|
||||
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sublist > li > a {
|
||||
outline: none;
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
white-space: nowrap;
|
||||
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sublist li:active {
|
||||
background-color: rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* replace build blocks CSS */
|
||||
.sublist li:hover:after,
|
||||
.sublist li > a:hover:after,
|
||||
.sublist li:active:after,
|
||||
.sublist li > a:active:after {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
78
gaia/dev_apps/uitest/style/tabs.css
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
/* ----------------------------------
|
||||
* Tabs
|
||||
* ---------------------------------- */
|
||||
|
||||
@media (orientation: landscape)
|
||||
{
|
||||
.bb-tablist {
|
||||
right: 0;
|
||||
width: 3.5rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bb-tablist > li {
|
||||
width: 100%;
|
||||
height: calc(100% / 3);
|
||||
}
|
||||
}
|
||||
|
||||
@media (orientation: portrait)
|
||||
{
|
||||
.bb-tablist {
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 3.5rem;
|
||||
}
|
||||
|
||||
.bb-tablist > li {
|
||||
width: calc(100% / 3);
|
||||
height: 100%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.bb-tablist {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.bb-tablist > li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a {
|
||||
font-size: 1.7rem;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
float: left;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000 no-repeat center top;
|
||||
position: relative;
|
||||
color: #fff;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bb-tablist > li > a:active {
|
||||
background-color: #00bbff;
|
||||
}
|
||||
|
||||
/* Selected state */
|
||||
.bb-tablist > li > a:target,
|
||||
.bb-tablist > li > a[aria-selected="true"] {
|
||||
color: #62c6f5
|
||||
}
|
||||
|
||||
.bb-tablist a:target ~.bb-tabpanel,
|
||||
.bb-tablist a[aria-selected="true"] ~.bb-tabpanel {
|
||||
z-index: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
84
gaia/dev_apps/uitest/style/uitest.css
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
html {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
|
||||
/* XXX: The below overflow property is being ignored by B2G Phone
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=777672
|
||||
*/
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel {
|
||||
position: fixed;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-moz-transition: -moz-transform 0.3s ease;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.test-panel {
|
||||
-moz-transform: translateX(100%);
|
||||
}
|
||||
|
||||
.list-panel{
|
||||
-moz-transform: translateX(0);
|
||||
}
|
||||
|
||||
body.test .list-panel{
|
||||
-moz-transform: translateX(-100%);
|
||||
}
|
||||
|
||||
body.test .test-panel {
|
||||
-moz-transform: translateX(0);
|
||||
}
|
||||
|
||||
|
||||
#test-iframe {
|
||||
border: none;
|
||||
width: 100%;
|
||||
height: calc(100% - 5rem);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@media (orientation: landscape)
|
||||
{
|
||||
.page {
|
||||
position: absolute;
|
||||
left: 0rem;
|
||||
right: 3.5rem; /* tabs are at right, keep some space for it */
|
||||
top: 0rem;
|
||||
bottom: 0rem;
|
||||
}
|
||||
|
||||
.sublist > li {
|
||||
height: calc(100% / 5) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (orientation: portrait)
|
||||
{
|
||||
.page {
|
||||
position: absolute;
|
||||
left: 0rem;
|
||||
right: 0rem;
|
||||
top: 0rem;
|
||||
bottom: 3.5rem; /* tabs are at bottom, keep some space for it */
|
||||
}
|
||||
|
||||
.sublist > li {
|
||||
height: calc(100% / 7) !important;
|
||||
}
|
||||
}
|
||||
39
gaia/dev_apps/uitest/tests_html/API/audiotag.html
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>Audio Tag test</title>
|
||||
<script defer src="../../js/API/audiotag.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
</head>
|
||||
<body>
|
||||
<fieldset>
|
||||
<legend><b>classic.ogg</b></legend>
|
||||
<button data-fn="play" data-src="classic.ogg">Play</button>
|
||||
</fieldset>
|
||||
<div>
|
||||
<fieldset>
|
||||
<legend><b>AC_prgrssv__Retro_Alarm_<br>Clock_v02_SOFT.ogg</b></legend>
|
||||
<button data-fn="play" data-src="AC_prgrssv__Retro_Alarm_Clock_v02_SOFT.ogg">Play</button></p>
|
||||
</fieldset>
|
||||
</div>
|
||||
<fieldset>
|
||||
<legend><b>AC_progressive_dapple10.ogg</b></legend>
|
||||
<button data-fn="play" data-src="AC_progressive_dapple10.ogg">Play</button></p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><b>AC_progressive_shimmer07.ogg</b></legend>
|
||||
<button data-fn="play" data-src="AC_progressive_shimmer07.ogg">Play</button></p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><b>ALARM_progressive_dapple.mp3</b></legend>
|
||||
<button data-fn="play" data-src="ALARM_progressive_dapple.mp3">Play</button></p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><b>ALARM_progressive2_dapple.mp3</b></legend>
|
||||
<button data-fn="play" data-src="ALARM_progressive2_dapple.mp3">Play</button></p>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
||||
17
gaia/dev_apps/uitest/tests_html/API/browseractivities.html
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>Browser Web Activities Test</title>
|
||||
<script defer src="../../js/API/browseractivities.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/input_areas.css">
|
||||
</head>
|
||||
<body>
|
||||
<h2>Go to:</h2>
|
||||
<p>URL: <input type="url" id="URL" value="http://" />
|
||||
<button id="go">Go</button></p>
|
||||
</body>
|
||||
</html>
|
||||
18
gaia/dev_apps/uitest/tests_html/API/composeemail.html
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>Compose Email test</title>
|
||||
<script defer src="../../js/API/composeemail.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
</head>
|
||||
<body>
|
||||
<h3>Compose Email with 'new' activity:</h3>
|
||||
<button id="compose-email">Compose Email</button>
|
||||
<h3>Compose Email with mailto url link:</h3>
|
||||
<a href="mailto:example@example.org">Compose Email</a>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
38
gaia/dev_apps/uitest/tests_html/API/contacts.html
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>Contacts testing tools</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<!-- We don't need localization for this app. -->
|
||||
<script type="text/javascript" src="../../js/API/contacts.js"></script>
|
||||
<script type="text/javascript" src="../../js/API/contacts_saver.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
</head>
|
||||
<body>
|
||||
<fieldset>
|
||||
<legend><b>Contacts manipulation</b></legend>
|
||||
<section>
|
||||
Contacts inserted: <span id="insertion-count">None, yet.</span>
|
||||
<button id="insert-contacts">Insert fake contacts</button>
|
||||
<button id="insert-social-contacts">Insert Social Contacts</button>
|
||||
<button id="clear-contacts">Clear all contacts</button>
|
||||
<button id="get-contacts">Get all contacts</button>
|
||||
</section>
|
||||
</fieldset>
|
||||
<!-- Activities tests -->
|
||||
<fieldset>
|
||||
<legend><b>Activities tests</b></legend>
|
||||
<section>
|
||||
<p id="activities-result"></p>
|
||||
<button id="activities-pick">Pick a contact</button>
|
||||
<button id="activities-new">New contact</button>
|
||||
<button id="activities-update">Update contact with<br>phone</button>
|
||||
<button id="activities-update-email">Update contact with<br>email</button>
|
||||
<button id="activities-update-email-phone">Update contact with<br>phone and email</button>
|
||||
<button id="activities-new-data">New contact with<br>data</button>
|
||||
</section>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
||||
24
gaia/dev_apps/uitest/tests_html/API/copypaste.html
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Copy and paste test</title>
|
||||
<style>
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 50rem;
|
||||
overflow: scroll;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<textarea id="textarea">Hollywood, California (CNN) -- Actor Brad Pitt was struck in the face as he was signing autographs at a movie premiere Wednesday, Los Angeles police said.' +
|
||||
'Pitt was at the Hollywood premiere of "Maleficent," starring his partner Angelina Jolie, when a man hopped a barrier and attacked the actor, Sgt. Leonard Calderon said.' +
|
||||
'Officers arrested the suspect, 25-year-old Vitalii Sediuk, on suspicion of battery.'+
|
||||
'Sediuk has a history of confronting celebrities at red carpet events. In 2012, he was slapped by actor Will Smith after he attempted to kiss Smith.'+
|
||||
'At the 2013 Grammy Awards, Sediuk charged the stage before singer Adele could accept her award.' +
|
||||
'Sediuk also hugged actors Leonardo DiCaprio and Bradley Cooper around the knees at separate events earlier this year.' +
|
||||
'Most recently, he put his head up America Ferraras dress at the Cannes premiere of "How to Train Your Dragon 2" last week.' +
|
||||
'After the attack Wednesday evening, Pitt and Jolie continued walking the blue carpet. Neither appeared to look fazed by the incident."</textarea>
|
||||
</body>
|
||||
</html>
|
||||
18
gaia/dev_apps/uitest/tests_html/API/csp.html
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>CSP Warning</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>CSP Warning test</h1>
|
||||
<p id="text">This line should not be removed by Javascript.</p>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
document.getElementById('text').textContent =
|
||||
'Error! CSP violation is executed!';
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
15
gaia/dev_apps/uitest/tests_html/API/dialnumber.html
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>Dial Number test</title>
|
||||
<script defer src="../../js/API/dialnumber.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
</head>
|
||||
<body>
|
||||
<button id="dial">Dial Number</button>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
29
gaia/dev_apps/uitest/tests_html/API/downloads.html
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Download test tools</title>
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<script defer type="text/javascript" src="/shared/js/lazy_loader.js"></script>
|
||||
<script defer type="text/javascript" src="../../js/API/downloads.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Wait few seconds for initializing the download</h3>
|
||||
<fieldset>
|
||||
<legend>Choose one to download</legend>
|
||||
<section>
|
||||
<a download="Toast.doc" href="http://owd.tid.es/dm/Toast.doc">
|
||||
<button>DOC (450KB)</button>
|
||||
</a>
|
||||
<a download="clipcanvas_14348_H264_320x180.mp4" href="http://owd.tid.es/dm/clipcanvas_14348_H264_320x180.mp4">
|
||||
<button>MP4(1.1 MB)</button>
|
||||
</a>
|
||||
</section>
|
||||
</fieldset>
|
||||
<div>
|
||||
<button id="downloadStatus" disabled="true">Status</button>
|
||||
<button id="downloadDelete" disabled="true">Delete download</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
31
gaia/dev_apps/uitest/tests_html/API/fxa.html
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>FxA Sign-in Demo</title>
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API/identity.css">
|
||||
<script type="text/javascript" src="../../js/API/fxa.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="panel">
|
||||
<fieldset>
|
||||
<legend>Request tests</legend>
|
||||
<section>
|
||||
<button id="request"><code>request()</code></button>
|
||||
<button id="logout"><code>logout()</button>
|
||||
</section>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<fieldset>
|
||||
<legend>Events</legend>
|
||||
<ol id="event-stream">
|
||||
<li>Page render</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
16
gaia/dev_apps/uitest/tests_html/API/geolocation.html
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>Geolocation test</title>
|
||||
<script defer src="../../js/API/geolocation.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
</head>
|
||||
<body>
|
||||
Latitude:<label id="lati"></label><br /><br />
|
||||
Longitude:<label id="longi"></label><br /><br />
|
||||
<button id="submit">Find Location</button>
|
||||
</body>
|
||||
</html>
|
||||
39
gaia/dev_apps/uitest/tests_html/API/getusermedia.html
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>gUM Test Page</title>
|
||||
<script defer src="../../js/API/getusermedia.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../style/API.css">
|
||||
<link rel="stylesheet" type="text/css" href="/shared/style/buttons.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="center">
|
||||
Modified from <a href="http://mozilla.github.io/webrtc-landing/gum_test.html" target="_blank">gUM test page</a><br>
|
||||
Note: Audio will feedback unless you use a headset!<br>
|
||||
<div id="contents"></div>
|
||||
<fieldset id="content_template" class="hidden">
|
||||
<div data-type="media" class="block">
|
||||
<div data-type="video-frame">
|
||||
<video width="320" height="240"></video>
|
||||
<div data-type="snapshots-frames" class="block"></div>
|
||||
</div>
|
||||
<audio controls="true"></audio>
|
||||
</div>
|
||||
<div data-type="message"></div>
|
||||
<div data-type="startbuttons" class="block">
|
||||
<button data-type="startVideoButton">Video</button>
|
||||
<button data-type="startAudioButton">Audio</button>
|
||||
<button data-type="startAudioVideoButton">Audio & Video</button>
|
||||
<button data-type="startDoubleRequest">Double Prompt</button>
|
||||
</div>
|
||||
<div data-type="stopbuttons" class="hidden">
|
||||
<button data-type="stopButton">Stop</button>
|
||||
<button data-type="pauseButton">Pause/Play</button>
|
||||
<button data-type="snapshotButton">Snapshot</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||