Skip to content

Commit

Permalink
Add autocompleteSeparator parameter (#406)
Browse files Browse the repository at this point in the history
* push improved autocomplete functionality

* actual autocomplete fixes

* push missing changes

* add autocompleteSeparator parameter

* remove debugger

* make gulfile syntax more consistent

* remove unnecessary gulpfile changes

* test autocompleteSeparator

Co-authored-by: Valentin Steinwandter <[email protected]>
  • Loading branch information
valentinstn and valentinsteinwandter authored May 2, 2020
1 parent b086424 commit 2d03516
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 27 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
.DS_Store
npm-debug.log
test/coverage
yarn-error.log
yarn-error.log
.idea
19 changes: 15 additions & 4 deletions dist/tribute.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -748,9 +748,14 @@ class TributeRange {

getLastWordInText(text) {
text = text.replace(/\u00A0/g, ' '); // https://stackoverflow.com/questions/29850407/how-do-i-replace-unicode-character-u00a0-with-a-space-in-javascript
let wordsArray = text.split(/\s+/);
let worldsCount = wordsArray.length - 1;
return wordsArray[worldsCount].trim()
var wordsArray;
if (this.tribute.autocompleteSeparator) {
wordsArray = text.split(this.tribute.autocompleteSeparator);
} else {
wordsArray = text.split(/\s+/);
}
var worldsCount = wordsArray.length - 1;
return wordsArray[worldsCount].trim();
}

getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces, isAutocomplete) {
Expand Down Expand Up @@ -1177,7 +1182,11 @@ class TributeSearch {
}

traverse(string, pattern, stringIndex, patternIndex, patternCache) {
// if the pattern search at end
if (this.tribute.autocompleteSeparator) {
// if the pattern search at end
pattern = pattern.split(this.tribute.autocompleteSeparator).splice(-1)[0];
}

if (pattern.length === patternIndex) {

// calculate score and copy the cache containing the indices where it's found
Expand Down Expand Up @@ -1292,6 +1301,7 @@ class Tribute {
itemClass = "",
trigger = "@",
autocompleteMode = false,
autocompleteSeparator = null,
selectTemplate = null,
menuItemTemplate = null,
lookup = "key",
Expand All @@ -1309,6 +1319,7 @@ class Tribute {
menuShowMinLength = 0
}) {
this.autocompleteMode = autocompleteMode;
this.autocompleteSeparator = autocompleteSeparator;
this.menuSelected = 0;
this.current = {};
this.inputEvent = false;
Expand Down
44 changes: 36 additions & 8 deletions dist/tribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,15 @@
}

function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}

function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}

function _iterableToArrayLimit(arr, i) {
if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
return;
}

if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
Expand All @@ -64,8 +61,25 @@
return _arr;
}

function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;

for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

return arr2;
}

function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

if (!Array.prototype.find) {
Expand Down Expand Up @@ -814,7 +828,14 @@
value: function getLastWordInText(text) {
text = text.replace(/\u00A0/g, ' '); // https://stackoverflow.com/questions/29850407/how-do-i-replace-unicode-character-u00a0-with-a-space-in-javascript

var wordsArray = text.split(/\s+/);
var wordsArray;

if (this.tribute.autocompleteSeparator) {
wordsArray = text.split(this.tribute.autocompleteSeparator);
} else {
wordsArray = text.split(/\s+/);
}

var worldsCount = wordsArray.length - 1;
return wordsArray[worldsCount].trim();
}
Expand Down Expand Up @@ -1210,7 +1231,11 @@
}, {
key: "traverse",
value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) {
// if the pattern search at end
if (this.tribute.autocompleteSeparator) {
// if the pattern search at end
pattern = pattern.split(this.tribute.autocompleteSeparator).splice(-1)[0];
}

if (pattern.length === patternIndex) {
// calculate score and copy the cache containing the indices where it's found
return {
Expand Down Expand Up @@ -1332,6 +1357,8 @@
trigger = _ref$trigger === void 0 ? "@" : _ref$trigger,
_ref$autocompleteMode = _ref.autocompleteMode,
autocompleteMode = _ref$autocompleteMode === void 0 ? false : _ref$autocompleteMode,
_ref$autocompleteSepa = _ref.autocompleteSeparator,
autocompleteSeparator = _ref$autocompleteSepa === void 0 ? null : _ref$autocompleteSepa,
_ref$selectTemplate = _ref.selectTemplate,
selectTemplate = _ref$selectTemplate === void 0 ? null : _ref$selectTemplate,
_ref$menuItemTemplate = _ref.menuItemTemplate,
Expand Down Expand Up @@ -1366,6 +1393,7 @@
_classCallCheck(this, Tribute);

this.autocompleteMode = autocompleteMode;
this.autocompleteSeparator = autocompleteSeparator;
this.menuSelected = 0;
this.current = {};
this.inputEvent = false;
Expand Down
2 changes: 1 addition & 1 deletion dist/tribute.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/tribute.min.js.map

Large diffs are not rendered by default.

44 changes: 36 additions & 8 deletions example/tribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,15 @@
}

function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}

function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}

function _iterableToArrayLimit(arr, i) {
if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
return;
}

if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
Expand All @@ -64,8 +61,25 @@
return _arr;
}

function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;

for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

return arr2;
}

function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

if (!Array.prototype.find) {
Expand Down Expand Up @@ -814,7 +828,14 @@
value: function getLastWordInText(text) {
text = text.replace(/\u00A0/g, ' '); // https://stackoverflow.com/questions/29850407/how-do-i-replace-unicode-character-u00a0-with-a-space-in-javascript

var wordsArray = text.split(/\s+/);
var wordsArray;

if (this.tribute.autocompleteSeparator) {
wordsArray = text.split(this.tribute.autocompleteSeparator);
} else {
wordsArray = text.split(/\s+/);
}

var worldsCount = wordsArray.length - 1;
return wordsArray[worldsCount].trim();
}
Expand Down Expand Up @@ -1210,7 +1231,11 @@
}, {
key: "traverse",
value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) {
// if the pattern search at end
if (this.tribute.autocompleteSeparator) {
// if the pattern search at end
pattern = pattern.split(this.tribute.autocompleteSeparator).splice(-1)[0];
}

if (pattern.length === patternIndex) {
// calculate score and copy the cache containing the indices where it's found
return {
Expand Down Expand Up @@ -1332,6 +1357,8 @@
trigger = _ref$trigger === void 0 ? "@" : _ref$trigger,
_ref$autocompleteMode = _ref.autocompleteMode,
autocompleteMode = _ref$autocompleteMode === void 0 ? false : _ref$autocompleteMode,
_ref$autocompleteSepa = _ref.autocompleteSeparator,
autocompleteSeparator = _ref$autocompleteSepa === void 0 ? null : _ref$autocompleteSepa,
_ref$selectTemplate = _ref.selectTemplate,
selectTemplate = _ref$selectTemplate === void 0 ? null : _ref$selectTemplate,
_ref$menuItemTemplate = _ref.menuItemTemplate,
Expand Down Expand Up @@ -1366,6 +1393,7 @@
_classCallCheck(this, Tribute);

this.autocompleteMode = autocompleteMode;
this.autocompleteSeparator = autocompleteSeparator;
this.menuSelected = 0;
this.current = {};
this.inputEvent = false;
Expand Down
2 changes: 2 additions & 0 deletions src/Tribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Tribute {
itemClass = "",
trigger = "@",
autocompleteMode = false,
autocompleteSeparator = null,
selectTemplate = null,
menuItemTemplate = null,
lookup = "key",
Expand All @@ -30,6 +31,7 @@ class Tribute {
menuShowMinLength = 0
}) {
this.autocompleteMode = autocompleteMode;
this.autocompleteSeparator = autocompleteSeparator;
this.menuSelected = 0;
this.current = {};
this.inputEvent = false;
Expand Down
11 changes: 8 additions & 3 deletions src/TributeRange.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,14 @@ class TributeRange {

getLastWordInText(text) {
text = text.replace(/\u00A0/g, ' '); // https://stackoverflow.com/questions/29850407/how-do-i-replace-unicode-character-u00a0-with-a-space-in-javascript
let wordsArray = text.split(/\s+/);
let worldsCount = wordsArray.length - 1
return wordsArray[worldsCount].trim()
var wordsArray;
if (this.tribute.autocompleteSeparator) {
wordsArray = text.split(this.tribute.autocompleteSeparator);
} else {
wordsArray = text.split(/\s+/);
}
var worldsCount = wordsArray.length - 1;
return wordsArray[worldsCount].trim();
}

getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces, isAutocomplete) {
Expand Down
6 changes: 5 additions & 1 deletion src/TributeSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ class TributeSearch {
}

traverse(string, pattern, stringIndex, patternIndex, patternCache) {
// if the pattern search at end
if (this.tribute.autocompleteSeparator) {
// if the pattern search at end
pattern = pattern.split(this.tribute.autocompleteSeparator).splice(-1)[0];
}

if (pattern.length === patternIndex) {

// calculate score and copy the cache containing the indices where it's found
Expand Down
37 changes: 37 additions & 0 deletions test/spec/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,43 @@ describe("Tribute autocomplete mode cases", function() {
clearDom();
});

['text', 'contenteditable'].forEach(elementType => {
it(`when values key with autocompleteSeparator option. For : ${elementType}`, () => {
let input = createDomElement(elementType);

let collectionObject = {
selectTemplate: function (item) {
return item.original.value;
},
autocompleteMode: true,
autocompleteSeparator: new RegExp(/\-|\+/),
values: [
{ key: 'Jordan Humphreys', value: 'Jordan Humphreys', email: '[email protected]' },
{ key: 'Sir Walter Riley', value: 'Sir Walter Riley', email: '[email protected]' }
],
}

let tribute = attachTribute(collectionObject, input.id);

fillIn(input, '+J');
let popupList = document.querySelectorAll('.tribute-container > ul > li');
expect(popupList.length).toBe(1);
simulateMouseClick(popupList[0]); // click on Jordan Humphreys

if (elementType === 'text') {
expect(input.value).toBe('+Jordan Humphreys ');
} else if (elementType === 'contenteditable') {
expect(input.innerText).toBe('+Jordan Humphreys ');
}

fillIn(input, ' Si');
popupList = document.querySelectorAll('.tribute-container > ul > li');
expect(popupList.length).toBe(1);

detachTribute(tribute, input.id);
});
});

["text", "contenteditable"].forEach(elementType => {
it(`when values key is predefined array. For : ${elementType}`, () => {
let input = createDomElement(elementType);
Expand Down

0 comments on commit 2d03516

Please sign in to comment.