Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
18
gaia/dev_apps/test-ime/ime_test.html
Executable file
18
gaia/dev_apps/test-ime/ime_test.html
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<title>IME Tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="lib/mocha.css" />
|
||||
<script src="lib/chai.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<div id="workspace"></div>
|
||||
<div id="sfw" style="height: 0px">
|
||||
<input type="text" value="sfw" style="height: 0px; font-size: 0px;" />
|
||||
</div>
|
||||
<script src="ime_test.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
333
gaia/dev_apps/test-ime/ime_test.js
Executable file
333
gaia/dev_apps/test-ime/ime_test.js
Executable file
|
|
@ -0,0 +1,333 @@
|
|||
/*global mocha requireApp suite test assert setup suiteTeardown */
|
||||
|
||||
window.assert = chai.assert;
|
||||
|
||||
/**
|
||||
* This is a set of tests that test mozInputMethod
|
||||
*/
|
||||
suite('Input Method', function() {
|
||||
this.timeout(10000);
|
||||
|
||||
var container = document.getElementById('workspace');
|
||||
|
||||
/**
|
||||
* Send a set of characters to the current inputcontext
|
||||
* @param {Array} chars Array of characters
|
||||
* @param {Boolean} expected Expected value of the field after input
|
||||
* @param {Function} next Callback
|
||||
*/
|
||||
function sendKeys(chars, expected, next) {
|
||||
var completed = 0;
|
||||
var icc = navigator.mozInputMethod.inputcontext;
|
||||
if (!icc)
|
||||
return;
|
||||
chars.forEach(function(c) {
|
||||
var sk;
|
||||
if (typeof c === 'string') {
|
||||
sk = icc.sendKey(0, c.charCodeAt(0), 0);
|
||||
}
|
||||
else {
|
||||
sk = icc.sendKey(c, 0, 0);
|
||||
}
|
||||
|
||||
sk.then(function() {
|
||||
if (++completed === chars.length) {
|
||||
navigator.mozInputMethod.inputcontext.getText().then(function(v) {
|
||||
assert.equal(expected, v);
|
||||
next();
|
||||
}, function(err) {
|
||||
assert.strictEqual(true, err);
|
||||
});
|
||||
}
|
||||
}, function(err) {
|
||||
assert.strictEqual(true, err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens once to an inputcontextchange and then discards the event
|
||||
* @param {Boolean} needIc Specify whether NULL for the inputcontext is OK
|
||||
* @param {Function} callback Callback with 1 arg that holds inputcontext
|
||||
*/
|
||||
function onIcc(needIc, callback) {
|
||||
navigator.mozInputMethod.addEventListener('inputcontextchange', function onicc() {
|
||||
if (!navigator.mozInputMethod.inputcontext && needIc) {
|
||||
return;
|
||||
}
|
||||
navigator.mozInputMethod.removeEventListener('inputcontextchange', onicc);
|
||||
callback(navigator.mozInputMethod.inputcontext);
|
||||
});
|
||||
}
|
||||
|
||||
setup(function(next) {
|
||||
container.innerHTML = '';
|
||||
|
||||
// no active context? go along
|
||||
if (!navigator.mozInputMethod.inputcontext) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// otherwise wait for the blur() action
|
||||
onIcc(false, function() {
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
container.innerHTML = '';
|
||||
});
|
||||
|
||||
suite('InputContextChange events', function() {
|
||||
test('Event fires on textbox focus', function(next) {
|
||||
onIcc(true, function(ic) {
|
||||
assert.equal(ic.inputType, 'text');
|
||||
next();
|
||||
});
|
||||
container.innerHTML = '<input type="text" id="test" />';
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
|
||||
test('Event fires on textarea focus', function(next) {
|
||||
onIcc(true, function(ic) {
|
||||
assert.equal(ic.inputType, 'textarea');
|
||||
next();
|
||||
});
|
||||
container.innerHTML = '<textarea id="test2">Hi!</textarea>';
|
||||
document.querySelector('#test2').focus();
|
||||
});
|
||||
|
||||
test('Event fires on contenteditable focus', function(next) {
|
||||
onIcc(true, function(ic) {
|
||||
assert.equal(ic.inputType,
|
||||
'textarea');
|
||||
next();
|
||||
});
|
||||
container.innerHTML = '<div id="test3" contenteditable="true">Hi</div>';
|
||||
document.querySelector('#test3').focus();
|
||||
});
|
||||
|
||||
test('Event fires on designMode=on focus', function(next) {
|
||||
onIcc(true, function(ic) {
|
||||
assert.equal(ic.inputType, 'textarea');
|
||||
next();
|
||||
});
|
||||
container.innerHTML = '<iframe id="test"></iframe>';
|
||||
var iframe = container.querySelector('iframe');
|
||||
iframe.contentDocument.designMode = 'on';
|
||||
iframe.focus();
|
||||
});
|
||||
|
||||
test('Event fires on iframe body contenteditable focus', function(next) {
|
||||
// <body contenteditable>contentEditable</body>
|
||||
onIcc(true, function(ic) {
|
||||
assert.equal(ic.inputType, 'textarea');
|
||||
next();
|
||||
});
|
||||
container.innerHTML = '<iframe id="test"></iframe>';
|
||||
var iframe = container.querySelector('iframe');
|
||||
iframe.contentDocument.body.setAttribute('contenteditable', true);
|
||||
iframe.focus();
|
||||
});
|
||||
|
||||
test('No event on type="range"', function(next) {
|
||||
var fired = false;
|
||||
onIcc(true, function() {
|
||||
fired = true;
|
||||
});
|
||||
container.innerHTML = '<input type="range" min="0" max="100" step="1"/>';
|
||||
document.querySelector('input[type=range]').focus();
|
||||
setTimeout(function() {
|
||||
assert.equal(fired, false);
|
||||
next();
|
||||
}, 150);
|
||||
});
|
||||
|
||||
test('Focus event on type="date"', function(next) {
|
||||
container.innerHTML = '<input type="date" id="date1"/>';
|
||||
var el = document.querySelector('#date1');
|
||||
el.onfocus = function() {
|
||||
next();
|
||||
};
|
||||
el.focus();
|
||||
});
|
||||
|
||||
test('Focus event on type="time"', function(next) {
|
||||
container.innerHTML = '<input type="time" id="time1"/>';
|
||||
var el = document.querySelector('#time1');
|
||||
el.onfocus = function() {
|
||||
next();
|
||||
};
|
||||
el.focus();
|
||||
});
|
||||
|
||||
test('Event fires on textbox blur', function(next) {
|
||||
container.innerHTML = '<input type="text" id="test" value="this is tb" />';
|
||||
var el = document.querySelector('#test');
|
||||
el.focus();
|
||||
|
||||
setTimeout(function() {
|
||||
onIcc(false, function(ic) {
|
||||
assert.equal(ic, null);
|
||||
next();
|
||||
});
|
||||
el.blur();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
test('Event fires on textarea blur', function(next) {
|
||||
container.innerHTML = '<textarea id="test2">Whatup</textarea>';
|
||||
var el = document.querySelector('#test2');
|
||||
el.focus();
|
||||
|
||||
setTimeout(function() {
|
||||
onIcc(false, function(ic) {
|
||||
assert.equal(ic, null);
|
||||
next();
|
||||
});
|
||||
el.blur();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
test('Event fires on contenteditable blur', function(next) {
|
||||
container.innerHTML = '<div id="test3" contenteditable="true">O</div>';
|
||||
var el = document.querySelector('#test3');
|
||||
el.focus();
|
||||
|
||||
setTimeout(function() {
|
||||
onIcc(false, function(ic) {
|
||||
assert.equal(ic, null);
|
||||
next();
|
||||
});
|
||||
el.blur();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
suite('GetText', function() {
|
||||
function getText(html, id, expected, next) {
|
||||
container.innerHTML = html;
|
||||
|
||||
onIcc(true, function(ic) {
|
||||
ic.getText().then(function(v) {
|
||||
assert.equal(expected, v);
|
||||
next();
|
||||
}, function(err) {
|
||||
assert.strictEqual(true, err);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelector('#' + id).focus();
|
||||
}
|
||||
|
||||
test('Textbox', function(next) {
|
||||
getText('<input type="text" id="test" value="Joehoe" />', 'test',
|
||||
'Joehoe', next);
|
||||
});
|
||||
|
||||
test('Textarea', function(next) {
|
||||
getText('<textarea id="test">Oh yeah</textarea>', 'test',
|
||||
'Oh yeah', next);
|
||||
});
|
||||
|
||||
test('ContentEditable', function(next) {
|
||||
getText('<div contenteditable="true" id="test">Que</div>', 'test',
|
||||
'Que', next);
|
||||
});
|
||||
});
|
||||
|
||||
suite('SendKeys', function() {
|
||||
test('Handle backspace', function(next) {
|
||||
container.innerHTML = '<input type="text" id="test" value="" />';
|
||||
|
||||
onIcc(true, function() {
|
||||
sendKeys(['J', 'a', 'm', KeyEvent.DOM_VK_BACK_SPACE, 'n'],
|
||||
'Jan', next);
|
||||
});
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
|
||||
test('Handle contenteditable CR', function(next) {
|
||||
container.innerHTML = '<div contenteditable="true" id="test"></div>';
|
||||
|
||||
onIcc(true, function() {
|
||||
sendKeys(['J', 'a', 'm', KeyEvent.DOM_VK_RETURN, 'n'],
|
||||
'Jam\nn', next);
|
||||
});
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
|
||||
test('Handle textarea CR', function(next) {
|
||||
container.innerHTML = '<textarea id="test"></textarea>';
|
||||
|
||||
onIcc(true, function() {
|
||||
sendKeys(['J', 'a', 'm', KeyEvent.DOM_VK_RETURN, 'n'],
|
||||
'Jam\nn', next);
|
||||
});
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
|
||||
test('Cursor movement', function(next) {
|
||||
container.innerHTML = '<input type="text" id="test" value="" />';
|
||||
|
||||
onIcc(true, function(ic) {
|
||||
sendKeys(['a', 'b', 'c'], 'abc', function() {
|
||||
var r = ic.setSelectionRange(1, 0).then(function() {
|
||||
sendKeys(['d', 'e'],
|
||||
'adebc', next);
|
||||
}, function(err) {
|
||||
assert.strictEqual(true, err);
|
||||
});
|
||||
});
|
||||
});
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
});
|
||||
|
||||
suite('ReplaceSurroundingText', function() {
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=902847
|
||||
test('Contenteditable with CR', function(next) {
|
||||
onIcc(true, function(ic) {
|
||||
sendKeys(['J', 'a'], 'Ja', function() {
|
||||
ic.replaceSurroundingText('Jay\r', -2, 2).then(function() {
|
||||
// The \n after to shouldn't be here. Wtf?
|
||||
sendKeys(['t', 'o'], 'Jay\nto\n', function() {
|
||||
ic.replaceSurroundingText('tof\r', -2, 2).then(function() {
|
||||
ic.getText().then(function(v) {
|
||||
// Oh hi, here's another newline...
|
||||
assert.equal(v, 'Jay\ntof\n\n');
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
container.innerHTML = '<div contenteditable="true" id="test"></div>';
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
|
||||
test('Textarea with CR', function(next) {
|
||||
onIcc(true, function(ic) {
|
||||
sendKeys(['J', 'a'], 'Ja', function() {
|
||||
ic.replaceSurroundingText('Jay\r', -2, 2).then(function() {
|
||||
sendKeys(['t', 'o'], 'Jay\nto', function() {
|
||||
ic.replaceSurroundingText('tof\r', -2, 2).then(function() {
|
||||
ic.getText().then(function(v) {
|
||||
assert.equal(v, 'Jay\ntof\n');
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
container.innerHTML = '<textarea id="test"></textarea>';
|
||||
document.querySelector('#test').focus();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
mocha.run();
|
||||
2229
gaia/dev_apps/test-ime/lib/chai.js
Executable file
2229
gaia/dev_apps/test-ime/lib/chai.js
Executable file
File diff suppressed because it is too large
Load diff
227
gaia/dev_apps/test-ime/lib/mocha.css
Executable file
227
gaia/dev_apps/test-ime/lib/mocha.css
Executable file
|
|
@ -0,0 +1,227 @@
|
|||
@charset "UTF-8";
|
||||
body {
|
||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
padding: 60px 50px;
|
||||
}
|
||||
|
||||
#mocha ul, #mocha li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#mocha ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#mocha h1, #mocha h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#mocha h1 {
|
||||
margin-top: 15px;
|
||||
font-size: 1em;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
#mocha h1 a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha h1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#mocha .suite .suite h1 {
|
||||
margin-top: 0;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mocha .suite {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test.pending:hover h2::after {
|
||||
content: '(pending)';
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
#mocha .test.pass.medium .duration {
|
||||
background: #C09853;
|
||||
}
|
||||
|
||||
#mocha .test.pass.slow .duration {
|
||||
background: #B94A48;
|
||||
}
|
||||
|
||||
#mocha .test.pass::before {
|
||||
content: '✓';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #00d6b2;
|
||||
}
|
||||
|
||||
#mocha .test.pass .duration {
|
||||
font-size: 9px;
|
||||
margin-left: 5px;
|
||||
padding: 2px 5px;
|
||||
color: white;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#mocha .test.pass.fast .duration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha .test.pending {
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.pending::before {
|
||||
content: '◦';
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.fail {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test.fail pre {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha .test.fail::before {
|
||||
content: '✖';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test pre.error {
|
||||
color: #c00;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#mocha .test pre {
|
||||
display: inline-block;
|
||||
font: 12px/1.5 monaco, monospace;
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eee;
|
||||
border-bottom-color: #ddd;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-box-shadow: 0 1px 3px #eee;
|
||||
-moz-border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 3px #eee;
|
||||
}
|
||||
|
||||
#mocha .test h2 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#mocha .test a.replay {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: -20px;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
background: #eee;
|
||||
font-size: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
border-radius: 15px;
|
||||
-webkit-transition: opacity 200ms;
|
||||
-moz-transition: opacity 200ms;
|
||||
transition: opacity 200ms;
|
||||
opacity: 0.2;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#mocha .test:hover a.replay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#mocha-report.pass .test.fail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.fail .test.pass {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-error {
|
||||
color: #c00;
|
||||
font-size: 1.5 em;
|
||||
font-weight: 100;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#mocha-stats {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#mocha-stats .progress {
|
||||
float: right;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#mocha-stats em {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha-stats a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha-stats a:hover {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#mocha-stats li {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
list-style: none;
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
code .comment { color: #ddd }
|
||||
code .init { color: #2F6FAD }
|
||||
code .string { color: #5890AD }
|
||||
code .keyword { color: #8A6343 }
|
||||
code .number { color: #2F6FAD }
|
||||
5011
gaia/dev_apps/test-ime/lib/mocha.js
Executable file
5011
gaia/dev_apps/test-ime/lib/mocha.js
Executable file
File diff suppressed because it is too large
Load diff
21
gaia/dev_apps/test-ime/manifest.webapp
Executable file
21
gaia/dev_apps/test-ime/manifest.webapp
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "IME Tests",
|
||||
"description": "Tests for InputMethod",
|
||||
"launch_path": "./ime_test.html",
|
||||
"type": "certified",
|
||||
"developer": {
|
||||
"name": "The Gaia Team",
|
||||
"url": "https://github.com/mozilla-b2g/gaia"
|
||||
},
|
||||
"permissions": {
|
||||
"input":{},
|
||||
"settings":{ "access": "readwrite" }
|
||||
},
|
||||
"icons": {
|
||||
"84": "/style/icons/default_84.png",
|
||||
"126": "/style/icons/default_126.png",
|
||||
"142": "/style/icons/default_142.png",
|
||||
"189": "/style/icons/default_189.png",
|
||||
"284": "/style/icons/default_284.png"
|
||||
}
|
||||
}
|
||||
BIN
gaia/dev_apps/test-ime/style/icons/default_126.png
Executable file
BIN
gaia/dev_apps/test-ime/style/icons/default_126.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
gaia/dev_apps/test-ime/style/icons/default_142.png
Executable file
BIN
gaia/dev_apps/test-ime/style/icons/default_142.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
gaia/dev_apps/test-ime/style/icons/default_189.png
Executable file
BIN
gaia/dev_apps/test-ime/style/icons/default_189.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
BIN
gaia/dev_apps/test-ime/style/icons/default_284.png
Executable file
BIN
gaia/dev_apps/test-ime/style/icons/default_284.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
BIN
gaia/dev_apps/test-ime/style/icons/default_84.png
Executable file
BIN
gaia/dev_apps/test-ime/style/icons/default_84.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in a new issue