autocomplete wip. separated keyup and keydown. wip.
This commit is contained in:
parent
6eafd73d2c
commit
2b25823253
2 changed files with 177 additions and 71 deletions
|
|
@ -2,7 +2,18 @@
|
||||||
* licensed under the Affero General Public License version 3 or later. See
|
* licensed under the Affero General Public License version 3 or later. See
|
||||||
* the COPYRIGHT file.
|
* the COPYRIGHT file.
|
||||||
*/
|
*/
|
||||||
|
var KEY = {
|
||||||
|
UP: 38,
|
||||||
|
DOWN: 40,
|
||||||
|
DEL: 46,
|
||||||
|
TAB: 9,
|
||||||
|
RETURN: 13,
|
||||||
|
ESC: 27,
|
||||||
|
COMMA: 188,
|
||||||
|
PAGEUP: 33,
|
||||||
|
PAGEDOWN: 34,
|
||||||
|
BACKSPACE: 8
|
||||||
|
};
|
||||||
//TODO: make this a widget
|
//TODO: make this a widget
|
||||||
var Publisher = {
|
var Publisher = {
|
||||||
close: function(){
|
close: function(){
|
||||||
|
|
@ -62,61 +73,145 @@ var Publisher = {
|
||||||
var visibleLoc = Publisher.autocompletion.addMentionToInput(visibleInput, visibleCursorIndex, formatted);
|
var visibleLoc = Publisher.autocompletion.addMentionToInput(visibleInput, visibleCursorIndex, formatted);
|
||||||
$.Autocompleter.Selection(visibleInput[0], visibleLoc[1], visibleLoc[1]);
|
$.Autocompleter.Selection(visibleInput[0], visibleLoc[1], visibleLoc[1]);
|
||||||
|
|
||||||
var hiddenCursorIndex = visibleCursorIndex + Publisher.autocompletion.mentionList.offsetFrom(visibleCursorIndex);
|
var mentionString = Publisher.autocompletion.hiddenMentionFromPerson(data);
|
||||||
var hiddenLoc = Publisher.autocompletion.addMentionToInput(Publisher.hiddenInput(), hiddenCursorIndex, Publisher.autocompletion.hiddenMentionFromPerson(data));
|
|
||||||
var mention = { visibleStart: visibleLoc[0],
|
var mention = { visibleStart: visibleLoc[0],
|
||||||
visibleEnd : visibleLoc[1],
|
visibleEnd : visibleLoc[1],
|
||||||
hiddenStart : hiddenLoc[0],
|
mentionString : mentionString
|
||||||
hiddenEnd : hiddenLoc[1]
|
|
||||||
};
|
};
|
||||||
|
Publisher.autocompletion.mentionList.push(mention);
|
||||||
|
Publisher.oldInputContent = visibleInput.val();
|
||||||
|
Publisher.hiddenInput().val(Publisher.autocompletion.mentionList.generateHiddenInput(visibleInput.val()));
|
||||||
},
|
},
|
||||||
|
|
||||||
mentionList : {
|
mentionList : {
|
||||||
mentions : [],
|
mentions : [],
|
||||||
|
sortedMentions : function(){
|
||||||
|
return this.mentions.sort(function(m1, m2){
|
||||||
|
if(m1.visibleStart > m2.visibleStart){
|
||||||
|
return -1;
|
||||||
|
} else if(m1.visibleStart < m2.visibleStart){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
push : function(mention){
|
push : function(mention){
|
||||||
mention.offset = mention.hiddenEnd - mention.visibleEnd;
|
|
||||||
this.mentions.push(mention);
|
this.mentions.push(mention);
|
||||||
},
|
},
|
||||||
keypressAt : function(visibleCursorIndex){
|
generateHiddenInput : function(visibleString){
|
||||||
var mentionIndex = this.mentionAt(visibleCursorIndex);
|
var resultString = visibleString;
|
||||||
var mention = this.mentions[mentionIndex];
|
for(i in this.sortedMentions()){
|
||||||
if(!mention){return;}
|
var mention = this.mentions[i];
|
||||||
var visibleMentionString = Publisher.input().val().slice(mention.visibleStart, mention.visibleEnd);
|
var start = resultString.slice(0, mention.visibleStart);
|
||||||
var hiddenContent = Publisher.hiddenInput().val();
|
var insertion = mention.mentionString;
|
||||||
hiddenContent = hiddenContent.slice(0,mention.hiddenStart) +
|
var end = resultString.slice(mention.visibleEnd);
|
||||||
visibleMentionString +
|
|
||||||
hiddenContent.slice(mention.hiddenEnd);
|
|
||||||
Publisher.hiddenInput().val(hiddenContent);
|
|
||||||
|
|
||||||
this.mentions.splice(mentionIndex, 1);
|
resultString = start + insertion + end;
|
||||||
|
}
|
||||||
|
return resultString;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertionAt : function(insertionEndIndex, insertionStartIndex, keyCode){
|
||||||
|
this.incrementMentionLocations(insertionStartIndex, insertionEndIndex - insertionStartIndex);
|
||||||
|
var mentionIndex = this.mentionAt(insertionEndIndex);
|
||||||
|
|
||||||
|
var mention = this.mentions[mentionIndex];
|
||||||
|
if(mention){
|
||||||
|
this.mentions.splice(mentionIndex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
deletionAt : function(visibleCursorIndex, keyCode){
|
||||||
|
|
||||||
|
var effectiveCursorIndex;
|
||||||
|
if(keyCode == KEY.DEL){
|
||||||
|
effectiveCursorIndex = visibleCursorIndex;
|
||||||
|
}else{
|
||||||
|
effectiveCursorIndex = visibleCursorIndex - 1;
|
||||||
|
}
|
||||||
|
this.decrementMentionLocations(effectiveCursorIndex, keyCode);
|
||||||
|
|
||||||
|
var mentionIndex = this.mentionAt(effectiveCursorIndex);
|
||||||
|
|
||||||
|
var mention = this.mentions[mentionIndex];
|
||||||
|
if(mention){
|
||||||
|
this.mentions.splice(mentionIndex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
incrementMentionLocations : function(effectiveCursorIndex, offset){
|
||||||
|
var changedMentions = this.mentionsAfter(effectiveCursorIndex);
|
||||||
|
for(i in changedMentions){
|
||||||
|
var mention = changedMentions[i];
|
||||||
|
mention.visibleStart += offset;
|
||||||
|
mention.visibleEnd += offset;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
decrementMentionLocations : function(effectiveCursorIndex){
|
||||||
|
var visibleOffset = -1;
|
||||||
|
var changedMentions = this.mentionsAfter(effectiveCursorIndex);
|
||||||
|
for(i in changedMentions){
|
||||||
|
var mention = changedMentions[i];
|
||||||
|
mention.visibleStart += visibleOffset;
|
||||||
|
mention.visibleEnd += visibleOffset;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mentionAt : function(visibleCursorIndex){
|
mentionAt : function(visibleCursorIndex){
|
||||||
for(i in this.mentions){
|
for(i in this.mentions){
|
||||||
var mention = this.mentions[i];
|
var mention = this.mentions[i];
|
||||||
if(visibleCursorIndex >= mention.visibleStart && visibleCursorIndex < mention.visibleEnd){
|
if(visibleCursorIndex > mention.visibleStart && visibleCursorIndex < mention.visibleEnd){
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
offsetFrom: function(visibleCursorIndex){
|
mentionsAfter : function(visibleCursorIndex){
|
||||||
var mention = {visibleStart : -1, fake: true};
|
var resultMentions = [];
|
||||||
var currentMention;
|
|
||||||
for(i in this.mentions){
|
for(i in this.mentions){
|
||||||
currentMention = this.mentions[i];
|
var mention = this.mentions[i];
|
||||||
if(visibleCursorIndex >= currentMention.visibleStart &&
|
if(visibleCursorIndex <= mention.visibleStart){
|
||||||
currentMention.visibleStart > mention.visibleStart){
|
resultMentions.push(mention);
|
||||||
mention = currentMention;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(mention && !mention.fake){
|
return resultMentions;
|
||||||
return mention.offset;
|
},
|
||||||
}else{
|
},
|
||||||
return 0;
|
repopulateHiddenInput: function(){
|
||||||
}
|
var newHiddenVal = Publisher.autocompletion.mentionList.generateHiddenInput(Publisher.input().val());
|
||||||
|
if(newHiddenVal != Publisher.hiddenInput().val()){
|
||||||
|
Publisher.hiddenInput().val(newHiddenVal);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
keyUpHandler : function(event){
|
||||||
|
var input = Publisher.input();
|
||||||
|
var cursorIndexAtKeydown = Publisher.cursorIndexAtKeydown;
|
||||||
|
Publisher.cursorIndexAtKeydown = -1;
|
||||||
|
if(input.val() == Publisher.oldInputContent || event.keyCode == KEY.RETURN || event.keyCode == KEY.DEL || event.keyCode == KEY.BACKSPACE){
|
||||||
|
Publisher.autocompletion.repopulateHiddenInput();
|
||||||
|
return;
|
||||||
|
}else {
|
||||||
|
Publisher.oldInputContent = input.val();
|
||||||
|
var visibleCursorIndex = input[0].selectionStart;
|
||||||
|
Publisher.autocompletion.mentionList.insertionAt(visibleCursorIndex, cursorIndexAtKeydown, event.keyCode);
|
||||||
|
Publisher.autocompletion.repopulateHiddenInput();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
keyDownHandler : function(event){
|
||||||
|
var input = Publisher.input();
|
||||||
|
var visibleCursorIndex = input[0].selectionStart;
|
||||||
|
if(Publisher.cursorIndexAtKeydown == -1){
|
||||||
|
Publisher.cursorIndexAtKeydown = visibleCursorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((event.keyCode == KEY.DEL && visibleCursorIndex < input.val().length) || (event.keyCode == KEY.BACKSPACE && visibleCursorIndex > 0)){
|
||||||
|
Publisher.autocompletion.mentionList.deletionAt(visibleCursorIndex, event.keyCode);
|
||||||
|
}
|
||||||
|
Publisher.autocompletion.repopulateHiddenInput();
|
||||||
|
},
|
||||||
|
|
||||||
addMentionToInput: function(input, cursorIndex, formatted){
|
addMentionToInput: function(input, cursorIndex, formatted){
|
||||||
var inputContent = input.val();
|
var inputContent = input.val();
|
||||||
|
|
||||||
|
|
@ -126,13 +221,15 @@ var Publisher = {
|
||||||
var stringEnd = inputContent.slice(stringLoc[1]);
|
var stringEnd = inputContent.slice(stringLoc[1]);
|
||||||
|
|
||||||
input.val(stringStart + formatted + stringEnd);
|
input.val(stringStart + formatted + stringEnd);
|
||||||
|
var offset = formatted.length - stringLoc[1] - stringLoc[0]
|
||||||
|
Publisher.autocompletion.mentionList.incrementMentionLocations(stringStart.length, offset);
|
||||||
return [stringStart.length, stringStart.length + formatted.length]
|
return [stringStart.length, stringStart.length + formatted.length]
|
||||||
},
|
},
|
||||||
|
|
||||||
findStringToReplace: function(value, cursorIndex){
|
findStringToReplace: function(value, cursorIndex){
|
||||||
var atLocation = value.lastIndexOf('@', cursorIndex);
|
var atLocation = value.lastIndexOf('@', cursorIndex);
|
||||||
if(atLocation == -1){return [0,0];}
|
if(atLocation == -1){return [0,0];}
|
||||||
var nextAt = cursorIndex//value.indexOf(' @', cursorIndex+1);
|
var nextAt = cursorIndex
|
||||||
|
|
||||||
if(nextAt == -1){nextAt = value.length;}
|
if(nextAt == -1){nextAt = value.length;}
|
||||||
return [atLocation, nextAt];
|
return [atLocation, nextAt];
|
||||||
|
|
@ -164,6 +261,7 @@ var Publisher = {
|
||||||
Publisher.input().autocomplete(Publisher.autocompletion.contactsJSON(),
|
Publisher.input().autocomplete(Publisher.autocompletion.contactsJSON(),
|
||||||
Publisher.autocompletion.options());
|
Publisher.autocompletion.options());
|
||||||
Publisher.input().result(Publisher.autocompletion.selectItemCallback);
|
Publisher.input().result(Publisher.autocompletion.selectItemCallback);
|
||||||
|
Publisher.oldInputContent = Publisher.input().val();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
|
|
@ -183,6 +281,8 @@ var Publisher = {
|
||||||
|
|
||||||
Publisher.autocompletion.initialize();
|
Publisher.autocompletion.initialize();
|
||||||
Publisher.hiddenInput().val(Publisher.input().val());
|
Publisher.hiddenInput().val(Publisher.input().val());
|
||||||
|
Publisher.input().keydown(Publisher.autocompletion.keyDownHandler);
|
||||||
|
Publisher.input().keyup(Publisher.autocompletion.keyUpHandler);
|
||||||
Publisher.form().find("textarea").bind("focus", function(evt) {
|
Publisher.form().find("textarea").bind("focus", function(evt) {
|
||||||
Publisher.open();
|
Publisher.open();
|
||||||
$(this).css('min-height', '42px');
|
$(this).css('min-height', '42px');
|
||||||
|
|
|
||||||
|
|
@ -62,19 +62,17 @@ describe("Publisher", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("autocompletion", function(){
|
describe("autocompletion", function(){
|
||||||
describe("onKeypress", function(){
|
|
||||||
});,
|
|
||||||
describe("searchTermFromValue", function(){
|
describe("searchTermFromValue", function(){
|
||||||
var func;
|
var func;
|
||||||
beforeEach(function(){func = Publisher.autocompletion.searchTermFromValue;});
|
beforeEach(function(){func = Publisher.autocompletion.searchTermFromValue;});
|
||||||
it("returns nothing if the cursor is before the @", function(){
|
it("returns nothing if the cursor is before the @", function(){
|
||||||
expect(func('not @dan grip', 2)).toBe('');
|
expect(func('not @dan grip', 2)).toBe('');
|
||||||
});
|
});
|
||||||
it("returns everything after an @ if the cursor is a word after that @", function(){
|
it("returns everything up to the cursor if the cursor is a word after that @", function(){
|
||||||
expect(func('not @dan grip', 13)).toBe('dan grip');
|
expect(func('not @dan grip', 13)).toBe('dan grip');
|
||||||
});
|
});
|
||||||
it("returns everything after an @ if the cursor is after that @", function(){
|
it("returns up to the cursor if the cursor is after that @", function(){
|
||||||
expect(func('not @dan grip', 7)).toBe('dan grip');
|
expect(func('not @dan grip', 7)).toBe('da');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns everything after an @ at the start of the line", function(){
|
it("returns everything after an @ at the start of the line", function(){
|
||||||
|
|
@ -89,11 +87,11 @@ describe("Publisher", function() {
|
||||||
it("returns nothing if there are letters preceding the @", function(){
|
it("returns nothing if there are letters preceding the @", function(){
|
||||||
expect(func('ioj@asdo', 8)).toBe('');
|
expect(func('ioj@asdo', 8)).toBe('');
|
||||||
});
|
});
|
||||||
it("returns everything between @s if there are 2 @s and the cursor is between them", function(){
|
it("returns everything up to the cursor if there are 2 @s and the cursor is between them", function(){
|
||||||
expect(func('@asdpo aoisdj @asodk', 8)).toBe('asdpo aoisdj');
|
expect(func('@asdpo aoisdj @asodk', 8)).toBe('asdpo');
|
||||||
});
|
});
|
||||||
it("returns everything after the 2nd @ if there are 2 @s and the cursor after them", function(){
|
it("returns everything from the 2nd @ up to the cursor if there are 2 @s and the cursor after them", function(){
|
||||||
expect(func('@asod asdo @asd asok', 15)).toBe('asd asok');
|
expect(func('@asod asdo @asd asok', 15)).toBe('asd');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -105,18 +103,15 @@ describe("Publisher", function() {
|
||||||
var visibleInput, visibleVal,
|
var visibleInput, visibleVal,
|
||||||
hiddenInput, hiddenVal,
|
hiddenInput, hiddenVal,
|
||||||
list,
|
list,
|
||||||
func,
|
|
||||||
mention;
|
mention;
|
||||||
beforeEach(function(){
|
beforeEach(function(){
|
||||||
spec.loadFixture('aspects_index');
|
spec.loadFixture('aspects_index');
|
||||||
list = Publisher.autocompletion.mentionList;
|
list = Publisher.autocompletion.mentionList;
|
||||||
func = list.keypressAt;
|
|
||||||
visibleInput = Publisher.input();
|
visibleInput = Publisher.input();
|
||||||
hiddenInput = Publisher.hiddenInput();
|
hiddenInput = Publisher.hiddenInput();
|
||||||
mention = { visibleStart : 0,
|
mention = { visibleStart : 0,
|
||||||
visibleEnd : 5,
|
visibleEnd : 5,
|
||||||
hiddenStart : 0,
|
mentionString : "@{Danny; dan@pod.org}"
|
||||||
hiddenEnd : 21
|
|
||||||
};
|
};
|
||||||
list.mentions = [];
|
list.mentions = [];
|
||||||
list.push(mention);
|
list.push(mention);
|
||||||
|
|
@ -125,6 +120,11 @@ describe("Publisher", function() {
|
||||||
hiddenVal = "@{Danny; dan@pod.org} loves testing javascript";
|
hiddenVal = "@{Danny; dan@pod.org} loves testing javascript";
|
||||||
hiddenInput.val(hiddenVal);
|
hiddenInput.val(hiddenVal);
|
||||||
});
|
});
|
||||||
|
describe("generateHiddenInput", function(){
|
||||||
|
it("replaces mentions in a string", function(){
|
||||||
|
expect(list.generateHiddenInput(visibleVal)).toBe(hiddenVal);
|
||||||
|
});
|
||||||
|
});
|
||||||
describe("push", function(){
|
describe("push", function(){
|
||||||
it("adds mention to mentions array", function(){
|
it("adds mention to mentions array", function(){
|
||||||
expect(list.mentions.length).toBe(1);
|
expect(list.mentions.length).toBe(1);
|
||||||
|
|
@ -142,34 +142,39 @@ describe("Publisher", function() {
|
||||||
describe("keypressAt", function(){
|
describe("keypressAt", function(){
|
||||||
it("does nothing if there is no visible mention at that index", function(){
|
it("does nothing if there is no visible mention at that index", function(){
|
||||||
list.keypressAt(8);
|
list.keypressAt(8);
|
||||||
expect(visibleInput.val()).toBe(visibleVal)
|
expect(visibleInput.val()).toBe(visibleVal);
|
||||||
expect(hiddenInput.val()).toBe(hiddenVal)
|
expect(hiddenInput.val()).toBe(hiddenVal);
|
||||||
});
|
});
|
||||||
it("deletes the mention from the hidden field if there is a mention", function(){
|
it("deletes the mention from the hidden field if there is a mention", function(){
|
||||||
list.keypressAt(3);
|
list.keypressAt(3);
|
||||||
expect(visibleInput.val()).toBe(visibleVal)
|
expect(visibleInput.val()).toBe(visibleVal);
|
||||||
expect(hiddenInput.val()).toBe(visibleVal)
|
expect(list.generateHiddenInput(visibleInput.val())).toBe(visibleVal);
|
||||||
});
|
});
|
||||||
it("deletes the mention from the list", function(){
|
it("deletes the mention from the list", function(){
|
||||||
list.keypressAt(3);
|
list.keypressAt(3);
|
||||||
expect(list.mentionAt(3)).toBeFalsy();
|
expect(list.mentionAt(3)).toBeFalsy();
|
||||||
});
|
});
|
||||||
it("updates the offsets of the remaining mentions in the list");
|
it("calls updateMentionLocations", function(){
|
||||||
|
mentionTwo = { visibleStart : 8,
|
||||||
|
visibleEnd : 15,
|
||||||
|
mentionString : "@{SomeoneElse; other@pod.org}"
|
||||||
|
};
|
||||||
|
list.push(mentionTwo);
|
||||||
|
spyOn(list, 'updateMentionLocations');
|
||||||
|
list.keypressAt(3, 60);
|
||||||
|
expect(list.updateMentionLocations).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe("offsetFrom", function(){
|
describe("updateMentionLocations", function(){
|
||||||
var func;
|
it("updates the offsets of the remaining mentions in the list", function(){
|
||||||
beforeEach(function(){
|
mentionTwo = { visibleStart : 8,
|
||||||
func = list.offsetFrom;
|
visibleEnd : 15,
|
||||||
});
|
mentionString : "@{SomeoneElse; other@pod.org}"
|
||||||
it("returns the offset of the mention at that location", function(){
|
};
|
||||||
expect(list.offsetFrom(3)).toBe(mention.offset);
|
list.push(mentionTwo);
|
||||||
});
|
list.updateMentionLocations(7, 60);
|
||||||
it("returns the offset of the previous mention if there is no mention there", function(){
|
expect(mentionTwo.visibleStart).toBe(9);
|
||||||
expect(list.offsetFrom(10)).toBe(mention.offset);
|
expect(mentionTwo.visibleEnd).toBe(16);
|
||||||
});
|
|
||||||
it("returns 0 if there are no mentions", function(){
|
|
||||||
list.mentions = [];
|
|
||||||
expect(list.offsetFrom(8)).toBe(0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -184,37 +189,38 @@ describe("Publisher", function() {
|
||||||
spec.loadFixture('aspects_index');
|
spec.loadFixture('aspects_index');
|
||||||
func = Publisher.autocompletion.addMentionToInput;
|
func = Publisher.autocompletion.addMentionToInput;
|
||||||
input = Publisher.input();
|
input = Publisher.input();
|
||||||
|
Publisher.autocompletion.mentionList = [];
|
||||||
replaceWith = "Replace with this.";
|
replaceWith = "Replace with this.";
|
||||||
});
|
});
|
||||||
it("replaces everything after an @ if the cursor is a word after that @", function(){
|
it("replaces everything up to the cursor if the cursor is a word after that @", function(){
|
||||||
input.val('not @dan grip');
|
input.val('not @dan grip');
|
||||||
var cursorIndex = 13;
|
var cursorIndex = 13;
|
||||||
func(input, cursorIndex, replaceWith);
|
func(input, cursorIndex, replaceWith);
|
||||||
expect(input.val()).toBe('not ' + replaceWith);
|
expect(input.val()).toBe('not ' + replaceWith);
|
||||||
});
|
});
|
||||||
it("replaces everything after an @ if the cursor is after that @", function(){
|
it("replaces everything between @ and the cursor if the cursor is after that @", function(){
|
||||||
input.val('not @dan grip');
|
input.val('not @dan grip');
|
||||||
var cursorIndex = 7;
|
var cursorIndex = 7;
|
||||||
func(input, cursorIndex, replaceWith);
|
func(input, cursorIndex, replaceWith);
|
||||||
expect(input.val()).toBe('not ' + replaceWith);
|
expect(input.val()).toBe('not ' + replaceWith + 'n grip');
|
||||||
});
|
});
|
||||||
it("replaces everything after an @ at the start of the line", function(){
|
it("replaces everything up to the cursor from @ at the start of the line", function(){
|
||||||
input.val('@dan grip');
|
input.val('@dan grip');
|
||||||
var cursorIndex = 9;
|
var cursorIndex = 9;
|
||||||
func(input, cursorIndex, replaceWith);
|
func(input, cursorIndex, replaceWith);
|
||||||
expect(input.val()).toBe(replaceWith);
|
expect(input.val()).toBe(replaceWith);
|
||||||
});
|
});
|
||||||
it("replaces everything between @s if there are 2 @s and the cursor is between them", function(){
|
it("replaces everything between the first @ and the cursor if there are 2 @s and the cursor is between them", function(){
|
||||||
input.val('@asdpo aoisdj @asodk');
|
input.val('@asdpo aoisdj @asodk');
|
||||||
var cursorIndex = 8;
|
var cursorIndex = 8;
|
||||||
func(input, cursorIndex, replaceWith);
|
func(input, cursorIndex, replaceWith);
|
||||||
expect(input.val()).toBe(replaceWith + ' @asodk');
|
expect(input.val()).toBe(replaceWith + 'aoisdj @asodk');
|
||||||
});
|
});
|
||||||
it("replaces everything after the 2nd @ if there are 2 @s and the cursor after them", function(){
|
it("replaces everything after the 2nd @ if there are 2 @s and the cursor after them", function(){
|
||||||
input.val('@asod asdo @asd asok');
|
input.val('@asod asdo @asd asok');
|
||||||
var cursorIndex = 15;
|
var cursorIndex = 15;
|
||||||
func(input, cursorIndex, replaceWith);
|
func(input, cursorIndex, replaceWith);
|
||||||
expect(input.val()).toBe('@asod asdo ' + replaceWith);
|
expect(input.val()).toBe('@asod asdo ' + replaceWith + ' asok');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue