Bug 1242208 - Fix cached form history results with a datalist present. r=MattN

This commit is contained in:
Blake Kaplan 2016-02-02 13:44:11 -08:00
Родитель f4ab72e1cf
Коммит 4da198b998
3 изменённых файлов: 158 добавлений и 13 удалений

Просмотреть файл

@ -214,23 +214,26 @@ FormAutoComplete.prototype = {
// If there were datalist results result is a FormAutoCompleteResult
// as defined in nsFormAutoCompleteResult.jsm with the entire list
// of results in wrappedResult._values and only the results from
// form history in wrappedResults.entries.
// form history in wrappedResult.entries.
// First, grab the entire list of old results.
let allResults = wrappedResult._labels;
let datalistResults, datalistLabels;
if (allResults) {
// We have datalist results, extract them from the values array.
datalistLabels = allResults.slice(wrappedResult.entries.length);
let filtered = [];
// Both allResults and values arrays are in the form of:
// |--wR.entries--|
// <history entries><datalist entries>
let oldLabels = allResults.slice(wrappedResult.entries.length);
let oldValues = wrappedResult._values.slice(wrappedResult.entries.length);
datalistLabels = [];
datalistResults = [];
for (let i = 0; i < datalistLabels.length; ++i) {
if (datalistLabels[i].toLowerCase().includes(searchString)) {
filtered.push(datalistLabels[i]);
datalistResults.push(wrappedResult._values[i]);
for (let i = 0; i < oldLabels.length; ++i) {
if (oldLabels[i].toLowerCase().includes(searchString)) {
datalistLabels.push(oldLabels[i]);
datalistResults.push(oldValues[i]);
}
}
datalistLabels = filtered;
}
let searchTokens = searchString.split(/\s+/);
@ -260,6 +263,9 @@ FormAutoComplete.prototype = {
let comments = new Array(filteredEntries.length + datalistResults.length).fill("");
comments[filteredEntries.length] = "separator";
// History entries don't have labels (their labels would be read
// from their values). Pad out the labels array so the datalist
// results (which do have separate values and labels) line up.
datalistLabels = new Array(filteredEntries.length).fill("").concat(datalistLabels);
wrappedResult._values = filteredEntries.concat(datalistResults);
wrappedResult._labels = datalistLabels;
@ -301,19 +307,18 @@ FormAutoComplete.prototype = {
mergeResults(historyResult, datalistResult) {
let values = datalistResult.wrappedJSObject._values;
let labels = datalistResult.wrappedJSObject._labels;
let comments = [];
let comments = new Array(values.length).fill("");
// formHistoryResult will be null if form autocomplete is disabled. We
// historyResult will be null if form autocomplete is disabled. We
// still want the list values to display.
let entries = historyResult.wrappedJSObject.entries;
let historyResults = entries.map(function(entry) { return entry.text });
let historyResults = entries.map(entry => entry.text);
let historyComments = new Array(entries.length).fill("");
// fill out the comment column for the suggestions
// if we have any suggestions, put a label at the top
if (values.length) {
comments[0] = "separator";
comments.fill(1, "");
}
// now put the history results above the datalist suggestions

Просмотреть файл

@ -10,6 +10,7 @@ support-files =
skip-if = e10s # bug 1162338 (needs refactoring to talk to the autocomplete popup)
[test_bug_787624.html]
skip-if = e10s # bug 1162338 (needs refactoring to talk to the autocomplete popup)
[test_datalist_with_caching.html]
[test_form_autocomplete.html]
skip-if = e10s # bug 1162329 or bug 1162338
[test_form_autocomplete_with_list.html]

Просмотреть файл

@ -0,0 +1,139 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Form History Autocomplete</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="satchel_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
Form History test: form field autocomplete
<p id="display"></p>
<!-- we presumably can't hide the content for this test. -->
<div id="content">
<!-- normal, basic form -->
<form id="form1" onsubmit="return false;">
<input list="suggest" type="text" name="field1">
<button type="submit">Submit</button>
</form>
<datalist id="suggest">
<option value="First"></option>
<option value="Second"></option>
<option value="Secomundo"></option>
</datalist>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var input = $_(1, "field1");
function setupFormHistory(aCallback) {
updateFormHistory([
{ op : "remove" },
{ op : "add", fieldname : "field1", value : "Sec" },
], () => {
spawn_task(aCallback);
});
}
function setForm(value) {
input.value = value;
input.focus();
}
// Restore the form to the default state.
function restoreForm() {
setForm("");
}
// Check for expected form data.
function checkForm(expectedValue) {
var formID = input.parentNode.id;
is(input.value, expectedValue, "Checking " + formID + " input");
}
SimpleTest.waitForExplicitFinish();
var expectingPopup = null;
function expectPopup() {
info("expecting a popup");
return new Promise(resolve => {
expectingPopup = resolve;
});
}
var testNum = 0;
function popupShownListener() {
info("popup shown for test " + testNum);
if (expectingPopup) {
expectingPopup();
expectingPopup = null;
}
else {
ok(false, "Autocomplete popup not expected during test " + testNum);
}
}
function waitForMenuChange(expectedCount) {
return new Promise(resolve => {
notifyMenuChanged(expectedCount, null, resolve);
});
}
registerPopupShownListener(popupShownListener);
function checkMenuEntries(expectedValues) {
var actualValues = getMenuEntries();
is(actualValues.length, expectedValues.length, testNum + " Checking length of expected menu");
for (var i = 0; i < expectedValues.length; i++)
is(actualValues[i], expectedValues[i], testNum + " Checking menu entry #"+i);
}
function* runTests() {
testNum++;
restoreForm();
doKey("down");
yield expectPopup();
checkMenuEntries(["Sec", "First", "Second", "Secomundo"]);
doKey("down");
doKey("return");
checkForm("Sec");
testNum++;
restoreForm();
sendString("Sec");
doKey("down");
yield expectPopup();
testNum++;
checkMenuEntries(["Sec", "Second", "Secomundo"]);
sendString("o");
yield waitForMenuChange(2);
testNum++;
checkMenuEntries(["Second", "Secomundo"]);
doKey("down");
doKey("return");
checkForm("Second");
SimpleTest.finish();
}
function startTest() {
setupFormHistory(runTests);
}
window.onload = startTest;
</script>
</pre>
</body>
</html>