1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Autocomplete emphasis test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<textbox id="richautocomplete" type="autocomplete"
autocompletesearch="simple"
onsearchcomplete="checkSearchCompleted();"
autocompletepopup="richpopup"/>
<panel id="richpopup" type="autocomplete-richlistbox" noautofocus="true"/>
<script class="testbody" type="application/javascript">
<![CDATA[
const ACR = Components.interfaces.nsIAutoCompleteResult;
// A global variable to hold the search result for the current search.
var resultText = "";
// This result can't be constructed in-line, because otherwise we leak memory.
function nsAutoCompleteSimpleResult(aString)
{
this.searchString = aString;
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
}
nsAutoCompleteSimpleResult.prototype = {
searchString: null,
searchResult: ACR.RESULT_FAILURE,
defaultIndex: -1,
errorDescription: null,
matchCount: 0,
getValueAt: function() { return resultText; },
getCommentAt: function() { return this.getValueAt(); },
getStyleAt: function() { return null; },
getImageAt: function() { return null; },
getFinalCompleteValueAt: function() { return this.getValueAt(); },
getLabelAt: function() { return this.getValueAt(); },
removeValueAt: function() {}
};
// A basic autocomplete implementation that returns the string contained in 'resultText'.
var autoCompleteSimpleID = Components.ID("0a2afbdb-f30e-47d1-9cb1-0cd160240aca");
var autoCompleteSimpleName = "@mozilla.org/autocomplete/search;1?name=simple"
var autoCompleteSimple = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIFactory) ||
iid.equals(Components.interfaces.nsIAutoCompleteSearch))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
startSearch: function(aString, aParam, aResult, aListener) {
var result = new nsAutoCompleteSimpleResult(aString);
aListener.onSearchResult(this, result);
},
stopSearch: function() {}
};
var componentManager = Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar);
componentManager.registerFactory(autoCompleteSimpleID, "Test Simple Autocomplete",
autoCompleteSimpleName, autoCompleteSimple);
SimpleTest.waitForExplicitFinish();
setTimeout(nextTest, 0);
/* Test cases have the following attributes:
* - search: A search string, to be emphasized in the result.
* - result: A fixed result string, so we can hardcode the expected emphasis.
* - emphasis: A list of chunks that should be emphasized or not, in strict alternation.
* - emphasizeFirst: Whether the first element of 'emphasis' should be emphasized;
* The emphasis of the other elements is defined by the strict alternation rule.
*/
let testcases = [
{ search: "test",
result: "A test string",
emphasis: ["A ", "test", " string"],
emphasizeFirst: false
},
{ search: "tea two",
result: "Tea for two, and two for tea...",
emphasis: ["Tea", " for ", "two", ", and ", "two", " for ", "tea", "..."],
emphasizeFirst: true
},
{ search: "tat",
result: "tatatat",
emphasis: ["tatatat"],
emphasizeFirst: true
},
{ search: "cheval valise",
result: "chevalise",
emphasis: ["chevalise"],
emphasizeFirst: true
}
];
let test = -1;
let currentTest = null;
function nextTest() {
test++;
if (test >= testcases.length) {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);
SimpleTest.finish();
return;
}
// blur the field to ensure that the popup is closed and that the previous
// search has stopped, then start a new search.
let autocomplete = $("richautocomplete");
autocomplete.blur();
autocomplete.focus();
currentTest = testcases[test];
resultText = currentTest.result;
autocomplete.value = currentTest.search;
synthesizeKey("VK_DOWN", {});
}
function checkSearchCompleted() {
let autocomplete = $("richautocomplete");
let result = autocomplete.popup.richlistbox.firstChild;
for (let attribute of [result._titleText, result._urlText]) {
is(attribute.childNodes.length, currentTest.emphasis.length,
"The element should have the expected number of children.");
for (let i = 0; i < currentTest.emphasis.length; i++) {
let node = attribute.childNodes[i];
// Emphasized parts strictly alternate.
if ((i % 2 == 0) == currentTest.emphasizeFirst) {
// Check that this part is correctly emphasized.
is(node.nodeName, "span", ". That child should be a span node");
ok(node.classList.contains("ac-emphasize-text"), ". That child should be emphasized");
is(node.textContent, currentTest.emphasis[i], ". That emphasis should be as expected.");
} else {
// Check that this part is _not_ emphasized.
is(node.nodeName, "#text", ". That child should be a text node");
is(node.textContent, currentTest.emphasis[i], ". That text should be as expected.");
}
}
}
setTimeout(nextTest, 0);
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>
|