Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,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>

View 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();

File diff suppressed because it is too large Load diff

View 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 }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
{"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"},"origin":"app://test-ime.gaiamobile.org","version":"2.5"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB