summaryrefslogtreecommitdiffstats
path: root/app/assets/javascripts/tribute.min.js.map
blob: 9ec73d5389989c23db49b289e0a039cf4dcc7ba5 (plain)
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 <li> 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        var wordsArray;\n        if (this.tribute.autocompleteSeparator) {\n            wordsArray = text.split(this.tribute.autocompleteSeparator);\n        } else {\n            wordsArray = text.split(/\\s+/);\n        }\n        var 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 (this.tribute.autocompleteSeparator) {\n            // if the pattern search at end\n            pattern = pattern.split(this.tribute.autocompleteSeparator).splice(-1)[0];\n        }\n\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    autocompleteSeparator = null,\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.autocompleteSeparator = autocompleteSeparator;\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 === \"string\") {\n              if (t.trim() === \"\") return null;\n              return t;\n            }\n            if (typeof t === \"function\") {\n              return t.bind(this);\n            }\n\n            return (\n              noMatchTemplate ||\n              function() {\n                return \"<li>No Match Found!</li>\";\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 === \"string\") {\n              if (t.trim() === \"\") return null;\n              return t;\n            }\n            if (typeof t === \"function\") {\n              return t.bind(this);\n            }\n\n            return (\n              noMatchTemplate ||\n              function() {\n                return \"<li>No Match Found!</li>\";\n              }.bind(this)\n            );\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\")\n      return `${this.current.collection.trigger}${this.current.mentionText}`;\n    if (this.range.isContentEditable(this.current.element)) {\n      return (\n        '<span class=\"tribute-mention\">' +\n        (this.current.collection.trigger +\n          item.original[this.current.collection.fillAttr]) +\n        \"</span>\"\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 || \"<span>\",\n        post: this.current.collection.searchOpts.post || \"</span>\",\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","autocompleteSeparator","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","splice","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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"}