зеркало из https://github.com/mozilla/gecko-dev.git
Bug 812618 - Autocomplete at cursor location; r=robcee
This commit is contained in:
Родитель
c980f78d30
Коммит
366007a69e
|
@ -279,5 +279,50 @@ function popupHideAfterReturnWithNoSelection()
|
|||
is(jsterm.history[jsterm.history.length-1], "window.testBug",
|
||||
"jsterm history is correct");
|
||||
|
||||
executeSoon(finishTest);
|
||||
executeSoon(testCompletionInText);
|
||||
}
|
||||
|
||||
function testCompletionInText()
|
||||
{
|
||||
info("test that completion works inside text, see bug 812618");
|
||||
|
||||
popup._panel.addEventListener("popupshown", function onShown() {
|
||||
popup._panel.removeEventListener("popupshown", onShown);
|
||||
|
||||
ok(popup.isOpen, "popup is open");
|
||||
is(popup.itemCount, 2, "popup.itemCount is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
is(popup.selectedIndex, 0, "popup.selectedIndex is correct");
|
||||
ok(!completeNode.value, "completeNode.value is empty");
|
||||
|
||||
let items = popup.getItems().reverse().map(e => e.label);
|
||||
let sameItems = items.every((prop, index) =>
|
||||
["testBug873250a", "testBug873250b"][index] === prop);
|
||||
ok(sameItems, "getItems returns the items we expect");
|
||||
|
||||
info("press Tab and wait for popup to hide");
|
||||
popup._panel.addEventListener("popuphidden", popupHideAfterCompletionInText);
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
});
|
||||
|
||||
jsterm.setInputValue("dump(window.testBu)");
|
||||
inputNode.selectionStart = inputNode.selectionEnd = 18;
|
||||
EventUtils.synthesizeKey("g", {});
|
||||
}
|
||||
|
||||
function popupHideAfterCompletionInText()
|
||||
{
|
||||
// At this point the completion suggestion should be accepted.
|
||||
popup._panel.removeEventListener("popuphidden", popupHideAfterCompletionInText);
|
||||
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
is(inputNode.value, "dump(window.testBug873250b)",
|
||||
"completion was successful after VK_TAB");
|
||||
is(inputNode.selectionStart, 26, "cursor location is correct");
|
||||
is(inputNode.selectionStart, inputNode.selectionEnd, "cursor location (confirmed)");
|
||||
ok(!completeNode.value, "completeNode is empty");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
|
|
@ -4077,9 +4077,8 @@ JSTerm.prototype = {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Only complete if the selection is empty and at the end of the input.
|
||||
if (inputNode.selectionStart == inputNode.selectionEnd &&
|
||||
inputNode.selectionEnd != inputValue.length) {
|
||||
// Only complete if the selection is empty.
|
||||
if (inputNode.selectionStart != inputNode.selectionEnd) {
|
||||
this.clearCompletion();
|
||||
return false;
|
||||
}
|
||||
|
@ -4215,6 +4214,11 @@ JSTerm.prototype = {
|
|||
|
||||
onAutocompleteSelect: function JSTF_onAutocompleteSelect()
|
||||
{
|
||||
// Render the suggestion only if the cursor is at the end of the input.
|
||||
if (this.inputNode.selectionStart != this.inputNode.value.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let currentItem = this.autocompletePopup.selectedItem;
|
||||
if (currentItem && this.lastCompletion.value) {
|
||||
let suffix = currentItem.label.substring(this.lastCompletion.
|
||||
|
@ -4256,7 +4260,11 @@ JSTerm.prototype = {
|
|||
if (currentItem && this.lastCompletion.value) {
|
||||
let suffix = currentItem.label.substring(this.lastCompletion.
|
||||
matchProp.length);
|
||||
this.setInputValue(this.inputNode.value + suffix);
|
||||
let cursor = this.inputNode.selectionStart;
|
||||
let value = this.inputNode.value;
|
||||
this.setInputValue(value.substr(0, cursor) + suffix + value.substr(cursor));
|
||||
let newCursor = cursor + suffix.length;
|
||||
this.inputNode.selectionStart = this.inputNode.selectionEnd = newCursor;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -626,7 +626,8 @@ WebConsoleActor.prototype =
|
|||
{
|
||||
// TODO: Bug 842682 - use the debugger API for autocomplete in the Web
|
||||
// Console, and provide suggestions from the selected debugger stack frame.
|
||||
let result = JSPropertyProvider(this.window, aRequest.text) || {};
|
||||
let result = JSPropertyProvider(this.window, aRequest.text,
|
||||
aRequest.cursor) || {};
|
||||
return {
|
||||
from: this.actorID,
|
||||
matches: result.matches || [],
|
||||
|
|
|
@ -727,10 +727,12 @@ function findCompletionBeginning(aStr)
|
|||
*
|
||||
* @param object aScope
|
||||
* Scope to use for the completion.
|
||||
*
|
||||
* @param string aInputValue
|
||||
* Value that should be completed.
|
||||
*
|
||||
* @param number [aCursor=aInputValue.length]
|
||||
* Optional offset in the input where the cursor is located. If this is
|
||||
* omitted then the cursor is assumed to be at the end of the input
|
||||
* value.
|
||||
* @returns null or object
|
||||
* If no completion valued could be computed, null is returned,
|
||||
* otherwise a object with the following form is returned:
|
||||
|
@ -740,13 +742,18 @@ function findCompletionBeginning(aStr)
|
|||
* the matches-strings.
|
||||
* }
|
||||
*/
|
||||
function JSPropertyProvider(aScope, aInputValue)
|
||||
function JSPropertyProvider(aScope, aInputValue, aCursor)
|
||||
{
|
||||
if (aCursor === undefined) {
|
||||
aCursor = aInputValue.length;
|
||||
}
|
||||
|
||||
let inputValue = aInputValue.substring(0, aCursor);
|
||||
let obj = WCU.unwrap(aScope);
|
||||
|
||||
// Analyse the aInputValue and find the beginning of the last part that
|
||||
// Analyse the inputValue and find the beginning of the last part that
|
||||
// should be completed.
|
||||
let beginning = findCompletionBeginning(aInputValue);
|
||||
let beginning = findCompletionBeginning(inputValue);
|
||||
|
||||
// There was an error analysing the string.
|
||||
if (beginning.err) {
|
||||
|
@ -759,7 +766,7 @@ function JSPropertyProvider(aScope, aInputValue)
|
|||
return null;
|
||||
}
|
||||
|
||||
let completionPart = aInputValue.substring(beginning.startPos);
|
||||
let completionPart = inputValue.substring(beginning.startPos);
|
||||
|
||||
// Don't complete on just an empty string.
|
||||
if (completionPart.trim() == "") {
|
||||
|
|
|
@ -37,15 +37,16 @@ function onAttach(aState, aResponse)
|
|||
|
||||
gState = aState;
|
||||
|
||||
let tests = [doAutocomplete1, doAutocomplete2, doSimpleEval, doWindowEval,
|
||||
doEvalWithException, doEvalWithHelper, doEvalString, doEvalLongString];
|
||||
let tests = [doAutocomplete1, doAutocomplete2, doAutocomplete3,
|
||||
doAutocomplete4, doSimpleEval, doWindowEval, doEvalWithException,
|
||||
doEvalWithHelper, doEvalString, doEvalLongString];
|
||||
runTests(tests, testEnd);
|
||||
}
|
||||
|
||||
function doAutocomplete1()
|
||||
{
|
||||
info("test autocomplete for 'window.foo'");
|
||||
gState.client.autocomplete("window.foo", 0, onAutocomplete1);
|
||||
gState.client.autocomplete("window.foo", 10, onAutocomplete1);
|
||||
}
|
||||
|
||||
function onAutocomplete1(aResponse)
|
||||
|
@ -62,7 +63,7 @@ function onAutocomplete1(aResponse)
|
|||
function doAutocomplete2()
|
||||
{
|
||||
info("test autocomplete for 'window.foobarObject.'");
|
||||
gState.client.autocomplete("window.foobarObject.", 0, onAutocomplete2);
|
||||
gState.client.autocomplete("window.foobarObject.", 20, onAutocomplete2);
|
||||
}
|
||||
|
||||
function onAutocomplete2(aResponse)
|
||||
|
@ -77,6 +78,40 @@ function onAutocomplete2(aResponse)
|
|||
nextTest();
|
||||
}
|
||||
|
||||
function doAutocomplete3()
|
||||
{
|
||||
// Check that completion suggestions are offered inside the string.
|
||||
info("test autocomplete for 'dump(window.foobarObject.)'");
|
||||
gState.client.autocomplete("dump(window.foobarObject.)", 25, onAutocomplete3);
|
||||
}
|
||||
|
||||
function onAutocomplete3(aResponse)
|
||||
{
|
||||
let matches = aResponse.matches;
|
||||
|
||||
ok(!aResponse.matchProp, "matchProp");
|
||||
is(matches.length, 7, "matches.length");
|
||||
checkObject(matches,
|
||||
["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function doAutocomplete4()
|
||||
{
|
||||
// Check that completion requests can have no suggestions.
|
||||
info("test autocomplete for 'dump(window.foobarObject.)'");
|
||||
gState.client.autocomplete("dump(window.foobarObject.)", 26, onAutocomplete4);
|
||||
}
|
||||
|
||||
function onAutocomplete4(aResponse)
|
||||
{
|
||||
ok(!aResponse.matchProp, "matchProp");
|
||||
is(aResponse.matches.length, 0, "matches.length");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function doSimpleEval()
|
||||
{
|
||||
info("test eval '2+2'");
|
||||
|
|
Загрузка…
Ссылка в новой задаче