From 189bf57ba71db52cff8c386742518efee45c2dda Mon Sep 17 00:00:00 2001 From: Jordan Humphreys Date: Fri, 6 Mar 2020 14:18:46 -0800 Subject: [PATCH] Set a default noMatchTemplate and update example. --- dist/tribute.esm.js | 4 ++-- dist/tribute.js | 4 ++-- dist/tribute.min.js | 2 +- dist/tribute.min.js.map | 2 +- example/index.html | 6 +++++- example/tribute.js | 4 ++-- src/Tribute.js | 4 ++-- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/dist/tribute.esm.js b/dist/tribute.esm.js index a96b4d92..c225b281 100644 --- a/dist/tribute.esm.js +++ b/dist/tribute.esm.js @@ -1362,7 +1362,7 @@ class Tribute { return ( noMatchTemplate || function() { - return ""; + return "
  • No Match Found!
  • "; }.bind(this) ); })(noMatchTemplate), @@ -1445,7 +1445,7 @@ class Tribute { } static defaultSelectTemplate(item) { - if (typeof item === "undefined") return null; + if (typeof item === "undefined") return "@" + this.current.mentionText; if (this.range.isContentEditable(this.current.element)) { return ( '' + diff --git a/dist/tribute.js b/dist/tribute.js index 1a6e7099..ff55e3ab 100644 --- a/dist/tribute.js +++ b/dist/tribute.js @@ -1405,7 +1405,7 @@ } return noMatchTemplate || function () { - return ""; + return "
  • No Match Found!
  • "; }.bind(_this); }(noMatchTemplate), // column to search against in the object @@ -1815,7 +1815,7 @@ }], [{ key: "defaultSelectTemplate", value: function defaultSelectTemplate(item) { - if (typeof item === "undefined") return null; + if (typeof item === "undefined") return "@" + this.current.mentionText; if (this.range.isContentEditable(this.current.element)) { return '' + (this.current.collection.trigger + item.original[this.current.collection.fillAttr]) + ""; diff --git a/dist/tribute.min.js b/dist/tribute.min.js index 9221c38c..903baab4 100644 --- a/dist/tribute.min.js +++ b/dist/tribute.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e=e||self).tribute=e.tribute||{},e.tribute.min=t())}(this,(function(){"use strict";function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;n>>0,r=arguments[1],o=0;o container for the click");n.selectItemAtIndex(i.getAttribute("data-index"),t),n.hideMenu()}else n.current.element&&!n.current.externalTrigger&&(n.current.externalTrigger=!1,setTimeout((function(){return n.hideMenu()})))}},{key:"keyup",value:function(e,t){if(e.inputEvent&&(e.inputEvent=!1),e.updateSelection(this),27!==t.keyCode){if(!e.tribute.allowSpaces&&e.tribute.hasTrailingSpace)return e.tribute.hasTrailingSpace=!1,e.commandEvent=!0,void e.callbacks().space(t,this);if(!e.tribute.isActive)if(e.tribute.autocompleteMode)e.callbacks().triggerChar(t,this,"");else{var n=e.getKeyCode(e,this,t);if(isNaN(n)||!n)return;var i=e.tribute.triggers().find((function(e){return e.charCodeAt(0)===n}));void 0!==i&&e.callbacks().triggerChar(t,this,i)}e.tribute.current.mentionText.length=r.current.collection.menuShowMinLength&&r.inputEvent&&r.showMenuFor(n,!0)},enter:function(t,n){e.tribute.isActive&&e.tribute.current.filteredItems&&(t.preventDefault(),t.stopPropagation(),setTimeout((function(){e.tribute.selectItemAtIndex(e.tribute.menuSelected,t),e.tribute.hideMenu()}),0))},escape:function(t,n){e.tribute.isActive&&(t.preventDefault(),t.stopPropagation(),e.tribute.isActive=!1,e.tribute.hideMenu())},tab:function(t,n){e.callbacks().enter(t,n)},space:function(t,n){e.tribute.isActive&&(e.tribute.spaceSelectsMatch?e.callbacks().enter(t,n):e.tribute.allowSpaces||(t.stopPropagation(),setTimeout((function(){e.tribute.hideMenu(),e.tribute.isActive=!1}),0)))},up:function(t,n){if(e.tribute.isActive&&e.tribute.current.filteredItems){t.preventDefault(),t.stopPropagation();var i=e.tribute.current.filteredItems.length,r=e.tribute.menuSelected;i>r&&r>0?(e.tribute.menuSelected--,e.setActiveLi()):0===r&&(e.tribute.menuSelected=i-1,e.setActiveLi(),e.tribute.menu.scrollTop=e.tribute.menu.scrollHeight)}},down:function(t,n){if(e.tribute.isActive&&e.tribute.current.filteredItems){t.preventDefault(),t.stopPropagation();var i=e.tribute.current.filteredItems.length-1,r=e.tribute.menuSelected;i>r?(e.tribute.menuSelected++,e.setActiveLi()):i===r&&(e.tribute.menuSelected=0,e.setActiveLi(),e.tribute.menu.scrollTop=0)}},delete:function(t,n){e.tribute.isActive&&e.tribute.current.mentionText.length<1?e.tribute.hideMenu():e.tribute.isActive&&e.tribute.showMenuFor(n)}}}},{key:"setActiveLi",value:function(e){var t=this.tribute.menu.querySelectorAll("li"),n=t.length>>>0;e&&(this.tribute.menuSelected=parseInt(e));for(var i=0;iu.bottom){var l=o.bottom-u.bottom;this.tribute.menu.scrollTop+=l}else if(o.topi.width&&(r.left||r.right),u=window.innerHeight>i.height&&(r.top||r.bottom);(o||u)&&(n.tribute.menu.style.cssText="display: none",n.positionMenuAtCaret(e))}),0)}else this.tribute.menu.style.cssText="display: none"}},{key:"selectElement",value:function(e,t,n){var i,r=e;if(t)for(var o=0;o=0&&(t=i.substring(0,r))}}else{var o=this.tribute.current.element;if(o){var u=o.selectionStart;o.value&&u>=0&&(t=o.value.substring(0,u))}}return t}},{key:"getLastWordInText",value:function(e){var t=(e=e.replace(/\u00A0/g," ")).split(/\s+/);return t[t.length-1].trim()}},{key:"getTriggerInfo",value:function(e,t,n,i,r){var o,u,l,s=this,a=this.tribute.current;if(this.isContentEditable(a.element)){var c=this.getContentEditableSelectedPath(a);c&&(o=c.selected,u=c.path,l=c.offset)}else o=this.tribute.current.element;var h=this.getTextPrecedingCurrentSelection(),d=this.getLastWordInText(h);if(r)return{mentionPosition:h.length-d.length,mentionText:d,mentionSelectedElement:o,mentionSelectedPath:u,mentionSelectedOffset:l};if(null!=h){var f,m=-1;if(this.tribute.collection.forEach((function(e){var t=e.trigger,i=e.requireLeadingSpace?s.lastIndexWithLeadingSpace(h,t):h.lastIndexOf(t);i>m&&(m=i,f=t,n=e.requireLeadingSpace)})),m>=0&&(0===m||!n||/[\xA0\s]/g.test(h.substring(m-1,m)))){var p=h.substring(m+f.length,h.length);f=h.substring(m,m+f.length);var v=p.substring(0,1),g=p.length>0&&(" "===v||" "===v);t&&(p=p.trim());var b=i?/[^\S ]/g:/[\xA0\s]/g;if(this.tribute.hasTrailingSpace=b.test(p),!g&&(e||!b.test(p)))return{mentionPosition:m,mentionText:p,mentionSelectedElement:o,mentionSelectedPath:u,mentionSelectedOffset:l,mentionTriggerChar:f}}}}},{key:"lastIndexWithLeadingSpace",value:function(e,t){for(var n=e.split("").reverse().join(""),i=-1,r=0,o=e.length;r=0;a--)if(t[a]!==n[r-a]){s=!1;break}if(s&&(u||l)){i=e.length-1-r;break}}return i}},{key:"isContentEditable",value:function(e){return"INPUT"!==e.nodeName&&"TEXTAREA"!==e.nodeName}},{key:"isMenuOffScreen",value:function(e,t){var n=window.innerWidth,i=window.innerHeight,r=document.documentElement,o=(window.pageXOffset||r.scrollLeft)-(r.clientLeft||0),u=(window.pageYOffset||r.scrollTop)-(r.clientTop||0),l="number"==typeof e.top?e.top:u+i-e.bottom-t.height,s="number"==typeof e.right?e.right:e.left+t.width,a="number"==typeof e.bottom?e.bottom:e.top+t.height,c="number"==typeof e.left?e.left:o+n-e.right-t.width;return{top:lMath.ceil(o+n),bottom:a>Math.ceil(u+i),left:cparseInt(u.height)&&(o.overflowY="scroll")):o.overflow="hidden",r.textContent=e.value.substring(0,t),"INPUT"===e.nodeName&&(r.textContent=r.textContent.replace(/\s/g," "));var l=this.getDocument().createElement("span");l.textContent=e.value.substring(t)||".",r.appendChild(l);var s=e.getBoundingClientRect(),a=document.documentElement,c=(window.pageXOffset||a.scrollLeft)-(a.clientLeft||0),h=(window.pageYOffset||a.scrollTop)-(a.clientTop||0),d=0,f=0;this.menuContainerIsBody&&(d=s.top,f=s.left);var m={top:d+h+l.offsetTop+parseInt(u.borderTopWidth)+parseInt(u.fontSize)-e.scrollTop,left:f+c+l.offsetLeft+parseInt(u.borderLeftWidth)},p=window.innerWidth,v=window.innerHeight,g=this.getMenuDimensions(),b=this.isMenuOffScreen(m,g);b.right&&(m.right=p-m.left,m.left="auto");var y=this.tribute.menuContainer?this.tribute.menuContainer.offsetHeight:this.getDocument().body.offsetHeight;if(b.bottom){var w=y-(v-(this.tribute.menuContainer?this.tribute.menuContainer.getBoundingClientRect():this.getDocument().body.getBoundingClientRect()).top);m.bottom=w+(v-s.top-l.offsetTop),m.top="auto"}return(b=this.isMenuOffScreen(m,g)).left&&(m.left=p>g.width?c+p-g.width:c,delete m.right),b.top&&(m.top=v>g.height?h+v-g.height:h,delete m.bottom),this.getDocument().body.removeChild(r),m}},{key:"getContentEditableCaretPosition",value:function(e){var t,n=this.getWindowSelection();(t=this.getDocument().createRange()).setStart(n.anchorNode,e),t.setEnd(n.anchorNode,e),t.collapse(!1);var i=t.getBoundingClientRect(),r=document.documentElement,o=(window.pageXOffset||r.scrollLeft)-(r.clientLeft||0),u=(window.pageYOffset||r.scrollTop)-(r.clientTop||0),l={left:i.left+o,top:i.top+i.height+u},s=window.innerWidth,a=window.innerHeight,c=this.getMenuDimensions(),h=this.isMenuOffScreen(l,c);h.right&&(l.left="auto",l.right=s-i.left-o);var d=this.tribute.menuContainer?this.tribute.menuContainer.offsetHeight:this.getDocument().body.offsetHeight;if(h.bottom){var f=d-(a-(this.tribute.menuContainer?this.tribute.menuContainer.getBoundingClientRect():this.getDocument().body.getBoundingClientRect()).top);l.top="auto",l.bottom=f+(a-i.top)}return(h=this.isMenuOffScreen(l,c)).left&&(l.left=s>c.width?o+s-c.width:o,delete l.right),h.top&&(l.top=a>c.height?u+a-c.height:u,delete l.bottom),this.menuContainerIsBody||(l.left=l.left?l.left-this.tribute.menuContainer.offsetLeft:l.left,l.top=l.top?l.top-this.tribute.menuContainer.offsetTop:l.top),l}},{key:"scrollIntoView",value:function(e){var t,n=this.menu;if(void 0!==n){for(;void 0===t||0===t.height;)if(0===(t=n.getBoundingClientRect()).height&&(void 0===(n=n.childNodes[0])||!n.getBoundingClientRect))return;var i=t.top,r=i+t.height;if(i<0)window.scrollTo(0,window.pageYOffset+t.top-20);else if(r>window.innerHeight){var o=window.pageYOffset+t.top-20;o-window.pageYOffset>100&&(o=window.pageYOffset+100);var u=window.pageYOffset-(window.innerHeight-r);u>o&&(u=o),window.scrollTo(0,u)}}}},{key:"menuContainerIsBody",get:function(){return this.tribute.menuContainer===document.body||!this.tribute.menuContainer}}]),t}(),s=function(){function t(n){e(this,t),this.tribute=n,this.tribute.search=this}return n(t,[{key:"simpleFilter",value:function(e,t){var n=this;return t.filter((function(t){return n.test(e,t)}))}},{key:"test",value:function(e,t){return null!==this.match(e,t)}},{key:"match",value:function(e,t,n){n=n||{};t.length;var i=n.pre||"",r=n.post||"",o=n.caseSensitive&&t||t.toLowerCase();if(n.skip)return{rendered:t,score:0};e=n.caseSensitive&&e||e.toLowerCase();var u=this.traverse(o,e,0,0,[]);return u?{rendered:this.render(t,u.cache,i,r),score:u.score}:null}},{key:"traverse",value:function(e,t,n,i,r){if(t.length===i)return{score:this.calculateScore(r),cache:r.slice()};if(!(e.length===n||t.length-i>e.length-n)){for(var o,u,l=t[i],s=e.indexOf(l,n);s>-1;){if(r.push(s),u=this.traverse(e,t,s+1,i+1,r),r.pop(),!u)return o;(!o||o.score0&&(e[r-1]+1===i?n+=n+1:n=1),t+=n})),t}},{key:"render",value:function(e,t,n,i){var r=e.substring(0,t[0]);return t.forEach((function(o,u){r+=n+e[o]+i+e.substring(o+1,t[u+1]?t[u+1]:e.length)})),r}},{key:"filter",value:function(e,t,n){var i=this;return n=n||{},t.reduce((function(t,r,o,u){var l=r;n.extract&&((l=n.extract(r))||(l=""));var s=i.match(e,l,n);return null!=s&&(t[t.length]={string:s.rendered,score:s.score,index:o,original:r}),t}),[]).sort((function(e,t){var n=t.score-e.score;return n||e.index-t.index}))}}]),t}();return function(){function t(n){var i,r=this,a=n.values,c=void 0===a?null:a,h=n.iframe,d=void 0===h?null:h,f=n.selectClass,m=void 0===f?"highlight":f,p=n.containerClass,v=void 0===p?"tribute-container":p,g=n.itemClass,b=void 0===g?"":g,y=n.trigger,w=void 0===y?"@":y,T=n.autocompleteMode,C=void 0!==T&&T,S=n.selectTemplate,E=void 0===S?null:S,k=n.menuItemTemplate,x=void 0===k?null:k,M=n.lookup,A=void 0===M?"key":M,L=n.fillAttr,I=void 0===L?"value":L,N=n.collection,O=void 0===N?null:N,D=n.menuContainer,P=void 0===D?null:D,R=n.noMatchTemplate,W=void 0===R?null:R,H=n.requireLeadingSpace,B=void 0===H||H,_=n.allowSpaces,F=void 0!==_&&_,j=n.replaceTextSuffix,Y=void 0===j?null:j,z=n.positionMenu,K=void 0===z||z,q=n.spaceSelectsMatch,U=void 0!==q&&q,X=n.searchOpts,Q=void 0===X?{}:X,V=n.menuItemLimit,G=void 0===V?null:V,J=n.menuShowMinLength,Z=void 0===J?0:J;if(e(this,t),this.autocompleteMode=C,this.menuSelected=0,this.current={},this.inputEvent=!1,this.isActive=!1,this.menuContainer=P,this.allowSpaces=F,this.replaceTextSuffix=Y,this.positionMenu=K,this.hasTrailingSpace=!1,this.spaceSelectsMatch=U,this.autocompleteMode&&(w="",F=!1),c)this.collection=[{trigger:w,iframe:d,selectClass:m,containerClass:v,itemClass:b,selectTemplate:(E||t.defaultSelectTemplate).bind(this),menuItemTemplate:(x||t.defaultMenuItemTemplate).bind(this),noMatchTemplate:(i=W,"function"==typeof i?i.bind(r):W||function(){return""}.bind(r)),lookup:A,fillAttr:I,values:c,requireLeadingSpace:B,searchOpts:Q,menuItemLimit:G,menuShowMinLength:Z}];else{if(!O)throw new Error("[Tribute] No collection specified.");this.autocompleteMode&&console.warn("Tribute in autocomplete mode does not work for collections"),this.collection=O.map((function(e){return{trigger:e.trigger||w,iframe:e.iframe||d,selectClass:e.selectClass||m,containerClass:e.containerClass||v,itemClass:e.itemClass||b,selectTemplate:(e.selectTemplate||t.defaultSelectTemplate).bind(r),menuItemTemplate:(e.menuItemTemplate||t.defaultMenuItemTemplate).bind(r),noMatchTemplate:function(e){return"function"==typeof e?e.bind(r):null}(W),lookup:e.lookup||A,fillAttr:e.fillAttr||I,values:e.values,requireLeadingSpace:e.requireLeadingSpace,searchOpts:e.searchOpts||Q,menuItemLimit:e.menuItemLimit||G,menuShowMinLength:e.menuShowMinLength||Z}}))}new l(this),new o(this),new u(this),new s(this)}return n(t,[{key:"triggers",value:function(){return this.collection.map((function(e){return e.trigger}))}},{key:"attach",value:function(e){if(!e)throw new Error("[Tribute] Must pass in a DOM node or NodeList.");if("undefined"!=typeof jQuery&&e instanceof jQuery&&(e=e.get()),e.constructor===NodeList||e.constructor===HTMLCollection||e.constructor===Array)for(var t=e.length,n=0;n",post:n.current.collection.searchOpts.post||"
    ",skip:n.current.collection.searchOpts.skip,extract:function(e){if("string"==typeof n.current.collection.lookup)return e[n.current.collection.lookup];if("function"==typeof n.current.collection.lookup)return n.current.collection.lookup(e,n.current.mentionText);throw new Error("Invalid lookup attribute, lookup must be string or function.")}});n.current.collection.menuItemLimit&&(r=r.slice(0,n.current.collection.menuItemLimit)),n.current.filteredItems=r;var o=n.menu.querySelector("ul");if(n.range.positionMenuAtCaret(t),!r.length){var u=new CustomEvent("tribute-no-match",{detail:n.menu});return n.current.element.dispatchEvent(u),void("function"==typeof n.current.collection.noMatchTemplate&&!n.current.collection.noMatchTemplate()||!n.current.collection.noMatchTemplate?n.hideMenu():"function"==typeof n.current.collection.noMatchTemplate?o.innerHTML=n.current.collection.noMatchTemplate():o.innerHTML=n.current.collection.noMatchTemplate)}o.innerHTML="";var l=n.range.getDocument().createDocumentFragment();r.forEach((function(e,t){var r=n.range.getDocument().createElement("li");r.setAttribute("data-index",t),r.className=n.current.collection.itemClass,r.addEventListener("mousemove",(function(e){var t=i(n._findLiTarget(e.target),2),r=(t[0],t[1]);0!==e.movementY&&n.events.setActiveLi(r)})),n.menuSelected===t&&r.classList.add(n.current.collection.selectClass),r.innerHTML=n.current.collection.menuItemTemplate(e),l.appendChild(r)})),o.appendChild(l)}};"function"==typeof this.current.collection.values?this.current.collection.values(this.current.mentionText,r):r(this.current.collection.values)}}},{key:"_findLiTarget",value:function(e){if(!e)return[];var t=e.getAttribute("data-index");return t?[e,t]:this._findLiTarget(e.parentNode)}},{key:"showMenuForCollection",value:function(e,t){e!==document.activeElement&&this.placeCaretAtEnd(e),this.current.collection=this.collection[t||0],this.current.externalTrigger=!0,this.current.element=e,e.isContentEditable?this.insertTextAtCursor(this.current.collection.trigger):this.insertAtCaret(e,this.current.collection.trigger),this.showMenuFor(e)}},{key:"placeCaretAtEnd",value:function(e){if(e.focus(),void 0!==window.getSelection&&void 0!==document.createRange){var t=document.createRange();t.selectNodeContents(e),t.collapse(!1);var n=window.getSelection();n.removeAllRanges(),n.addRange(t)}else if(void 0!==document.body.createTextRange){var i=document.body.createTextRange();i.moveToElementText(e),i.collapse(!1),i.select()}}},{key:"insertTextAtCursor",value:function(e){var t,n;(n=(t=window.getSelection()).getRangeAt(0)).deleteContents();var i=document.createTextNode(e);n.insertNode(i),n.selectNodeContents(i),n.collapse(!1),t.removeAllRanges(),t.addRange(n)}},{key:"insertAtCaret",value:function(e,t){var n=e.scrollTop,i=e.selectionStart,r=e.value.substring(0,i),o=e.value.substring(e.selectionEnd,e.value.length);e.value=r+t+o,i+=t.length,e.selectionStart=i,e.selectionEnd=i,e.focus(),e.scrollTop=n}},{key:"hideMenu",value:function(){this.menu&&(this.menu.style.cssText="display: none;",this.isActive=!1,this.menuSelected=0,this.current={})}},{key:"selectItemAtIndex",value:function(e,t){if("number"==typeof(e=parseInt(e))&&!isNaN(e)){var n=this.current.filteredItems[e],i=this.current.collection.selectTemplate(n);null!==i&&this.replaceText(i,t,n)}}},{key:"replaceText",value:function(e,t,n){this.range.replaceTriggerText(e,!0,!0,t,n)}},{key:"_append",value:function(e,t,n){if("function"==typeof e.values)throw new Error("Unable to append to values, as it is a function.");e.values=n?t:e.values.concat(t)}},{key:"append",value:function(e,t,n){var i=parseInt(e);if("number"!=typeof i)throw new Error("please provide an index for the collection to update.");var r=this.collection[i];this._append(r,t,n)}},{key:"appendCurrent",value:function(e,t){if(!this.isActive)throw new Error("No active state. Please use append instead and pass an index.");this._append(this.current.collection,e,t)}},{key:"detach",value:function(e){if(!e)throw new Error("[Tribute] Must pass in a DOM node or NodeList.");if("undefined"!=typeof jQuery&&e instanceof jQuery&&(e=e.get()),e.constructor===NodeList||e.constructor===HTMLCollection||e.constructor===Array)for(var t=e.length,n=0;n'+(this.current.collection.trigger+e.original[this.current.collection.fillAttr])+"":this.current.collection.trigger+e.original[this.current.collection.fillAttr]}},{key:"defaultMenuItemTemplate",value:function(e){return e.string}},{key:"inputTypes",value:function(){return["TEXTAREA","INPUT"]}}]),t}()})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e=e||self).tribute=e.tribute||{},e.tribute.min=t())}(this,(function(){"use strict";function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;n>>0,r=arguments[1],o=0;o container for the click");n.selectItemAtIndex(i.getAttribute("data-index"),t),n.hideMenu()}else n.current.element&&!n.current.externalTrigger&&(n.current.externalTrigger=!1,setTimeout((function(){return n.hideMenu()})))}},{key:"keyup",value:function(e,t){if(e.inputEvent&&(e.inputEvent=!1),e.updateSelection(this),27!==t.keyCode){if(!e.tribute.allowSpaces&&e.tribute.hasTrailingSpace)return e.tribute.hasTrailingSpace=!1,e.commandEvent=!0,void e.callbacks().space(t,this);if(!e.tribute.isActive)if(e.tribute.autocompleteMode)e.callbacks().triggerChar(t,this,"");else{var n=e.getKeyCode(e,this,t);if(isNaN(n)||!n)return;var i=e.tribute.triggers().find((function(e){return e.charCodeAt(0)===n}));void 0!==i&&e.callbacks().triggerChar(t,this,i)}e.tribute.current.mentionText.length=r.current.collection.menuShowMinLength&&r.inputEvent&&r.showMenuFor(n,!0)},enter:function(t,n){e.tribute.isActive&&e.tribute.current.filteredItems&&(t.preventDefault(),t.stopPropagation(),setTimeout((function(){e.tribute.selectItemAtIndex(e.tribute.menuSelected,t),e.tribute.hideMenu()}),0))},escape:function(t,n){e.tribute.isActive&&(t.preventDefault(),t.stopPropagation(),e.tribute.isActive=!1,e.tribute.hideMenu())},tab:function(t,n){e.callbacks().enter(t,n)},space:function(t,n){e.tribute.isActive&&(e.tribute.spaceSelectsMatch?e.callbacks().enter(t,n):e.tribute.allowSpaces||(t.stopPropagation(),setTimeout((function(){e.tribute.hideMenu(),e.tribute.isActive=!1}),0)))},up:function(t,n){if(e.tribute.isActive&&e.tribute.current.filteredItems){t.preventDefault(),t.stopPropagation();var i=e.tribute.current.filteredItems.length,r=e.tribute.menuSelected;i>r&&r>0?(e.tribute.menuSelected--,e.setActiveLi()):0===r&&(e.tribute.menuSelected=i-1,e.setActiveLi(),e.tribute.menu.scrollTop=e.tribute.menu.scrollHeight)}},down:function(t,n){if(e.tribute.isActive&&e.tribute.current.filteredItems){t.preventDefault(),t.stopPropagation();var i=e.tribute.current.filteredItems.length-1,r=e.tribute.menuSelected;i>r?(e.tribute.menuSelected++,e.setActiveLi()):i===r&&(e.tribute.menuSelected=0,e.setActiveLi(),e.tribute.menu.scrollTop=0)}},delete:function(t,n){e.tribute.isActive&&e.tribute.current.mentionText.length<1?e.tribute.hideMenu():e.tribute.isActive&&e.tribute.showMenuFor(n)}}}},{key:"setActiveLi",value:function(e){var t=this.tribute.menu.querySelectorAll("li"),n=t.length>>>0;e&&(this.tribute.menuSelected=parseInt(e));for(var i=0;iu.bottom){var l=o.bottom-u.bottom;this.tribute.menu.scrollTop+=l}else if(o.topi.width&&(r.left||r.right),u=window.innerHeight>i.height&&(r.top||r.bottom);(o||u)&&(n.tribute.menu.style.cssText="display: none",n.positionMenuAtCaret(e))}),0)}else this.tribute.menu.style.cssText="display: none"}},{key:"selectElement",value:function(e,t,n){var i,r=e;if(t)for(var o=0;o=0&&(t=i.substring(0,r))}}else{var o=this.tribute.current.element;if(o){var u=o.selectionStart;o.value&&u>=0&&(t=o.value.substring(0,u))}}return t}},{key:"getLastWordInText",value:function(e){var t=(e=e.replace(/\u00A0/g," ")).split(/\s+/);return t[t.length-1].trim()}},{key:"getTriggerInfo",value:function(e,t,n,i,r){var o,u,l,s=this,a=this.tribute.current;if(this.isContentEditable(a.element)){var c=this.getContentEditableSelectedPath(a);c&&(o=c.selected,u=c.path,l=c.offset)}else o=this.tribute.current.element;var h=this.getTextPrecedingCurrentSelection(),d=this.getLastWordInText(h);if(r)return{mentionPosition:h.length-d.length,mentionText:d,mentionSelectedElement:o,mentionSelectedPath:u,mentionSelectedOffset:l};if(null!=h){var f,m=-1;if(this.tribute.collection.forEach((function(e){var t=e.trigger,i=e.requireLeadingSpace?s.lastIndexWithLeadingSpace(h,t):h.lastIndexOf(t);i>m&&(m=i,f=t,n=e.requireLeadingSpace)})),m>=0&&(0===m||!n||/[\xA0\s]/g.test(h.substring(m-1,m)))){var p=h.substring(m+f.length,h.length);f=h.substring(m,m+f.length);var v=p.substring(0,1),g=p.length>0&&(" "===v||" "===v);t&&(p=p.trim());var b=i?/[^\S ]/g:/[\xA0\s]/g;if(this.tribute.hasTrailingSpace=b.test(p),!g&&(e||!b.test(p)))return{mentionPosition:m,mentionText:p,mentionSelectedElement:o,mentionSelectedPath:u,mentionSelectedOffset:l,mentionTriggerChar:f}}}}},{key:"lastIndexWithLeadingSpace",value:function(e,t){for(var n=e.split("").reverse().join(""),i=-1,r=0,o=e.length;r=0;a--)if(t[a]!==n[r-a]){s=!1;break}if(s&&(u||l)){i=e.length-1-r;break}}return i}},{key:"isContentEditable",value:function(e){return"INPUT"!==e.nodeName&&"TEXTAREA"!==e.nodeName}},{key:"isMenuOffScreen",value:function(e,t){var n=window.innerWidth,i=window.innerHeight,r=document.documentElement,o=(window.pageXOffset||r.scrollLeft)-(r.clientLeft||0),u=(window.pageYOffset||r.scrollTop)-(r.clientTop||0),l="number"==typeof e.top?e.top:u+i-e.bottom-t.height,s="number"==typeof e.right?e.right:e.left+t.width,a="number"==typeof e.bottom?e.bottom:e.top+t.height,c="number"==typeof e.left?e.left:o+n-e.right-t.width;return{top:lMath.ceil(o+n),bottom:a>Math.ceil(u+i),left:cparseInt(u.height)&&(o.overflowY="scroll")):o.overflow="hidden",r.textContent=e.value.substring(0,t),"INPUT"===e.nodeName&&(r.textContent=r.textContent.replace(/\s/g," "));var l=this.getDocument().createElement("span");l.textContent=e.value.substring(t)||".",r.appendChild(l);var s=e.getBoundingClientRect(),a=document.documentElement,c=(window.pageXOffset||a.scrollLeft)-(a.clientLeft||0),h=(window.pageYOffset||a.scrollTop)-(a.clientTop||0),d=0,f=0;this.menuContainerIsBody&&(d=s.top,f=s.left);var m={top:d+h+l.offsetTop+parseInt(u.borderTopWidth)+parseInt(u.fontSize)-e.scrollTop,left:f+c+l.offsetLeft+parseInt(u.borderLeftWidth)},p=window.innerWidth,v=window.innerHeight,g=this.getMenuDimensions(),b=this.isMenuOffScreen(m,g);b.right&&(m.right=p-m.left,m.left="auto");var y=this.tribute.menuContainer?this.tribute.menuContainer.offsetHeight:this.getDocument().body.offsetHeight;if(b.bottom){var w=y-(v-(this.tribute.menuContainer?this.tribute.menuContainer.getBoundingClientRect():this.getDocument().body.getBoundingClientRect()).top);m.bottom=w+(v-s.top-l.offsetTop),m.top="auto"}return(b=this.isMenuOffScreen(m,g)).left&&(m.left=p>g.width?c+p-g.width:c,delete m.right),b.top&&(m.top=v>g.height?h+v-g.height:h,delete m.bottom),this.getDocument().body.removeChild(r),m}},{key:"getContentEditableCaretPosition",value:function(e){var t,n=this.getWindowSelection();(t=this.getDocument().createRange()).setStart(n.anchorNode,e),t.setEnd(n.anchorNode,e),t.collapse(!1);var i=t.getBoundingClientRect(),r=document.documentElement,o=(window.pageXOffset||r.scrollLeft)-(r.clientLeft||0),u=(window.pageYOffset||r.scrollTop)-(r.clientTop||0),l={left:i.left+o,top:i.top+i.height+u},s=window.innerWidth,a=window.innerHeight,c=this.getMenuDimensions(),h=this.isMenuOffScreen(l,c);h.right&&(l.left="auto",l.right=s-i.left-o);var d=this.tribute.menuContainer?this.tribute.menuContainer.offsetHeight:this.getDocument().body.offsetHeight;if(h.bottom){var f=d-(a-(this.tribute.menuContainer?this.tribute.menuContainer.getBoundingClientRect():this.getDocument().body.getBoundingClientRect()).top);l.top="auto",l.bottom=f+(a-i.top)}return(h=this.isMenuOffScreen(l,c)).left&&(l.left=s>c.width?o+s-c.width:o,delete l.right),h.top&&(l.top=a>c.height?u+a-c.height:u,delete l.bottom),this.menuContainerIsBody||(l.left=l.left?l.left-this.tribute.menuContainer.offsetLeft:l.left,l.top=l.top?l.top-this.tribute.menuContainer.offsetTop:l.top),l}},{key:"scrollIntoView",value:function(e){var t,n=this.menu;if(void 0!==n){for(;void 0===t||0===t.height;)if(0===(t=n.getBoundingClientRect()).height&&(void 0===(n=n.childNodes[0])||!n.getBoundingClientRect))return;var i=t.top,r=i+t.height;if(i<0)window.scrollTo(0,window.pageYOffset+t.top-20);else if(r>window.innerHeight){var o=window.pageYOffset+t.top-20;o-window.pageYOffset>100&&(o=window.pageYOffset+100);var u=window.pageYOffset-(window.innerHeight-r);u>o&&(u=o),window.scrollTo(0,u)}}}},{key:"menuContainerIsBody",get:function(){return this.tribute.menuContainer===document.body||!this.tribute.menuContainer}}]),t}(),s=function(){function t(n){e(this,t),this.tribute=n,this.tribute.search=this}return n(t,[{key:"simpleFilter",value:function(e,t){var n=this;return t.filter((function(t){return n.test(e,t)}))}},{key:"test",value:function(e,t){return null!==this.match(e,t)}},{key:"match",value:function(e,t,n){n=n||{};t.length;var i=n.pre||"",r=n.post||"",o=n.caseSensitive&&t||t.toLowerCase();if(n.skip)return{rendered:t,score:0};e=n.caseSensitive&&e||e.toLowerCase();var u=this.traverse(o,e,0,0,[]);return u?{rendered:this.render(t,u.cache,i,r),score:u.score}:null}},{key:"traverse",value:function(e,t,n,i,r){if(t.length===i)return{score:this.calculateScore(r),cache:r.slice()};if(!(e.length===n||t.length-i>e.length-n)){for(var o,u,l=t[i],s=e.indexOf(l,n);s>-1;){if(r.push(s),u=this.traverse(e,t,s+1,i+1,r),r.pop(),!u)return o;(!o||o.score0&&(e[r-1]+1===i?n+=n+1:n=1),t+=n})),t}},{key:"render",value:function(e,t,n,i){var r=e.substring(0,t[0]);return t.forEach((function(o,u){r+=n+e[o]+i+e.substring(o+1,t[u+1]?t[u+1]:e.length)})),r}},{key:"filter",value:function(e,t,n){var i=this;return n=n||{},t.reduce((function(t,r,o,u){var l=r;n.extract&&((l=n.extract(r))||(l=""));var s=i.match(e,l,n);return null!=s&&(t[t.length]={string:s.rendered,score:s.score,index:o,original:r}),t}),[]).sort((function(e,t){var n=t.score-e.score;return n||e.index-t.index}))}}]),t}();return function(){function t(n){var i,r=this,a=n.values,c=void 0===a?null:a,h=n.iframe,d=void 0===h?null:h,f=n.selectClass,m=void 0===f?"highlight":f,p=n.containerClass,v=void 0===p?"tribute-container":p,g=n.itemClass,b=void 0===g?"":g,y=n.trigger,w=void 0===y?"@":y,T=n.autocompleteMode,C=void 0!==T&&T,S=n.selectTemplate,E=void 0===S?null:S,k=n.menuItemTemplate,x=void 0===k?null:k,M=n.lookup,A=void 0===M?"key":M,L=n.fillAttr,I=void 0===L?"value":L,N=n.collection,O=void 0===N?null:N,D=n.menuContainer,P=void 0===D?null:D,R=n.noMatchTemplate,W=void 0===R?null:R,H=n.requireLeadingSpace,B=void 0===H||H,F=n.allowSpaces,_=void 0!==F&&F,j=n.replaceTextSuffix,Y=void 0===j?null:j,z=n.positionMenu,K=void 0===z||z,q=n.spaceSelectsMatch,U=void 0!==q&&q,X=n.searchOpts,Q=void 0===X?{}:X,V=n.menuItemLimit,G=void 0===V?null:V,J=n.menuShowMinLength,Z=void 0===J?0:J;if(e(this,t),this.autocompleteMode=C,this.menuSelected=0,this.current={},this.inputEvent=!1,this.isActive=!1,this.menuContainer=P,this.allowSpaces=_,this.replaceTextSuffix=Y,this.positionMenu=K,this.hasTrailingSpace=!1,this.spaceSelectsMatch=U,this.autocompleteMode&&(w="",_=!1),c)this.collection=[{trigger:w,iframe:d,selectClass:m,containerClass:v,itemClass:b,selectTemplate:(E||t.defaultSelectTemplate).bind(this),menuItemTemplate:(x||t.defaultMenuItemTemplate).bind(this),noMatchTemplate:(i=W,"function"==typeof i?i.bind(r):W||function(){return"
  • No Match Found!
  • "}.bind(r)),lookup:A,fillAttr:I,values:c,requireLeadingSpace:B,searchOpts:Q,menuItemLimit:G,menuShowMinLength:Z}];else{if(!O)throw new Error("[Tribute] No collection specified.");this.autocompleteMode&&console.warn("Tribute in autocomplete mode does not work for collections"),this.collection=O.map((function(e){return{trigger:e.trigger||w,iframe:e.iframe||d,selectClass:e.selectClass||m,containerClass:e.containerClass||v,itemClass:e.itemClass||b,selectTemplate:(e.selectTemplate||t.defaultSelectTemplate).bind(r),menuItemTemplate:(e.menuItemTemplate||t.defaultMenuItemTemplate).bind(r),noMatchTemplate:function(e){return"function"==typeof e?e.bind(r):null}(W),lookup:e.lookup||A,fillAttr:e.fillAttr||I,values:e.values,requireLeadingSpace:e.requireLeadingSpace,searchOpts:e.searchOpts||Q,menuItemLimit:e.menuItemLimit||G,menuShowMinLength:e.menuShowMinLength||Z}}))}new l(this),new o(this),new u(this),new s(this)}return n(t,[{key:"triggers",value:function(){return this.collection.map((function(e){return e.trigger}))}},{key:"attach",value:function(e){if(!e)throw new Error("[Tribute] Must pass in a DOM node or NodeList.");if("undefined"!=typeof jQuery&&e instanceof jQuery&&(e=e.get()),e.constructor===NodeList||e.constructor===HTMLCollection||e.constructor===Array)for(var t=e.length,n=0;n",post:n.current.collection.searchOpts.post||"",skip:n.current.collection.searchOpts.skip,extract:function(e){if("string"==typeof n.current.collection.lookup)return e[n.current.collection.lookup];if("function"==typeof n.current.collection.lookup)return n.current.collection.lookup(e,n.current.mentionText);throw new Error("Invalid lookup attribute, lookup must be string or function.")}});n.current.collection.menuItemLimit&&(r=r.slice(0,n.current.collection.menuItemLimit)),n.current.filteredItems=r;var o=n.menu.querySelector("ul");if(n.range.positionMenuAtCaret(t),!r.length){var u=new CustomEvent("tribute-no-match",{detail:n.menu});return n.current.element.dispatchEvent(u),void("function"==typeof n.current.collection.noMatchTemplate&&!n.current.collection.noMatchTemplate()||!n.current.collection.noMatchTemplate?n.hideMenu():"function"==typeof n.current.collection.noMatchTemplate?o.innerHTML=n.current.collection.noMatchTemplate():o.innerHTML=n.current.collection.noMatchTemplate)}o.innerHTML="";var l=n.range.getDocument().createDocumentFragment();r.forEach((function(e,t){var r=n.range.getDocument().createElement("li");r.setAttribute("data-index",t),r.className=n.current.collection.itemClass,r.addEventListener("mousemove",(function(e){var t=i(n._findLiTarget(e.target),2),r=(t[0],t[1]);0!==e.movementY&&n.events.setActiveLi(r)})),n.menuSelected===t&&r.classList.add(n.current.collection.selectClass),r.innerHTML=n.current.collection.menuItemTemplate(e),l.appendChild(r)})),o.appendChild(l)}};"function"==typeof this.current.collection.values?this.current.collection.values(this.current.mentionText,r):r(this.current.collection.values)}}},{key:"_findLiTarget",value:function(e){if(!e)return[];var t=e.getAttribute("data-index");return t?[e,t]:this._findLiTarget(e.parentNode)}},{key:"showMenuForCollection",value:function(e,t){e!==document.activeElement&&this.placeCaretAtEnd(e),this.current.collection=this.collection[t||0],this.current.externalTrigger=!0,this.current.element=e,e.isContentEditable?this.insertTextAtCursor(this.current.collection.trigger):this.insertAtCaret(e,this.current.collection.trigger),this.showMenuFor(e)}},{key:"placeCaretAtEnd",value:function(e){if(e.focus(),void 0!==window.getSelection&&void 0!==document.createRange){var t=document.createRange();t.selectNodeContents(e),t.collapse(!1);var n=window.getSelection();n.removeAllRanges(),n.addRange(t)}else if(void 0!==document.body.createTextRange){var i=document.body.createTextRange();i.moveToElementText(e),i.collapse(!1),i.select()}}},{key:"insertTextAtCursor",value:function(e){var t,n;(n=(t=window.getSelection()).getRangeAt(0)).deleteContents();var i=document.createTextNode(e);n.insertNode(i),n.selectNodeContents(i),n.collapse(!1),t.removeAllRanges(),t.addRange(n)}},{key:"insertAtCaret",value:function(e,t){var n=e.scrollTop,i=e.selectionStart,r=e.value.substring(0,i),o=e.value.substring(e.selectionEnd,e.value.length);e.value=r+t+o,i+=t.length,e.selectionStart=i,e.selectionEnd=i,e.focus(),e.scrollTop=n}},{key:"hideMenu",value:function(){this.menu&&(this.menu.style.cssText="display: none;",this.isActive=!1,this.menuSelected=0,this.current={})}},{key:"selectItemAtIndex",value:function(e,t){if("number"==typeof(e=parseInt(e))&&!isNaN(e)){var n=this.current.filteredItems[e],i=this.current.collection.selectTemplate(n);null!==i&&this.replaceText(i,t,n)}}},{key:"replaceText",value:function(e,t,n){this.range.replaceTriggerText(e,!0,!0,t,n)}},{key:"_append",value:function(e,t,n){if("function"==typeof e.values)throw new Error("Unable to append to values, as it is a function.");e.values=n?t:e.values.concat(t)}},{key:"append",value:function(e,t,n){var i=parseInt(e);if("number"!=typeof i)throw new Error("please provide an index for the collection to update.");var r=this.collection[i];this._append(r,t,n)}},{key:"appendCurrent",value:function(e,t){if(!this.isActive)throw new Error("No active state. Please use append instead and pass an index.");this._append(this.current.collection,e,t)}},{key:"detach",value:function(e){if(!e)throw new Error("[Tribute] Must pass in a DOM node or NodeList.");if("undefined"!=typeof jQuery&&e instanceof jQuery&&(e=e.get()),e.constructor===NodeList||e.constructor===HTMLCollection||e.constructor===Array)for(var t=e.length,n=0;n'+(this.current.collection.trigger+e.original[this.current.collection.fillAttr])+"":this.current.collection.trigger+e.original[this.current.collection.fillAttr]}},{key:"defaultMenuItemTemplate",value:function(e){return e.string}},{key:"inputTypes",value:function(){return["TEXTAREA","INPUT"]}}]),t}()})); //# sourceMappingURL=tribute.min.js.map diff --git a/dist/tribute.min.js.map b/dist/tribute.min.js.map index 604891a4..ecd0d801 100644 --- a/dist/tribute.min.js.map +++ b/dist/tribute.min.js.map @@ -1 +1 @@ -{"version":3,"file":"tribute.min.js","sources":["../src/utils.js","../src/TributeEvents.js","../src/TributeMenuEvents.js","../src/TributeRange.js","../src/TributeSearch.js","../src/Tribute.js"],"sourcesContent":["if (!Array.prototype.find) {\n Array.prototype.find = function(predicate) {\n if (this === null) {\n throw new TypeError('Array.prototype.find called on null or undefined')\n }\n if (typeof predicate !== 'function') {\n throw new TypeError('predicate must be a function')\n }\n var list = Object(this)\n var length = list.length >>> 0\n var thisArg = arguments[1]\n var value\n\n for (var i = 0; i < length; i++) {\n value = list[i]\n if (predicate.call(thisArg, value, i, list)) {\n return value\n }\n }\n return undefined\n }\n}\n\nif (window && typeof window.CustomEvent !== \"function\") {\n function CustomEvent(event, params) {\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n }\n var evt = document.createEvent('CustomEvent')\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)\n return evt\n }\n\n if (typeof window.Event !== 'undefined') {\n CustomEvent.prototype = window.Event.prototype\n }\n\n window.CustomEvent = CustomEvent\n}","class TributeEvents {\n constructor(tribute) {\n this.tribute = tribute;\n this.tribute.events = this;\n }\n\n static keys() {\n return [\n {\n key: 9,\n value: \"TAB\"\n },\n {\n key: 8,\n value: \"DELETE\"\n },\n {\n key: 13,\n value: \"ENTER\"\n },\n {\n key: 27,\n value: \"ESCAPE\"\n },\n {\n key: 32,\n value: \"SPACE\"\n },\n {\n key: 38,\n value: \"UP\"\n },\n {\n key: 40,\n value: \"DOWN\"\n }\n ];\n }\n\n bind(element) {\n element.boundKeydown = this.keydown.bind(element, this);\n element.boundKeyup = this.keyup.bind(element, this);\n element.boundInput = this.input.bind(element, this);\n\n element.addEventListener(\"keydown\", element.boundKeydown, false);\n element.addEventListener(\"keyup\", element.boundKeyup, false);\n element.addEventListener(\"input\", element.boundInput, false);\n }\n\n unbind(element) {\n element.removeEventListener(\"keydown\", element.boundKeydown, false);\n element.removeEventListener(\"keyup\", element.boundKeyup, false);\n element.removeEventListener(\"input\", element.boundInput, false);\n\n delete element.boundKeydown;\n delete element.boundKeyup;\n delete element.boundInput;\n }\n\n keydown(instance, event) {\n if (instance.shouldDeactivate(event)) {\n instance.tribute.isActive = false;\n instance.tribute.hideMenu();\n }\n\n let element = this;\n instance.commandEvent = false;\n\n TributeEvents.keys().forEach(o => {\n if (o.key === event.keyCode) {\n instance.commandEvent = true;\n instance.callbacks()[o.value.toLowerCase()](event, element);\n }\n });\n }\n\n input(instance, event) {\n instance.inputEvent = true;\n instance.keyup.call(this, instance, event);\n }\n\n click(instance, event) {\n let tribute = instance.tribute;\n if (tribute.menu && tribute.menu.contains(event.target)) {\n let li = event.target;\n event.preventDefault();\n event.stopPropagation();\n while (li.nodeName.toLowerCase() !== \"li\") {\n li = li.parentNode;\n if (!li || li === tribute.menu) {\n throw new Error(\"cannot find the
  • container for the click\");\n }\n }\n tribute.selectItemAtIndex(li.getAttribute(\"data-index\"), event);\n tribute.hideMenu();\n\n // TODO: should fire with externalTrigger and target is outside of menu\n } else if (tribute.current.element && !tribute.current.externalTrigger) {\n tribute.current.externalTrigger = false;\n setTimeout(() => tribute.hideMenu());\n }\n }\n\n keyup(instance, event) {\n if (instance.inputEvent) {\n instance.inputEvent = false;\n }\n instance.updateSelection(this);\n\n if (event.keyCode === 27) return;\n\n if (!instance.tribute.allowSpaces && instance.tribute.hasTrailingSpace) {\n instance.tribute.hasTrailingSpace = false;\n instance.commandEvent = true;\n instance.callbacks()[\"space\"](event, this);\n return;\n }\n\n if (!instance.tribute.isActive) {\n if (instance.tribute.autocompleteMode) {\n instance.callbacks().triggerChar(event, this, \"\");\n } else {\n let keyCode = instance.getKeyCode(instance, this, event);\n\n if (isNaN(keyCode) || !keyCode) return;\n\n let trigger = instance.tribute.triggers().find(trigger => {\n return trigger.charCodeAt(0) === keyCode;\n });\n\n if (typeof trigger !== \"undefined\") {\n instance.callbacks().triggerChar(event, this, trigger);\n }\n }\n }\n\n if (\n instance.tribute.current.mentionText.length <\n instance.tribute.current.collection.menuShowMinLength\n ) {\n return;\n }\n\n if (\n ((instance.tribute.current.trigger ||\n instance.tribute.autocompleteMode) &&\n instance.commandEvent === false) ||\n (instance.tribute.isActive && event.keyCode === 8)\n ) {\n instance.tribute.showMenuFor(this, true);\n }\n }\n\n shouldDeactivate(event) {\n if (!this.tribute.isActive) return false;\n\n if (this.tribute.current.mentionText.length === 0) {\n let eventKeyPressed = false;\n TributeEvents.keys().forEach(o => {\n if (event.keyCode === o.key) eventKeyPressed = true;\n });\n\n return !eventKeyPressed;\n }\n\n return false;\n }\n\n getKeyCode(instance, el, event) {\n let char;\n let tribute = instance.tribute;\n let info = tribute.range.getTriggerInfo(\n false,\n tribute.hasTrailingSpace,\n true,\n tribute.allowSpaces,\n tribute.autocompleteMode\n );\n\n if (info) {\n return info.mentionTriggerChar.charCodeAt(0);\n } else {\n return false;\n }\n }\n\n updateSelection(el) {\n this.tribute.current.element = el;\n let info = this.tribute.range.getTriggerInfo(\n false,\n this.tribute.hasTrailingSpace,\n true,\n this.tribute.allowSpaces,\n this.tribute.autocompleteMode\n );\n\n if (info) {\n this.tribute.current.selectedPath = info.mentionSelectedPath;\n this.tribute.current.mentionText = info.mentionText;\n this.tribute.current.selectedOffset = info.mentionSelectedOffset;\n }\n }\n\n callbacks() {\n return {\n triggerChar: (e, el, trigger) => {\n let tribute = this.tribute;\n tribute.current.trigger = trigger;\n\n let collectionItem = tribute.collection.find(item => {\n return item.trigger === trigger;\n });\n\n tribute.current.collection = collectionItem;\n\n if (\n tribute.current.mentionText.length >=\n tribute.current.collection.menuShowMinLength &&\n tribute.inputEvent\n ) {\n tribute.showMenuFor(el, true);\n }\n },\n enter: (e, el) => {\n // choose selection\n if (this.tribute.isActive && this.tribute.current.filteredItems) {\n e.preventDefault();\n e.stopPropagation();\n setTimeout(() => {\n this.tribute.selectItemAtIndex(this.tribute.menuSelected, e);\n this.tribute.hideMenu();\n }, 0);\n }\n },\n escape: (e, el) => {\n if (this.tribute.isActive) {\n e.preventDefault();\n e.stopPropagation();\n this.tribute.isActive = false;\n this.tribute.hideMenu();\n }\n },\n tab: (e, el) => {\n // choose first match\n this.callbacks().enter(e, el);\n },\n space: (e, el) => {\n if (this.tribute.isActive) {\n if (this.tribute.spaceSelectsMatch) {\n this.callbacks().enter(e, el);\n } else if (!this.tribute.allowSpaces) {\n e.stopPropagation();\n setTimeout(() => {\n this.tribute.hideMenu();\n this.tribute.isActive = false;\n }, 0);\n }\n }\n },\n up: (e, el) => {\n // navigate up ul\n if (this.tribute.isActive && this.tribute.current.filteredItems) {\n e.preventDefault();\n e.stopPropagation();\n let count = this.tribute.current.filteredItems.length,\n selected = this.tribute.menuSelected;\n\n if (count > selected && selected > 0) {\n this.tribute.menuSelected--;\n this.setActiveLi();\n } else if (selected === 0) {\n this.tribute.menuSelected = count - 1;\n this.setActiveLi();\n this.tribute.menu.scrollTop = this.tribute.menu.scrollHeight;\n }\n }\n },\n down: (e, el) => {\n // navigate down ul\n if (this.tribute.isActive && this.tribute.current.filteredItems) {\n e.preventDefault();\n e.stopPropagation();\n let count = this.tribute.current.filteredItems.length - 1,\n selected = this.tribute.menuSelected;\n\n if (count > selected) {\n this.tribute.menuSelected++;\n this.setActiveLi();\n } else if (count === selected) {\n this.tribute.menuSelected = 0;\n this.setActiveLi();\n this.tribute.menu.scrollTop = 0;\n }\n }\n },\n delete: (e, el) => {\n if (\n this.tribute.isActive &&\n this.tribute.current.mentionText.length < 1\n ) {\n this.tribute.hideMenu();\n } else if (this.tribute.isActive) {\n this.tribute.showMenuFor(el);\n }\n }\n };\n }\n\n setActiveLi(index) {\n let lis = this.tribute.menu.querySelectorAll(\"li\"),\n length = lis.length >>> 0;\n\n if (index) this.tribute.menuSelected = parseInt(index);\n\n for (let i = 0; i < length; i++) {\n let li = lis[i];\n if (i === this.tribute.menuSelected) {\n li.classList.add(this.tribute.current.collection.selectClass);\n\n let liClientRect = li.getBoundingClientRect();\n let menuClientRect = this.tribute.menu.getBoundingClientRect();\n\n if (liClientRect.bottom > menuClientRect.bottom) {\n let scrollDistance = liClientRect.bottom - menuClientRect.bottom;\n this.tribute.menu.scrollTop += scrollDistance;\n } else if (liClientRect.top < menuClientRect.top) {\n let scrollDistance = menuClientRect.top - liClientRect.top;\n this.tribute.menu.scrollTop -= scrollDistance;\n }\n } else {\n li.classList.remove(this.tribute.current.collection.selectClass);\n }\n }\n }\n\n getFullHeight(elem, includeMargin) {\n let height = elem.getBoundingClientRect().height;\n\n if (includeMargin) {\n let style = elem.currentStyle || window.getComputedStyle(elem);\n return (\n height + parseFloat(style.marginTop) + parseFloat(style.marginBottom)\n );\n }\n\n return height;\n }\n}\n\nexport default TributeEvents;\n","class TributeMenuEvents {\n constructor(tribute) {\n this.tribute = tribute;\n this.tribute.menuEvents = this;\n this.menu = this.tribute.menu;\n }\n\n bind(menu) {\n this.menuClickEvent = this.tribute.events.click.bind(null, this);\n this.menuContainerScrollEvent = this.debounce(\n () => {\n if (this.tribute.isActive) {\n this.tribute.showMenuFor(this.tribute.current.element, false);\n }\n },\n 300,\n false\n );\n this.windowResizeEvent = this.debounce(\n () => {\n if (this.tribute.isActive) {\n this.tribute.range.positionMenuAtCaret(true);\n }\n },\n 300,\n false\n );\n\n // fixes IE11 issues with mousedown\n this.tribute.range\n .getDocument()\n .addEventListener(\"MSPointerDown\", this.menuClickEvent, false);\n this.tribute.range\n .getDocument()\n .addEventListener(\"mousedown\", this.menuClickEvent, false);\n window.addEventListener(\"resize\", this.windowResizeEvent);\n\n if (this.menuContainer) {\n this.menuContainer.addEventListener(\n \"scroll\",\n this.menuContainerScrollEvent,\n false\n );\n } else {\n window.addEventListener(\"scroll\", this.menuContainerScrollEvent);\n }\n }\n\n unbind(menu) {\n this.tribute.range\n .getDocument()\n .removeEventListener(\"mousedown\", this.menuClickEvent, false);\n this.tribute.range\n .getDocument()\n .removeEventListener(\"MSPointerDown\", this.menuClickEvent, false);\n window.removeEventListener(\"resize\", this.windowResizeEvent);\n\n if (this.menuContainer) {\n this.menuContainer.removeEventListener(\n \"scroll\",\n this.menuContainerScrollEvent,\n false\n );\n } else {\n window.removeEventListener(\"scroll\", this.menuContainerScrollEvent);\n }\n }\n\n debounce(func, wait, immediate) {\n var timeout;\n return () => {\n var context = this,\n args = arguments;\n var later = () => {\n timeout = null;\n if (!immediate) func.apply(context, args);\n };\n var callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) func.apply(context, args);\n };\n }\n}\n\nexport default TributeMenuEvents;\n","// Thanks to https://github.com/jeff-collins/ment.io\nimport \"./utils\";\n\nclass TributeRange {\n constructor(tribute) {\n this.tribute = tribute\n this.tribute.range = this\n }\n\n getDocument() {\n let iframe\n if (this.tribute.current.collection) {\n iframe = this.tribute.current.collection.iframe\n }\n\n if (!iframe) {\n return document\n }\n\n return iframe.contentWindow.document\n }\n\n positionMenuAtCaret(scrollTo) {\n let context = this.tribute.current,\n coordinates\n\n let info = this.getTriggerInfo(false, this.tribute.hasTrailingSpace, true, this.tribute.allowSpaces, this.tribute.autocompleteMode)\n\n if (typeof info !== 'undefined') {\n\n if(!this.tribute.positionMenu){\n this.tribute.menu.style.cssText = `display: block;`\n return\n }\n\n if (!this.isContentEditable(context.element)) {\n coordinates = this.getTextAreaOrInputUnderlinePosition(this.tribute.current.element,\n info.mentionPosition)\n }\n else {\n coordinates = this.getContentEditableCaretPosition(info.mentionPosition)\n }\n\n this.tribute.menu.style.cssText = `top: ${coordinates.top}px;\n left: ${coordinates.left}px;\n right: ${coordinates.right}px;\n bottom: ${coordinates.bottom}px;\n position: absolute;\n display: block;`\n\n if (coordinates.left === 'auto') {\n this.tribute.menu.style.left = 'auto'\n }\n\n if (coordinates.top === 'auto') {\n this.tribute.menu.style.top = 'auto'\n }\n\n if (scrollTo) this.scrollIntoView()\n\n window.setTimeout(() => {\n let menuDimensions = {\n width: this.tribute.menu.offsetWidth,\n height: this.tribute.menu.offsetHeight\n }\n let menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n\n let menuIsOffScreenHorizontally = window.innerWidth > menuDimensions.width && (menuIsOffScreen.left || menuIsOffScreen.right)\n let menuIsOffScreenVertically = window.innerHeight > menuDimensions.height && (menuIsOffScreen.top || menuIsOffScreen.bottom)\n if (menuIsOffScreenHorizontally || menuIsOffScreenVertically) {\n this.tribute.menu.style.cssText = 'display: none'\n this.positionMenuAtCaret(scrollTo)\n }\n }, 0)\n\n } else {\n this.tribute.menu.style.cssText = 'display: none'\n }\n }\n\n get menuContainerIsBody() {\n return this.tribute.menuContainer === document.body || !this.tribute.menuContainer;\n }\n\n\n selectElement(targetElement, path, offset) {\n let range\n let elem = targetElement\n\n if (path) {\n for (var i = 0; i < path.length; i++) {\n elem = elem.childNodes[path[i]]\n if (elem === undefined) {\n return\n }\n while (elem.length < offset) {\n offset -= elem.length\n elem = elem.nextSibling\n }\n if (elem.childNodes.length === 0 && !elem.length) {\n elem = elem.previousSibling\n }\n }\n }\n let sel = this.getWindowSelection()\n\n range = this.getDocument().createRange()\n range.setStart(elem, offset)\n range.setEnd(elem, offset)\n range.collapse(true)\n\n try {\n sel.removeAllRanges()\n } catch (error) {}\n\n sel.addRange(range)\n targetElement.focus()\n }\n\n replaceTriggerText(text, requireLeadingSpace, hasTrailingSpace, originalEvent, item) {\n let info = this.getTriggerInfo(true, hasTrailingSpace, requireLeadingSpace, this.tribute.allowSpaces, this.tribute.autocompleteMode)\n\n if (info !== undefined) {\n let context = this.tribute.current\n let replaceEvent = new CustomEvent('tribute-replaced', {\n detail: {\n item: item,\n instance: context,\n context: info,\n event: originalEvent,\n }\n })\n\n if (!this.isContentEditable(context.element)) {\n let myField = this.tribute.current.element\n let textSuffix = typeof this.tribute.replaceTextSuffix == 'string'\n ? this.tribute.replaceTextSuffix\n : ' '\n text += textSuffix\n let startPos = info.mentionPosition\n let endPos = info.mentionPosition + info.mentionText.length + textSuffix.length\n if (!this.tribute.autocompleteMode) {\n endPos += info.mentionTriggerChar.length - 1\n }\n myField.value = myField.value.substring(0, startPos) + text +\n myField.value.substring(endPos, myField.value.length)\n myField.selectionStart = startPos + text.length\n myField.selectionEnd = startPos + text.length\n } else {\n // add a space to the end of the pasted text\n let textSuffix = typeof this.tribute.replaceTextSuffix == 'string'\n ? this.tribute.replaceTextSuffix\n : '\\xA0'\n text += textSuffix\n let endPos = info.mentionPosition + info.mentionText.length\n if (!this.tribute.autocompleteMode) {\n endPos += info.mentionTriggerChar.length\n }\n this.pasteHtml(text, info.mentionPosition, endPos)\n }\n\n context.element.dispatchEvent(new CustomEvent('input', { bubbles: true }))\n context.element.dispatchEvent(replaceEvent)\n }\n }\n\n pasteHtml(html, startPos, endPos) {\n let range, sel\n sel = this.getWindowSelection()\n range = this.getDocument().createRange()\n range.setStart(sel.anchorNode, startPos)\n range.setEnd(sel.anchorNode, endPos)\n range.deleteContents()\n\n let el = this.getDocument().createElement('div')\n el.innerHTML = html\n let frag = this.getDocument().createDocumentFragment(),\n node, lastNode\n while ((node = el.firstChild)) {\n lastNode = frag.appendChild(node)\n }\n range.insertNode(frag)\n\n // Preserve the selection\n if (lastNode) {\n range = range.cloneRange()\n range.setStartAfter(lastNode)\n range.collapse(true)\n sel.removeAllRanges()\n sel.addRange(range)\n }\n }\n\n getWindowSelection() {\n if (this.tribute.collection.iframe) {\n return this.tribute.collection.iframe.contentWindow.getSelection()\n }\n\n return window.getSelection()\n }\n\n getNodePositionInParent(element) {\n if (element.parentNode === null) {\n return 0\n }\n\n for (var i = 0; i < element.parentNode.childNodes.length; i++) {\n let node = element.parentNode.childNodes[i]\n\n if (node === element) {\n return i\n }\n }\n }\n\n getContentEditableSelectedPath(ctx) {\n let sel = this.getWindowSelection()\n let selected = sel.anchorNode\n let path = []\n let offset\n\n if (selected != null) {\n let i\n let ce = selected.contentEditable\n while (selected !== null && ce !== 'true') {\n i = this.getNodePositionInParent(selected)\n path.push(i)\n selected = selected.parentNode\n if (selected !== null) {\n ce = selected.contentEditable\n }\n }\n path.reverse()\n\n // getRangeAt may not exist, need alternative\n offset = sel.getRangeAt(0).startOffset\n\n return {\n selected: selected,\n path: path,\n offset: offset\n }\n }\n }\n\n getTextPrecedingCurrentSelection() {\n let context = this.tribute.current,\n text = ''\n\n if (!this.isContentEditable(context.element)) {\n let textComponent = this.tribute.current.element;\n if (textComponent) {\n let startPos = textComponent.selectionStart\n if (textComponent.value && startPos >= 0) {\n text = textComponent.value.substring(0, startPos)\n }\n }\n\n } else {\n let selectedElem = this.getWindowSelection().anchorNode\n\n if (selectedElem != null) {\n let workingNodeContent = selectedElem.textContent\n let selectStartOffset = this.getWindowSelection().getRangeAt(0).startOffset\n\n if (workingNodeContent && selectStartOffset >= 0) {\n text = workingNodeContent.substring(0, selectStartOffset)\n }\n }\n }\n\n return text\n }\n\n getLastWordInText(text) {\n text = text.replace(/\\u00A0/g, ' '); // https://stackoverflow.com/questions/29850407/how-do-i-replace-unicode-character-u00a0-with-a-space-in-javascript\n let wordsArray = text.split(/\\s+/);\n let worldsCount = wordsArray.length - 1\n return wordsArray[worldsCount].trim()\n }\n\n getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces, isAutocomplete) {\n let ctx = this.tribute.current\n let selected, path, offset\n\n if (!this.isContentEditable(ctx.element)) {\n selected = this.tribute.current.element\n } else {\n let selectionInfo = this.getContentEditableSelectedPath(ctx)\n\n if (selectionInfo) {\n selected = selectionInfo.selected\n path = selectionInfo.path\n offset = selectionInfo.offset\n }\n }\n\n let effectiveRange = this.getTextPrecedingCurrentSelection()\n let lastWordOfEffectiveRange = this.getLastWordInText(effectiveRange)\n\n if (isAutocomplete) {\n return {\n mentionPosition: effectiveRange.length - lastWordOfEffectiveRange.length,\n mentionText: lastWordOfEffectiveRange,\n mentionSelectedElement: selected,\n mentionSelectedPath: path,\n mentionSelectedOffset: offset\n }\n }\n\n if (effectiveRange !== undefined && effectiveRange !== null) {\n let mostRecentTriggerCharPos = -1\n let triggerChar\n\n this.tribute.collection.forEach(config => {\n let c = config.trigger\n let idx = config.requireLeadingSpace ?\n this.lastIndexWithLeadingSpace(effectiveRange, c) :\n effectiveRange.lastIndexOf(c)\n\n if (idx > mostRecentTriggerCharPos) {\n mostRecentTriggerCharPos = idx\n triggerChar = c\n requireLeadingSpace = config.requireLeadingSpace\n }\n })\n\n if (mostRecentTriggerCharPos >= 0 &&\n (\n mostRecentTriggerCharPos === 0 ||\n !requireLeadingSpace ||\n /[\\xA0\\s]/g.test(\n effectiveRange.substring(\n mostRecentTriggerCharPos - 1,\n mostRecentTriggerCharPos)\n )\n )\n ) {\n let currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + triggerChar.length,\n effectiveRange.length)\n\n triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos + triggerChar.length)\n let firstSnippetChar = currentTriggerSnippet.substring(0, 1)\n let leadingSpace = currentTriggerSnippet.length > 0 &&\n (\n firstSnippetChar === ' ' ||\n firstSnippetChar === '\\xA0'\n )\n if (hasTrailingSpace) {\n currentTriggerSnippet = currentTriggerSnippet.trim()\n }\n\n let regex = allowSpaces ? /[^\\S ]/g : /[\\xA0\\s]/g;\n\n this.tribute.hasTrailingSpace = regex.test(currentTriggerSnippet);\n\n if (!leadingSpace && (menuAlreadyActive || !(regex.test(currentTriggerSnippet)))) {\n return {\n mentionPosition: mostRecentTriggerCharPos,\n mentionText: currentTriggerSnippet,\n mentionSelectedElement: selected,\n mentionSelectedPath: path,\n mentionSelectedOffset: offset,\n mentionTriggerChar: triggerChar\n }\n }\n }\n }\n }\n\n lastIndexWithLeadingSpace (str, trigger) {\n let reversedStr = str.split('').reverse().join('')\n let index = -1\n\n for (let cidx = 0, len = str.length; cidx < len; cidx++) {\n let firstChar = cidx === str.length - 1\n let leadingSpace = /\\s/.test(reversedStr[cidx + 1])\n\n let match = true\n for (let triggerIdx = trigger.length - 1; triggerIdx >= 0; triggerIdx--) {\n if (trigger[triggerIdx] !== reversedStr[cidx-triggerIdx]) {\n match = false\n break\n }\n }\n\n if (match && (firstChar || leadingSpace)) {\n index = str.length - 1 - cidx\n break\n }\n }\n\n return index\n }\n\n isContentEditable(element) {\n return element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA'\n }\n\n isMenuOffScreen(coordinates, menuDimensions) {\n let windowWidth = window.innerWidth\n let windowHeight = window.innerHeight\n let doc = document.documentElement\n let windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)\n let windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\n\n let menuTop = typeof coordinates.top === 'number' ? coordinates.top : windowTop + windowHeight - coordinates.bottom - menuDimensions.height\n let menuRight = typeof coordinates.right === 'number' ? coordinates.right : coordinates.left + menuDimensions.width\n let menuBottom = typeof coordinates.bottom === 'number' ? coordinates.bottom : coordinates.top + menuDimensions.height\n let menuLeft = typeof coordinates.left === 'number' ? coordinates.left : windowLeft + windowWidth - coordinates.right - menuDimensions.width\n\n return {\n top: menuTop < Math.floor(windowTop),\n right: menuRight > Math.ceil(windowLeft + windowWidth),\n bottom: menuBottom > Math.ceil(windowTop + windowHeight),\n left: menuLeft < Math.floor(windowLeft)\n }\n }\n\n getMenuDimensions() {\n // Width of the menu depends of its contents and position\n // We must check what its width would be without any obstruction\n // This way, we can achieve good positioning for flipping the menu\n let dimensions = {\n width: null,\n height: null\n }\n\n this.tribute.menu.style.cssText = `top: 0px;\n left: 0px;\n position: fixed;\n display: block;\n visibility; hidden;`\n dimensions.width = this.tribute.menu.offsetWidth\n dimensions.height = this.tribute.menu.offsetHeight\n\n this.tribute.menu.style.cssText = `display: none;`\n\n return dimensions\n }\n\n getTextAreaOrInputUnderlinePosition(element, position, flipped) {\n let properties = ['direction', 'boxSizing', 'width', 'height', 'overflowX',\n 'overflowY', 'borderTopWidth', 'borderRightWidth',\n 'borderBottomWidth', 'borderLeftWidth', 'paddingTop',\n 'paddingRight', 'paddingBottom', 'paddingLeft',\n 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch',\n 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily',\n 'textAlign', 'textTransform', 'textIndent',\n 'textDecoration', 'letterSpacing', 'wordSpacing'\n ]\n\n let isFirefox = (window.mozInnerScreenX !== null)\n\n let div = this.getDocument().createElement('div')\n div.id = 'input-textarea-caret-position-mirror-div'\n this.getDocument().body.appendChild(div)\n\n let style = div.style\n let computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle\n\n style.whiteSpace = 'pre-wrap'\n if (element.nodeName !== 'INPUT') {\n style.wordWrap = 'break-word'\n }\n\n // position off-screen\n style.position = 'absolute'\n style.visibility = 'hidden'\n\n // transfer the element's properties to the div\n properties.forEach(prop => {\n style[prop] = computed[prop]\n })\n\n if (isFirefox) {\n style.width = `${(parseInt(computed.width) - 2)}px`\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll'\n } else {\n style.overflow = 'hidden'\n }\n\n div.textContent = element.value.substring(0, position)\n\n if (element.nodeName === 'INPUT') {\n div.textContent = div.textContent.replace(/\\s/g, ' ')\n }\n\n let span = this.getDocument().createElement('span')\n span.textContent = element.value.substring(position) || '.'\n div.appendChild(span)\n\n let rect = element.getBoundingClientRect()\n let doc = document.documentElement\n let windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)\n let windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\n\n let top = 0;\n let left = 0;\n if (this.menuContainerIsBody) {\n top = rect.top;\n left = rect.left;\n }\n\n let coordinates = {\n top: top + windowTop + span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize) - element.scrollTop,\n left: left + windowLeft + span.offsetLeft + parseInt(computed.borderLeftWidth)\n }\n\n let windowWidth = window.innerWidth\n let windowHeight = window.innerHeight\n\n let menuDimensions = this.getMenuDimensions()\n let menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n\n if (menuIsOffScreen.right) {\n coordinates.right = windowWidth - coordinates.left\n coordinates.left = 'auto'\n }\n\n let parentHeight = this.tribute.menuContainer\n ? this.tribute.menuContainer.offsetHeight\n : this.getDocument().body.offsetHeight\n\n if (menuIsOffScreen.bottom) {\n let parentRect = this.tribute.menuContainer\n ? this.tribute.menuContainer.getBoundingClientRect()\n : this.getDocument().body.getBoundingClientRect()\n let scrollStillAvailable = parentHeight - (windowHeight - parentRect.top)\n\n coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top - span.offsetTop)\n coordinates.top = 'auto'\n }\n\n menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n if (menuIsOffScreen.left) {\n coordinates.left = windowWidth > menuDimensions.width\n ? windowLeft + windowWidth - menuDimensions.width\n : windowLeft\n delete coordinates.right\n }\n if (menuIsOffScreen.top) {\n coordinates.top = windowHeight > menuDimensions.height\n ? windowTop + windowHeight - menuDimensions.height\n : windowTop\n delete coordinates.bottom\n }\n\n this.getDocument().body.removeChild(div)\n return coordinates\n }\n\n getContentEditableCaretPosition(selectedNodePosition) {\n let range\n let sel = this.getWindowSelection()\n\n range = this.getDocument().createRange()\n range.setStart(sel.anchorNode, selectedNodePosition)\n range.setEnd(sel.anchorNode, selectedNodePosition)\n\n range.collapse(false)\n\n let rect = range.getBoundingClientRect()\n let doc = document.documentElement\n let windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)\n let windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\n\n let left = rect.left\n let top = rect.top\n\n let coordinates = {\n left: left + windowLeft,\n top: top + rect.height + windowTop\n }\n let windowWidth = window.innerWidth\n let windowHeight = window.innerHeight\n\n let menuDimensions = this.getMenuDimensions()\n let menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n\n if (menuIsOffScreen.right) {\n coordinates.left = 'auto'\n coordinates.right = windowWidth - rect.left - windowLeft\n }\n\n let parentHeight = this.tribute.menuContainer\n ? this.tribute.menuContainer.offsetHeight\n : this.getDocument().body.offsetHeight\n\n if (menuIsOffScreen.bottom) {\n let parentRect = this.tribute.menuContainer\n ? this.tribute.menuContainer.getBoundingClientRect()\n : this.getDocument().body.getBoundingClientRect()\n let scrollStillAvailable = parentHeight - (windowHeight - parentRect.top)\n\n coordinates.top = 'auto'\n coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top)\n }\n\n menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n if (menuIsOffScreen.left) {\n coordinates.left = windowWidth > menuDimensions.width\n ? windowLeft + windowWidth - menuDimensions.width\n : windowLeft\n delete coordinates.right\n }\n if (menuIsOffScreen.top) {\n coordinates.top = windowHeight > menuDimensions.height\n ? windowTop + windowHeight - menuDimensions.height\n : windowTop\n delete coordinates.bottom\n }\n\n if (!this.menuContainerIsBody) {\n coordinates.left = coordinates.left ? coordinates.left - this.tribute.menuContainer.offsetLeft : coordinates.left\n coordinates.top = coordinates.top ? coordinates.top - this.tribute.menuContainer.offsetTop : coordinates.top\n }\n\n return coordinates\n }\n\n scrollIntoView(elem) {\n let reasonableBuffer = 20,\n clientRect\n let maxScrollDisplacement = 100\n let e = this.menu\n\n if (typeof e === 'undefined') return;\n\n while (clientRect === undefined || clientRect.height === 0) {\n clientRect = e.getBoundingClientRect()\n\n if (clientRect.height === 0) {\n e = e.childNodes[0]\n if (e === undefined || !e.getBoundingClientRect) {\n return\n }\n }\n }\n\n let elemTop = clientRect.top\n let elemBottom = elemTop + clientRect.height\n\n if (elemTop < 0) {\n window.scrollTo(0, window.pageYOffset + clientRect.top - reasonableBuffer)\n } else if (elemBottom > window.innerHeight) {\n let maxY = window.pageYOffset + clientRect.top - reasonableBuffer\n\n if (maxY - window.pageYOffset > maxScrollDisplacement) {\n maxY = window.pageYOffset + maxScrollDisplacement\n }\n\n let targetY = window.pageYOffset - (window.innerHeight - elemBottom)\n\n if (targetY > maxY) {\n targetY = maxY\n }\n\n window.scrollTo(0, targetY)\n }\n }\n}\n\n\nexport default TributeRange;\n","// Thanks to https://github.com/mattyork/fuzzy\nclass TributeSearch {\n constructor(tribute) {\n this.tribute = tribute\n this.tribute.search = this\n }\n\n simpleFilter(pattern, array) {\n return array.filter(string => {\n return this.test(pattern, string)\n })\n }\n\n test(pattern, string) {\n return this.match(pattern, string) !== null\n }\n\n match(pattern, string, opts) {\n opts = opts || {}\n let patternIdx = 0,\n result = [],\n len = string.length,\n totalScore = 0,\n currScore = 0,\n pre = opts.pre || '',\n post = opts.post || '',\n compareString = opts.caseSensitive && string || string.toLowerCase(),\n ch, compareChar\n\n if (opts.skip) {\n return {rendered: string, score: 0}\n }\n\n pattern = opts.caseSensitive && pattern || pattern.toLowerCase()\n\n let patternCache = this.traverse(compareString, pattern, 0, 0, [])\n if (!patternCache) {\n return null\n }\n return {\n rendered: this.render(string, patternCache.cache, pre, post),\n score: patternCache.score\n }\n }\n\n traverse(string, pattern, stringIndex, patternIndex, patternCache) {\n // if the pattern search at end\n if (pattern.length === patternIndex) {\n\n // calculate score and copy the cache containing the indices where it's found\n return {\n score: this.calculateScore(patternCache),\n cache: patternCache.slice()\n }\n }\n\n // if string at end or remaining pattern > remaining string\n if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) {\n return undefined\n }\n\n let c = pattern[patternIndex]\n let index = string.indexOf(c, stringIndex)\n let best, temp\n\n while (index > -1) {\n patternCache.push(index)\n temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache)\n patternCache.pop()\n\n // if downstream traversal failed, return best answer so far\n if (!temp) {\n return best\n }\n\n if (!best || best.score < temp.score) {\n best = temp\n }\n\n index = string.indexOf(c, index + 1)\n }\n\n return best\n }\n\n calculateScore(patternCache) {\n let score = 0\n let temp = 1\n\n patternCache.forEach((index, i) => {\n if (i > 0) {\n if (patternCache[i - 1] + 1 === index) {\n temp += temp + 1\n }\n else {\n temp = 1\n }\n }\n\n score += temp\n })\n\n return score\n }\n\n render(string, indices, pre, post) {\n var rendered = string.substring(0, indices[0])\n\n indices.forEach((index, i) => {\n rendered += pre + string[index] + post +\n string.substring(index + 1, (indices[i + 1]) ? indices[i + 1] : string.length)\n })\n\n return rendered\n }\n\n filter(pattern, arr, opts) {\n opts = opts || {}\n return arr\n .reduce((prev, element, idx, arr) => {\n let str = element\n\n if (opts.extract) {\n str = opts.extract(element)\n\n if (!str) { // take care of undefineds / nulls / etc.\n str = ''\n }\n }\n\n let rendered = this.match(pattern, str, opts)\n\n if (rendered != null) {\n prev[prev.length] = {\n string: rendered.rendered,\n score: rendered.score,\n index: idx,\n original: element\n }\n }\n\n return prev\n }, [])\n\n .sort((a, b) => {\n let compare = b.score - a.score\n if (compare) return compare\n return a.index - b.index\n })\n }\n}\n\nexport default TributeSearch;\n","import \"./utils\";\nimport TributeEvents from \"./TributeEvents\";\nimport TributeMenuEvents from \"./TributeMenuEvents\";\nimport TributeRange from \"./TributeRange\";\nimport TributeSearch from \"./TributeSearch\";\n\nclass Tribute {\n constructor({\n values = null,\n iframe = null,\n selectClass = \"highlight\",\n containerClass = \"tribute-container\",\n itemClass = \"\",\n trigger = \"@\",\n autocompleteMode = false,\n selectTemplate = null,\n menuItemTemplate = null,\n lookup = \"key\",\n fillAttr = \"value\",\n collection = null,\n menuContainer = null,\n noMatchTemplate = null,\n requireLeadingSpace = true,\n allowSpaces = false,\n replaceTextSuffix = null,\n positionMenu = true,\n spaceSelectsMatch = false,\n searchOpts = {},\n menuItemLimit = null,\n menuShowMinLength = 0\n }) {\n this.autocompleteMode = autocompleteMode;\n this.menuSelected = 0;\n this.current = {};\n this.inputEvent = false;\n this.isActive = false;\n this.menuContainer = menuContainer;\n this.allowSpaces = allowSpaces;\n this.replaceTextSuffix = replaceTextSuffix;\n this.positionMenu = positionMenu;\n this.hasTrailingSpace = false;\n this.spaceSelectsMatch = spaceSelectsMatch;\n\n if (this.autocompleteMode) {\n trigger = \"\";\n allowSpaces = false;\n }\n\n if (values) {\n this.collection = [\n {\n // symbol that starts the lookup\n trigger: trigger,\n\n // is it wrapped in an iframe\n iframe: iframe,\n\n // class applied to selected item\n selectClass: selectClass,\n\n // class applied to the Container\n containerClass: containerClass,\n\n // class applied to each item\n itemClass: itemClass,\n\n // function called on select that retuns the content to insert\n selectTemplate: (\n selectTemplate || Tribute.defaultSelectTemplate\n ).bind(this),\n\n // function called that returns content for an item\n menuItemTemplate: (\n menuItemTemplate || Tribute.defaultMenuItemTemplate\n ).bind(this),\n\n // function called when menu is empty, disables hiding of menu.\n noMatchTemplate: (t => {\n if (typeof t === \"function\") {\n return t.bind(this);\n }\n\n return (\n noMatchTemplate ||\n function() {\n return \"\";\n }.bind(this)\n );\n })(noMatchTemplate),\n\n // column to search against in the object\n lookup: lookup,\n\n // column that contains the content to insert by default\n fillAttr: fillAttr,\n\n // array of objects or a function returning an array of objects\n values: values,\n\n requireLeadingSpace: requireLeadingSpace,\n\n searchOpts: searchOpts,\n\n menuItemLimit: menuItemLimit,\n\n menuShowMinLength: menuShowMinLength\n }\n ];\n } else if (collection) {\n if (this.autocompleteMode)\n console.warn(\n \"Tribute in autocomplete mode does not work for collections\"\n );\n this.collection = collection.map(item => {\n return {\n trigger: item.trigger || trigger,\n iframe: item.iframe || iframe,\n selectClass: item.selectClass || selectClass,\n containerClass: item.containerClass || containerClass,\n itemClass: item.itemClass || itemClass,\n selectTemplate: (\n item.selectTemplate || Tribute.defaultSelectTemplate\n ).bind(this),\n menuItemTemplate: (\n item.menuItemTemplate || Tribute.defaultMenuItemTemplate\n ).bind(this),\n // function called when menu is empty, disables hiding of menu.\n noMatchTemplate: (t => {\n if (typeof t === \"function\") {\n return t.bind(this);\n }\n\n return null;\n })(noMatchTemplate),\n lookup: item.lookup || lookup,\n fillAttr: item.fillAttr || fillAttr,\n values: item.values,\n requireLeadingSpace: item.requireLeadingSpace,\n searchOpts: item.searchOpts || searchOpts,\n menuItemLimit: item.menuItemLimit || menuItemLimit,\n menuShowMinLength: item.menuShowMinLength || menuShowMinLength\n };\n });\n } else {\n throw new Error(\"[Tribute] No collection specified.\");\n }\n\n new TributeRange(this);\n new TributeEvents(this);\n new TributeMenuEvents(this);\n new TributeSearch(this);\n }\n\n get isActive() {\n return this._isActive;\n }\n\n set isActive(val) {\n if (this._isActive != val) {\n this._isActive = val;\n if (this.current.element) {\n let noMatchEvent = new CustomEvent(`tribute-active-${val}`);\n this.current.element.dispatchEvent(noMatchEvent);\n }\n }\n }\n\n static defaultSelectTemplate(item) {\n if (typeof item === \"undefined\") return null;\n if (this.range.isContentEditable(this.current.element)) {\n return (\n '' +\n (this.current.collection.trigger +\n item.original[this.current.collection.fillAttr]) +\n \"\"\n );\n }\n\n return (\n this.current.collection.trigger +\n item.original[this.current.collection.fillAttr]\n );\n }\n\n static defaultMenuItemTemplate(matchItem) {\n return matchItem.string;\n }\n\n static inputTypes() {\n return [\"TEXTAREA\", \"INPUT\"];\n }\n\n triggers() {\n return this.collection.map(config => {\n return config.trigger;\n });\n }\n\n attach(el) {\n if (!el) {\n throw new Error(\"[Tribute] Must pass in a DOM node or NodeList.\");\n }\n\n // Check if it is a jQuery collection\n if (typeof jQuery !== \"undefined\" && el instanceof jQuery) {\n el = el.get();\n }\n\n // Is el an Array/Array-like object?\n if (\n el.constructor === NodeList ||\n el.constructor === HTMLCollection ||\n el.constructor === Array\n ) {\n let length = el.length;\n for (var i = 0; i < length; ++i) {\n this._attach(el[i]);\n }\n } else {\n this._attach(el);\n }\n }\n\n _attach(el) {\n if (el.hasAttribute(\"data-tribute\")) {\n console.warn(\"Tribute was already bound to \" + el.nodeName);\n }\n\n this.ensureEditable(el);\n this.events.bind(el);\n el.setAttribute(\"data-tribute\", true);\n }\n\n ensureEditable(element) {\n if (Tribute.inputTypes().indexOf(element.nodeName) === -1) {\n if (element.contentEditable) {\n element.contentEditable = true;\n } else {\n throw new Error(\"[Tribute] Cannot bind to \" + element.nodeName);\n }\n }\n }\n\n createMenu(containerClass) {\n let wrapper = this.range.getDocument().createElement(\"div\"),\n ul = this.range.getDocument().createElement(\"ul\");\n wrapper.className = containerClass;\n wrapper.appendChild(ul);\n\n if (this.menuContainer) {\n return this.menuContainer.appendChild(wrapper);\n }\n\n return this.range.getDocument().body.appendChild(wrapper);\n }\n\n showMenuFor(element, scrollTo) {\n // Only proceed if menu isn't already shown for the current element & mentionText\n if (\n this.isActive &&\n this.current.element === element &&\n this.current.mentionText === this.currentMentionTextSnapshot\n ) {\n return;\n }\n this.currentMentionTextSnapshot = this.current.mentionText;\n\n // create the menu if it doesn't exist.\n if (!this.menu) {\n this.menu = this.createMenu(this.current.collection.containerClass);\n element.tributeMenu = this.menu;\n this.menuEvents.bind(this.menu);\n }\n\n this.isActive = true;\n this.menuSelected = 0;\n\n if (!this.current.mentionText) {\n this.current.mentionText = \"\";\n }\n\n const processValues = values => {\n // Tribute may not be active any more by the time the value callback returns\n if (!this.isActive) {\n return;\n }\n\n let items = this.search.filter(this.current.mentionText, values, {\n pre: this.current.collection.searchOpts.pre || \"\",\n post: this.current.collection.searchOpts.post || \"\",\n skip: this.current.collection.searchOpts.skip,\n extract: el => {\n if (typeof this.current.collection.lookup === \"string\") {\n return el[this.current.collection.lookup];\n } else if (typeof this.current.collection.lookup === \"function\") {\n return this.current.collection.lookup(el, this.current.mentionText);\n } else {\n throw new Error(\n \"Invalid lookup attribute, lookup must be string or function.\"\n );\n }\n }\n });\n\n if (this.current.collection.menuItemLimit) {\n items = items.slice(0, this.current.collection.menuItemLimit);\n }\n\n this.current.filteredItems = items;\n\n let ul = this.menu.querySelector(\"ul\");\n\n this.range.positionMenuAtCaret(scrollTo);\n\n if (!items.length) {\n let noMatchEvent = new CustomEvent(\"tribute-no-match\", {\n detail: this.menu\n });\n this.current.element.dispatchEvent(noMatchEvent);\n if (\n (typeof this.current.collection.noMatchTemplate === \"function\" &&\n !this.current.collection.noMatchTemplate()) ||\n !this.current.collection.noMatchTemplate\n ) {\n this.hideMenu();\n } else {\n typeof this.current.collection.noMatchTemplate === \"function\"\n ? (ul.innerHTML = this.current.collection.noMatchTemplate())\n : (ul.innerHTML = this.current.collection.noMatchTemplate);\n }\n\n return;\n }\n\n ul.innerHTML = \"\";\n let fragment = this.range.getDocument().createDocumentFragment();\n\n items.forEach((item, index) => {\n let li = this.range.getDocument().createElement(\"li\");\n li.setAttribute(\"data-index\", index);\n li.className = this.current.collection.itemClass;\n li.addEventListener(\"mousemove\", e => {\n let [li, index] = this._findLiTarget(e.target);\n if (e.movementY !== 0) {\n this.events.setActiveLi(index);\n }\n });\n if (this.menuSelected === index) {\n li.classList.add(this.current.collection.selectClass);\n }\n li.innerHTML = this.current.collection.menuItemTemplate(item);\n fragment.appendChild(li);\n });\n ul.appendChild(fragment);\n };\n\n if (typeof this.current.collection.values === \"function\") {\n this.current.collection.values(this.current.mentionText, processValues);\n } else {\n processValues(this.current.collection.values);\n }\n }\n\n _findLiTarget(el) {\n if (!el) return [];\n const index = el.getAttribute(\"data-index\");\n return !index ? this._findLiTarget(el.parentNode) : [el, index];\n }\n\n showMenuForCollection(element, collectionIndex) {\n if (element !== document.activeElement) {\n this.placeCaretAtEnd(element);\n }\n\n this.current.collection = this.collection[collectionIndex || 0];\n this.current.externalTrigger = true;\n this.current.element = element;\n\n if (element.isContentEditable)\n this.insertTextAtCursor(this.current.collection.trigger);\n else this.insertAtCaret(element, this.current.collection.trigger);\n\n this.showMenuFor(element);\n }\n\n // TODO: make sure this works for inputs/textareas\n placeCaretAtEnd(el) {\n el.focus();\n if (\n typeof window.getSelection != \"undefined\" &&\n typeof document.createRange != \"undefined\"\n ) {\n var range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n var sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n } else if (typeof document.body.createTextRange != \"undefined\") {\n var textRange = document.body.createTextRange();\n textRange.moveToElementText(el);\n textRange.collapse(false);\n textRange.select();\n }\n }\n\n // for contenteditable\n insertTextAtCursor(text) {\n var sel, range, html;\n sel = window.getSelection();\n range = sel.getRangeAt(0);\n range.deleteContents();\n var textNode = document.createTextNode(text);\n range.insertNode(textNode);\n range.selectNodeContents(textNode);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n // for regular inputs\n insertAtCaret(textarea, text) {\n var scrollPos = textarea.scrollTop;\n var caretPos = textarea.selectionStart;\n\n var front = textarea.value.substring(0, caretPos);\n var back = textarea.value.substring(\n textarea.selectionEnd,\n textarea.value.length\n );\n textarea.value = front + text + back;\n caretPos = caretPos + text.length;\n textarea.selectionStart = caretPos;\n textarea.selectionEnd = caretPos;\n textarea.focus();\n textarea.scrollTop = scrollPos;\n }\n\n hideMenu() {\n if (this.menu) {\n this.menu.style.cssText = \"display: none;\";\n this.isActive = false;\n this.menuSelected = 0;\n this.current = {};\n }\n }\n\n selectItemAtIndex(index, originalEvent) {\n index = parseInt(index);\n if (typeof index !== \"number\" || isNaN(index)) return;\n let item = this.current.filteredItems[index];\n let content = this.current.collection.selectTemplate(item);\n if (content !== null) this.replaceText(content, originalEvent, item);\n }\n\n replaceText(content, originalEvent, item) {\n this.range.replaceTriggerText(content, true, true, originalEvent, item);\n }\n\n _append(collection, newValues, replace) {\n if (typeof collection.values === \"function\") {\n throw new Error(\"Unable to append to values, as it is a function.\");\n } else if (!replace) {\n collection.values = collection.values.concat(newValues);\n } else {\n collection.values = newValues;\n }\n }\n\n append(collectionIndex, newValues, replace) {\n let index = parseInt(collectionIndex);\n if (typeof index !== \"number\")\n throw new Error(\"please provide an index for the collection to update.\");\n\n let collection = this.collection[index];\n\n this._append(collection, newValues, replace);\n }\n\n appendCurrent(newValues, replace) {\n if (this.isActive) {\n this._append(this.current.collection, newValues, replace);\n } else {\n throw new Error(\n \"No active state. Please use append instead and pass an index.\"\n );\n }\n }\n\n detach(el) {\n if (!el) {\n throw new Error(\"[Tribute] Must pass in a DOM node or NodeList.\");\n }\n\n // Check if it is a jQuery collection\n if (typeof jQuery !== \"undefined\" && el instanceof jQuery) {\n el = el.get();\n }\n\n // Is el an Array/Array-like object?\n if (\n el.constructor === NodeList ||\n el.constructor === HTMLCollection ||\n el.constructor === Array\n ) {\n let length = el.length;\n for (var i = 0; i < length; ++i) {\n this._detach(el[i]);\n }\n } else {\n this._detach(el);\n }\n }\n\n _detach(el) {\n this.events.unbind(el);\n if (el.tributeMenu) {\n this.menuEvents.unbind(el.tributeMenu);\n }\n\n setTimeout(() => {\n el.removeAttribute(\"data-tribute\");\n this.isActive = false;\n if (el.tributeMenu) {\n el.tributeMenu.remove();\n }\n });\n }\n}\n\nexport default Tribute;\n"],"names":["Array","prototype","find","predicate","this","TypeError","value","list","Object","length","thisArg","arguments","i","call","window","CustomEvent","event","params","bubbles","cancelable","detail","undefined","evt","document","createEvent","initCustomEvent","Event","TributeEvents","tribute","events","element","boundKeydown","keydown","bind","boundKeyup","keyup","boundInput","input","addEventListener","removeEventListener","instance","shouldDeactivate","isActive","hideMenu","commandEvent","keys","forEach","o","key","keyCode","callbacks","toLowerCase","inputEvent","menu","contains","target","li","preventDefault","stopPropagation","nodeName","parentNode","Error","selectItemAtIndex","getAttribute","current","externalTrigger","setTimeout","updateSelection","allowSpaces","hasTrailingSpace","autocompleteMode","triggerChar","getKeyCode","isNaN","trigger","triggers","charCodeAt","mentionText","collection","menuShowMinLength","showMenuFor","eventKeyPressed","el","info","range","getTriggerInfo","mentionTriggerChar","selectedPath","mentionSelectedPath","selectedOffset","mentionSelectedOffset","e","_this","collectionItem","item","enter","filteredItems","menuSelected","escape","tab","space","spaceSelectsMatch","up","count","selected","setActiveLi","scrollTop","scrollHeight","down","index","lis","querySelectorAll","parseInt","classList","add","selectClass","liClientRect","getBoundingClientRect","menuClientRect","bottom","scrollDistance","top","remove","elem","includeMargin","height","style","currentStyle","getComputedStyle","parseFloat","marginTop","marginBottom","TributeMenuEvents","menuEvents","menuClickEvent","click","menuContainerScrollEvent","debounce","windowResizeEvent","positionMenuAtCaret","getDocument","menuContainer","func","wait","immediate","timeout","context","_this2","args","callNow","clearTimeout","apply","TributeRange","iframe","contentWindow","scrollTo","coordinates","positionMenu","cssText","isContentEditable","getContentEditableCaretPosition","mentionPosition","getTextAreaOrInputUnderlinePosition","left","right","scrollIntoView","menuDimensions","width","offsetWidth","offsetHeight","menuIsOffScreen","isMenuOffScreen","menuIsOffScreenHorizontally","innerWidth","menuIsOffScreenVertically","innerHeight","targetElement","path","offset","childNodes","nextSibling","previousSibling","sel","getWindowSelection","createRange","setStart","setEnd","collapse","removeAllRanges","error","addRange","focus","text","requireLeadingSpace","originalEvent","replaceEvent","replaceTextSuffix","endPos","pasteHtml","myField","textSuffix","startPos","substring","selectionStart","selectionEnd","dispatchEvent","html","anchorNode","deleteContents","createElement","innerHTML","node","lastNode","frag","createDocumentFragment","firstChild","appendChild","insertNode","cloneRange","setStartAfter","getSelection","ctx","ce","contentEditable","getNodePositionInParent","push","reverse","getRangeAt","startOffset","selectedElem","workingNodeContent","textContent","selectStartOffset","textComponent","wordsArray","replace","split","trim","menuAlreadyActive","isAutocomplete","selectionInfo","getContentEditableSelectedPath","effectiveRange","getTextPrecedingCurrentSelection","lastWordOfEffectiveRange","getLastWordInText","mentionSelectedElement","mostRecentTriggerCharPos","config","c","idx","lastIndexWithLeadingSpace","lastIndexOf","test","currentTriggerSnippet","firstSnippetChar","leadingSpace","regex","str","reversedStr","join","cidx","len","firstChar","match","triggerIdx","windowWidth","windowHeight","doc","documentElement","windowLeft","pageXOffset","scrollLeft","clientLeft","windowTop","pageYOffset","clientTop","menuTop","menuRight","menuBottom","menuLeft","Math","floor","ceil","dimensions","position","flipped","isFirefox","mozInnerScreenX","div","id","body","computed","whiteSpace","wordWrap","visibility","prop","overflowY","overflow","span","rect","menuContainerIsBody","offsetTop","borderTopWidth","fontSize","offsetLeft","borderLeftWidth","getMenuDimensions","parentHeight","scrollStillAvailable","removeChild","selectedNodePosition","clientRect","elemTop","elemBottom","maxY","targetY","TributeSearch","search","pattern","array","filter","string","opts","pre","post","compareString","caseSensitive","skip","rendered","score","patternCache","traverse","render","cache","stringIndex","patternIndex","calculateScore","slice","best","temp","indexOf","pop","indices","arr","reduce","prev","extract","original","sort","a","b","compare","t","values","containerClass","itemClass","selectTemplate","menuItemTemplate","lookup","fillAttr","noMatchTemplate","searchOpts","menuItemLimit","Tribute","defaultSelectTemplate","defaultMenuItemTemplate","console","warn","map","jQuery","get","constructor","NodeList","HTMLCollection","_attach","hasAttribute","ensureEditable","setAttribute","inputTypes","wrapper","ul","className","currentMentionTextSnapshot","createMenu","tributeMenu","processValues","items","querySelector","noMatchEvent","fragment","_findLiTarget","movementY","collectionIndex","activeElement","placeCaretAtEnd","insertTextAtCursor","insertAtCaret","selectNodeContents","createTextRange","textRange","moveToElementText","select","textNode","createTextNode","textarea","scrollPos","caretPos","front","back","content","replaceText","replaceTriggerText","newValues","concat","_append","_detach","unbind","removeAttribute","_this3","_isActive","val","matchItem"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"tribute.min.js","sources":["../src/utils.js","../src/TributeEvents.js","../src/TributeMenuEvents.js","../src/TributeRange.js","../src/TributeSearch.js","../src/Tribute.js"],"sourcesContent":["if (!Array.prototype.find) {\n Array.prototype.find = function(predicate) {\n if (this === null) {\n throw new TypeError('Array.prototype.find called on null or undefined')\n }\n if (typeof predicate !== 'function') {\n throw new TypeError('predicate must be a function')\n }\n var list = Object(this)\n var length = list.length >>> 0\n var thisArg = arguments[1]\n var value\n\n for (var i = 0; i < length; i++) {\n value = list[i]\n if (predicate.call(thisArg, value, i, list)) {\n return value\n }\n }\n return undefined\n }\n}\n\nif (window && typeof window.CustomEvent !== \"function\") {\n function CustomEvent(event, params) {\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n }\n var evt = document.createEvent('CustomEvent')\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)\n return evt\n }\n\n if (typeof window.Event !== 'undefined') {\n CustomEvent.prototype = window.Event.prototype\n }\n\n window.CustomEvent = CustomEvent\n}","class TributeEvents {\n constructor(tribute) {\n this.tribute = tribute;\n this.tribute.events = this;\n }\n\n static keys() {\n return [\n {\n key: 9,\n value: \"TAB\"\n },\n {\n key: 8,\n value: \"DELETE\"\n },\n {\n key: 13,\n value: \"ENTER\"\n },\n {\n key: 27,\n value: \"ESCAPE\"\n },\n {\n key: 32,\n value: \"SPACE\"\n },\n {\n key: 38,\n value: \"UP\"\n },\n {\n key: 40,\n value: \"DOWN\"\n }\n ];\n }\n\n bind(element) {\n element.boundKeydown = this.keydown.bind(element, this);\n element.boundKeyup = this.keyup.bind(element, this);\n element.boundInput = this.input.bind(element, this);\n\n element.addEventListener(\"keydown\", element.boundKeydown, false);\n element.addEventListener(\"keyup\", element.boundKeyup, false);\n element.addEventListener(\"input\", element.boundInput, false);\n }\n\n unbind(element) {\n element.removeEventListener(\"keydown\", element.boundKeydown, false);\n element.removeEventListener(\"keyup\", element.boundKeyup, false);\n element.removeEventListener(\"input\", element.boundInput, false);\n\n delete element.boundKeydown;\n delete element.boundKeyup;\n delete element.boundInput;\n }\n\n keydown(instance, event) {\n if (instance.shouldDeactivate(event)) {\n instance.tribute.isActive = false;\n instance.tribute.hideMenu();\n }\n\n let element = this;\n instance.commandEvent = false;\n\n TributeEvents.keys().forEach(o => {\n if (o.key === event.keyCode) {\n instance.commandEvent = true;\n instance.callbacks()[o.value.toLowerCase()](event, element);\n }\n });\n }\n\n input(instance, event) {\n instance.inputEvent = true;\n instance.keyup.call(this, instance, event);\n }\n\n click(instance, event) {\n let tribute = instance.tribute;\n if (tribute.menu && tribute.menu.contains(event.target)) {\n let li = event.target;\n event.preventDefault();\n event.stopPropagation();\n while (li.nodeName.toLowerCase() !== \"li\") {\n li = li.parentNode;\n if (!li || li === tribute.menu) {\n throw new Error(\"cannot find the
  • container for the click\");\n }\n }\n tribute.selectItemAtIndex(li.getAttribute(\"data-index\"), event);\n tribute.hideMenu();\n\n // TODO: should fire with externalTrigger and target is outside of menu\n } else if (tribute.current.element && !tribute.current.externalTrigger) {\n tribute.current.externalTrigger = false;\n setTimeout(() => tribute.hideMenu());\n }\n }\n\n keyup(instance, event) {\n if (instance.inputEvent) {\n instance.inputEvent = false;\n }\n instance.updateSelection(this);\n\n if (event.keyCode === 27) return;\n\n if (!instance.tribute.allowSpaces && instance.tribute.hasTrailingSpace) {\n instance.tribute.hasTrailingSpace = false;\n instance.commandEvent = true;\n instance.callbacks()[\"space\"](event, this);\n return;\n }\n\n if (!instance.tribute.isActive) {\n if (instance.tribute.autocompleteMode) {\n instance.callbacks().triggerChar(event, this, \"\");\n } else {\n let keyCode = instance.getKeyCode(instance, this, event);\n\n if (isNaN(keyCode) || !keyCode) return;\n\n let trigger = instance.tribute.triggers().find(trigger => {\n return trigger.charCodeAt(0) === keyCode;\n });\n\n if (typeof trigger !== \"undefined\") {\n instance.callbacks().triggerChar(event, this, trigger);\n }\n }\n }\n\n if (\n instance.tribute.current.mentionText.length <\n instance.tribute.current.collection.menuShowMinLength\n ) {\n return;\n }\n\n if (\n ((instance.tribute.current.trigger ||\n instance.tribute.autocompleteMode) &&\n instance.commandEvent === false) ||\n (instance.tribute.isActive && event.keyCode === 8)\n ) {\n instance.tribute.showMenuFor(this, true);\n }\n }\n\n shouldDeactivate(event) {\n if (!this.tribute.isActive) return false;\n\n if (this.tribute.current.mentionText.length === 0) {\n let eventKeyPressed = false;\n TributeEvents.keys().forEach(o => {\n if (event.keyCode === o.key) eventKeyPressed = true;\n });\n\n return !eventKeyPressed;\n }\n\n return false;\n }\n\n getKeyCode(instance, el, event) {\n let char;\n let tribute = instance.tribute;\n let info = tribute.range.getTriggerInfo(\n false,\n tribute.hasTrailingSpace,\n true,\n tribute.allowSpaces,\n tribute.autocompleteMode\n );\n\n if (info) {\n return info.mentionTriggerChar.charCodeAt(0);\n } else {\n return false;\n }\n }\n\n updateSelection(el) {\n this.tribute.current.element = el;\n let info = this.tribute.range.getTriggerInfo(\n false,\n this.tribute.hasTrailingSpace,\n true,\n this.tribute.allowSpaces,\n this.tribute.autocompleteMode\n );\n\n if (info) {\n this.tribute.current.selectedPath = info.mentionSelectedPath;\n this.tribute.current.mentionText = info.mentionText;\n this.tribute.current.selectedOffset = info.mentionSelectedOffset;\n }\n }\n\n callbacks() {\n return {\n triggerChar: (e, el, trigger) => {\n let tribute = this.tribute;\n tribute.current.trigger = trigger;\n\n let collectionItem = tribute.collection.find(item => {\n return item.trigger === trigger;\n });\n\n tribute.current.collection = collectionItem;\n\n if (\n tribute.current.mentionText.length >=\n tribute.current.collection.menuShowMinLength &&\n tribute.inputEvent\n ) {\n tribute.showMenuFor(el, true);\n }\n },\n enter: (e, el) => {\n // choose selection\n if (this.tribute.isActive && this.tribute.current.filteredItems) {\n e.preventDefault();\n e.stopPropagation();\n setTimeout(() => {\n this.tribute.selectItemAtIndex(this.tribute.menuSelected, e);\n this.tribute.hideMenu();\n }, 0);\n }\n },\n escape: (e, el) => {\n if (this.tribute.isActive) {\n e.preventDefault();\n e.stopPropagation();\n this.tribute.isActive = false;\n this.tribute.hideMenu();\n }\n },\n tab: (e, el) => {\n // choose first match\n this.callbacks().enter(e, el);\n },\n space: (e, el) => {\n if (this.tribute.isActive) {\n if (this.tribute.spaceSelectsMatch) {\n this.callbacks().enter(e, el);\n } else if (!this.tribute.allowSpaces) {\n e.stopPropagation();\n setTimeout(() => {\n this.tribute.hideMenu();\n this.tribute.isActive = false;\n }, 0);\n }\n }\n },\n up: (e, el) => {\n // navigate up ul\n if (this.tribute.isActive && this.tribute.current.filteredItems) {\n e.preventDefault();\n e.stopPropagation();\n let count = this.tribute.current.filteredItems.length,\n selected = this.tribute.menuSelected;\n\n if (count > selected && selected > 0) {\n this.tribute.menuSelected--;\n this.setActiveLi();\n } else if (selected === 0) {\n this.tribute.menuSelected = count - 1;\n this.setActiveLi();\n this.tribute.menu.scrollTop = this.tribute.menu.scrollHeight;\n }\n }\n },\n down: (e, el) => {\n // navigate down ul\n if (this.tribute.isActive && this.tribute.current.filteredItems) {\n e.preventDefault();\n e.stopPropagation();\n let count = this.tribute.current.filteredItems.length - 1,\n selected = this.tribute.menuSelected;\n\n if (count > selected) {\n this.tribute.menuSelected++;\n this.setActiveLi();\n } else if (count === selected) {\n this.tribute.menuSelected = 0;\n this.setActiveLi();\n this.tribute.menu.scrollTop = 0;\n }\n }\n },\n delete: (e, el) => {\n if (\n this.tribute.isActive &&\n this.tribute.current.mentionText.length < 1\n ) {\n this.tribute.hideMenu();\n } else if (this.tribute.isActive) {\n this.tribute.showMenuFor(el);\n }\n }\n };\n }\n\n setActiveLi(index) {\n let lis = this.tribute.menu.querySelectorAll(\"li\"),\n length = lis.length >>> 0;\n\n if (index) this.tribute.menuSelected = parseInt(index);\n\n for (let i = 0; i < length; i++) {\n let li = lis[i];\n if (i === this.tribute.menuSelected) {\n li.classList.add(this.tribute.current.collection.selectClass);\n\n let liClientRect = li.getBoundingClientRect();\n let menuClientRect = this.tribute.menu.getBoundingClientRect();\n\n if (liClientRect.bottom > menuClientRect.bottom) {\n let scrollDistance = liClientRect.bottom - menuClientRect.bottom;\n this.tribute.menu.scrollTop += scrollDistance;\n } else if (liClientRect.top < menuClientRect.top) {\n let scrollDistance = menuClientRect.top - liClientRect.top;\n this.tribute.menu.scrollTop -= scrollDistance;\n }\n } else {\n li.classList.remove(this.tribute.current.collection.selectClass);\n }\n }\n }\n\n getFullHeight(elem, includeMargin) {\n let height = elem.getBoundingClientRect().height;\n\n if (includeMargin) {\n let style = elem.currentStyle || window.getComputedStyle(elem);\n return (\n height + parseFloat(style.marginTop) + parseFloat(style.marginBottom)\n );\n }\n\n return height;\n }\n}\n\nexport default TributeEvents;\n","class TributeMenuEvents {\n constructor(tribute) {\n this.tribute = tribute;\n this.tribute.menuEvents = this;\n this.menu = this.tribute.menu;\n }\n\n bind(menu) {\n this.menuClickEvent = this.tribute.events.click.bind(null, this);\n this.menuContainerScrollEvent = this.debounce(\n () => {\n if (this.tribute.isActive) {\n this.tribute.showMenuFor(this.tribute.current.element, false);\n }\n },\n 300,\n false\n );\n this.windowResizeEvent = this.debounce(\n () => {\n if (this.tribute.isActive) {\n this.tribute.range.positionMenuAtCaret(true);\n }\n },\n 300,\n false\n );\n\n // fixes IE11 issues with mousedown\n this.tribute.range\n .getDocument()\n .addEventListener(\"MSPointerDown\", this.menuClickEvent, false);\n this.tribute.range\n .getDocument()\n .addEventListener(\"mousedown\", this.menuClickEvent, false);\n window.addEventListener(\"resize\", this.windowResizeEvent);\n\n if (this.menuContainer) {\n this.menuContainer.addEventListener(\n \"scroll\",\n this.menuContainerScrollEvent,\n false\n );\n } else {\n window.addEventListener(\"scroll\", this.menuContainerScrollEvent);\n }\n }\n\n unbind(menu) {\n this.tribute.range\n .getDocument()\n .removeEventListener(\"mousedown\", this.menuClickEvent, false);\n this.tribute.range\n .getDocument()\n .removeEventListener(\"MSPointerDown\", this.menuClickEvent, false);\n window.removeEventListener(\"resize\", this.windowResizeEvent);\n\n if (this.menuContainer) {\n this.menuContainer.removeEventListener(\n \"scroll\",\n this.menuContainerScrollEvent,\n false\n );\n } else {\n window.removeEventListener(\"scroll\", this.menuContainerScrollEvent);\n }\n }\n\n debounce(func, wait, immediate) {\n var timeout;\n return () => {\n var context = this,\n args = arguments;\n var later = () => {\n timeout = null;\n if (!immediate) func.apply(context, args);\n };\n var callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) func.apply(context, args);\n };\n }\n}\n\nexport default TributeMenuEvents;\n","// Thanks to https://github.com/jeff-collins/ment.io\nimport \"./utils\";\n\nclass TributeRange {\n constructor(tribute) {\n this.tribute = tribute\n this.tribute.range = this\n }\n\n getDocument() {\n let iframe\n if (this.tribute.current.collection) {\n iframe = this.tribute.current.collection.iframe\n }\n\n if (!iframe) {\n return document\n }\n\n return iframe.contentWindow.document\n }\n\n positionMenuAtCaret(scrollTo) {\n let context = this.tribute.current,\n coordinates\n\n let info = this.getTriggerInfo(false, this.tribute.hasTrailingSpace, true, this.tribute.allowSpaces, this.tribute.autocompleteMode)\n\n if (typeof info !== 'undefined') {\n\n if(!this.tribute.positionMenu){\n this.tribute.menu.style.cssText = `display: block;`\n return\n }\n\n if (!this.isContentEditable(context.element)) {\n coordinates = this.getTextAreaOrInputUnderlinePosition(this.tribute.current.element,\n info.mentionPosition)\n }\n else {\n coordinates = this.getContentEditableCaretPosition(info.mentionPosition)\n }\n\n this.tribute.menu.style.cssText = `top: ${coordinates.top}px;\n left: ${coordinates.left}px;\n right: ${coordinates.right}px;\n bottom: ${coordinates.bottom}px;\n position: absolute;\n display: block;`\n\n if (coordinates.left === 'auto') {\n this.tribute.menu.style.left = 'auto'\n }\n\n if (coordinates.top === 'auto') {\n this.tribute.menu.style.top = 'auto'\n }\n\n if (scrollTo) this.scrollIntoView()\n\n window.setTimeout(() => {\n let menuDimensions = {\n width: this.tribute.menu.offsetWidth,\n height: this.tribute.menu.offsetHeight\n }\n let menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n\n let menuIsOffScreenHorizontally = window.innerWidth > menuDimensions.width && (menuIsOffScreen.left || menuIsOffScreen.right)\n let menuIsOffScreenVertically = window.innerHeight > menuDimensions.height && (menuIsOffScreen.top || menuIsOffScreen.bottom)\n if (menuIsOffScreenHorizontally || menuIsOffScreenVertically) {\n this.tribute.menu.style.cssText = 'display: none'\n this.positionMenuAtCaret(scrollTo)\n }\n }, 0)\n\n } else {\n this.tribute.menu.style.cssText = 'display: none'\n }\n }\n\n get menuContainerIsBody() {\n return this.tribute.menuContainer === document.body || !this.tribute.menuContainer;\n }\n\n\n selectElement(targetElement, path, offset) {\n let range\n let elem = targetElement\n\n if (path) {\n for (var i = 0; i < path.length; i++) {\n elem = elem.childNodes[path[i]]\n if (elem === undefined) {\n return\n }\n while (elem.length < offset) {\n offset -= elem.length\n elem = elem.nextSibling\n }\n if (elem.childNodes.length === 0 && !elem.length) {\n elem = elem.previousSibling\n }\n }\n }\n let sel = this.getWindowSelection()\n\n range = this.getDocument().createRange()\n range.setStart(elem, offset)\n range.setEnd(elem, offset)\n range.collapse(true)\n\n try {\n sel.removeAllRanges()\n } catch (error) {}\n\n sel.addRange(range)\n targetElement.focus()\n }\n\n replaceTriggerText(text, requireLeadingSpace, hasTrailingSpace, originalEvent, item) {\n let info = this.getTriggerInfo(true, hasTrailingSpace, requireLeadingSpace, this.tribute.allowSpaces, this.tribute.autocompleteMode)\n\n if (info !== undefined) {\n let context = this.tribute.current\n let replaceEvent = new CustomEvent('tribute-replaced', {\n detail: {\n item: item,\n instance: context,\n context: info,\n event: originalEvent,\n }\n })\n\n if (!this.isContentEditable(context.element)) {\n let myField = this.tribute.current.element\n let textSuffix = typeof this.tribute.replaceTextSuffix == 'string'\n ? this.tribute.replaceTextSuffix\n : ' '\n text += textSuffix\n let startPos = info.mentionPosition\n let endPos = info.mentionPosition + info.mentionText.length + textSuffix.length\n if (!this.tribute.autocompleteMode) {\n endPos += info.mentionTriggerChar.length - 1\n }\n myField.value = myField.value.substring(0, startPos) + text +\n myField.value.substring(endPos, myField.value.length)\n myField.selectionStart = startPos + text.length\n myField.selectionEnd = startPos + text.length\n } else {\n // add a space to the end of the pasted text\n let textSuffix = typeof this.tribute.replaceTextSuffix == 'string'\n ? this.tribute.replaceTextSuffix\n : '\\xA0'\n text += textSuffix\n let endPos = info.mentionPosition + info.mentionText.length\n if (!this.tribute.autocompleteMode) {\n endPos += info.mentionTriggerChar.length\n }\n this.pasteHtml(text, info.mentionPosition, endPos)\n }\n\n context.element.dispatchEvent(new CustomEvent('input', { bubbles: true }))\n context.element.dispatchEvent(replaceEvent)\n }\n }\n\n pasteHtml(html, startPos, endPos) {\n let range, sel\n sel = this.getWindowSelection()\n range = this.getDocument().createRange()\n range.setStart(sel.anchorNode, startPos)\n range.setEnd(sel.anchorNode, endPos)\n range.deleteContents()\n\n let el = this.getDocument().createElement('div')\n el.innerHTML = html\n let frag = this.getDocument().createDocumentFragment(),\n node, lastNode\n while ((node = el.firstChild)) {\n lastNode = frag.appendChild(node)\n }\n range.insertNode(frag)\n\n // Preserve the selection\n if (lastNode) {\n range = range.cloneRange()\n range.setStartAfter(lastNode)\n range.collapse(true)\n sel.removeAllRanges()\n sel.addRange(range)\n }\n }\n\n getWindowSelection() {\n if (this.tribute.collection.iframe) {\n return this.tribute.collection.iframe.contentWindow.getSelection()\n }\n\n return window.getSelection()\n }\n\n getNodePositionInParent(element) {\n if (element.parentNode === null) {\n return 0\n }\n\n for (var i = 0; i < element.parentNode.childNodes.length; i++) {\n let node = element.parentNode.childNodes[i]\n\n if (node === element) {\n return i\n }\n }\n }\n\n getContentEditableSelectedPath(ctx) {\n let sel = this.getWindowSelection()\n let selected = sel.anchorNode\n let path = []\n let offset\n\n if (selected != null) {\n let i\n let ce = selected.contentEditable\n while (selected !== null && ce !== 'true') {\n i = this.getNodePositionInParent(selected)\n path.push(i)\n selected = selected.parentNode\n if (selected !== null) {\n ce = selected.contentEditable\n }\n }\n path.reverse()\n\n // getRangeAt may not exist, need alternative\n offset = sel.getRangeAt(0).startOffset\n\n return {\n selected: selected,\n path: path,\n offset: offset\n }\n }\n }\n\n getTextPrecedingCurrentSelection() {\n let context = this.tribute.current,\n text = ''\n\n if (!this.isContentEditable(context.element)) {\n let textComponent = this.tribute.current.element;\n if (textComponent) {\n let startPos = textComponent.selectionStart\n if (textComponent.value && startPos >= 0) {\n text = textComponent.value.substring(0, startPos)\n }\n }\n\n } else {\n let selectedElem = this.getWindowSelection().anchorNode\n\n if (selectedElem != null) {\n let workingNodeContent = selectedElem.textContent\n let selectStartOffset = this.getWindowSelection().getRangeAt(0).startOffset\n\n if (workingNodeContent && selectStartOffset >= 0) {\n text = workingNodeContent.substring(0, selectStartOffset)\n }\n }\n }\n\n return text\n }\n\n getLastWordInText(text) {\n text = text.replace(/\\u00A0/g, ' '); // https://stackoverflow.com/questions/29850407/how-do-i-replace-unicode-character-u00a0-with-a-space-in-javascript\n let wordsArray = text.split(/\\s+/);\n let worldsCount = wordsArray.length - 1\n return wordsArray[worldsCount].trim()\n }\n\n getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces, isAutocomplete) {\n let ctx = this.tribute.current\n let selected, path, offset\n\n if (!this.isContentEditable(ctx.element)) {\n selected = this.tribute.current.element\n } else {\n let selectionInfo = this.getContentEditableSelectedPath(ctx)\n\n if (selectionInfo) {\n selected = selectionInfo.selected\n path = selectionInfo.path\n offset = selectionInfo.offset\n }\n }\n\n let effectiveRange = this.getTextPrecedingCurrentSelection()\n let lastWordOfEffectiveRange = this.getLastWordInText(effectiveRange)\n\n if (isAutocomplete) {\n return {\n mentionPosition: effectiveRange.length - lastWordOfEffectiveRange.length,\n mentionText: lastWordOfEffectiveRange,\n mentionSelectedElement: selected,\n mentionSelectedPath: path,\n mentionSelectedOffset: offset\n }\n }\n\n if (effectiveRange !== undefined && effectiveRange !== null) {\n let mostRecentTriggerCharPos = -1\n let triggerChar\n\n this.tribute.collection.forEach(config => {\n let c = config.trigger\n let idx = config.requireLeadingSpace ?\n this.lastIndexWithLeadingSpace(effectiveRange, c) :\n effectiveRange.lastIndexOf(c)\n\n if (idx > mostRecentTriggerCharPos) {\n mostRecentTriggerCharPos = idx\n triggerChar = c\n requireLeadingSpace = config.requireLeadingSpace\n }\n })\n\n if (mostRecentTriggerCharPos >= 0 &&\n (\n mostRecentTriggerCharPos === 0 ||\n !requireLeadingSpace ||\n /[\\xA0\\s]/g.test(\n effectiveRange.substring(\n mostRecentTriggerCharPos - 1,\n mostRecentTriggerCharPos)\n )\n )\n ) {\n let currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + triggerChar.length,\n effectiveRange.length)\n\n triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos + triggerChar.length)\n let firstSnippetChar = currentTriggerSnippet.substring(0, 1)\n let leadingSpace = currentTriggerSnippet.length > 0 &&\n (\n firstSnippetChar === ' ' ||\n firstSnippetChar === '\\xA0'\n )\n if (hasTrailingSpace) {\n currentTriggerSnippet = currentTriggerSnippet.trim()\n }\n\n let regex = allowSpaces ? /[^\\S ]/g : /[\\xA0\\s]/g;\n\n this.tribute.hasTrailingSpace = regex.test(currentTriggerSnippet);\n\n if (!leadingSpace && (menuAlreadyActive || !(regex.test(currentTriggerSnippet)))) {\n return {\n mentionPosition: mostRecentTriggerCharPos,\n mentionText: currentTriggerSnippet,\n mentionSelectedElement: selected,\n mentionSelectedPath: path,\n mentionSelectedOffset: offset,\n mentionTriggerChar: triggerChar\n }\n }\n }\n }\n }\n\n lastIndexWithLeadingSpace (str, trigger) {\n let reversedStr = str.split('').reverse().join('')\n let index = -1\n\n for (let cidx = 0, len = str.length; cidx < len; cidx++) {\n let firstChar = cidx === str.length - 1\n let leadingSpace = /\\s/.test(reversedStr[cidx + 1])\n\n let match = true\n for (let triggerIdx = trigger.length - 1; triggerIdx >= 0; triggerIdx--) {\n if (trigger[triggerIdx] !== reversedStr[cidx-triggerIdx]) {\n match = false\n break\n }\n }\n\n if (match && (firstChar || leadingSpace)) {\n index = str.length - 1 - cidx\n break\n }\n }\n\n return index\n }\n\n isContentEditable(element) {\n return element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA'\n }\n\n isMenuOffScreen(coordinates, menuDimensions) {\n let windowWidth = window.innerWidth\n let windowHeight = window.innerHeight\n let doc = document.documentElement\n let windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)\n let windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\n\n let menuTop = typeof coordinates.top === 'number' ? coordinates.top : windowTop + windowHeight - coordinates.bottom - menuDimensions.height\n let menuRight = typeof coordinates.right === 'number' ? coordinates.right : coordinates.left + menuDimensions.width\n let menuBottom = typeof coordinates.bottom === 'number' ? coordinates.bottom : coordinates.top + menuDimensions.height\n let menuLeft = typeof coordinates.left === 'number' ? coordinates.left : windowLeft + windowWidth - coordinates.right - menuDimensions.width\n\n return {\n top: menuTop < Math.floor(windowTop),\n right: menuRight > Math.ceil(windowLeft + windowWidth),\n bottom: menuBottom > Math.ceil(windowTop + windowHeight),\n left: menuLeft < Math.floor(windowLeft)\n }\n }\n\n getMenuDimensions() {\n // Width of the menu depends of its contents and position\n // We must check what its width would be without any obstruction\n // This way, we can achieve good positioning for flipping the menu\n let dimensions = {\n width: null,\n height: null\n }\n\n this.tribute.menu.style.cssText = `top: 0px;\n left: 0px;\n position: fixed;\n display: block;\n visibility; hidden;`\n dimensions.width = this.tribute.menu.offsetWidth\n dimensions.height = this.tribute.menu.offsetHeight\n\n this.tribute.menu.style.cssText = `display: none;`\n\n return dimensions\n }\n\n getTextAreaOrInputUnderlinePosition(element, position, flipped) {\n let properties = ['direction', 'boxSizing', 'width', 'height', 'overflowX',\n 'overflowY', 'borderTopWidth', 'borderRightWidth',\n 'borderBottomWidth', 'borderLeftWidth', 'paddingTop',\n 'paddingRight', 'paddingBottom', 'paddingLeft',\n 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch',\n 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily',\n 'textAlign', 'textTransform', 'textIndent',\n 'textDecoration', 'letterSpacing', 'wordSpacing'\n ]\n\n let isFirefox = (window.mozInnerScreenX !== null)\n\n let div = this.getDocument().createElement('div')\n div.id = 'input-textarea-caret-position-mirror-div'\n this.getDocument().body.appendChild(div)\n\n let style = div.style\n let computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle\n\n style.whiteSpace = 'pre-wrap'\n if (element.nodeName !== 'INPUT') {\n style.wordWrap = 'break-word'\n }\n\n // position off-screen\n style.position = 'absolute'\n style.visibility = 'hidden'\n\n // transfer the element's properties to the div\n properties.forEach(prop => {\n style[prop] = computed[prop]\n })\n\n if (isFirefox) {\n style.width = `${(parseInt(computed.width) - 2)}px`\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll'\n } else {\n style.overflow = 'hidden'\n }\n\n div.textContent = element.value.substring(0, position)\n\n if (element.nodeName === 'INPUT') {\n div.textContent = div.textContent.replace(/\\s/g, ' ')\n }\n\n let span = this.getDocument().createElement('span')\n span.textContent = element.value.substring(position) || '.'\n div.appendChild(span)\n\n let rect = element.getBoundingClientRect()\n let doc = document.documentElement\n let windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)\n let windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\n\n let top = 0;\n let left = 0;\n if (this.menuContainerIsBody) {\n top = rect.top;\n left = rect.left;\n }\n\n let coordinates = {\n top: top + windowTop + span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize) - element.scrollTop,\n left: left + windowLeft + span.offsetLeft + parseInt(computed.borderLeftWidth)\n }\n\n let windowWidth = window.innerWidth\n let windowHeight = window.innerHeight\n\n let menuDimensions = this.getMenuDimensions()\n let menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n\n if (menuIsOffScreen.right) {\n coordinates.right = windowWidth - coordinates.left\n coordinates.left = 'auto'\n }\n\n let parentHeight = this.tribute.menuContainer\n ? this.tribute.menuContainer.offsetHeight\n : this.getDocument().body.offsetHeight\n\n if (menuIsOffScreen.bottom) {\n let parentRect = this.tribute.menuContainer\n ? this.tribute.menuContainer.getBoundingClientRect()\n : this.getDocument().body.getBoundingClientRect()\n let scrollStillAvailable = parentHeight - (windowHeight - parentRect.top)\n\n coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top - span.offsetTop)\n coordinates.top = 'auto'\n }\n\n menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n if (menuIsOffScreen.left) {\n coordinates.left = windowWidth > menuDimensions.width\n ? windowLeft + windowWidth - menuDimensions.width\n : windowLeft\n delete coordinates.right\n }\n if (menuIsOffScreen.top) {\n coordinates.top = windowHeight > menuDimensions.height\n ? windowTop + windowHeight - menuDimensions.height\n : windowTop\n delete coordinates.bottom\n }\n\n this.getDocument().body.removeChild(div)\n return coordinates\n }\n\n getContentEditableCaretPosition(selectedNodePosition) {\n let range\n let sel = this.getWindowSelection()\n\n range = this.getDocument().createRange()\n range.setStart(sel.anchorNode, selectedNodePosition)\n range.setEnd(sel.anchorNode, selectedNodePosition)\n\n range.collapse(false)\n\n let rect = range.getBoundingClientRect()\n let doc = document.documentElement\n let windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)\n let windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\n\n let left = rect.left\n let top = rect.top\n\n let coordinates = {\n left: left + windowLeft,\n top: top + rect.height + windowTop\n }\n let windowWidth = window.innerWidth\n let windowHeight = window.innerHeight\n\n let menuDimensions = this.getMenuDimensions()\n let menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n\n if (menuIsOffScreen.right) {\n coordinates.left = 'auto'\n coordinates.right = windowWidth - rect.left - windowLeft\n }\n\n let parentHeight = this.tribute.menuContainer\n ? this.tribute.menuContainer.offsetHeight\n : this.getDocument().body.offsetHeight\n\n if (menuIsOffScreen.bottom) {\n let parentRect = this.tribute.menuContainer\n ? this.tribute.menuContainer.getBoundingClientRect()\n : this.getDocument().body.getBoundingClientRect()\n let scrollStillAvailable = parentHeight - (windowHeight - parentRect.top)\n\n coordinates.top = 'auto'\n coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top)\n }\n\n menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions)\n if (menuIsOffScreen.left) {\n coordinates.left = windowWidth > menuDimensions.width\n ? windowLeft + windowWidth - menuDimensions.width\n : windowLeft\n delete coordinates.right\n }\n if (menuIsOffScreen.top) {\n coordinates.top = windowHeight > menuDimensions.height\n ? windowTop + windowHeight - menuDimensions.height\n : windowTop\n delete coordinates.bottom\n }\n\n if (!this.menuContainerIsBody) {\n coordinates.left = coordinates.left ? coordinates.left - this.tribute.menuContainer.offsetLeft : coordinates.left\n coordinates.top = coordinates.top ? coordinates.top - this.tribute.menuContainer.offsetTop : coordinates.top\n }\n\n return coordinates\n }\n\n scrollIntoView(elem) {\n let reasonableBuffer = 20,\n clientRect\n let maxScrollDisplacement = 100\n let e = this.menu\n\n if (typeof e === 'undefined') return;\n\n while (clientRect === undefined || clientRect.height === 0) {\n clientRect = e.getBoundingClientRect()\n\n if (clientRect.height === 0) {\n e = e.childNodes[0]\n if (e === undefined || !e.getBoundingClientRect) {\n return\n }\n }\n }\n\n let elemTop = clientRect.top\n let elemBottom = elemTop + clientRect.height\n\n if (elemTop < 0) {\n window.scrollTo(0, window.pageYOffset + clientRect.top - reasonableBuffer)\n } else if (elemBottom > window.innerHeight) {\n let maxY = window.pageYOffset + clientRect.top - reasonableBuffer\n\n if (maxY - window.pageYOffset > maxScrollDisplacement) {\n maxY = window.pageYOffset + maxScrollDisplacement\n }\n\n let targetY = window.pageYOffset - (window.innerHeight - elemBottom)\n\n if (targetY > maxY) {\n targetY = maxY\n }\n\n window.scrollTo(0, targetY)\n }\n }\n}\n\n\nexport default TributeRange;\n","// Thanks to https://github.com/mattyork/fuzzy\nclass TributeSearch {\n constructor(tribute) {\n this.tribute = tribute\n this.tribute.search = this\n }\n\n simpleFilter(pattern, array) {\n return array.filter(string => {\n return this.test(pattern, string)\n })\n }\n\n test(pattern, string) {\n return this.match(pattern, string) !== null\n }\n\n match(pattern, string, opts) {\n opts = opts || {}\n let patternIdx = 0,\n result = [],\n len = string.length,\n totalScore = 0,\n currScore = 0,\n pre = opts.pre || '',\n post = opts.post || '',\n compareString = opts.caseSensitive && string || string.toLowerCase(),\n ch, compareChar\n\n if (opts.skip) {\n return {rendered: string, score: 0}\n }\n\n pattern = opts.caseSensitive && pattern || pattern.toLowerCase()\n\n let patternCache = this.traverse(compareString, pattern, 0, 0, [])\n if (!patternCache) {\n return null\n }\n return {\n rendered: this.render(string, patternCache.cache, pre, post),\n score: patternCache.score\n }\n }\n\n traverse(string, pattern, stringIndex, patternIndex, patternCache) {\n // if the pattern search at end\n if (pattern.length === patternIndex) {\n\n // calculate score and copy the cache containing the indices where it's found\n return {\n score: this.calculateScore(patternCache),\n cache: patternCache.slice()\n }\n }\n\n // if string at end or remaining pattern > remaining string\n if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) {\n return undefined\n }\n\n let c = pattern[patternIndex]\n let index = string.indexOf(c, stringIndex)\n let best, temp\n\n while (index > -1) {\n patternCache.push(index)\n temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache)\n patternCache.pop()\n\n // if downstream traversal failed, return best answer so far\n if (!temp) {\n return best\n }\n\n if (!best || best.score < temp.score) {\n best = temp\n }\n\n index = string.indexOf(c, index + 1)\n }\n\n return best\n }\n\n calculateScore(patternCache) {\n let score = 0\n let temp = 1\n\n patternCache.forEach((index, i) => {\n if (i > 0) {\n if (patternCache[i - 1] + 1 === index) {\n temp += temp + 1\n }\n else {\n temp = 1\n }\n }\n\n score += temp\n })\n\n return score\n }\n\n render(string, indices, pre, post) {\n var rendered = string.substring(0, indices[0])\n\n indices.forEach((index, i) => {\n rendered += pre + string[index] + post +\n string.substring(index + 1, (indices[i + 1]) ? indices[i + 1] : string.length)\n })\n\n return rendered\n }\n\n filter(pattern, arr, opts) {\n opts = opts || {}\n return arr\n .reduce((prev, element, idx, arr) => {\n let str = element\n\n if (opts.extract) {\n str = opts.extract(element)\n\n if (!str) { // take care of undefineds / nulls / etc.\n str = ''\n }\n }\n\n let rendered = this.match(pattern, str, opts)\n\n if (rendered != null) {\n prev[prev.length] = {\n string: rendered.rendered,\n score: rendered.score,\n index: idx,\n original: element\n }\n }\n\n return prev\n }, [])\n\n .sort((a, b) => {\n let compare = b.score - a.score\n if (compare) return compare\n return a.index - b.index\n })\n }\n}\n\nexport default TributeSearch;\n","import \"./utils\";\nimport TributeEvents from \"./TributeEvents\";\nimport TributeMenuEvents from \"./TributeMenuEvents\";\nimport TributeRange from \"./TributeRange\";\nimport TributeSearch from \"./TributeSearch\";\n\nclass Tribute {\n constructor({\n values = null,\n iframe = null,\n selectClass = \"highlight\",\n containerClass = \"tribute-container\",\n itemClass = \"\",\n trigger = \"@\",\n autocompleteMode = false,\n selectTemplate = null,\n menuItemTemplate = null,\n lookup = \"key\",\n fillAttr = \"value\",\n collection = null,\n menuContainer = null,\n noMatchTemplate = null,\n requireLeadingSpace = true,\n allowSpaces = false,\n replaceTextSuffix = null,\n positionMenu = true,\n spaceSelectsMatch = false,\n searchOpts = {},\n menuItemLimit = null,\n menuShowMinLength = 0\n }) {\n this.autocompleteMode = autocompleteMode;\n this.menuSelected = 0;\n this.current = {};\n this.inputEvent = false;\n this.isActive = false;\n this.menuContainer = menuContainer;\n this.allowSpaces = allowSpaces;\n this.replaceTextSuffix = replaceTextSuffix;\n this.positionMenu = positionMenu;\n this.hasTrailingSpace = false;\n this.spaceSelectsMatch = spaceSelectsMatch;\n\n if (this.autocompleteMode) {\n trigger = \"\";\n allowSpaces = false;\n }\n\n if (values) {\n this.collection = [\n {\n // symbol that starts the lookup\n trigger: trigger,\n\n // is it wrapped in an iframe\n iframe: iframe,\n\n // class applied to selected item\n selectClass: selectClass,\n\n // class applied to the Container\n containerClass: containerClass,\n\n // class applied to each item\n itemClass: itemClass,\n\n // function called on select that retuns the content to insert\n selectTemplate: (\n selectTemplate || Tribute.defaultSelectTemplate\n ).bind(this),\n\n // function called that returns content for an item\n menuItemTemplate: (\n menuItemTemplate || Tribute.defaultMenuItemTemplate\n ).bind(this),\n\n // function called when menu is empty, disables hiding of menu.\n noMatchTemplate: (t => {\n if (typeof t === \"function\") {\n return t.bind(this);\n }\n\n return (\n noMatchTemplate ||\n function() {\n return \"
  • No Match Found!
  • \";\n }.bind(this)\n );\n })(noMatchTemplate),\n\n // column to search against in the object\n lookup: lookup,\n\n // column that contains the content to insert by default\n fillAttr: fillAttr,\n\n // array of objects or a function returning an array of objects\n values: values,\n\n requireLeadingSpace: requireLeadingSpace,\n\n searchOpts: searchOpts,\n\n menuItemLimit: menuItemLimit,\n\n menuShowMinLength: menuShowMinLength\n }\n ];\n } else if (collection) {\n if (this.autocompleteMode)\n console.warn(\n \"Tribute in autocomplete mode does not work for collections\"\n );\n this.collection = collection.map(item => {\n return {\n trigger: item.trigger || trigger,\n iframe: item.iframe || iframe,\n selectClass: item.selectClass || selectClass,\n containerClass: item.containerClass || containerClass,\n itemClass: item.itemClass || itemClass,\n selectTemplate: (\n item.selectTemplate || Tribute.defaultSelectTemplate\n ).bind(this),\n menuItemTemplate: (\n item.menuItemTemplate || Tribute.defaultMenuItemTemplate\n ).bind(this),\n // function called when menu is empty, disables hiding of menu.\n noMatchTemplate: (t => {\n if (typeof t === \"function\") {\n return t.bind(this);\n }\n\n return null;\n })(noMatchTemplate),\n lookup: item.lookup || lookup,\n fillAttr: item.fillAttr || fillAttr,\n values: item.values,\n requireLeadingSpace: item.requireLeadingSpace,\n searchOpts: item.searchOpts || searchOpts,\n menuItemLimit: item.menuItemLimit || menuItemLimit,\n menuShowMinLength: item.menuShowMinLength || menuShowMinLength\n };\n });\n } else {\n throw new Error(\"[Tribute] No collection specified.\");\n }\n\n new TributeRange(this);\n new TributeEvents(this);\n new TributeMenuEvents(this);\n new TributeSearch(this);\n }\n\n get isActive() {\n return this._isActive;\n }\n\n set isActive(val) {\n if (this._isActive != val) {\n this._isActive = val;\n if (this.current.element) {\n let noMatchEvent = new CustomEvent(`tribute-active-${val}`);\n this.current.element.dispatchEvent(noMatchEvent);\n }\n }\n }\n\n static defaultSelectTemplate(item) {\n if (typeof item === \"undefined\") return \"@\" + this.current.mentionText;\n if (this.range.isContentEditable(this.current.element)) {\n return (\n '' +\n (this.current.collection.trigger +\n item.original[this.current.collection.fillAttr]) +\n \"\"\n );\n }\n\n return (\n this.current.collection.trigger +\n item.original[this.current.collection.fillAttr]\n );\n }\n\n static defaultMenuItemTemplate(matchItem) {\n return matchItem.string;\n }\n\n static inputTypes() {\n return [\"TEXTAREA\", \"INPUT\"];\n }\n\n triggers() {\n return this.collection.map(config => {\n return config.trigger;\n });\n }\n\n attach(el) {\n if (!el) {\n throw new Error(\"[Tribute] Must pass in a DOM node or NodeList.\");\n }\n\n // Check if it is a jQuery collection\n if (typeof jQuery !== \"undefined\" && el instanceof jQuery) {\n el = el.get();\n }\n\n // Is el an Array/Array-like object?\n if (\n el.constructor === NodeList ||\n el.constructor === HTMLCollection ||\n el.constructor === Array\n ) {\n let length = el.length;\n for (var i = 0; i < length; ++i) {\n this._attach(el[i]);\n }\n } else {\n this._attach(el);\n }\n }\n\n _attach(el) {\n if (el.hasAttribute(\"data-tribute\")) {\n console.warn(\"Tribute was already bound to \" + el.nodeName);\n }\n\n this.ensureEditable(el);\n this.events.bind(el);\n el.setAttribute(\"data-tribute\", true);\n }\n\n ensureEditable(element) {\n if (Tribute.inputTypes().indexOf(element.nodeName) === -1) {\n if (element.contentEditable) {\n element.contentEditable = true;\n } else {\n throw new Error(\"[Tribute] Cannot bind to \" + element.nodeName);\n }\n }\n }\n\n createMenu(containerClass) {\n let wrapper = this.range.getDocument().createElement(\"div\"),\n ul = this.range.getDocument().createElement(\"ul\");\n wrapper.className = containerClass;\n wrapper.appendChild(ul);\n\n if (this.menuContainer) {\n return this.menuContainer.appendChild(wrapper);\n }\n\n return this.range.getDocument().body.appendChild(wrapper);\n }\n\n showMenuFor(element, scrollTo) {\n // Only proceed if menu isn't already shown for the current element & mentionText\n if (\n this.isActive &&\n this.current.element === element &&\n this.current.mentionText === this.currentMentionTextSnapshot\n ) {\n return;\n }\n this.currentMentionTextSnapshot = this.current.mentionText;\n\n // create the menu if it doesn't exist.\n if (!this.menu) {\n this.menu = this.createMenu(this.current.collection.containerClass);\n element.tributeMenu = this.menu;\n this.menuEvents.bind(this.menu);\n }\n\n this.isActive = true;\n this.menuSelected = 0;\n\n if (!this.current.mentionText) {\n this.current.mentionText = \"\";\n }\n\n const processValues = values => {\n // Tribute may not be active any more by the time the value callback returns\n if (!this.isActive) {\n return;\n }\n\n let items = this.search.filter(this.current.mentionText, values, {\n pre: this.current.collection.searchOpts.pre || \"\",\n post: this.current.collection.searchOpts.post || \"\",\n skip: this.current.collection.searchOpts.skip,\n extract: el => {\n if (typeof this.current.collection.lookup === \"string\") {\n return el[this.current.collection.lookup];\n } else if (typeof this.current.collection.lookup === \"function\") {\n return this.current.collection.lookup(el, this.current.mentionText);\n } else {\n throw new Error(\n \"Invalid lookup attribute, lookup must be string or function.\"\n );\n }\n }\n });\n\n if (this.current.collection.menuItemLimit) {\n items = items.slice(0, this.current.collection.menuItemLimit);\n }\n\n this.current.filteredItems = items;\n\n let ul = this.menu.querySelector(\"ul\");\n\n this.range.positionMenuAtCaret(scrollTo);\n\n if (!items.length) {\n let noMatchEvent = new CustomEvent(\"tribute-no-match\", {\n detail: this.menu\n });\n this.current.element.dispatchEvent(noMatchEvent);\n if (\n (typeof this.current.collection.noMatchTemplate === \"function\" &&\n !this.current.collection.noMatchTemplate()) ||\n !this.current.collection.noMatchTemplate\n ) {\n this.hideMenu();\n } else {\n typeof this.current.collection.noMatchTemplate === \"function\"\n ? (ul.innerHTML = this.current.collection.noMatchTemplate())\n : (ul.innerHTML = this.current.collection.noMatchTemplate);\n }\n\n return;\n }\n\n ul.innerHTML = \"\";\n let fragment = this.range.getDocument().createDocumentFragment();\n\n items.forEach((item, index) => {\n let li = this.range.getDocument().createElement(\"li\");\n li.setAttribute(\"data-index\", index);\n li.className = this.current.collection.itemClass;\n li.addEventListener(\"mousemove\", e => {\n let [li, index] = this._findLiTarget(e.target);\n if (e.movementY !== 0) {\n this.events.setActiveLi(index);\n }\n });\n if (this.menuSelected === index) {\n li.classList.add(this.current.collection.selectClass);\n }\n li.innerHTML = this.current.collection.menuItemTemplate(item);\n fragment.appendChild(li);\n });\n ul.appendChild(fragment);\n };\n\n if (typeof this.current.collection.values === \"function\") {\n this.current.collection.values(this.current.mentionText, processValues);\n } else {\n processValues(this.current.collection.values);\n }\n }\n\n _findLiTarget(el) {\n if (!el) return [];\n const index = el.getAttribute(\"data-index\");\n return !index ? this._findLiTarget(el.parentNode) : [el, index];\n }\n\n showMenuForCollection(element, collectionIndex) {\n if (element !== document.activeElement) {\n this.placeCaretAtEnd(element);\n }\n\n this.current.collection = this.collection[collectionIndex || 0];\n this.current.externalTrigger = true;\n this.current.element = element;\n\n if (element.isContentEditable)\n this.insertTextAtCursor(this.current.collection.trigger);\n else this.insertAtCaret(element, this.current.collection.trigger);\n\n this.showMenuFor(element);\n }\n\n // TODO: make sure this works for inputs/textareas\n placeCaretAtEnd(el) {\n el.focus();\n if (\n typeof window.getSelection != \"undefined\" &&\n typeof document.createRange != \"undefined\"\n ) {\n var range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n var sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n } else if (typeof document.body.createTextRange != \"undefined\") {\n var textRange = document.body.createTextRange();\n textRange.moveToElementText(el);\n textRange.collapse(false);\n textRange.select();\n }\n }\n\n // for contenteditable\n insertTextAtCursor(text) {\n var sel, range, html;\n sel = window.getSelection();\n range = sel.getRangeAt(0);\n range.deleteContents();\n var textNode = document.createTextNode(text);\n range.insertNode(textNode);\n range.selectNodeContents(textNode);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n\n // for regular inputs\n insertAtCaret(textarea, text) {\n var scrollPos = textarea.scrollTop;\n var caretPos = textarea.selectionStart;\n\n var front = textarea.value.substring(0, caretPos);\n var back = textarea.value.substring(\n textarea.selectionEnd,\n textarea.value.length\n );\n textarea.value = front + text + back;\n caretPos = caretPos + text.length;\n textarea.selectionStart = caretPos;\n textarea.selectionEnd = caretPos;\n textarea.focus();\n textarea.scrollTop = scrollPos;\n }\n\n hideMenu() {\n if (this.menu) {\n this.menu.style.cssText = \"display: none;\";\n this.isActive = false;\n this.menuSelected = 0;\n this.current = {};\n }\n }\n\n selectItemAtIndex(index, originalEvent) {\n index = parseInt(index);\n if (typeof index !== \"number\" || isNaN(index)) return;\n let item = this.current.filteredItems[index];\n let content = this.current.collection.selectTemplate(item);\n if (content !== null) this.replaceText(content, originalEvent, item);\n }\n\n replaceText(content, originalEvent, item) {\n this.range.replaceTriggerText(content, true, true, originalEvent, item);\n }\n\n _append(collection, newValues, replace) {\n if (typeof collection.values === \"function\") {\n throw new Error(\"Unable to append to values, as it is a function.\");\n } else if (!replace) {\n collection.values = collection.values.concat(newValues);\n } else {\n collection.values = newValues;\n }\n }\n\n append(collectionIndex, newValues, replace) {\n let index = parseInt(collectionIndex);\n if (typeof index !== \"number\")\n throw new Error(\"please provide an index for the collection to update.\");\n\n let collection = this.collection[index];\n\n this._append(collection, newValues, replace);\n }\n\n appendCurrent(newValues, replace) {\n if (this.isActive) {\n this._append(this.current.collection, newValues, replace);\n } else {\n throw new Error(\n \"No active state. Please use append instead and pass an index.\"\n );\n }\n }\n\n detach(el) {\n if (!el) {\n throw new Error(\"[Tribute] Must pass in a DOM node or NodeList.\");\n }\n\n // Check if it is a jQuery collection\n if (typeof jQuery !== \"undefined\" && el instanceof jQuery) {\n el = el.get();\n }\n\n // Is el an Array/Array-like object?\n if (\n el.constructor === NodeList ||\n el.constructor === HTMLCollection ||\n el.constructor === Array\n ) {\n let length = el.length;\n for (var i = 0; i < length; ++i) {\n this._detach(el[i]);\n }\n } else {\n this._detach(el);\n }\n }\n\n _detach(el) {\n this.events.unbind(el);\n if (el.tributeMenu) {\n this.menuEvents.unbind(el.tributeMenu);\n }\n\n setTimeout(() => {\n el.removeAttribute(\"data-tribute\");\n this.isActive = false;\n if (el.tributeMenu) {\n el.tributeMenu.remove();\n }\n });\n }\n}\n\nexport default Tribute;\n"],"names":["Array","prototype","find","predicate","this","TypeError","value","list","Object","length","thisArg","arguments","i","call","window","CustomEvent","event","params","bubbles","cancelable","detail","undefined","evt","document","createEvent","initCustomEvent","Event","TributeEvents","tribute","events","element","boundKeydown","keydown","bind","boundKeyup","keyup","boundInput","input","addEventListener","removeEventListener","instance","shouldDeactivate","isActive","hideMenu","commandEvent","keys","forEach","o","key","keyCode","callbacks","toLowerCase","inputEvent","menu","contains","target","li","preventDefault","stopPropagation","nodeName","parentNode","Error","selectItemAtIndex","getAttribute","current","externalTrigger","setTimeout","updateSelection","allowSpaces","hasTrailingSpace","autocompleteMode","triggerChar","getKeyCode","isNaN","trigger","triggers","charCodeAt","mentionText","collection","menuShowMinLength","showMenuFor","eventKeyPressed","el","info","range","getTriggerInfo","mentionTriggerChar","selectedPath","mentionSelectedPath","selectedOffset","mentionSelectedOffset","e","_this","collectionItem","item","enter","filteredItems","menuSelected","escape","tab","space","spaceSelectsMatch","up","count","selected","setActiveLi","scrollTop","scrollHeight","down","index","lis","querySelectorAll","parseInt","classList","add","selectClass","liClientRect","getBoundingClientRect","menuClientRect","bottom","scrollDistance","top","remove","elem","includeMargin","height","style","currentStyle","getComputedStyle","parseFloat","marginTop","marginBottom","TributeMenuEvents","menuEvents","menuClickEvent","click","menuContainerScrollEvent","debounce","windowResizeEvent","positionMenuAtCaret","getDocument","menuContainer","func","wait","immediate","timeout","context","_this2","args","callNow","clearTimeout","apply","TributeRange","iframe","contentWindow","scrollTo","coordinates","positionMenu","cssText","isContentEditable","getContentEditableCaretPosition","mentionPosition","getTextAreaOrInputUnderlinePosition","left","right","scrollIntoView","menuDimensions","width","offsetWidth","offsetHeight","menuIsOffScreen","isMenuOffScreen","menuIsOffScreenHorizontally","innerWidth","menuIsOffScreenVertically","innerHeight","targetElement","path","offset","childNodes","nextSibling","previousSibling","sel","getWindowSelection","createRange","setStart","setEnd","collapse","removeAllRanges","error","addRange","focus","text","requireLeadingSpace","originalEvent","replaceEvent","replaceTextSuffix","endPos","pasteHtml","myField","textSuffix","startPos","substring","selectionStart","selectionEnd","dispatchEvent","html","anchorNode","deleteContents","createElement","innerHTML","node","lastNode","frag","createDocumentFragment","firstChild","appendChild","insertNode","cloneRange","setStartAfter","getSelection","ctx","ce","contentEditable","getNodePositionInParent","push","reverse","getRangeAt","startOffset","selectedElem","workingNodeContent","textContent","selectStartOffset","textComponent","wordsArray","replace","split","trim","menuAlreadyActive","isAutocomplete","selectionInfo","getContentEditableSelectedPath","effectiveRange","getTextPrecedingCurrentSelection","lastWordOfEffectiveRange","getLastWordInText","mentionSelectedElement","mostRecentTriggerCharPos","config","c","idx","lastIndexWithLeadingSpace","lastIndexOf","test","currentTriggerSnippet","firstSnippetChar","leadingSpace","regex","str","reversedStr","join","cidx","len","firstChar","match","triggerIdx","windowWidth","windowHeight","doc","documentElement","windowLeft","pageXOffset","scrollLeft","clientLeft","windowTop","pageYOffset","clientTop","menuTop","menuRight","menuBottom","menuLeft","Math","floor","ceil","dimensions","position","flipped","isFirefox","mozInnerScreenX","div","id","body","computed","whiteSpace","wordWrap","visibility","prop","overflowY","overflow","span","rect","menuContainerIsBody","offsetTop","borderTopWidth","fontSize","offsetLeft","borderLeftWidth","getMenuDimensions","parentHeight","scrollStillAvailable","removeChild","selectedNodePosition","clientRect","elemTop","elemBottom","maxY","targetY","TributeSearch","search","pattern","array","filter","string","opts","pre","post","compareString","caseSensitive","skip","rendered","score","patternCache","traverse","render","cache","stringIndex","patternIndex","calculateScore","slice","best","temp","indexOf","pop","indices","arr","reduce","prev","extract","original","sort","a","b","compare","t","values","containerClass","itemClass","selectTemplate","menuItemTemplate","lookup","fillAttr","noMatchTemplate","searchOpts","menuItemLimit","Tribute","defaultSelectTemplate","defaultMenuItemTemplate","console","warn","map","jQuery","get","constructor","NodeList","HTMLCollection","_attach","hasAttribute","ensureEditable","setAttribute","inputTypes","wrapper","ul","className","currentMentionTextSnapshot","createMenu","tributeMenu","processValues","items","querySelector","noMatchEvent","fragment","_findLiTarget","movementY","collectionIndex","activeElement","placeCaretAtEnd","insertTextAtCursor","insertAtCaret","selectNodeContents","createTextRange","textRange","moveToElementText","select","textNode","createTextNode","textarea","scrollPos","caretPos","front","back","content","replaceText","replaceTriggerText","newValues","concat","_append","_detach","unbind","removeAttribute","_this3","_isActive","val","matchItem"],"mappings":"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"} \ No newline at end of file diff --git a/example/index.html b/example/index.html index 5e569cb8..48d579da 100644 --- a/example/index.html +++ b/example/index.html @@ -190,7 +190,8 @@
    Tribute on traditional form elements!
    } return "@" + item.original.value; - } + }, + requireLeadingSpace: false }); tribute.attach(document.getElementById("test")); @@ -270,9 +271,11 @@
    Tribute on traditional form elements!
    console.log("Matched item:", e.detail.item); }); + var noMatchRunOnce = false; document .getElementById("test") .addEventListener("tribute-no-match", function(e) { + if (noMatchRunOnce) return; var values = [ { key: "Cheese Tacos", @@ -281,6 +284,7 @@
    Tribute on traditional form elements!
    } ]; tribute.appendCurrent(values); + noMatchRunOnce = true; }); var activateLink = document.getElementById("activateInput"); diff --git a/example/tribute.js b/example/tribute.js index 1a6e7099..ff55e3ab 100644 --- a/example/tribute.js +++ b/example/tribute.js @@ -1405,7 +1405,7 @@ } return noMatchTemplate || function () { - return ""; + return "
  • No Match Found!
  • "; }.bind(_this); }(noMatchTemplate), // column to search against in the object @@ -1815,7 +1815,7 @@ }], [{ key: "defaultSelectTemplate", value: function defaultSelectTemplate(item) { - if (typeof item === "undefined") return null; + if (typeof item === "undefined") return "@" + this.current.mentionText; if (this.range.isContentEditable(this.current.element)) { return '' + (this.current.collection.trigger + item.original[this.current.collection.fillAttr]) + ""; diff --git a/src/Tribute.js b/src/Tribute.js index b54d81c0..3a1b128e 100755 --- a/src/Tribute.js +++ b/src/Tribute.js @@ -83,7 +83,7 @@ class Tribute { return ( noMatchTemplate || function() { - return ""; + return "
  • No Match Found!
  • "; }.bind(this) ); })(noMatchTemplate), @@ -166,7 +166,7 @@ class Tribute { } static defaultSelectTemplate(item) { - if (typeof item === "undefined") return null; + if (typeof item === "undefined") return "@" + this.current.mentionText; if (this.range.isContentEditable(this.current.element)) { return ( '' +