mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 08:17:31 +09:00
Issue #439 - Remove tests from toolkit/
This commit is contained in:
parent
3210cc7d95
commit
e5bacc6f6e
2362 changed files with 95 additions and 246993 deletions
|
|
@ -4,8 +4,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIAutoCompleteController.idl',
|
||||
'nsIAutoCompleteInput.idl',
|
||||
|
|
@ -23,6 +21,3 @@ UNIFIED_SOURCES += [
|
|||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Autocomplete')
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInputBase(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInputBase.prototype = {
|
||||
|
||||
// Array of AutoCompleteSearch names
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
// Text selection range
|
||||
_selStart: 0,
|
||||
_selEnd: 0,
|
||||
get selectionStart() {
|
||||
return this._selStart;
|
||||
},
|
||||
get selectionEnd() {
|
||||
return this._selEnd;
|
||||
},
|
||||
selectTextRange: function(aStart, aEnd) {
|
||||
this._selStart = aStart;
|
||||
this._selEnd = aEnd;
|
||||
},
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
get popup() {
|
||||
if (!this._popup) {
|
||||
this._popup = new AutocompletePopupBase(this);
|
||||
}
|
||||
return this._popup;
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput])
|
||||
}
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteResult implementation
|
||||
*/
|
||||
function AutoCompleteResultBase(aValues) {
|
||||
this._values = aValues;
|
||||
}
|
||||
AutoCompleteResultBase.prototype = {
|
||||
|
||||
// Arrays
|
||||
_values: null,
|
||||
_comments: [],
|
||||
_styles: [],
|
||||
_finalCompleteValues: [],
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
defaultIndex: -1,
|
||||
|
||||
_typeAheadResult: false,
|
||||
get typeAheadResult() {
|
||||
return this._typeAheadResult;
|
||||
},
|
||||
|
||||
get matchCount() {
|
||||
return this._values.length;
|
||||
},
|
||||
|
||||
getValueAt: function(aIndex) {
|
||||
return this._values[aIndex];
|
||||
},
|
||||
|
||||
getLabelAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
getCommentAt: function(aIndex) {
|
||||
return this._comments[aIndex];
|
||||
},
|
||||
|
||||
getStyleAt: function(aIndex) {
|
||||
return this._styles[aIndex];
|
||||
},
|
||||
|
||||
getImageAt: function(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this._finalCompleteValues[aIndex] || this._values[aIndex];
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult])
|
||||
}
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation that always returns
|
||||
* the same result set.
|
||||
*/
|
||||
function AutoCompleteSearchBase(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearchBase.prototype = {
|
||||
|
||||
// Search name. Used by AutoCompleteController
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result: null,
|
||||
|
||||
startSearch: function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener) {
|
||||
var result = this._result;
|
||||
|
||||
result.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
aListener.onSearchResult(this, result);
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory,
|
||||
Ci.nsIAutoCompleteSearch]),
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
function AutocompletePopupBase(input) {
|
||||
this.input = input;
|
||||
}
|
||||
AutocompletePopupBase.prototype = {
|
||||
selectedIndex: 0,
|
||||
invalidate() {},
|
||||
selectBy(reverse, page) {
|
||||
let numRows = this.input.controller.matchCount;
|
||||
if (numRows > 0) {
|
||||
let delta = reverse ? -1 : 1;
|
||||
this.selectedIndex = (this.selectedIndex + delta) % numRows;
|
||||
if (this.selectedIndex < 0) {
|
||||
this.selectedIndex = numRows - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]),
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch) {
|
||||
var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
var cid = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator).
|
||||
generateUUID();
|
||||
|
||||
var desc = "Test AutoCompleteSearch";
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var gResultListener = {
|
||||
_lastResult: null,
|
||||
_lastValue: "",
|
||||
_lastRemoveFromDb: false,
|
||||
|
||||
onValueRemoved: function(aResult, aValue, aRemoveFromDb) {
|
||||
this._lastResult = aResult;
|
||||
this._lastValue = aValue;
|
||||
this._lastRemoveFromDb = aRemoveFromDb;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var result = Cc["@mozilla.org/autocomplete/simple-result;1"].
|
||||
createInstance(Ci.nsIAutoCompleteSimpleResult);
|
||||
result.appendMatch("a", "");
|
||||
result.appendMatch("b", "");
|
||||
result.appendMatch("c", "");
|
||||
result.setListener(gResultListener);
|
||||
do_check_eq(result.matchCount, 3);
|
||||
result.removeValueAt(0, true);
|
||||
do_check_eq(result.matchCount, 2);
|
||||
do_check_eq(gResultListener._lastResult, result);
|
||||
do_check_eq(gResultListener._lastValue, "a");
|
||||
do_check_eq(gResultListener._lastRemoveFromDb, true);
|
||||
|
||||
result.removeValueAt(0, false);
|
||||
do_check_eq(result.matchCount, 1);
|
||||
do_check_eq(gResultListener._lastValue, "b");
|
||||
do_check_eq(gResultListener._lastRemoveFromDb, false);
|
||||
|
||||
// check that we don't get notified if the listener is unset
|
||||
result.setListener(null);
|
||||
result.removeValueAt(0, true); // "c"
|
||||
do_check_eq(result.matchCount, 0);
|
||||
do_check_eq(gResultListener._lastValue, "b");
|
||||
}
|
||||
|
|
@ -1,285 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Unit test for Bug 378079 - AutoComplete returns invalid rows when
|
||||
* more than one AutoCompleteSearch is used.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
// Array of AutoCompleteSearch names
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteResult implementation
|
||||
*/
|
||||
function AutoCompleteResult(aValues, aComments, aStyles) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._styles = aStyles;
|
||||
|
||||
if (this._values.length > 0) {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
} else {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.NOMATCH;
|
||||
}
|
||||
}
|
||||
AutoCompleteResult.prototype = {
|
||||
constructor: AutoCompleteResult,
|
||||
|
||||
// Arrays
|
||||
_values: null,
|
||||
_comments: null,
|
||||
_styles: null,
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
defaultIndex: 0,
|
||||
|
||||
get matchCount() {
|
||||
return this._values.length;
|
||||
},
|
||||
|
||||
getValueAt: function(aIndex) {
|
||||
return this._values[aIndex];
|
||||
},
|
||||
|
||||
getLabelAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
getCommentAt: function(aIndex) {
|
||||
return this._comments[aIndex];
|
||||
},
|
||||
|
||||
getStyleAt: function(aIndex) {
|
||||
return this._styles[aIndex];
|
||||
},
|
||||
|
||||
getImageAt: function(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteResult))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation that always returns
|
||||
* the same result set.
|
||||
*/
|
||||
function AutoCompleteSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
|
||||
// Search name. Used by AutoCompleteController
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result:null,
|
||||
|
||||
|
||||
/**
|
||||
* Return the same result set for every search
|
||||
*/
|
||||
startSearch: function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener)
|
||||
{
|
||||
aListener.onSearchResult(this, this._result);
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIAutoCompleteSearch))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch) {
|
||||
var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
var cid = uuidGenerator.generateUUID();
|
||||
|
||||
var desc = "Test AutoCompleteSearch";
|
||||
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test AutoComplete with multiple AutoCompleteSearch sources.
|
||||
*/
|
||||
function run_test() {
|
||||
|
||||
// Make an AutoCompleteSearch that always returns nothing
|
||||
var emptySearch = new AutoCompleteSearch("test-empty-search",
|
||||
new AutoCompleteResult([], [], []));
|
||||
|
||||
// Make an AutoCompleteSearch that returns two values
|
||||
var expectedValues = ["test1", "test2"];
|
||||
var regularSearch = new AutoCompleteSearch("test-regular-search",
|
||||
new AutoCompleteResult(expectedValues, [], []));
|
||||
|
||||
// Register searches so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(emptySearch);
|
||||
registerAutoCompleteSearch(regularSearch);
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput([emptySearch.name, regularSearch.name]);
|
||||
var numSearchesStarted = 0;
|
||||
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, 2);
|
||||
|
||||
// Confirm expected result values
|
||||
for (var i = 0; i < expectedValues.length; i++) {
|
||||
do_check_eq(expectedValues[i], controller.getValueAt(i));
|
||||
}
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(emptySearch);
|
||||
unregisterAutoCompleteSearch(regularSearch);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
controller.startSearch("test");
|
||||
}
|
||||
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Unit test for Bug 393191 - AutoComplete crashes if result is null
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
// Array of AutoCompleteSearch names
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteResult implementation
|
||||
*/
|
||||
function AutoCompleteResult(aValues, aComments, aStyles) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._styles = aStyles;
|
||||
|
||||
if (this._values.length > 0) {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
} else {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.NOMATCH;
|
||||
}
|
||||
}
|
||||
AutoCompleteResult.prototype = {
|
||||
constructor: AutoCompleteResult,
|
||||
|
||||
// Arrays
|
||||
_values: null,
|
||||
_comments: null,
|
||||
_styles: null,
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
defaultIndex: 0,
|
||||
|
||||
get matchCount() {
|
||||
return this._values.length;
|
||||
},
|
||||
|
||||
getValueAt: function(aIndex) {
|
||||
return this._values[aIndex];
|
||||
},
|
||||
|
||||
getLabelAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
getCommentAt: function(aIndex) {
|
||||
return this._comments[aIndex];
|
||||
},
|
||||
|
||||
getStyleAt: function(aIndex) {
|
||||
return this._styles[aIndex];
|
||||
},
|
||||
|
||||
getImageAt: function(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteResult))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation that always returns
|
||||
* the same result set.
|
||||
*/
|
||||
function AutoCompleteSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
|
||||
// Search name. Used by AutoCompleteController
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result: null,
|
||||
|
||||
|
||||
/**
|
||||
* Return the same result set for every search
|
||||
*/
|
||||
startSearch: function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener)
|
||||
{
|
||||
aListener.onSearchResult(this, this._result);
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIAutoCompleteSearch))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch) {
|
||||
var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
var cid = uuidGenerator.generateUUID();
|
||||
|
||||
var desc = "Test AutoCompleteSearch";
|
||||
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test AutoComplete with a search that returns a null result
|
||||
*/
|
||||
function run_test() {
|
||||
|
||||
// Make an AutoCompleteSearch that always returns nothing
|
||||
var emptySearch = new AutoCompleteSearch("test-empty-search",
|
||||
new AutoCompleteResult([], [], []));
|
||||
|
||||
// Register search so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(emptySearch);
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our search
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput([emptySearch.name]);
|
||||
var numSearchesStarted = 0;
|
||||
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
|
||||
do_check_eq(controller.matchCount, 0);
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(emptySearch);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
controller.startSearch("test");
|
||||
}
|
||||
|
||||
|
|
@ -1,285 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Unit test for Bug 440866 - First AutoCompleteSearch that returns
|
||||
* RESULT_NOMATCH cancels all other searches when popup is open
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
// Array of AutoCompleteSearch names
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteResult implementation
|
||||
*/
|
||||
function AutoCompleteResult(aValues, aComments, aStyles) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._styles = aStyles;
|
||||
|
||||
if (this._values.length > 0) {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
} else {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.NOMATCH;
|
||||
}
|
||||
}
|
||||
AutoCompleteResult.prototype = {
|
||||
constructor: AutoCompleteResult,
|
||||
|
||||
// Arrays
|
||||
_values: null,
|
||||
_comments: null,
|
||||
_styles: null,
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
defaultIndex: 0,
|
||||
|
||||
get matchCount() {
|
||||
return this._values.length;
|
||||
},
|
||||
|
||||
getValueAt: function(aIndex) {
|
||||
return this._values[aIndex];
|
||||
},
|
||||
|
||||
getLabelAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
getCommentAt: function(aIndex) {
|
||||
return this._comments[aIndex];
|
||||
},
|
||||
|
||||
getStyleAt: function(aIndex) {
|
||||
return this._styles[aIndex];
|
||||
},
|
||||
|
||||
getImageAt: function(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteResult))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation that always returns
|
||||
* the same result set.
|
||||
*/
|
||||
function AutoCompleteSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
|
||||
// Search name. Used by AutoCompleteController
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result:null,
|
||||
|
||||
|
||||
/**
|
||||
* Return the same result set for every search
|
||||
*/
|
||||
startSearch: function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener)
|
||||
{
|
||||
aListener.onSearchResult(this, this._result);
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIAutoCompleteSearch))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch) {
|
||||
var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
var cid = uuidGenerator.generateUUID();
|
||||
|
||||
var desc = "Test AutoCompleteSearch";
|
||||
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test AutoComplete with multiple AutoCompleteSearch sources.
|
||||
*/
|
||||
function run_test() {
|
||||
|
||||
// Make an AutoCompleteSearch that always returns nothing
|
||||
var emptySearch = new AutoCompleteSearch("test-empty-search",
|
||||
new AutoCompleteResult([], [], []));
|
||||
|
||||
// Make an AutoCompleteSearch that returns two values
|
||||
var expectedValues = ["test1", "test2"];
|
||||
var regularSearch = new AutoCompleteSearch("test-regular-search",
|
||||
new AutoCompleteResult(expectedValues, [], []));
|
||||
|
||||
// Register searches so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(emptySearch);
|
||||
registerAutoCompleteSearch(regularSearch);
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput([emptySearch.name, regularSearch.name]);
|
||||
var numSearchesStarted = 0;
|
||||
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
do_check_eq(input.searchCount, 2);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, 2);
|
||||
|
||||
// Confirm expected result values
|
||||
for (var i = 0; i < expectedValues.length; i++) {
|
||||
do_check_eq(expectedValues[i], controller.getValueAt(i));
|
||||
}
|
||||
|
||||
do_check_true(input.popupOpen);
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(emptySearch);
|
||||
unregisterAutoCompleteSearch(regularSearch);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
controller.startSearch("test");
|
||||
}
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var result = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
createInstance(Ci.nsIAutoCompleteController);
|
||||
do_check_eq(result.searchStatus, Ci.nsIAutoCompleteController.STATUS_NONE);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/**
|
||||
* Search object that returns results at different times.
|
||||
* First, the search that returns results asynchronously.
|
||||
*/
|
||||
function AutoCompleteAsyncSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteAsyncSearch.prototype = Object.create(AutoCompleteSearchBase.prototype);
|
||||
AutoCompleteAsyncSearch.prototype.startSearch = function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener) {
|
||||
this._result.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH_ONGOING;
|
||||
aListener.onSearchResult(this, this._result);
|
||||
|
||||
do_timeout(500, () => {
|
||||
this._returnResults(aListener);
|
||||
});
|
||||
};
|
||||
|
||||
AutoCompleteAsyncSearch.prototype._returnResults = function(aListener) {
|
||||
var result = this._result;
|
||||
|
||||
result.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
aListener.onSearchResult(this, result);
|
||||
};
|
||||
|
||||
/**
|
||||
* The synchronous version
|
||||
*/
|
||||
function AutoCompleteSyncSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSyncSearch.prototype = Object.create(AutoCompleteAsyncSearch.prototype);
|
||||
AutoCompleteSyncSearch.prototype.startSearch = function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener) {
|
||||
this._returnResults(aListener);
|
||||
};
|
||||
|
||||
/**
|
||||
* Results object
|
||||
*/
|
||||
function AutoCompleteResult(aValues, aDefaultIndex) {
|
||||
this._values = aValues;
|
||||
this.defaultIndex = aDefaultIndex;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
|
||||
/**
|
||||
* Test AutoComplete with multiple AutoCompleteSearch sources, with one of them
|
||||
* (index != 0) returning before the rest.
|
||||
*/
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
var results = ["mozillaTest"];
|
||||
var inputStr = "moz";
|
||||
|
||||
// Async search
|
||||
var asyncSearch = new AutoCompleteAsyncSearch("Async",
|
||||
new AutoCompleteResult(results, -1));
|
||||
// Sync search
|
||||
var syncSearch = new AutoCompleteSyncSearch("Sync",
|
||||
new AutoCompleteResult(results, 0));
|
||||
|
||||
// Register searches so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(asyncSearch);
|
||||
registerAutoCompleteSearch(syncSearch);
|
||||
|
||||
var controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete.
|
||||
// Async search MUST be FIRST to trigger the bug this tests.
|
||||
var input = new AutoCompleteInputBase([asyncSearch.name, syncSearch.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = inputStr;
|
||||
|
||||
// Caret must be at the end. Autofill doesn't happen unless you're typing
|
||||
// characters at the end.
|
||||
var strLen = inputStr.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(inputStr);
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(input.textValue, results[0]);
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(asyncSearch);
|
||||
unregisterAutoCompleteSearch(syncSearch);
|
||||
do_test_finished();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,276 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
// Array of AutoCompleteSearch names
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteResult implementation
|
||||
*/
|
||||
function AutoCompleteResult(aValues, aComments, aStyles) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._styles = aStyles;
|
||||
}
|
||||
AutoCompleteResult.prototype = {
|
||||
constructor: AutoCompleteResult,
|
||||
|
||||
// Arrays
|
||||
_values: null,
|
||||
_comments: null,
|
||||
_styles: null,
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
defaultIndex: 0,
|
||||
|
||||
get matchCount() {
|
||||
return this._values.length;
|
||||
},
|
||||
|
||||
getValueAt: function(aIndex) {
|
||||
return this._values[aIndex];
|
||||
},
|
||||
|
||||
getLabelAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
getCommentAt: function(aIndex) {
|
||||
return this._comments[aIndex];
|
||||
},
|
||||
|
||||
getStyleAt: function(aIndex) {
|
||||
return this._styles[aIndex];
|
||||
},
|
||||
|
||||
getImageAt: function(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteResult))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation that always returns
|
||||
* the same result set.
|
||||
*/
|
||||
function AutoCompleteSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
|
||||
// Search name. Used by AutoCompleteController
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result:null,
|
||||
|
||||
|
||||
/**
|
||||
* Return the same result set for every search
|
||||
*/
|
||||
startSearch: function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener)
|
||||
{
|
||||
var result = this._result;
|
||||
if (result._values.length > 0) {
|
||||
result.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS_ONGOING;
|
||||
} else {
|
||||
result.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH_ONGOING;
|
||||
}
|
||||
aListener.onSearchResult(this, result);
|
||||
|
||||
if (result._values.length > 0) {
|
||||
result.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
} else {
|
||||
result.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
|
||||
}
|
||||
aListener.onSearchResult(this, result);
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIAutoCompleteSearch))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch) {
|
||||
var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
var cid = uuidGenerator.generateUUID();
|
||||
|
||||
var desc = "Test AutoCompleteSearch";
|
||||
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test AutoComplete with multiple AutoCompleteSearch sources.
|
||||
*/
|
||||
function run_test() {
|
||||
var expected1 = ["1", "2", "3"];
|
||||
var expected2 = ["a", "b", "c"];
|
||||
var search1 = new AutoCompleteSearch("search1",
|
||||
new AutoCompleteResult(expected1, [], []));
|
||||
var search2 = new AutoCompleteSearch("search2",
|
||||
new AutoCompleteResult(expected2, [], []));
|
||||
|
||||
// Register searches so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(search1);
|
||||
registerAutoCompleteSearch(search2);
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput([search1.name, search2.name]);
|
||||
var numSearchesStarted = 0;
|
||||
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
|
||||
do_check_eq(numSearchesStarted, 1);
|
||||
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, expected1.length + expected2.length);
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(search1);
|
||||
unregisterAutoCompleteSearch(search2);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
controller.startSearch("test");
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
function AutoCompleteInput(aSearches, aUserContextId) {
|
||||
this.searches = aSearches;
|
||||
this.userContextId = aUserContextId;
|
||||
this.popup.selectedIndex = -1;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function AutoCompleteSearch(aName) {
|
||||
this.name = aName;
|
||||
}
|
||||
AutoCompleteSearch.prototype = Object.create(AutoCompleteSearchBase.prototype);
|
||||
|
||||
add_task(function *test_userContextId() {
|
||||
let searchParam = yield doSearch("test", 1);
|
||||
Assert.equal(searchParam, " user-context-id:1");
|
||||
});
|
||||
|
||||
function doSearch(aString, aUserContextId) {
|
||||
let deferred = Promise.defer();
|
||||
let search = new AutoCompleteSearch("test");
|
||||
|
||||
search.startSearch = function (aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener) {
|
||||
unregisterAutoCompleteSearch(search);
|
||||
deferred.resolve(aSearchParam);
|
||||
};
|
||||
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
let input = new AutoCompleteInput([ search.name ], aUserContextId);
|
||||
controller.input = input;
|
||||
controller.startSearch(aString);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
add_task(function* sameCaseAsMatch() {
|
||||
yield runTest("moz");
|
||||
});
|
||||
|
||||
add_task(function* differentCaseFromMatch() {
|
||||
yield runTest("MOZ");
|
||||
});
|
||||
|
||||
function* runTest(searchStr) {
|
||||
let matches = [
|
||||
"mozilla.org",
|
||||
"example.com",
|
||||
];
|
||||
let result = new AutoCompleteResultBase(matches);
|
||||
result.defaultIndex = 0;
|
||||
|
||||
let search = new AutoCompleteSearchBase("search", result);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let input = new AutoCompleteInputBase([search.name]);
|
||||
input.completeSelectedIndex = true;
|
||||
input.completeDefaultIndex = true;
|
||||
|
||||
// Start off with the search string in the input. The selection must be
|
||||
// collapsed and the caret must be at the end to trigger autofill below.
|
||||
input.textValue = searchStr;
|
||||
input.selectTextRange(searchStr.length, searchStr.length);
|
||||
Assert.equal(input.selectionStart, searchStr.length,
|
||||
"Selection should start at the end of the input");
|
||||
Assert.equal(input.selectionEnd, searchStr.length,
|
||||
"Selection should end at the end of the input");
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
createInstance(Ci.nsIAutoCompleteController);
|
||||
controller.input = input;
|
||||
input.controller = controller;
|
||||
|
||||
// Start a search.
|
||||
yield new Promise(resolve => {
|
||||
controller.startSearch(searchStr);
|
||||
input.onSearchComplete = () => {
|
||||
// The first match should have autofilled, but the case of the search
|
||||
// string should be preserved.
|
||||
let expectedValue = searchStr + matches[0].substr(searchStr.length);
|
||||
Assert.equal(input.textValue, expectedValue,
|
||||
"Should have autofilled");
|
||||
Assert.equal(input.selectionStart, searchStr.length,
|
||||
"Selection should start after search string");
|
||||
Assert.equal(input.selectionEnd, expectedValue.length,
|
||||
"Selection should end at the end of the input");
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
|
||||
// Key down to select the second match in the popup.
|
||||
controller.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_DOWN);
|
||||
let expectedValue = matches[1];
|
||||
Assert.equal(input.textValue, expectedValue,
|
||||
"Should have filled second match");
|
||||
Assert.equal(input.selectionStart, expectedValue.length,
|
||||
"Selection should start at the end of the input");
|
||||
Assert.equal(input.selectionEnd, expectedValue.length,
|
||||
"Selection should end at the end of the input");
|
||||
|
||||
// Key up to select the first match again. The input should be restored
|
||||
// exactly as it was when the first match was autofilled above: the search
|
||||
// string's case should be preserved, and the selection should be preserved.
|
||||
controller.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_UP);
|
||||
expectedValue = searchStr + matches[0].substr(searchStr.length);
|
||||
Assert.equal(input.textValue, expectedValue,
|
||||
"Should have filled first match again");
|
||||
Assert.equal(input.selectionStart, searchStr.length,
|
||||
"Selection should start after search string again");
|
||||
Assert.equal(input.selectionEnd, expectedValue.length,
|
||||
"Selection should end at the end of the input again");
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* A results that wants to defaultComplete to 0, but it has no matches,
|
||||
* though it notifies SUCCESS to the controller.
|
||||
*/
|
||||
function AutoCompleteNoMatchResult() {
|
||||
this.defaultIndex = 0;
|
||||
}
|
||||
AutoCompleteNoMatchResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
/**
|
||||
* A results that wants to defaultComplete to an index greater than the number
|
||||
* of matches.
|
||||
*/
|
||||
function AutoCompleteBadIndexResult(aValues, aDefaultIndex) {
|
||||
do_check_true(aValues.length <= aDefaultIndex);
|
||||
this._values = aValues;
|
||||
this.defaultIndex = aDefaultIndex;
|
||||
}
|
||||
AutoCompleteBadIndexResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
add_test(function autocomplete_noMatch_success() {
|
||||
const INPUT_STR = "moz";
|
||||
|
||||
let searchNoMatch =
|
||||
new AutoCompleteSearchBase("searchNoMatch",
|
||||
new AutoCompleteNoMatchResult());
|
||||
registerAutoCompleteSearch(searchNoMatch);
|
||||
|
||||
// Make an AutoCompleteInput that uses our search and confirms results.
|
||||
let input = new AutoCompleteInputBase([searchNoMatch.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = INPUT_STR;
|
||||
|
||||
// Caret must be at the end for autoFill to happen.
|
||||
let strLen = INPUT_STR.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
do_check_eq(input.selectionStart, strLen);
|
||||
do_check_eq(input.selectionEnd, strLen);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
controller.input = input;
|
||||
controller.startSearch(INPUT_STR);
|
||||
|
||||
input.onSearchComplete = function () {
|
||||
// Should not try to autoFill to an empty value.
|
||||
do_check_eq(input.textValue, "moz");
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(searchNoMatch);
|
||||
run_next_test();
|
||||
};
|
||||
});
|
||||
|
||||
add_test(function autocomplete_defaultIndex_exceeds_matchCount() {
|
||||
const INPUT_STR = "moz";
|
||||
|
||||
// Result returning matches, but a bad defaultIndex.
|
||||
let searchBadIndex =
|
||||
new AutoCompleteSearchBase("searchBadIndex",
|
||||
new AutoCompleteBadIndexResult(["mozillaTest"], 1));
|
||||
registerAutoCompleteSearch(searchBadIndex);
|
||||
|
||||
// Make an AutoCompleteInput that uses our search and confirms results.
|
||||
let input = new AutoCompleteInputBase([searchBadIndex.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = INPUT_STR;
|
||||
|
||||
// Caret must be at the end for autoFill to happen.
|
||||
let strLen = INPUT_STR.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
do_check_eq(input.selectionStart, strLen);
|
||||
do_check_eq(input.selectionEnd, strLen);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
controller.input = input;
|
||||
controller.startSearch(INPUT_STR);
|
||||
|
||||
input.onSearchComplete = function () {
|
||||
// Should not try to autoFill to an empty value.
|
||||
do_check_eq(input.textValue, "moz");
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(searchBadIndex);
|
||||
run_next_test();
|
||||
};
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteResult(aValues) {
|
||||
this._values = aValues;
|
||||
this.defaultIndex = 0;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = -1;
|
||||
this.completeDefaultIndex = true;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_keyNavigation() {
|
||||
doSearch("MOZ", "mozilla", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "MOZilla");
|
||||
aController.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_RIGHT);
|
||||
do_check_eq(aController.input.textValue, "mozilla");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnter() {
|
||||
doSearch("MOZ", "mozilla", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "MOZilla");
|
||||
aController.handleEnter(false);
|
||||
do_check_eq(aController.input.textValue, "mozilla");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase("search",
|
||||
new AutoCompleteResult([ "mozilla", "toolkit" ], 0));
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
// Caret must be at the end for autofill to happen.
|
||||
let strLen = aSearchString.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
function AutoCompleteResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = 0;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
add_test(function test_handleEnter_mouse() {
|
||||
doSearch("moz", "mozilla.com", "http://www.mozilla.com", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "moz");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
// Keyboard interaction is tested by test_finalCompleteValueSelectedIndex.js
|
||||
// so here just test popup selection.
|
||||
aController.handleEnter(true);
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
function AutoCompleteResult(aResultValues) {
|
||||
this._values = aResultValues.map(x => x[0]);
|
||||
this._finalCompleteValues = aResultValues.map(x => x[1]);
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
var selectByWasCalled = false;
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = 0;
|
||||
this.popup.selectBy = function(reverse, page) {
|
||||
Assert.equal(selectByWasCalled, false);
|
||||
selectByWasCalled = true;
|
||||
Assert.equal(reverse, false);
|
||||
Assert.equal(page, false);
|
||||
this.selectedIndex += (reverse ? -1 : 1) * (page ? 100 : 1);
|
||||
};
|
||||
this.completeSelectedIndex = true;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
add_test(function test_handleEnter_key() {
|
||||
let results = [
|
||||
["mozilla.com", "http://www.mozilla.com"],
|
||||
["mozilla.org", "http://www.mozilla.org"],
|
||||
];
|
||||
// First check the case where we do select a value with the keyboard:
|
||||
doSearch("moz", results, function(aController) {
|
||||
Assert.equal(aController.input.textValue, "moz");
|
||||
Assert.equal(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
Assert.equal(aController.getFinalCompleteValueAt(1), "http://www.mozilla.org");
|
||||
|
||||
Assert.equal(aController.input.popup.selectedIndex, 0);
|
||||
aController.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_DOWN);
|
||||
Assert.equal(aController.input.popup.selectedIndex, 1);
|
||||
// Simulate mouse interaction changing selectedIndex
|
||||
// ie NOT keyboard interaction:
|
||||
aController.input.popup.selectedIndex = 0;
|
||||
|
||||
aController.handleEnter(false);
|
||||
// Verify that the keyboard-selected thing got inserted,
|
||||
// and not the mouse selection:
|
||||
Assert.equal(aController.input.textValue, "http://www.mozilla.org");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnter_mouse() {
|
||||
let results = [
|
||||
["mozilla.com", "http://www.mozilla.com"],
|
||||
["mozilla.org", "http://www.mozilla.org"],
|
||||
];
|
||||
// Then the case where we do not:
|
||||
doSearch("moz", results, function(aController) {
|
||||
Assert.equal(aController.input.textValue, "moz");
|
||||
Assert.equal(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
Assert.equal(aController.getFinalCompleteValueAt(1), "http://www.mozilla.org");
|
||||
|
||||
Assert.equal(aController.input.popup.selectedIndex, 0);
|
||||
aController.input.popupOpen = true;
|
||||
// Simulate mouse interaction changing selectedIndex
|
||||
// ie NOT keyboard interaction:
|
||||
aController.input.popup.selectedIndex = 1;
|
||||
Assert.equal(selectByWasCalled, false);
|
||||
Assert.equal(aController.input.popup.selectedIndex, 1);
|
||||
|
||||
aController.handleEnter(false);
|
||||
// Verify that the input stayed the same, because no selection was made
|
||||
// with the keyboard:
|
||||
Assert.equal(aController.input.textValue, "moz");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnter_preselected() {
|
||||
let results = [
|
||||
["mozilla.com", "http://www.mozilla.com"],
|
||||
["mozilla.org", "http://www.mozilla.org"],
|
||||
];
|
||||
// Then test a preselection.
|
||||
doSearch("moz", results, function(aController) {
|
||||
Assert.equal(aController.input.textValue, "moz");
|
||||
Assert.equal(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
Assert.equal(aController.getFinalCompleteValueAt(1), "http://www.mozilla.org");
|
||||
|
||||
aController.setInitiallySelectedIndex(0);
|
||||
|
||||
aController.handleEnter(false);
|
||||
// Verify that the input stayed the same, because no selection was made
|
||||
// with the keyboard:
|
||||
Assert.equal(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResults, aOnCompleteCallback) {
|
||||
selectByWasCalled = false;
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult(aResults)
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
function AutoCompleteResult(aResultValues) {
|
||||
this.defaultIndex = 0;
|
||||
this._values = aResultValues.map(x => x[0]);
|
||||
this._finalCompleteValues = aResultValues.map(x => x[1]);
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = 0;
|
||||
this.completeSelectedIndex = true;
|
||||
this.completeDefaultIndex = true;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
add_test(function test_handleEnter() {
|
||||
let results = [
|
||||
["mozilla.com", "https://www.mozilla.com"],
|
||||
["gomozilla.org", "http://www.gomozilla.org"],
|
||||
];
|
||||
doSearch("moz", results, { selectedIndex: 0 }, controller => {
|
||||
let input = controller.input;
|
||||
Assert.equal(input.textValue, "mozilla.com");
|
||||
Assert.equal(controller.getFinalCompleteValueAt(0), results[0][1]);
|
||||
Assert.equal(controller.getFinalCompleteValueAt(1), results[1][1]);
|
||||
Assert.equal(input.popup.selectedIndex, 0);
|
||||
|
||||
controller.handleEnter(false);
|
||||
// Verify that the keyboard-selected thing got inserted,
|
||||
// and not the mouse selection:
|
||||
Assert.equal(controller.input.textValue, "https://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnter_otherSelected() {
|
||||
// The popup selection may not coincide with what is filled into the input
|
||||
// field, for example if the user changed it with the mouse and then pressed
|
||||
// Enter. In such a case we should still use the inputField value and not the
|
||||
// popup selected value.
|
||||
let results = [
|
||||
["mozilla.com", "https://www.mozilla.com"],
|
||||
["gomozilla.org", "http://www.gomozilla.org"],
|
||||
];
|
||||
doSearch("moz", results, { selectedIndex: 1 }, controller => {
|
||||
let input = controller.input;
|
||||
Assert.equal(input.textValue, "mozilla.com");
|
||||
Assert.equal(controller.getFinalCompleteValueAt(0), results[0][1]);
|
||||
Assert.equal(controller.getFinalCompleteValueAt(1), results[1][1]);
|
||||
Assert.equal(input.popup.selectedIndex, 1);
|
||||
|
||||
controller.handleEnter(false);
|
||||
// Verify that the keyboard-selected thing got inserted,
|
||||
// and not the mouse selection:
|
||||
Assert.equal(controller.input.textValue, "https://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnter_otherSelected_nocompleteselectedindex() {
|
||||
let results = [
|
||||
["mozilla.com", "https://www.mozilla.com"],
|
||||
["gomozilla.org", "http://www.gomozilla.org"],
|
||||
];
|
||||
doSearch("moz", results, { selectedIndex: 1,
|
||||
completeSelectedIndex: false }, controller => {
|
||||
let input = controller.input;
|
||||
Assert.equal(input.textValue, "mozilla.com");
|
||||
Assert.equal(controller.getFinalCompleteValueAt(0), results[0][1]);
|
||||
Assert.equal(controller.getFinalCompleteValueAt(1), results[1][1]);
|
||||
Assert.equal(input.popup.selectedIndex, 1);
|
||||
|
||||
controller.handleEnter(false);
|
||||
// Verify that the keyboard-selected result is inserted, not the
|
||||
// defaultComplete.
|
||||
Assert.equal(controller.input.textValue, "http://www.gomozilla.org");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResults, aOptions, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult(aResults)
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
if ("selectedIndex" in aOptions) {
|
||||
input.popup.selectedIndex = aOptions.selectedIndex;
|
||||
}
|
||||
if ("completeSelectedIndex" in aOptions) {
|
||||
input.completeSelectedIndex = aOptions.completeSelectedIndex;
|
||||
}
|
||||
// Needed for defaultIndex completion.
|
||||
input.selectTextRange(aSearchString.length, aSearchString.length);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
this.defaultIndex = 0;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = -1;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_handleEnterWithDirectMatchCompleteSelectedIndex() {
|
||||
doSearch("moz", "mozilla.com", "http://www.mozilla.com",
|
||||
{ forceComplete: true, completeSelectedIndex: true }, function(aController) {
|
||||
do_check_eq(aController.input.textValue, "moz");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
aController.handleEnter(false);
|
||||
// After enter the final complete value should be shown in the input.
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnterWithDirectMatch() {
|
||||
doSearch("mozilla", "mozilla.com", "http://www.mozilla.com",
|
||||
{ forceComplete: true, completeDefaultIndex: true }, function(aController) {
|
||||
// Should autocomplete the search string to a suggestion.
|
||||
do_check_eq(aController.input.textValue, "mozilla.com");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
aController.handleEnter(false);
|
||||
// After enter the final complete value should be shown in the input.
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnterWithNoMatch() {
|
||||
doSearch("mozilla", "mozilla.com", "http://www.mozilla.com",
|
||||
{ forceComplete: true, completeDefaultIndex: true }, function(aController) {
|
||||
// Should autocomplete the search string to a suggestion.
|
||||
do_check_eq(aController.input.textValue, "mozilla.com");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
// Now input something that does not match...
|
||||
aController.input.textValue = "mozillax";
|
||||
// ... and confirm. We don't want one of the values from the previous
|
||||
// results to be taken, since what's now in the input field doesn't match.
|
||||
aController.handleEnter(false);
|
||||
do_check_eq(aController.input.textValue, "mozillax");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnterWithIndirectMatch() {
|
||||
doSearch("com", "mozilla.com", "http://www.mozilla.com",
|
||||
{ forceComplete: true, completeDefaultIndex: true }, function(aController) {
|
||||
// Should autocomplete the search string to a suggestion.
|
||||
do_check_eq(aController.input.textValue, "com >> mozilla.com");
|
||||
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
|
||||
aController.handleEnter(false);
|
||||
// After enter the final complete value from the suggestion should be shown
|
||||
// in the input.
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aFinalCompleteValue,
|
||||
aInputProps, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
for (var p in aInputProps) {
|
||||
input[p] = aInputProps[p];
|
||||
}
|
||||
input.textValue = aSearchString;
|
||||
// Place the cursor at the end of the input so that completion to
|
||||
// default index will kick in.
|
||||
input.selectTextRange(aSearchString.length, aSearchString.length);
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
this.defaultIndex = 0;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popup.selectedIndex = -1;
|
||||
this.completeDefaultIndex = true;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_keyNavigation() {
|
||||
doSearch("moz", "mozilla.com", "http://www.mozilla.com", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "mozilla.com");
|
||||
aController.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_RIGHT);
|
||||
do_check_eq(aController.input.textValue, "mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_handleEnter() {
|
||||
doSearch("moz", "mozilla.com", "http://www.mozilla.com", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "mozilla.com");
|
||||
aController.handleEnter(false);
|
||||
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
// Caret must be at the end for autofill to happen.
|
||||
let strLen = aSearchString.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function AutoCompleteResult(aValues) {
|
||||
this._values = aValues;
|
||||
this.defaultIndex = -1;
|
||||
this._typeAheadResult = false;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteTypeAheadResult(aValues) {
|
||||
this._values = aValues;
|
||||
this.defaultIndex = 0;
|
||||
this._typeAheadResult = true;
|
||||
}
|
||||
AutoCompleteTypeAheadResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
|
||||
/**
|
||||
* Test AutoComplete with multiple AutoCompleteSearch sources, with one of them
|
||||
* being hidden from the popup, but can still do typeahead completion.
|
||||
*/
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
var inputStr = "moz";
|
||||
|
||||
// Type ahead result
|
||||
var searchTypeAhead = new AutoCompleteSearchBase("search1",
|
||||
new AutoCompleteTypeAheadResult(["mozillaTest1"]));
|
||||
// Regular result
|
||||
var searchNormal = new AutoCompleteSearchBase("search2",
|
||||
new AutoCompleteResult(["mozillaTest2"]));
|
||||
|
||||
// Register searches so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(searchNormal);
|
||||
registerAutoCompleteSearch(searchTypeAhead);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete.
|
||||
var input = new AutoCompleteInputBase([searchTypeAhead.name, searchNormal.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = inputStr;
|
||||
|
||||
// Caret must be at the end. Autofill doesn't happen unless you're typing
|
||||
// characters at the end.
|
||||
var strLen = inputStr.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
do_check_eq(input.selectionStart, strLen);
|
||||
do_check_eq(input.selectionEnd, strLen);
|
||||
|
||||
var controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(inputStr);
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
// Hidden results should still be able to do inline autocomplete
|
||||
do_check_eq(input.textValue, "mozillaTest1");
|
||||
|
||||
// Now, let's fill the textbox with the first result of the popup.
|
||||
// The first search is marked as hidden, so we must always get the
|
||||
// second search.
|
||||
controller.handleEnter(true);
|
||||
do_check_eq(input.textValue, "mozillaTest2");
|
||||
|
||||
// Only one item in the popup.
|
||||
do_check_eq(controller.matchCount, 1);
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(searchNormal);
|
||||
unregisterAutoCompleteSearch(searchTypeAhead);
|
||||
do_test_finished();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
function AutoCompleteImmediateSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteImmediateSearch.prototype = Object.create(AutoCompleteSearchBase.prototype);
|
||||
AutoCompleteImmediateSearch.prototype.searchType =
|
||||
Ci.nsIAutoCompleteSearchDescriptor.SEARCH_TYPE_IMMEDIATE;
|
||||
AutoCompleteImmediateSearch.prototype.QueryInterface =
|
||||
XPCOMUtils.generateQI([Ci.nsIFactory,
|
||||
Ci.nsIAutoCompleteSearch,
|
||||
Ci.nsIAutoCompleteSearchDescriptor]);
|
||||
|
||||
function AutoCompleteDelayedSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteDelayedSearch.prototype = Object.create(AutoCompleteSearchBase.prototype);
|
||||
|
||||
function AutoCompleteResult(aValues, aDefaultIndex) {
|
||||
this._values = aValues;
|
||||
this.defaultIndex = aDefaultIndex;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
/**
|
||||
* An immediate search should be executed synchronously.
|
||||
*/
|
||||
add_test(function test_immediate_search() {
|
||||
let inputStr = "moz";
|
||||
|
||||
let immediateSearch = new AutoCompleteImmediateSearch(
|
||||
"immediate", new AutoCompleteResult(["moz-immediate"], 0));
|
||||
registerAutoCompleteSearch(immediateSearch);
|
||||
let delayedSearch = new AutoCompleteDelayedSearch(
|
||||
"delayed", new AutoCompleteResult(["moz-delayed"], 0));
|
||||
registerAutoCompleteSearch(delayedSearch);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
let input = new AutoCompleteInputBase([delayedSearch.name,
|
||||
immediateSearch.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = inputStr;
|
||||
|
||||
// Caret must be at the end. Autofill doesn't happen unless you're typing
|
||||
// characters at the end.
|
||||
let strLen = inputStr.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
|
||||
controller.input = input;
|
||||
controller.startSearch(inputStr);
|
||||
|
||||
// Immediately check the result, the immediate search should have finished.
|
||||
do_check_eq(input.textValue, "moz-immediate");
|
||||
|
||||
// Wait for both queries to finish.
|
||||
input.onSearchComplete = function() {
|
||||
// Sanity check.
|
||||
do_check_eq(input.textValue, "moz-immediate");
|
||||
|
||||
unregisterAutoCompleteSearch(immediateSearch);
|
||||
unregisterAutoCompleteSearch(delayedSearch);
|
||||
run_next_test();
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* An immediate search should be executed before any delayed search.
|
||||
*/
|
||||
add_test(function test_immediate_search_notimeout() {
|
||||
let inputStr = "moz";
|
||||
|
||||
let immediateSearch = new AutoCompleteImmediateSearch(
|
||||
"immediate", new AutoCompleteResult(["moz-immediate"], 0));
|
||||
registerAutoCompleteSearch(immediateSearch);
|
||||
|
||||
let delayedSearch = new AutoCompleteDelayedSearch(
|
||||
"delayed", new AutoCompleteResult(["moz-delayed"], 0));
|
||||
registerAutoCompleteSearch(delayedSearch);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
let input = new AutoCompleteInputBase([delayedSearch.name,
|
||||
immediateSearch.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = inputStr;
|
||||
input.timeout = 0;
|
||||
|
||||
// Caret must be at the end. Autofill doesn't happen unless you're typing
|
||||
// characters at the end.
|
||||
let strLen = inputStr.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
|
||||
controller.input = input;
|
||||
let complete = false;
|
||||
input.onSearchComplete = function() {
|
||||
complete = true;
|
||||
};
|
||||
controller.startSearch(inputStr);
|
||||
do_check_true(complete);
|
||||
|
||||
// Immediately check the result, the immediate search should have finished.
|
||||
do_check_eq(input.textValue, "moz-immediate");
|
||||
|
||||
unregisterAutoCompleteSearch(immediateSearch);
|
||||
unregisterAutoCompleteSearch(delayedSearch);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* A delayed search should be executed synchronously with a zero timeout.
|
||||
*/
|
||||
add_test(function test_delayed_search_notimeout() {
|
||||
let inputStr = "moz";
|
||||
|
||||
let delayedSearch = new AutoCompleteDelayedSearch(
|
||||
"delayed", new AutoCompleteResult(["moz-delayed"], 0));
|
||||
registerAutoCompleteSearch(delayedSearch);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
let input = new AutoCompleteInputBase([delayedSearch.name]);
|
||||
input.completeDefaultIndex = true;
|
||||
input.textValue = inputStr;
|
||||
input.timeout = 0;
|
||||
|
||||
// Caret must be at the end. Autofill doesn't happen unless you're typing
|
||||
// characters at the end.
|
||||
let strLen = inputStr.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
|
||||
controller.input = input;
|
||||
let complete = false;
|
||||
input.onSearchComplete = function() {
|
||||
complete = true;
|
||||
};
|
||||
controller.startSearch(inputStr);
|
||||
do_check_true(complete);
|
||||
|
||||
// Immediately check the result, the delayed search should have finished.
|
||||
do_check_eq(input.textValue, "moz-delayed");
|
||||
|
||||
unregisterAutoCompleteSearch(delayedSearch);
|
||||
run_next_test();
|
||||
});
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
function run_test() {
|
||||
let result = Cc["@mozilla.org/autocomplete/simple-result;1"]
|
||||
.createInstance(Ci.nsIAutoCompleteSimpleResult);
|
||||
result.appendMatch("a", "");
|
||||
result.appendMatch("c", "");
|
||||
result.insertMatchAt(1, "b", "");
|
||||
result.insertMatchAt(3, "d", "");
|
||||
|
||||
Assert.equal(result.matchCount, 4);
|
||||
Assert.equal(result.getValueAt(0), "a");
|
||||
Assert.equal(result.getValueAt(1), "b");
|
||||
Assert.equal(result.getValueAt(2), "c");
|
||||
Assert.equal(result.getValueAt(3), "d");
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function AutoCompleteTypeAheadResult(aValues, aFinalCompleteValues) {
|
||||
this._values = aValues;
|
||||
this._finalCompleteValues = aFinalCompleteValues;
|
||||
this.defaultIndex = 0;
|
||||
this._typeAheadResult = true;
|
||||
}
|
||||
AutoCompleteTypeAheadResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteResult(aValues) {
|
||||
this._values = aValues;
|
||||
}
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
this.popupOpen = true;
|
||||
this.completeDefaultIndex = true;
|
||||
this.completeSelectedIndex = true;
|
||||
}
|
||||
AutoCompleteInput.prototype = Object.create(AutoCompleteInputBase.prototype);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_handleEnter() {
|
||||
doSearch("moz", function(aController) {
|
||||
do_check_eq(aController.input.textValue, "mozilla.com");
|
||||
aController.handleEnter(true);
|
||||
do_check_eq(aController.input.textValue, "mozilla.org");
|
||||
});
|
||||
});
|
||||
|
||||
function doSearch(aSearchString, aOnCompleteCallback) {
|
||||
let typeAheadSearch = new AutoCompleteSearchBase(
|
||||
"typeAheadSearch",
|
||||
new AutoCompleteTypeAheadResult([ "mozilla.com" ], [ "http://www.mozilla.com" ])
|
||||
);
|
||||
registerAutoCompleteSearch(typeAheadSearch);
|
||||
|
||||
let search = new AutoCompleteSearchBase(
|
||||
"search",
|
||||
new AutoCompleteResult([ "mozilla.org" ])
|
||||
);
|
||||
registerAutoCompleteSearch(search);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput([ typeAheadSearch.name, search.name ]);
|
||||
input.textValue = aSearchString;
|
||||
|
||||
// Caret must be at the end for autofill to happen.
|
||||
let strLen = aSearchString.length;
|
||||
input.selectTextRange(strLen, strLen);
|
||||
controller.input = input;
|
||||
controller.startSearch(aSearchString);
|
||||
|
||||
input.onSearchComplete = function onSearchComplete() {
|
||||
aOnCompleteCallback(controller);
|
||||
|
||||
// Clean up.
|
||||
unregisterAutoCompleteSearch(search);
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
|
@ -1,280 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Unit test for Bug 438861 - Previous search results not returned to multiple
|
||||
* searches.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
|
||||
// Array of AutoCompleteSearch names
|
||||
searches: null,
|
||||
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
|
||||
get searchCount() {
|
||||
return this.searches.length;
|
||||
},
|
||||
|
||||
getSearchAt: function(aIndex) {
|
||||
return this.searches[aIndex];
|
||||
},
|
||||
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
|
||||
popupOpen: false,
|
||||
|
||||
popup: {
|
||||
setSelectedIndex: function(aIndex) {},
|
||||
invalidate: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompletePopup))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteInput))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteResult implementation
|
||||
*/
|
||||
function AutoCompleteResult(aValues, aComments, aStyles) {
|
||||
this._values = aValues;
|
||||
this._comments = aComments;
|
||||
this._styles = aStyles;
|
||||
if (this._values.length > 0) {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
|
||||
} else {
|
||||
this.searchResult = Ci.nsIAutoCompleteResult.NOMATCH;
|
||||
}
|
||||
}
|
||||
AutoCompleteResult.prototype = {
|
||||
constructor: AutoCompleteResult,
|
||||
|
||||
// Arrays
|
||||
_values: null,
|
||||
_comments: null,
|
||||
_styles: null,
|
||||
|
||||
searchString: "",
|
||||
searchResult: null,
|
||||
|
||||
defaultIndex: 0,
|
||||
|
||||
get matchCount() {
|
||||
return this._values.length;
|
||||
},
|
||||
|
||||
getValueAt: function(aIndex) {
|
||||
return this._values[aIndex];
|
||||
},
|
||||
|
||||
getLabelAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
getCommentAt: function(aIndex) {
|
||||
return this._comments[aIndex];
|
||||
},
|
||||
|
||||
getStyleAt: function(aIndex) {
|
||||
return this._styles[aIndex];
|
||||
},
|
||||
|
||||
getImageAt: function(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIAutoCompleteResult))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation that always returns
|
||||
* the same result set.
|
||||
*/
|
||||
function AutoCompleteSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
|
||||
// Search name. Used by AutoCompleteController
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result: null,
|
||||
|
||||
_previousResult: null,
|
||||
|
||||
|
||||
/**
|
||||
* Return the same result set for every search
|
||||
*/
|
||||
startSearch: function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener)
|
||||
{
|
||||
this._previousResult = aPreviousResult;
|
||||
aListener.onSearchResult(this, this._result);
|
||||
},
|
||||
|
||||
stopSearch: function() {},
|
||||
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIAutoCompleteSearch))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch) {
|
||||
var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
|
||||
var uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
var cid = uuidGenerator.generateUUID();
|
||||
|
||||
var desc = "Test AutoCompleteSearch";
|
||||
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
function run_test() {
|
||||
// Make an AutoCompleteSearch that always returns nothing
|
||||
var search1 = new AutoCompleteSearch("test-previous-result1",
|
||||
new AutoCompleteResult(["hello1"], [""], [""]));
|
||||
|
||||
var search2 = new AutoCompleteSearch("test-previous-result2",
|
||||
new AutoCompleteResult(["hello2"], [""], [""]));
|
||||
|
||||
// Register search so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(search1);
|
||||
registerAutoCompleteSearch(search2);
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our search
|
||||
// and confirms results on search complete
|
||||
var input = new AutoCompleteInput([search1.name,
|
||||
search2.name]);
|
||||
var numSearchesStarted = 0;
|
||||
|
||||
input.onSearchBegin = function() {
|
||||
numSearchesStarted++;
|
||||
};
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
do_check_eq(controller.matchCount, 2);
|
||||
|
||||
if (numSearchesStarted == 1) {
|
||||
do_check_eq(search1._previousResult, null);
|
||||
do_check_eq(search2._previousResult, null);
|
||||
|
||||
// Now start it again
|
||||
controller.startSearch("test");
|
||||
return;
|
||||
}
|
||||
do_check_neq(search1._previousResult, null);
|
||||
do_check_neq(search2._previousResult, null);
|
||||
|
||||
// Unregister searches
|
||||
unregisterAutoCompleteSearch(search1);
|
||||
unregisterAutoCompleteSearch(search2);
|
||||
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
controller.startSearch("test");
|
||||
}
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Purpose of the test is to check that a stopSearch call comes always before a
|
||||
* startSearch call.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
|
||||
/**
|
||||
* Dummy nsIAutoCompleteInput source that returns
|
||||
* the given list of AutoCompleteSearch names.
|
||||
*
|
||||
* Implements only the methods needed for this test.
|
||||
*/
|
||||
function AutoCompleteInput(aSearches)
|
||||
{
|
||||
this.searches = aSearches;
|
||||
}
|
||||
AutoCompleteInput.prototype = {
|
||||
constructor: AutoCompleteInput,
|
||||
minResultsForPopup: 0,
|
||||
timeout: 10,
|
||||
searchParam: "",
|
||||
textValue: "hello",
|
||||
disableAutoComplete: false,
|
||||
completeDefaultIndex: false,
|
||||
set popupOpen(val) { return val; }, // ignore
|
||||
get popupOpen() { return false; },
|
||||
get searchCount() { return this.searches.length; },
|
||||
getSearchAt: function(aIndex) { return this.searches[aIndex]; },
|
||||
onSearchBegin: function() {},
|
||||
onSearchComplete: function() {},
|
||||
onTextReverted: function () {},
|
||||
onTextEntered: function () {},
|
||||
popup: {
|
||||
selectBy: function() {},
|
||||
invalidate: function() {},
|
||||
set selectedIndex(val) { return val; }, // ignore
|
||||
get selectedIndex() { return -1 },
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup])
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput])
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nsIAutoCompleteSearch implementation.
|
||||
*/
|
||||
function AutoCompleteSearch(aName)
|
||||
{
|
||||
this.name = aName;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
stopSearchInvoked: true,
|
||||
startSearch: function(aSearchString, aSearchParam, aPreviousResult, aListener)
|
||||
{
|
||||
print("Check stop search has been called");
|
||||
do_check_true(this.stopSearchInvoked);
|
||||
this.stopSearchInvoked = false;
|
||||
},
|
||||
stopSearch: function()
|
||||
{
|
||||
this.stopSearchInvoked = true;
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIFactory
|
||||
, Ci.nsIAutoCompleteSearch
|
||||
]),
|
||||
createInstance: function(outer, iid)
|
||||
{
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to register an AutoCompleteSearch with the given name.
|
||||
* Allows the AutoCompleteController to find the search.
|
||||
*/
|
||||
function registerAutoCompleteSearch(aSearch)
|
||||
{
|
||||
let name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;
|
||||
let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].
|
||||
getService(Ci.nsIUUIDGenerator);
|
||||
let cid = uuidGenerator.generateUUID();
|
||||
let desc = "Test AutoCompleteSearch";
|
||||
let componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(cid, desc, name, aSearch);
|
||||
// Keep the id on the object so we can unregister later
|
||||
aSearch.cid = cid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to unregister an AutoCompleteSearch.
|
||||
*/
|
||||
function unregisterAutoCompleteSearch(aSearch) {
|
||||
let componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aSearch.cid, aSearch);
|
||||
}
|
||||
|
||||
|
||||
var gTests = [
|
||||
function(controller) {
|
||||
print("handleText");
|
||||
controller.input.textValue = "hel";
|
||||
controller.handleText();
|
||||
},
|
||||
function(controller) {
|
||||
print("handleStartComposition");
|
||||
controller.handleStartComposition();
|
||||
},
|
||||
function(controller) {
|
||||
print("handleEndComposition");
|
||||
controller.handleEndComposition();
|
||||
// an input event always follows compositionend event.
|
||||
controller.handleText();
|
||||
},
|
||||
function(controller) {
|
||||
print("handleEscape");
|
||||
controller.handleEscape();
|
||||
},
|
||||
function(controller) {
|
||||
print("handleEnter");
|
||||
controller.handleEnter(false);
|
||||
},
|
||||
function(controller) {
|
||||
print("handleTab");
|
||||
controller.handleTab();
|
||||
},
|
||||
|
||||
function(controller) {
|
||||
print("handleKeyNavigation");
|
||||
controller.handleKeyNavigation(Ci.nsIDOMKeyEvent.DOM_VK_UP);
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
var gSearch;
|
||||
var gCurrentTest;
|
||||
function run_test() {
|
||||
// Make an AutoCompleteSearch that always returns nothing
|
||||
gSearch = new AutoCompleteSearch("test");
|
||||
registerAutoCompleteSearch(gSearch);
|
||||
|
||||
let controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our search.
|
||||
let input = new AutoCompleteInput([gSearch.name]);
|
||||
controller.input = input;
|
||||
|
||||
input.onSearchBegin = function() {
|
||||
do_execute_soon(function() {
|
||||
gCurrentTest(controller);
|
||||
});
|
||||
};
|
||||
input.onSearchComplete = function() {
|
||||
run_next_test(controller);
|
||||
}
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
run_next_test(controller);
|
||||
}
|
||||
|
||||
function run_next_test(controller) {
|
||||
if (gTests.length == 0) {
|
||||
unregisterAutoCompleteSearch(gSearch);
|
||||
controller.stopSearch();
|
||||
controller.input = null;
|
||||
do_test_finished();
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentTest = gTests.shift();
|
||||
controller.startSearch("hello");
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
[DEFAULT]
|
||||
head = head_autocomplete.js
|
||||
tail =
|
||||
|
||||
[test_330578.js]
|
||||
[test_378079.js]
|
||||
[test_393191.js]
|
||||
[test_440866.js]
|
||||
[test_463023.js]
|
||||
[test_660156.js]
|
||||
[test_autocomplete_multiple.js]
|
||||
[test_autocomplete_userContextId.js]
|
||||
[test_autofillSelectedPopupIndex.js]
|
||||
[test_badDefaultIndex.js]
|
||||
[test_completeDefaultIndex_casing.js]
|
||||
[test_finalCompleteValue.js]
|
||||
[test_finalCompleteValue_defaultIndex.js]
|
||||
[test_finalCompleteValue_forceComplete.js]
|
||||
[test_finalCompleteValueSelectedIndex.js]
|
||||
[test_finalDefaultCompleteValue.js]
|
||||
[test_hiddenResult.js]
|
||||
[test_immediate_search.js]
|
||||
[test_insertMatchAt.js]
|
||||
[test_popupSelectionVsDefaultCompleteValue.js]
|
||||
[test_previousResult.js]
|
||||
[test_stopSearch.js]
|
||||
Loading…
Add table
Add a link
Reference in a new issue