Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 // nsDoTestsForAutoCompleteWithComposition tests autocomplete with composition.
2 // Users must include SimpleTest.js and EventUtils.js.
4 function nsDoTestsForAutoCompleteWithComposition(aDescription,
5 aWindow,
6 aTarget,
7 aAutoCompleteController,
8 aIsFunc,
9 aGetTargetValueFunc,
10 aOnFinishFunc)
11 {
12 this._description = aDescription;
13 this._window = aWindow;
14 this._target = aTarget;
15 this._controller = aAutoCompleteController;
17 this._is = aIsFunc;
18 this._getTargetValue = aGetTargetValueFunc;
19 this._onFinish = aOnFinishFunc;
21 this._target.focus();
23 this._DefaultCompleteDefaultIndex =
24 this._controller.input.completeDefaultIndex;
26 this._doTests();
27 }
29 nsDoTestsForAutoCompleteWithComposition.prototype = {
30 _window: null,
31 _target: null,
32 _controller: null,
33 _DefaultCompleteDefaultIndex: false,
34 _description: "",
36 _is: null,
37 _getTargetValue: function () { return "not initialized"; },
38 _onFinish: null,
40 _doTests: function ()
41 {
42 if (++this._testingIndex == this._tests.length) {
43 this._controller.input.completeDefaultIndex =
44 this._DefaultCompleteDefaultIndex;
45 this._onFinish();
46 return;
47 }
49 var test = this._tests[this._testingIndex];
50 if (this._controller.input.completeDefaultIndex != test.completeDefaultIndex) {
51 this._controller.input.completeDefaultIndex = test.completeDefaultIndex;
52 }
53 test.execute(this._window);
55 var timeout = this._controller.input.timeout + 10;
56 this._waitResult(timeout);
57 },
59 _waitResult: function (aTimes)
60 {
61 var obj = this;
62 if (aTimes-- > 0) {
63 setTimeout(function () { obj._waitResult(aTimes); }, 0);
64 } else {
65 setTimeout(function () { obj._checkResult(); }, 0);
66 }
67 },
69 _checkResult: function ()
70 {
71 var test = this._tests[this._testingIndex];
72 this._is(this._getTargetValue(), test.value,
73 this._description + ", " + test.description + ": value");
74 this._is(this._controller.searchString, test.searchString,
75 this._description + ", " + test.description +": searchString");
76 this._is(this._controller.input.popupOpen, test.popup,
77 this._description + ", " + test.description + ": popupOpen");
78 this._doTests();
79 },
81 _testingIndex: -1,
82 _tests: [
83 // Simple composition when popup hasn't been shown.
84 // The autocomplete popup should not be shown during composition, but
85 // after compositionend, the popup should be shown.
86 { description: "compositionstart shouldn't open the popup",
87 completeDefaultIndex: false,
88 execute: function (aWindow) {
89 synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
90 synthesizeComposition({ type: "compositionstart" }, aWindow);
91 synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow);
92 synthesizeText(
93 { "composition":
94 { "string": "M",
95 "clauses":
96 [
97 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
98 ]
99 },
100 "caret": { "start": 1, "length": 0 }
101 }, aWindow);
102 }, popup: false, value: "M", searchString: ""
103 },
104 { description: "compositionupdate shouldn't open the popup",
105 completeDefaultIndex: false,
106 execute: function (aWindow) {
107 synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow);
108 synthesizeText(
109 { "composition":
110 { "string": "Mo",
111 "clauses":
112 [
113 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
114 ]
115 },
116 "caret": { "start": 2, "length": 0 }
117 }, aWindow);
118 }, popup: false, value: "Mo", searchString: ""
119 },
120 { description: "compositionend should open the popup",
121 completeDefaultIndex: false,
122 execute: function (aWindow) {
123 synthesizeText(
124 { "composition":
125 { "string": "Mo",
126 "clauses":
127 [
128 { "length": 0, "attr": 0 }
129 ]
130 },
131 "caret": { "start": 2, "length": 0 }
132 }, aWindow);
133 synthesizeComposition({ type: "compositionend", data: "Mo" }, aWindow);
134 synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow);
135 }, popup: true, value: "Mo", searchString: "Mo"
136 },
137 // If composition starts when popup is shown, the compositionstart event
138 // should cause closing the popup.
139 { description: "compositionstart should close the popup",
140 completeDefaultIndex: false,
141 execute: function (aWindow) {
142 synthesizeKey("z", { type: "keydown" }, aWindow);
143 synthesizeComposition({ type: "compositionstart" }, aWindow);
144 synthesizeComposition({ type: "compositionupdate", data: "z" }, aWindow);
145 synthesizeText(
146 { "composition":
147 { "string": "z",
148 "clauses":
149 [
150 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
151 ]
152 },
153 "caret": { "start": 1, "length": 0 }
154 }, aWindow);
155 }, popup: false, value: "Moz", searchString: "Mo"
156 },
157 { description: "compositionupdate shouldn't reopen the popup",
158 completeDefaultIndex: false,
159 execute: function (aWindow) {
160 synthesizeComposition({ type: "compositionupdate", data: "zi" }, aWindow);
161 synthesizeText(
162 { "composition":
163 { "string": "zi",
164 "clauses":
165 [
166 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
167 ]
168 },
169 "caret": { "start": 2, "length": 0 }
170 }, aWindow);
171 }, popup: false, value: "Mozi", searchString: "Mo"
172 },
173 { description: "compositionend should research the result and open the popup",
174 completeDefaultIndex: false,
175 execute: function (aWindow) {
176 synthesizeText(
177 { "composition":
178 { "string": "zi",
179 "clauses":
180 [
181 { "length": 0, "attr": 0 }
182 ]
183 },
184 "caret": { "start": 2, "length": 0 }
185 });
186 synthesizeComposition({ type: "compositionend", data: "zi" }, aWindow);
187 synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow);
188 }, popup: true, value: "Mozi", searchString: "Mozi"
189 },
190 // If composition is cancelled, the value shouldn't be changed.
191 { description: "compositionstart should reclose the popup",
192 completeDefaultIndex: false,
193 execute: function (aWindow) {
194 synthesizeKey("l", { type: "keydown" }, aWindow);
195 synthesizeComposition({ type: "compositionstart" }, aWindow);
196 synthesizeComposition({ type: "compositionupdate", data: "l" }, aWindow);
197 synthesizeText(
198 { "composition":
199 { "string": "l",
200 "clauses":
201 [
202 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
203 ]
204 },
205 "caret": { "start": 1, "length": 0 }
206 }, aWindow);
207 }, popup: false, value: "Mozil", searchString: "Mozi"
208 },
209 { description: "compositionupdate shouldn't reopen the popup",
210 completeDefaultIndex: false,
211 execute: function (aWindow) {
212 synthesizeComposition({ type: "compositionupdate", data: "ll" }, aWindow);
213 synthesizeText(
214 { "composition":
215 { "string": "ll",
216 "clauses":
217 [
218 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
219 ]
220 },
221 "caret": { "start": 2, "length": 0 }
222 }, aWindow);
223 }, popup: false, value: "Mozill", searchString: "Mozi"
224 },
225 { description: "empty compositionupdate shouldn't reopen the popup",
226 completeDefaultIndex: false,
227 execute: function (aWindow) {
228 synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow);
229 synthesizeText(
230 { "composition":
231 { "string": "",
232 "clauses":
233 [
234 { "length": 0, "attr": 0 }
235 ]
236 },
237 "caret": { "start": 0, "length": 0 }
238 }, aWindow);
239 }, popup: false, value: "Mozi", searchString: "Mozi"
240 },
241 { description: "cancled compositionend should reopen the popup",
242 completeDefaultIndex: false,
243 execute: function (aWindow) {
244 synthesizeText(
245 { "composition":
246 { "string": "",
247 "clauses":
248 [
249 { "length": 0, "attr": 0 }
250 ]
251 },
252 "caret": { "start": 0, "length": 0 }
253 }, aWindow);
254 synthesizeComposition({ type: "compositionend", data: "" }, aWindow);
255 synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
256 }, popup: true, value: "Mozi", searchString: "Mozi"
257 },
258 // But if composition replaces some characters and canceled, the search
259 // string should be the latest value.
260 { description: "compositionstart with selected string should close the popup",
261 completeDefaultIndex: false,
262 execute: function (aWindow) {
263 synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
264 synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
265 synthesizeKey("z", { type: "keydown" }, aWindow);
266 synthesizeComposition({ type: "compositionstart" }, aWindow);
267 synthesizeComposition({ type: "compositionupdate", data: "z" }, aWindow);
268 synthesizeText(
269 { "composition":
270 { "string": "z",
271 "clauses":
272 [
273 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
274 ]
275 },
276 "caret": { "start": 1, "length": 0 }
277 }, aWindow);
278 }, popup: false, value: "Moz", searchString: "Mozi"
279 },
280 { description: "compositionupdate shouldn't reopen the popup",
281 completeDefaultIndex: false,
282 execute: function (aWindow) {
283 synthesizeComposition({ type: "compositionupdate", data: "zi" }, aWindow);
284 synthesizeText(
285 { "composition":
286 { "string": "zi",
287 "clauses":
288 [
289 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
290 ]
291 },
292 "caret": { "start": 2, "length": 0 }
293 }, aWindow);
294 }, popup: false, value: "Mozi", searchString: "Mozi"
295 },
296 { description: "empty compositionupdate shouldn't reopen the popup",
297 completeDefaultIndex: false,
298 execute: function (aWindow) {
299 synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow);
300 synthesizeText(
301 { "composition":
302 { "string": "",
303 "clauses":
304 [
305 { "length": 0, "attr": 0 }
306 ]
307 },
308 "caret": { "start": 0, "length": 0 }
309 }, aWindow);
310 }, popup: false, value: "Mo", searchString: "Mozi"
311 },
312 { description: "canceled compositionend should seach the result with the latest value",
313 completeDefaultIndex: false,
314 execute: function (aWindow) {
315 synthesizeText(
316 { "composition":
317 { "string": "",
318 "clauses":
319 [
320 { "length": 0, "attr": 0 }
321 ]
322 },
323 "caret": { "start": 0, "length": 0 }
324 }, aWindow);
325 synthesizeComposition({ type: "compositionend", data: "" }, aWindow);
326 synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
327 }, popup: true, value: "Mo", searchString: "Mo"
328 },
329 //If all characters are removed, the popup should be closed.
330 { description: "the value becomes empty by backspace, the popup should be closed",
331 completeDefaultIndex: false,
332 execute: function (aWindow) {
333 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
334 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
335 }, popup: false, value: "", searchString: ""
336 },
337 // composition which is canceled shouldn't cause opening the popup.
338 { description: "compositionstart shouldn't open the popup",
339 completeDefaultIndex: false,
340 execute: function (aWindow) {
341 synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
342 synthesizeComposition({ type: "compositionstart" }, aWindow);
343 synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow);
344 synthesizeText(
345 { "composition":
346 { "string": "M",
347 "clauses":
348 [
349 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
350 ]
351 },
352 "caret": { "start": 1, "length": 0 }
353 }, aWindow);
354 }, popup: false, value: "M", searchString: ""
355 },
356 { description: "compositionupdate shouldn't open the popup",
357 completeDefaultIndex: false,
358 execute: function (aWindow) {
359 synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow);
360 synthesizeText(
361 { "composition":
362 { "string": "Mo",
363 "clauses":
364 [
365 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
366 ]
367 },
368 "caret": { "start": 2, "length": 0 }
369 }, aWindow);
370 }, popup: false, value: "Mo", searchString: ""
371 },
372 { description: "empty compositionupdate shouldn't open the popup",
373 completeDefaultIndex: false,
374 execute: function (aWindow) {
375 synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow);
376 synthesizeText(
377 { "composition":
378 { "string": "",
379 "clauses":
380 [
381 { "length": 0, "attr": 0 }
382 ]
383 },
384 "caret": { "start": 0, "length": 0 }
385 }, aWindow);
386 }, popup: false, value: "", searchString: ""
387 },
388 { description: "canceled compositionend shouldn't open the popup if it was closed",
389 completeDefaultIndex: false,
390 execute: function (aWindow) {
391 synthesizeText(
392 { "composition":
393 { "string": "",
394 "clauses":
395 [
396 { "length": 0, "attr": 0 }
397 ]
398 },
399 "caret": { "start": 0, "length": 0 }
400 }, aWindow);
401 synthesizeComposition({ type: "compositionend", data: "" }, aWindow);
402 synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
403 }, popup: false, value: "", searchString: ""
404 },
405 // Down key should open the popup even if the editor is empty.
406 { description: "DOWN key should open the popup even if the value is empty",
407 completeDefaultIndex: false,
408 execute: function (aWindow) {
409 synthesizeKey("VK_DOWN", {}, aWindow);
410 }, popup: true, value: "", searchString: ""
411 },
412 // If popup is open at starting composition, the popup should be reopened
413 // after composition anyway.
414 { description: "compositionstart shouldn't open the popup",
415 completeDefaultIndex: false,
416 execute: function (aWindow) {
417 synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
418 synthesizeComposition({ type: "compositionstart" }, aWindow);
419 synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow);
420 synthesizeText(
421 { "composition":
422 { "string": "M",
423 "clauses":
424 [
425 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
426 ]
427 },
428 "caret": { "start": 1, "length": 0 }
429 }, aWindow);
430 }, popup: false, value: "M", searchString: ""
431 },
432 { description: "compositionupdate shouldn't open the popup",
433 completeDefaultIndex: false,
434 execute: function (aWindow) {
435 synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow);
436 synthesizeText(
437 { "composition":
438 { "string": "Mo",
439 "clauses":
440 [
441 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
442 ]
443 },
444 "caret": { "start": 2, "length": 0 }
445 }, aWindow);
446 }, popup: false, value: "Mo", searchString: ""
447 },
448 { description: "empty compositionupdate shouldn't open the popup",
449 completeDefaultIndex: false,
450 execute: function (aWindow) {
451 synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow);
452 synthesizeText(
453 { "composition":
454 { "string": "",
455 "clauses":
456 [
457 { "length": 0, "attr": 0 }
458 ]
459 },
460 "caret": { "start": 0, "length": 0 }
461 }, aWindow);
462 }, popup: false, value: "", searchString: ""
463 },
464 { description: "canceled compositionend should open the popup if it was opened",
465 completeDefaultIndex: false,
466 execute: function (aWindow) {
467 synthesizeText(
468 { "composition":
469 { "string": "",
470 "clauses":
471 [
472 { "length": 0, "attr": 0 }
473 ]
474 },
475 "caret": { "start": 0, "length": 0 }
476 }, aWindow);
477 synthesizeComposition({ type: "compositionend", data: "" }, aWindow);
478 synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
479 }, popup: true, value: "", searchString: ""
480 },
481 // Type normally, and hit escape, the popup should be closed.
482 { description: "ESCAPE should close the popup after typing something",
483 completeDefaultIndex: false,
484 execute: function (aWindow) {
485 synthesizeKey("M", { shiftKey: true }, aWindow);
486 synthesizeKey("o", { shiftKey: true }, aWindow);
487 synthesizeKey("VK_ESCAPE", {}, aWindow);
488 }, popup: false, value: "Mo", searchString: "Mo"
489 },
490 // Even if the popup is closed, composition which is canceled should open
491 // the popup if the value isn't empty.
492 // XXX This might not be good behavior, but anyway, this is minor issue...
493 { description: "compositionstart shouldn't open the popup",
494 completeDefaultIndex: false,
495 execute: function (aWindow) {
496 synthesizeKey("z", { type: "keydown", shiftKey: true }, aWindow);
497 synthesizeComposition({ type: "compositionstart" }, aWindow);
498 synthesizeComposition({ type: "compositionupdate", data: "z" }, aWindow);
499 synthesizeText(
500 { "composition":
501 { "string": "z",
502 "clauses":
503 [
504 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
505 ]
506 },
507 "caret": { "start": 1, "length": 0 }
508 }, aWindow);
509 }, popup: false, value: "Moz", searchString: "Mo"
510 },
511 { description: "compositionupdate shouldn't open the popup",
512 completeDefaultIndex: false,
513 execute: function (aWindow) {
514 synthesizeComposition({ type: "compositionupdate", data: "zi" }, aWindow);
515 synthesizeText(
516 { "composition":
517 { "string": "zi",
518 "clauses":
519 [
520 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
521 ]
522 },
523 "caret": { "start": 2, "length": 0 }
524 }, aWindow);
525 }, popup: false, value: "Mozi", searchString: "Mo"
526 },
527 { description: "empty compositionupdate shouldn't open the popup",
528 completeDefaultIndex: false,
529 execute: function (aWindow) {
530 synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow);
531 synthesizeText(
532 { "composition":
533 { "string": "",
534 "clauses":
535 [
536 { "length": 0, "attr": 0 }
537 ]
538 },
539 "caret": { "start": 0, "length": 0 }
540 }, aWindow);
541 }, popup: false, value: "Mo", searchString: "Mo"
542 },
543 { description: "canceled compositionend shouldn't open the popup if the popup was closed",
544 completeDefaultIndex: false,
545 execute: function (aWindow) {
546 synthesizeText(
547 { "composition":
548 { "string": "",
549 "clauses":
550 [
551 { "length": 0, "attr": 0 }
552 ]
553 },
554 "caret": { "start": 0, "length": 0 }
555 }, aWindow);
556 synthesizeComposition({ type: "compositionend", data: "" }, aWindow);
557 synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow);
558 }, popup: true, value: "Mo", searchString: "Mo"
559 },
560 // House keeping...
561 { description: "house keeping for next tests",
562 completeDefaultIndex: false,
563 execute: function (aWindow) {
564 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
565 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
566 }, popup: false, value: "", searchString: ""
567 },
568 // Testing for nsIAutoCompleteInput.completeDefaultIndex being true.
569 { description: "compositionstart shouldn't open the popup (completeDefaultIndex is true)",
570 completeDefaultIndex: true,
571 execute: function (aWindow) {
572 synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow);
573 synthesizeComposition({ type: "compositionstart" }, aWindow);
574 synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow);
575 synthesizeText(
576 { "composition":
577 { "string": "M",
578 "clauses":
579 [
580 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
581 ]
582 },
583 "caret": { "start": 1, "length": 0 }
584 }, aWindow);
585 }, popup: false, value: "M", searchString: ""
586 },
587 { description: "compositionupdate shouldn't open the popup (completeDefaultIndex is true)",
588 completeDefaultIndex: true,
589 execute: function (aWindow) {
590 synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow);
591 synthesizeText(
592 { "composition":
593 { "string": "Mo",
594 "clauses":
595 [
596 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
597 ]
598 },
599 "caret": { "start": 2, "length": 0 }
600 }, aWindow);
601 }, popup: false, value: "Mo", searchString: ""
602 },
603 { description: "compositionend should open the popup (completeDefaultIndex is true)",
604 completeDefaultIndex: true,
605 execute: function (aWindow) {
606 synthesizeText(
607 { "composition":
608 { "string": "Mo",
609 "clauses":
610 [
611 { "length": 0, "attr": 0 }
612 ]
613 },
614 "caret": { "start": 2, "length": 0 }
615 }, aWindow);
616 synthesizeComposition({ type: "compositionend", data: "Mo" }, aWindow);
617 synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow);
618 }, popup: true, value: "Mozilla", searchString: "Mo"
619 },
620 // House keeping...
621 { description: "house keeping for next tests",
622 completeDefaultIndex: false,
623 execute: function (aWindow) {
624 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
625 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
626 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
627 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
628 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
629 synthesizeKey("VK_BACK_SPACE", {}, aWindow);
630 }, popup: false, value: "", searchString: ""
631 }
632 ]
633 };