');i.append(s),i.children().hover((function(){clearTimeout(r),r=setTimeout((function(){!s.hasClass("in")&&s.is(":visible")||(m.render(s[0],n.map((function(t){return m("li",{"data-number":t.number()},l.a.component({post:t,onclick:o}))}))),s.show(),setTimeout((function(){return s.off("transitionend").addClass("in")})))}),500)}),(function(){clearTimeout(r),r=setTimeout(o,250)})),i.find(".Post-mentionedBy-summary a").hover((function(){s.find('[data-number="'+$(this).data("number")+'"]').addClass("active")}),(function(){s.find("[data-number]").removeClass("active")}))}}},m("span",{className:"Post-mentionedBy-summary"},S()("fas fa-reply"),app.translator.transChoice("flarum-mentions.forum.post.mentioned_by"+(i[0].user()===app.session.user?"_self":"")+"_text",a.length,{count:a.length,users:x()(a)}))))}})),Object(o.extend)(p.a.prototype,"actionItems",(function(t){var e=this.props.post;e.isHidden()||app.session.user&&!e.discussion().canReply()||t.add("reply",j.a.component({className:"Button Button--link",children:app.translator.trans("flarum-mentions.forum.post.reply_link"),onclick:function(){return k(e)}}))})),N(),nt(),i.a.notificationComponents.postMentioned=it,i.a.notificationComponents.userMentioned=st,Object(o.extend)(a.a.prototype,"notificationTypes",(function(t){t.add("postMentioned",{name:"postMentioned",icon:"fas fa-reply",label:i.a.translator.trans("flarum-mentions.forum.settings.notify_post_mentioned_label")}),t.add("userMentioned",{name:"userMentioned",icon:"fas fa-at",label:i.a.translator.trans("flarum-mentions.forum.settings.notify_user_mentioned_label")})})),i.a.routes["user.mentions"]={path:"/u/:username/mentions",component:lt.component()},Object(o.extend)(ut.a.prototype,"navItems",(function(t){var e=this.user;t.add("mentions",pt.a.component({href:i.a.route("user.mentions",{username:e.username()}),name:"mentions",children:[i.a.translator.trans("flarum-mentions.forum.user.mentions_link")],icon:"fas fa-at"}),80)})),u.getPlainContent.removeSelectors.push("a.PostMention")}))}]);
//# sourceMappingURL=forum.js.map
\ No newline at end of file
diff --git a/extensions/mentions/js/dist/forum.js.map b/extensions/mentions/js/dist/forum.js.map
index 3ea56a424..457557072 100644
--- a/extensions/mentions/js/dist/forum.js.map
+++ b/extensions/mentions/js/dist/forum.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack://@flarum/mentions/webpack/bootstrap","webpack://@flarum/mentions/external \"flarum.core.compat['extend']\"","webpack://@flarum/mentions/external \"flarum.core.compat['app']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/string']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/CommentPost']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/username']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/PostPreview']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Button']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Notification']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/extract']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditor']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/extractText']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/NotificationGrid']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/LoadingIndicator']\"","webpack://@flarum/mentions/external \"flarum.core.compat['Model']\"","webpack://@flarum/mentions/external \"flarum.core.compat['models/Post']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/punctuateSeries']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/icon']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/DiscussionControls']\"","webpack://@flarum/mentions/./node_modules/textarea-caret/index.js","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditorButton']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/ReplyComposer']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/EditPostComposer']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/avatar']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/highlight']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/KeyboardNavigatable']\"","webpack://@flarum/mentions/external \"flarum.core.compat['Component']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/UserPage']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/LinkButton']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/PostsUserPage']\"","webpack://@flarum/mentions/./src/forum/utils/reply.js","webpack://@flarum/mentions/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@flarum/mentions/./src/forum/components/PostQuoteButton.js","webpack://@flarum/mentions/./src/forum/addPostQuoteButton.js","webpack://@flarum/mentions/./src/forum/utils/selectedText.js","webpack://@flarum/mentions/./src/forum/components/AutocompleteDropdown.js","webpack://@flarum/mentions/./src/forum/addComposerAutocomplete.js","webpack://@flarum/mentions/./src/forum/components/PostMentionedNotification.js","webpack://@flarum/mentions/./src/forum/components/UserMentionedNotification.js","webpack://@flarum/mentions/./src/forum/components/MentionsUserPage.js","webpack://@flarum/mentions/./src/forum/utils/textFormatter.js","webpack://@flarum/mentions/./src/forum/index.js","webpack://@flarum/mentions/./src/forum/addPostMentionPreviews.js","webpack://@flarum/mentions/./src/forum/addMentionedByList.js","webpack://@flarum/mentions/./src/forum/addPostReplyAction.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","flarum","core","compat","properties","isBrowser","window","isFirefox","mozInnerScreenX","getCaretCoordinates","element","position","options","Error","debug","el","document","querySelector","parentNode","removeChild","div","createElement","id","body","appendChild","style","computed","getComputedStyle","currentStyle","isInput","nodeName","whiteSpace","wordWrap","visibility","forEach","prop","lineHeight","height","scrollHeight","parseInt","overflowY","overflow","textContent","substring","replace","span","coordinates","top","offsetTop","left","offsetLeft","backgroundColor","insertMention","post","component","quote","user","mention","username","number","content","props","originalContent","cursorPosition","editor","getSelectionRange","preceding","slice","precedingNewlines","length","match","insertAtCursor","Array","join","trim","reply","app","composer","discussion","DiscussionControls","replyAction","then","newComponent","_inheritsLoose","subClass","superClass","constructor","__proto__","PostQuoteButton","view","extract","this","className","icon","children","translator","trans","onclick","hide","onmousedown","e","stopPropagation","config","isInitialized","$","on","show","$this","parentOffset","offsetParent","offset","css","showStart","scrollTop","outerHeight","showEnd","right","bottom","outerWidth","Button","addPostQuoteButton","extend","CommentPost","original","isHidden","session","canReply","$postBody","$container","handler","setTimeout","selection","getSelection","rangeCount","range","getRangeAt","parent","commonAncestorContainer","contains","clone","append","cloneContents","find","replaceWith","alt","src","innerText","href","text","selectedText","button","render","rects","getClientRects","firstRect","clientY","clientX","lastRect","after","addEventListener","AutocompleteDropdown","init","active","index","keyWasJustPressed","items","map","item","navigate","delta","setIndex","clearTimeout","keyWasJustPressedTimeout","complete","eq","click","scrollToItem","$dropdown","$items","rangedIndex","$item","removeClass","addClass","dropdownScroll","dropdownTop","dropdownBottom","itemTop","itemBottom","stop","animate","Component","addComposerAutocomplete","TextEditor","mentionStart","typed","searchTimeout","dropdown","$textarea","wrap","searched","returnedUsers","from","store","all","returnedUserIds","Set","u","navigator","KeyboardNavigatable","when","onUp","onDown","onSelect","onCancel","bindTo","indexOf","which","cursor","selectionStart","selectionEnd","substr","toLowerCase","makeSuggestion","replacement","usernameHelper","highlight","replaceBeforeCursor","applySuggestion","onmouseenter","avatar","userMatches","displayName","some","buildSuggestions","suggestions","push","bodyMatches","ReplyComposer","EditPostComposer","composerAttrs","attrs","composerPost","posts","filter","contentType","sort","a","b","createdAt","splice","truncate","contentPlain","width","typedLower","q","page","limit","results","has","add","PostMentionedNotification","notification","subject","route","replyNumber","fromUser","transChoice","excerpt","Notification","UserMentionedNotification","MentionsUserPage","loadResults","type","mentioned","loadLimit","PostsUserPage","filterUserMentions","tag","getBy","getAttribute","setAttribute","extractText","filterPostMentions","getById","initializers","contentHtml","oldPostContentHtml","isEditing","parentPost","$parentPost","each","timeout","data","$preview","getPostElement","showPreview","$post","visible","pageYOffset","positionPreview","previewHeight","showPost","title","PostPreview","LoadingIndicator","off","hidePreview","hasClass","one","preventDefault","hover","Post","mentionedBy","Model","hasMany","replies","users","repliers","overLimit","names","data-number","count","is","punctuateSeries","notificationComponents","postMentioned","userMentioned","NotificationGrid","label","routes","path","UserPage","LinkButton","getPlainContent","removeSelectors"],"mappings":"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","file":"forum.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 29);\n","module.exports = flarum.core.compat['extend'];","module.exports = flarum.core.compat['app'];","module.exports = flarum.core.compat['utils/string'];","module.exports = flarum.core.compat['components/CommentPost'];","module.exports = flarum.core.compat['helpers/username'];","module.exports = flarum.core.compat['components/PostPreview'];","module.exports = flarum.core.compat['components/Button'];","module.exports = flarum.core.compat['components/Notification'];","module.exports = flarum.core.compat['utils/extract'];","module.exports = flarum.core.compat['components/TextEditor'];","module.exports = flarum.core.compat['utils/extractText'];","module.exports = flarum.core.compat['components/NotificationGrid'];","module.exports = flarum.core.compat['components/LoadingIndicator'];","module.exports = flarum.core.compat['Model'];","module.exports = flarum.core.compat['models/Post'];","module.exports = flarum.core.compat['helpers/punctuateSeries'];","module.exports = flarum.core.compat['helpers/icon'];","module.exports = flarum.core.compat['utils/DiscussionControls'];","/* jshint browser: true */\n\n(function () {\n\n// We'll copy the properties below into the mirror div.\n// Note that some browsers, such as Firefox, do not concatenate properties\n// into their shorthand (e.g. padding-top, padding-bottom etc. -> padding),\n// so we have to list every single property explicitly.\nvar properties = [\n 'direction', // RTL support\n 'boxSizing',\n 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does\n 'height',\n 'overflowX',\n 'overflowY', // copy the scrollbar for IE\n\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderStyle',\n\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n 'fontStyle',\n 'fontVariant',\n 'fontWeight',\n 'fontStretch',\n 'fontSize',\n 'fontSizeAdjust',\n 'lineHeight',\n 'fontFamily',\n\n 'textAlign',\n 'textTransform',\n 'textIndent',\n 'textDecoration', // might not make a difference, but better be safe\n\n 'letterSpacing',\n 'wordSpacing',\n\n 'tabSize',\n 'MozTabSize'\n\n];\n\nvar isBrowser = (typeof window !== 'undefined');\nvar isFirefox = (isBrowser && window.mozInnerScreenX != null);\n\nfunction getCaretCoordinates(element, position, options) {\n if (!isBrowser) {\n throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');\n }\n\n var debug = options && options.debug || false;\n if (debug) {\n var el = document.querySelector('#input-textarea-caret-position-mirror-div');\n if (el) el.parentNode.removeChild(el);\n }\n\n // The mirror div will replicate the textarea's style\n var div = document.createElement('div');\n div.id = 'input-textarea-caret-position-mirror-div';\n document.body.appendChild(div);\n\n var style = div.style;\n var computed = window.getComputedStyle ? window.getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9\n var isInput = element.nodeName === 'INPUT';\n\n // Default textarea styles\n style.whiteSpace = 'pre-wrap';\n if (!isInput)\n style.wordWrap = 'break-word'; // only for textarea-s\n\n // Position off-screen\n style.position = 'absolute'; // required to return coordinates properly\n if (!debug)\n style.visibility = 'hidden'; // not 'display: none' because we want rendering\n\n // Transfer the element's properties to the div\n properties.forEach(function (prop) {\n if (isInput && prop === 'lineHeight') {\n // Special case for s because text is rendered centered and line height may be != height\n style.lineHeight = computed.height;\n } else {\n style[prop] = computed[prop];\n }\n });\n\n if (isFirefox) {\n // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll';\n } else {\n style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'\n }\n\n div.textContent = element.value.substring(0, position);\n // The second special handling for input type=\"text\" vs textarea:\n // spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037\n if (isInput)\n div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n\n var span = document.createElement('span');\n // Wrapping must be replicated *exactly*, including when a long word gets\n // onto the next line, with whitespace at the end of the line before (#7).\n // The *only* reliable way to do that is to copy the *entire* rest of the\n // textarea's content into the created at the caret position.\n // For inputs, just '.' would be enough, but no need to bother.\n span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all\n div.appendChild(span);\n\n var coordinates = {\n top: span.offsetTop + parseInt(computed['borderTopWidth']),\n left: span.offsetLeft + parseInt(computed['borderLeftWidth']),\n height: parseInt(computed['lineHeight'])\n };\n\n if (debug) {\n span.style.backgroundColor = '#aaa';\n } else {\n document.body.removeChild(div);\n }\n\n return coordinates;\n}\n\nif (typeof module != 'undefined' && typeof module.exports != 'undefined') {\n module.exports = getCaretCoordinates;\n} else if(isBrowser) {\n window.getCaretCoordinates = getCaretCoordinates;\n}\n\n}());\n","module.exports = flarum.core.compat['components/TextEditorButton'];","module.exports = flarum.core.compat['components/ReplyComposer'];","module.exports = flarum.core.compat['components/EditPostComposer'];","module.exports = flarum.core.compat['helpers/avatar'];","module.exports = flarum.core.compat['helpers/highlight'];","module.exports = flarum.core.compat['utils/KeyboardNavigatable'];","module.exports = flarum.core.compat['Component'];","module.exports = flarum.core.compat['components/UserPage'];","module.exports = flarum.core.compat['components/LinkButton'];","module.exports = flarum.core.compat['components/PostsUserPage'];","import DiscussionControls from 'flarum/utils/DiscussionControls';\n\nfunction insertMention(post, component, quote) {\n const user = post.user();\n const mention = '@' + (user ? user.username() : post.number()) + '#' + post.id() + ' ';\n\n // If the composer is empty, then assume we're starting a new reply.\n // In which case we don't want the user to have to confirm if they\n // close the composer straight away.\n if (!component.content()) {\n component.props.originalContent = mention;\n }\n\n const cursorPosition = component.editor.getSelectionRange()[0];\n const preceding = component.editor.value().slice(0, cursorPosition);\n const precedingNewlines = preceding.length == 0 ? 0 : 3 - preceding.match(/(\\n{0,2})$/)[0].length;\n\n component.editor.insertAtCursor(\n Array(precedingNewlines).join('\\n') + // Insert up to two newlines, depending on preceding whitespace\n (quote\n ? '> ' + mention + quote.trim().replace(/\\n/g, '\\n> ') + '\\n\\n'\n : mention)\n );\n}\n\nexport default function reply(post, quote) {\n const component = app.composer.component;\n if (component && component.props.post && component.props.post.discussion() === post.discussion()) {\n insertMention(post, component, quote);\n } else {\n DiscussionControls.replyAction.call(post.discussion())\n .then(newComponent => insertMention(post, newComponent, quote));\n }\n}\n","export default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}","import Button from 'flarum/components/Button';\nimport extract from 'flarum/utils/extract';\n\nimport reply from '../utils/reply';\n\nexport default class PostQuoteButton extends Button {\n view() {\n const post = extract(this.props, 'post');\n const content = extract(this.props, 'content');\n\n this.props.className = 'Button PostQuoteButton';\n this.props.icon = 'fas fa-quote-left';\n this.props.children = app.translator.trans('flarum-mentions.forum.post.quote_button');\n this.props.onclick = () => {\n this.hide();\n reply(post, content);\n };\n this.props.onmousedown = (e) => e.stopPropagation();\n\n return super.view();\n }\n\n config(isInitialized) {\n if (isInitialized) return;\n\n $(document).on('mousedown', this.hide.bind(this));\n }\n\n show(left, top) {\n const $this = this.$().show();\n const parentOffset = $this.offsetParent().offset();\n\n $this\n .css('left', left - parentOffset.left)\n .css('top', top - parentOffset.top);\n }\n\n showStart(left, top) {\n const $this = this.$();\n\n this.show(left, $(window).scrollTop() + top - $this.outerHeight() - 5);\n }\n\n showEnd(right, bottom) {\n const $this = this.$();\n\n this.show(right - $this.outerWidth(), $(window).scrollTop() + bottom + 5);\n }\n\n hide() {\n this.$().hide();\n }\n}\n","import { extend } from 'flarum/extend';\nimport CommentPost from 'flarum/components/CommentPost';\n\nimport PostQuoteButton from './components/PostQuoteButton';\nimport selectedText from './utils/selectedText';\n\nexport default function addPostQuoteButton() {\n extend(CommentPost.prototype, 'config', function(original, isInitialized) {\n const post = this.props.post;\n\n if (isInitialized || post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n const $postBody = this.$('.Post-body');\n\n // Wrap the quote button in a wrapper element so that we can render\n // button into it.\n const $container = $('');\n\n const handler = function(e) {\n setTimeout(() => {\n const content = selectedText($postBody);\n if (content) {\n const button = new PostQuoteButton({post, content});\n m.render($container[0], button.render());\n\n const rects = window.getSelection().getRangeAt(0).getClientRects();\n const firstRect = rects[0];\n\n if (e.clientY < firstRect.bottom && e.clientX - firstRect.right < firstRect.left - e.clientX) {\n button.showStart(firstRect.left, firstRect.top);\n } else {\n const lastRect = rects[rects.length - 1];\n button.showEnd(lastRect.right, lastRect.bottom);\n }\n }\n }, 1);\n };\n\n this.$().after($container).on('mouseup', handler);\n\n if ('ontouchstart' in window) {\n document.addEventListener('selectionchange', handler, false);\n }\n });\n}\n","export default function selectedText(body) {\n const selection = window.getSelection();\n if (selection.rangeCount) {\n const range = selection.getRangeAt(0);\n const parent = range.commonAncestorContainer;\n if (body[0] === parent || $.contains(body[0], parent)) {\n const clone = $(\"
\").append(range.cloneContents());\n\n // Replace emoji images with their shortcode (found in alt attribute)\n clone.find('img.emoji').replaceWith(function() {\n return this.alt;\n });\n\n // Replace all other images with a Markdown image\n clone.find('img').replaceWith(function() {\n return '';\n });\n\n // Replace all links with a Markdown link\n clone.find('a').replaceWith(function() {\n return '[' + this.innerText + '](' + this.href + ')';\n });\n\n return clone.text();\n }\n }\n return \"\";\n}\n","import Component from 'flarum/Component';\n\nexport default class AutocompleteDropdown extends Component {\n init() {\n this.active = false;\n this.index = 0;\n this.keyWasJustPressed = false;\n }\n\n view() {\n return (\n
\n {this.props.items.map(item =>
{item}
)}\n
\n );\n }\n\n show(left, top) {\n this.$().show().css({\n left: left + 'px',\n top: top + 'px'\n });\n this.active = true;\n }\n\n hide() {\n this.$().hide();\n this.active = false;\n }\n\n navigate(delta) {\n this.keyWasJustPressed = true;\n this.setIndex(this.index + delta, true);\n clearTimeout(this.keyWasJustPressedTimeout);\n this.keyWasJustPressedTimeout = setTimeout(() => this.keyWasJustPressed = false, 500);\n }\n\n complete() {\n this.$('li').eq(this.index).find('button').click();\n }\n\n setIndex(index, scrollToItem) {\n if (this.keyWasJustPressed && !scrollToItem) return;\n\n const $dropdown = this.$();\n const $items = $dropdown.find('li');\n let rangedIndex = index;\n\n if (rangedIndex < 0) {\n rangedIndex = $items.length - 1;\n } else if (rangedIndex >= $items.length) {\n rangedIndex = 0;\n }\n\n this.index = rangedIndex;\n\n const $item = $items.removeClass('active').eq(rangedIndex).addClass('active');\n\n if (scrollToItem) {\n const dropdownScroll = $dropdown.scrollTop();\n const dropdownTop = $dropdown.offset().top;\n const dropdownBottom = dropdownTop + $dropdown.outerHeight();\n const itemTop = $item.offset().top;\n const itemBottom = itemTop + $item.outerHeight();\n\n let scrollTop;\n if (itemTop < dropdownTop) {\n scrollTop = dropdownScroll - dropdownTop + itemTop - parseInt($dropdown.css('padding-top'), 10);\n } else if (itemBottom > dropdownBottom) {\n scrollTop = dropdownScroll - dropdownBottom + itemBottom + parseInt($dropdown.css('padding-bottom'), 10);\n }\n\n if (typeof scrollTop !== 'undefined') {\n $dropdown.stop(true).animate({scrollTop}, 100);\n }\n }\n }\n}\n","import getCaretCoordinates from 'textarea-caret';\n\nimport { extend } from 'flarum/extend';\nimport TextEditor from 'flarum/components/TextEditor';\nimport TextEditorButton from 'flarum/components/TextEditorButton';\nimport ReplyComposer from 'flarum/components/ReplyComposer';\nimport EditPostComposer from 'flarum/components/EditPostComposer';\nimport avatar from 'flarum/helpers/avatar';\nimport usernameHelper from 'flarum/helpers/username';\nimport highlight from 'flarum/helpers/highlight';\nimport KeyboardNavigatable from 'flarum/utils/KeyboardNavigatable';\nimport { truncate } from 'flarum/utils/string';\n\nimport AutocompleteDropdown from './components/AutocompleteDropdown';\n\nexport default function addComposerAutocomplete() {\n extend(TextEditor.prototype, 'config', function(original, isInitialized) {\n if (isInitialized) return;\n\n const $container = $('');\n const dropdown = new AutocompleteDropdown({items: []});\n const $textarea = this.$('textarea').wrap('');\n const searched = [];\n let mentionStart;\n let typed;\n let searchTimeout;\n\n // We store users returned from an API here to preserve order in which they are returned\n // This prevents the user list jumping around while users are returned.\n // We also use a hashset for user IDs to provide O(1) lookup for the users already in the list.\n const returnedUsers = Array.from(app.store.all('users'));\n const returnedUserIds = new Set(returnedUsers.map(u => u.id()));\n\n const applySuggestion = (replacement) => {\n app.composer.editor.replaceBeforeCursor(mentionStart - 1, replacement + ' ');\n\n dropdown.hide();\n };\n\n this.navigator = new KeyboardNavigatable();\n this.navigator\n .when(() => dropdown.active)\n .onUp(() => dropdown.navigate(-1))\n .onDown(() => dropdown.navigate(1))\n .onSelect(dropdown.complete.bind(dropdown))\n .onCancel(dropdown.hide.bind(dropdown))\n .bindTo($textarea);\n\n $textarea\n .after($container)\n .on('click keyup input', function(e) {\n // Up, down, enter, tab, escape, left, right.\n if ([9, 13, 27, 40, 38, 37, 39].indexOf(e.which) !== -1) return;\n\n const cursor = this.selectionStart;\n\n if (this.selectionEnd - cursor > 0) return;\n\n // Search backwards from the cursor for an '@' symbol. If we find one,\n // we will want to show the autocomplete dropdown!\n const value = this.value;\n mentionStart = 0;\n for (let i = cursor - 1; i >= cursor - 30; i--) {\n const character = value.substr(i, 1);\n if (character === '@') {\n mentionStart = i + 1;\n break;\n }\n }\n\n dropdown.hide();\n dropdown.active = false;\n\n if (mentionStart) {\n typed = value.substring(mentionStart, cursor).toLowerCase();\n\n const makeSuggestion = function(user, replacement, content, className = '') {\n const username = usernameHelper(user);\n if (typed) {\n username.children[0] = highlight(username.children[0], typed);\n }\n\n return (\n \n );\n };\n\n const userMatches = function(user) {\n const names = [\n user.username(),\n user.displayName()\n ];\n\n return names.some(value => value.toLowerCase().substr(0, typed.length) === typed);\n };\n\n const buildSuggestions = () => {\n const suggestions = [];\n\n // If the user has started to type a username, then suggest users\n // matching that username.\n if (typed) {\n returnedUsers.forEach(user => {\n if (!userMatches(user)) return;\n\n suggestions.push(\n makeSuggestion(user, '@' + user.username(), '', 'MentionsDropdown-user')\n );\n });\n }\n\n // If the user is replying to a discussion, or if they are editing a\n // post, then we can suggest other posts in the discussion to mention.\n // We will add the 5 most recent comments in the discussion which\n // match any username characters that have been typed.\n if (app.composer.bodyMatches(ReplyComposer) || app.composer.bodyMatches(EditPostComposer)) {\n const composerAttrs = app.composer.body.attrs;\n const composerPost = composerAttrs.post;\n const discussion = (composerPost && composerPost.discussion()) || composerAttrs.discussion;\n\n if (discussion) {\n discussion.posts()\n .filter(post => post && post.contentType() === 'comment' && (!composerPost || post.number() < composerPost.number()))\n .sort((a, b) => b.createdAt() - a.createdAt())\n .filter(post => {\n const user = post.user();\n return user && userMatches(user);\n })\n .splice(0, 5)\n .forEach(post => {\n const user = post.user();\n suggestions.push(\n makeSuggestion(user, '@' + user.username() + '#' + post.id(), [\n app.translator.trans('flarum-mentions.forum.composer.reply_to_post_text', {number: post.number()}), ' — ',\n truncate(post.contentPlain(), 200)\n ], 'MentionsDropdown-post')\n );\n });\n }\n }\n\n if (suggestions.length) {\n dropdown.props.items = suggestions;\n m.render($container[0], dropdown.render());\n\n dropdown.show();\n const coordinates = getCaretCoordinates(this, mentionStart);\n const width = dropdown.$().outerWidth();\n const height = dropdown.$().outerHeight();\n const parent = dropdown.$().offsetParent();\n let left = coordinates.left;\n let top = coordinates.top - this.scrollTop + 15;\n if (top + height > parent.height()) {\n top = coordinates.top - this.scrollTop - height - 15;\n }\n if (left + width > parent.width()) {\n left = parent.width() - width;\n }\n dropdown.show(left, top);\n } else {\n dropdown.active = false;\n dropdown.hide();\n }\n };\n\n dropdown.active = true;\n\n buildSuggestions();\n\n dropdown.setIndex(0);\n dropdown.$().scrollTop(0);\n\n clearTimeout(searchTimeout);\n // Don't send API calls searching for users until at least 2 characters have been typed.\n // This focuses the mention results on users and posts in the discussion.\n if (typed.length > 1) {\n searchTimeout = setTimeout(function() {\n const typedLower = typed.toLowerCase();\n if (searched.indexOf(typedLower) === -1) {\n app.store.find('users', { filter: { q: typed }, page: { limit: 5 } }).then(results => {\n results.forEach(u => {\n if (!returnedUserIds.has(u.id())) {\n returnedUserIds.add(u.id());\n returnedUsers.push(u);\n }\n })\n if (dropdown.active) buildSuggestions();\n });\n searched.push(typedLower);\n }\n }, 250);\n }\n }\n });\n });\n\n extend(TextEditor.prototype, 'toolbarItems', function(items) {\n items.add('mention', (\n this.insertAtCursor('@')} icon=\"fas fa-at\">\n {app.translator.trans('flarum-mentions.forum.composer.mention_tooltip')}\n \n ));\n });\n}\n","import Notification from 'flarum/components/Notification';\nimport { truncate } from 'flarum/utils/string';\n\nexport default class PostMentionedNotification extends Notification {\n icon() {\n return 'fas fa-reply';\n }\n\n href() {\n const notification = this.props.notification;\n const post = notification.subject();\n const content = notification.content();\n\n return app.route.discussion(post.discussion(), content && content.replyNumber);\n }\n\n content() {\n const notification = this.props.notification;\n const user = notification.fromUser();\n\n return app.translator.transChoice('flarum-mentions.forum.notifications.post_mentioned_text', 1, {user});\n }\n\n excerpt() {\n return truncate(this.props.notification.subject().contentPlain(), 200);\n }\n}\n","import Notification from 'flarum/components/Notification';\nimport { truncate } from 'flarum/utils/string';\n\nexport default class UserMentionedNotification extends Notification {\n icon() {\n return 'fas fa-at';\n }\n\n href() {\n const post = this.props.notification.subject();\n\n return app.route.discussion(post.discussion(), post.number());\n }\n\n content() {\n const user = this.props.notification.fromUser();\n\n return app.translator.trans('flarum-mentions.forum.notifications.user_mentioned_text', {user});\n }\n\n excerpt() {\n return truncate(this.props.notification.subject().contentPlain(), 200);\n }\n}\n","import PostsUserPage from 'flarum/components/PostsUserPage';\n\n/**\n * The `MentionsUserPage` component shows post which user Mentioned at\n */\nexport default class MentionsUserPage extends PostsUserPage {\n /**\n * Load a new page of the user's activity feed.\n *\n * @param {Integer} [offset] The position to start getting results from.\n * @return {Promise}\n * @protected\n */\n loadResults(offset) {\n return app.store.find('posts', {\n filter: {\n type: 'comment',\n mentioned: this.user.id()\n },\n page: {offset, limit: this.loadLimit},\n sort: '-createdAt'\n });\n }\n}\n","import username from 'flarum/helpers/username';\nimport extractText from 'flarum/utils/extractText';\n\nexport function filterUserMentions(tag) {\n const user = app.store.getBy('users', 'username', tag.getAttribute('username'));\n\n if (user) {\n tag.setAttribute('id', user.id());\n tag.setAttribute('displayname', extractText(username(user)));\n\n return true;\n }\n}\n\nexport function filterPostMentions(tag) {\n const post = app.store.getById('posts', tag.getAttribute('id'));\n\n if (post) {\n tag.setAttribute('discussionid', post.discussion().id());\n tag.setAttribute('number', post.number());\n tag.setAttribute('displayname', extractText(username(post.user())));\n\n return true;\n }\n}\n","import { extend } from 'flarum/extend';\nimport app from 'flarum/app';\nimport NotificationGrid from 'flarum/components/NotificationGrid';\nimport { getPlainContent } from 'flarum/utils/string';\n\nimport addPostMentionPreviews from './addPostMentionPreviews';\nimport addMentionedByList from './addMentionedByList';\nimport addPostReplyAction from './addPostReplyAction';\nimport addPostQuoteButton from './addPostQuoteButton';\nimport addComposerAutocomplete from './addComposerAutocomplete';\nimport PostMentionedNotification from './components/PostMentionedNotification';\nimport UserMentionedNotification from './components/UserMentionedNotification';\nimport UserPage from 'flarum/components/UserPage'\nimport LinkButton from 'flarum/components/LinkButton';\nimport MentionsUserPage from './components/MentionsUserPage';\n\napp.initializers.add('flarum-mentions', function() {\n // For every mention of a post inside a post's content, set up a hover handler\n // that shows a preview of the mentioned post.\n addPostMentionPreviews();\n\n // In the footer of each post, show information about who has replied (i.e.\n // who the post has been mentioned by).\n addMentionedByList();\n\n // Add a 'reply' control to the footer of each post. When clicked, it will\n // open up the composer and add a post mention to its contents.\n addPostReplyAction();\n\n // Show a Quote button when Post text is selected\n addPostQuoteButton();\n\n // After typing '@' in the composer, show a dropdown suggesting a bunch of\n // posts or users that the user could mention.\n addComposerAutocomplete();\n\n app.notificationComponents.postMentioned = PostMentionedNotification;\n app.notificationComponents.userMentioned = UserMentionedNotification;\n\n // Add notification preferences.\n extend(NotificationGrid.prototype, 'notificationTypes', function(items) {\n items.add('postMentioned', {\n name: 'postMentioned',\n icon: 'fas fa-reply',\n label: app.translator.trans('flarum-mentions.forum.settings.notify_post_mentioned_label')\n });\n\n items.add('userMentioned', {\n name: 'userMentioned',\n icon: 'fas fa-at',\n label: app.translator.trans('flarum-mentions.forum.settings.notify_user_mentioned_label')\n });\n });\n\n // Add mentions tab in user profile\n app.routes['user.mentions'] = {path: '/u/:username/mentions', component: MentionsUserPage.component()};\n extend(UserPage.prototype, 'navItems', function(items) {\n const user = this.user;\n items.add('mentions',\n LinkButton.component({\n href: app.route('user.mentions', {username: user.username()}),\n name: 'mentions',\n children: [app.translator.trans('flarum-mentions.forum.user.mentions_link')],\n icon: 'fas fa-at'\n }),\n 80\n );\n });\n\n // Remove post mentions when rendering post previews.\n getPlainContent.removeSelectors.push('a.PostMention');\n});\n\nexport * from './utils/textFormatter';\n","import { extend } from 'flarum/extend';\nimport CommentPost from 'flarum/components/CommentPost';\nimport PostPreview from 'flarum/components/PostPreview';\nimport LoadingIndicator from 'flarum/components/LoadingIndicator';\n\nexport default function addPostMentionPreviews() {\n extend(CommentPost.prototype, 'config', function() {\n const contentHtml = this.props.post.contentHtml();\n\n if (contentHtml === this.oldPostContentHtml || this.isEditing()) return;\n\n this.oldPostContentHtml = contentHtml;\n\n const parentPost = this.props.post;\n const $parentPost = this.$();\n\n this.$('.UserMention, .PostMention').each(function() {\n m.route.call(this, this, false, {}, {attrs: {href: this.getAttribute('href')}});\n });\n\n this.$('.PostMention').each(function() {\n const $this = $(this);\n const id = $this.data('id');\n let timeout;\n\n // Wrap the mention link in a wrapper element so that we can insert a\n // preview popup as its sibling and relatively position it.\n const $preview = $('
');\n $parentPost.append($preview);\n\n const getPostElement = () => {\n return $(`.PostStream-item[data-id=\"${id}\"]`);\n };\n\n const showPreview = () => {\n // When the user hovers their mouse over the mention, look for the\n // post that it's referring to in the stream, and determine if it's\n // in the viewport. If it is, we will \"pulsate\" it.\n const $post = getPostElement();\n let visible = false;\n if ($post.length) {\n const top = $post.offset().top;\n const scrollTop = window.pageYOffset;\n if (top > scrollTop && top + $post.height() < scrollTop + $(window).height()) {\n $post.addClass('pulsate');\n visible = true;\n }\n }\n\n // Otherwise, we will show a popup preview of the post. If the post\n // hasn't yet been loaded, we will need to do that.\n if (!visible) {\n // Position the preview so that it appears above the mention.\n // (The offsetParent should be .Post-body.)\n const positionPreview = () => {\n const previewHeight = $preview.outerHeight(true);\n let offset = 0;\n\n // If the preview goes off the top of the viewport, reposition it to\n // be below the mention.\n if ($this.offset().top - previewHeight < $(window).scrollTop() + $('#header').outerHeight()) {\n offset += $this.outerHeight(true);\n } else {\n offset -= previewHeight;\n }\n\n $preview.show()\n .css('top', $this.offset().top - $parentPost.offset().top + offset)\n .css('left', $this.offsetParent().offset().left - $parentPost.offset().left)\n .css('max-width', $this.offsetParent().width());\n };\n\n const showPost = post => {\n const discussion = post.discussion();\n\n m.render($preview[0], [\n discussion !== parentPost.discussion()\n ?
{discussion.title()}
\n : '',\n
{PostPreview.component({post})}
\n ]);\n positionPreview();\n };\n\n const post = app.store.getById('posts', id);\n if (post && post.discussion()) {\n showPost(post);\n } else {\n m.render($preview[0], LoadingIndicator.component());\n app.store.find('posts', id).then(showPost);\n positionPreview();\n }\n\n setTimeout(() => $preview.off('transitionend').addClass('in'));\n }\n };\n\n const hidePreview = () => {\n getPostElement().removeClass('pulsate');\n if ($preview.hasClass('in')) {\n $preview.removeClass('in').one('transitionend', () => $preview.hide());\n }\n };\n\n $this.on('touchstart', e => e.preventDefault());\n\n $this.add($preview).hover(\n () => {\n clearTimeout(timeout);\n timeout = setTimeout(showPreview, 250);\n },\n () => {\n clearTimeout(timeout);\n getPostElement().removeClass('pulsate');\n timeout = setTimeout(hidePreview, 250);\n }\n )\n .on('touchend', e => {\n showPreview();\n e.stopPropagation();\n });\n\n $(document).on('touchend', hidePreview);\n });\n });\n}\n","import { extend } from 'flarum/extend';\nimport Model from 'flarum/Model';\nimport Post from 'flarum/models/Post';\nimport CommentPost from 'flarum/components/CommentPost';\nimport PostPreview from 'flarum/components/PostPreview';\nimport punctuateSeries from 'flarum/helpers/punctuateSeries';\nimport username from 'flarum/helpers/username';\nimport icon from 'flarum/helpers/icon';\n\nexport default function addMentionedByList() {\n Post.prototype.mentionedBy = Model.hasMany('mentionedBy');\n\n extend(CommentPost.prototype, 'footerItems', function(items) {\n const post = this.props.post;\n const replies = post.mentionedBy();\n\n if (replies && replies.length) {\n const hidePreview = () => {\n this.$('.Post-mentionedBy-preview')\n .removeClass('in')\n .one('transitionend', function() { $(this).hide(); });\n };\n\n const config = function(element, isInitialized) {\n if (isInitialized) return;\n\n const $this = $(element);\n let timeout;\n\n const $preview = $('
');\n $this.append($preview);\n\n $this.children().hover(function() {\n clearTimeout(timeout);\n timeout = setTimeout(function() {\n if (!$preview.hasClass('in') && $preview.is(':visible')) return;\n\n // When the user hovers their mouse over the list of people who have\n // replied to the post, render a list of reply previews into a\n // popup.\n m.render($preview[0], replies.map(reply => (\n
\n )));\n $preview.show();\n setTimeout(() => $preview.off('transitionend').addClass('in'));\n }, 500);\n }, function() {\n clearTimeout(timeout);\n timeout = setTimeout(hidePreview, 250);\n });\n\n // Whenever the user hovers their mouse over a particular name in the\n // list of repliers, highlight the corresponding post in the preview\n // popup.\n $this.find('.Post-mentionedBy-summary a').hover(function() {\n $preview.find('[data-number=\"' + $(this).data('number') + '\"]').addClass('active');\n }, function() {\n $preview.find('[data-number]').removeClass('active');\n });\n };\n\n const users = [];\n const repliers = replies\n .sort(reply => reply.user() === app.session.user ? -1 : 0)\n .filter(reply => {\n const user = reply.user();\n if (users.indexOf(user) === -1) {\n users.push(user);\n return true;\n }\n });\n\n const limit = 4;\n const overLimit = repliers.length > limit;\n\n // Create a list of unique users who have replied. So even if a user has\n // replied twice, they will only be in this array once.\n const names = repliers\n .slice(0, overLimit ? limit - 1 : limit)\n .map(reply => {\n const user = reply.user();\n\n return (\n \n {app.session.user === user ? app.translator.trans('flarum-mentions.forum.post.you_text') : username(user)}\n \n );\n });\n\n // If there are more users that we've run out of room to display, add a \"x\n // others\" name to the end of the list. Clicking on it will display a modal\n // with a full list of names.\n if (overLimit) {\n const count = repliers.length - names.length;\n\n names.push(\n app.translator.transChoice('flarum-mentions.forum.post.others_text', count, {count})\n );\n }\n\n items.add('replies',\n
\n );\n }\n });\n}\n","import { extend } from 'flarum/extend';\nimport Button from 'flarum/components/Button';\nimport CommentPost from 'flarum/components/CommentPost';\n\nimport reply from './utils/reply';\n\nexport default function () {\n extend(CommentPost.prototype, 'actionItems', function (items) {\n\n const post = this.props.post;\n\n if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n items.add('reply',\n Button.component({\n className: 'Button Button--link',\n children: app.translator.trans('flarum-mentions.forum.post.reply_link'),\n onclick: () => reply(post)\n })\n );\n });\n}\n"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack://@flarum/mentions/webpack/bootstrap","webpack://@flarum/mentions/external \"flarum.core.compat['extend']\"","webpack://@flarum/mentions/external \"flarum.core.compat['app']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/string']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/CommentPost']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/username']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/PostPreview']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Button']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Notification']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/extract']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditor']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/extractText']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/NotificationGrid']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/LoadingIndicator']\"","webpack://@flarum/mentions/external \"flarum.core.compat['Model']\"","webpack://@flarum/mentions/external \"flarum.core.compat['models/Post']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/punctuateSeries']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/icon']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/DiscussionControls']\"","webpack://@flarum/mentions/./node_modules/textarea-caret/index.js","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditorButton']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/ReplyComposer']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/EditPostComposer']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/avatar']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/highlight']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/KeyboardNavigatable']\"","webpack://@flarum/mentions/external \"flarum.core.compat['Component']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/UserPage']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/LinkButton']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/PostsUserPage']\"","webpack://@flarum/mentions/./src/forum/utils/reply.js","webpack://@flarum/mentions/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@flarum/mentions/./src/forum/components/PostQuoteButton.js","webpack://@flarum/mentions/./src/forum/addPostQuoteButton.js","webpack://@flarum/mentions/./src/forum/utils/selectedText.js","webpack://@flarum/mentions/./src/forum/components/AutocompleteDropdown.js","webpack://@flarum/mentions/./src/forum/addComposerAutocomplete.js","webpack://@flarum/mentions/./src/forum/components/PostMentionedNotification.js","webpack://@flarum/mentions/./src/forum/components/UserMentionedNotification.js","webpack://@flarum/mentions/./src/forum/components/MentionsUserPage.js","webpack://@flarum/mentions/./src/forum/utils/textFormatter.js","webpack://@flarum/mentions/./src/forum/index.js","webpack://@flarum/mentions/./src/forum/addPostMentionPreviews.js","webpack://@flarum/mentions/./src/forum/addMentionedByList.js","webpack://@flarum/mentions/./src/forum/addPostReplyAction.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","flarum","core","compat","properties","isBrowser","window","isFirefox","mozInnerScreenX","getCaretCoordinates","element","position","options","Error","debug","el","document","querySelector","parentNode","removeChild","div","createElement","id","body","appendChild","style","computed","getComputedStyle","currentStyle","isInput","nodeName","whiteSpace","wordWrap","visibility","forEach","prop","lineHeight","height","scrollHeight","parseInt","overflowY","overflow","textContent","substring","replace","span","coordinates","top","offsetTop","left","offsetLeft","backgroundColor","insertMention","post","component","quote","user","mention","username","number","content","props","originalContent","cursorPosition","editor","getSelectionRange","preceding","slice","precedingNewlines","length","match","insertAtCursor","Array","join","trim","reply","app","composer","discussion","DiscussionControls","replyAction","then","newComponent","_inheritsLoose","subClass","superClass","constructor","__proto__","PostQuoteButton","view","extract","this","className","icon","children","translator","trans","onclick","hide","onmousedown","e","stopPropagation","config","isInitialized","$","on","show","$this","parentOffset","offsetParent","offset","css","showStart","scrollTop","outerHeight","showEnd","right","bottom","outerWidth","Button","addPostQuoteButton","extend","CommentPost","original","isHidden","session","canReply","$postBody","$container","handler","setTimeout","selection","getSelection","rangeCount","range","getRangeAt","parent","commonAncestorContainer","contains","clone","append","cloneContents","find","replaceWith","alt","src","innerText","href","text","selectedText","button","render","rects","getClientRects","firstRect","clientY","clientX","lastRect","after","addEventListener","AutocompleteDropdown","init","active","index","keyWasJustPressed","items","map","item","navigate","delta","setIndex","clearTimeout","keyWasJustPressedTimeout","complete","eq","click","scrollToItem","$dropdown","$items","rangedIndex","$item","removeClass","addClass","dropdownScroll","dropdownTop","dropdownBottom","itemTop","itemBottom","stop","animate","Component","addComposerAutocomplete","TextEditor","mentionStart","typed","searchTimeout","dropdown","$textarea","wrap","searched","returnedUsers","from","store","all","returnedUserIds","Set","u","navigator","KeyboardNavigatable","when","onUp","onDown","onSelect","onCancel","bindTo","indexOf","which","cursor","selectionStart","selectionEnd","substr","toLowerCase","makeSuggestion","replacement","usernameHelper","highlight","replaceBeforeCursor","applySuggestion","onmouseenter","avatar","userMatches","displayName","some","buildSuggestions","suggestions","push","bodyMatches","ReplyComposer","EditPostComposer","composerAttrs","attrs","composerPost","posts","filter","contentType","sort","a","b","createdAt","splice","truncate","contentPlain","width","typedLower","q","page","limit","results","has","add","PostMentionedNotification","notification","subject","route","replyNumber","fromUser","transChoice","excerpt","Notification","UserMentionedNotification","MentionsUserPage","loadResults","type","mentioned","loadLimit","PostsUserPage","filterUserMentions","tag","getBy","getAttribute","setAttribute","extractText","filterPostMentions","getById","initializers","contentHtml","oldPostContentHtml","isEditing","parentPost","$parentPost","each","timeout","data","$preview","getPostElement","showPreview","$post","visible","pageYOffset","positionPreview","previewHeight","showPost","title","PostPreview","LoadingIndicator","off","hidePreview","hasClass","one","preventDefault","hover","Post","mentionedBy","Model","hasMany","replies","users","repliers","overLimit","names","data-number","count","is","punctuateSeries","notificationComponents","postMentioned","userMentioned","NotificationGrid","label","routes","path","UserPage","LinkButton","getPlainContent","removeSelectors"],"mappings":"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","file":"forum.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 29);\n","module.exports = flarum.core.compat['extend'];","module.exports = flarum.core.compat['app'];","module.exports = flarum.core.compat['utils/string'];","module.exports = flarum.core.compat['components/CommentPost'];","module.exports = flarum.core.compat['helpers/username'];","module.exports = flarum.core.compat['components/PostPreview'];","module.exports = flarum.core.compat['components/Button'];","module.exports = flarum.core.compat['components/Notification'];","module.exports = flarum.core.compat['utils/extract'];","module.exports = flarum.core.compat['components/TextEditor'];","module.exports = flarum.core.compat['utils/extractText'];","module.exports = flarum.core.compat['components/NotificationGrid'];","module.exports = flarum.core.compat['components/LoadingIndicator'];","module.exports = flarum.core.compat['Model'];","module.exports = flarum.core.compat['models/Post'];","module.exports = flarum.core.compat['helpers/punctuateSeries'];","module.exports = flarum.core.compat['helpers/icon'];","module.exports = flarum.core.compat['utils/DiscussionControls'];","/* jshint browser: true */\n\n(function () {\n\n// We'll copy the properties below into the mirror div.\n// Note that some browsers, such as Firefox, do not concatenate properties\n// into their shorthand (e.g. padding-top, padding-bottom etc. -> padding),\n// so we have to list every single property explicitly.\nvar properties = [\n 'direction', // RTL support\n 'boxSizing',\n 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does\n 'height',\n 'overflowX',\n 'overflowY', // copy the scrollbar for IE\n\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderStyle',\n\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n 'fontStyle',\n 'fontVariant',\n 'fontWeight',\n 'fontStretch',\n 'fontSize',\n 'fontSizeAdjust',\n 'lineHeight',\n 'fontFamily',\n\n 'textAlign',\n 'textTransform',\n 'textIndent',\n 'textDecoration', // might not make a difference, but better be safe\n\n 'letterSpacing',\n 'wordSpacing',\n\n 'tabSize',\n 'MozTabSize'\n\n];\n\nvar isBrowser = (typeof window !== 'undefined');\nvar isFirefox = (isBrowser && window.mozInnerScreenX != null);\n\nfunction getCaretCoordinates(element, position, options) {\n if (!isBrowser) {\n throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');\n }\n\n var debug = options && options.debug || false;\n if (debug) {\n var el = document.querySelector('#input-textarea-caret-position-mirror-div');\n if (el) el.parentNode.removeChild(el);\n }\n\n // The mirror div will replicate the textarea's style\n var div = document.createElement('div');\n div.id = 'input-textarea-caret-position-mirror-div';\n document.body.appendChild(div);\n\n var style = div.style;\n var computed = window.getComputedStyle ? window.getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9\n var isInput = element.nodeName === 'INPUT';\n\n // Default textarea styles\n style.whiteSpace = 'pre-wrap';\n if (!isInput)\n style.wordWrap = 'break-word'; // only for textarea-s\n\n // Position off-screen\n style.position = 'absolute'; // required to return coordinates properly\n if (!debug)\n style.visibility = 'hidden'; // not 'display: none' because we want rendering\n\n // Transfer the element's properties to the div\n properties.forEach(function (prop) {\n if (isInput && prop === 'lineHeight') {\n // Special case for s because text is rendered centered and line height may be != height\n style.lineHeight = computed.height;\n } else {\n style[prop] = computed[prop];\n }\n });\n\n if (isFirefox) {\n // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll';\n } else {\n style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'\n }\n\n div.textContent = element.value.substring(0, position);\n // The second special handling for input type=\"text\" vs textarea:\n // spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037\n if (isInput)\n div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n\n var span = document.createElement('span');\n // Wrapping must be replicated *exactly*, including when a long word gets\n // onto the next line, with whitespace at the end of the line before (#7).\n // The *only* reliable way to do that is to copy the *entire* rest of the\n // textarea's content into the created at the caret position.\n // For inputs, just '.' would be enough, but no need to bother.\n span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all\n div.appendChild(span);\n\n var coordinates = {\n top: span.offsetTop + parseInt(computed['borderTopWidth']),\n left: span.offsetLeft + parseInt(computed['borderLeftWidth']),\n height: parseInt(computed['lineHeight'])\n };\n\n if (debug) {\n span.style.backgroundColor = '#aaa';\n } else {\n document.body.removeChild(div);\n }\n\n return coordinates;\n}\n\nif (typeof module != 'undefined' && typeof module.exports != 'undefined') {\n module.exports = getCaretCoordinates;\n} else if(isBrowser) {\n window.getCaretCoordinates = getCaretCoordinates;\n}\n\n}());\n","module.exports = flarum.core.compat['components/TextEditorButton'];","module.exports = flarum.core.compat['components/ReplyComposer'];","module.exports = flarum.core.compat['components/EditPostComposer'];","module.exports = flarum.core.compat['helpers/avatar'];","module.exports = flarum.core.compat['helpers/highlight'];","module.exports = flarum.core.compat['utils/KeyboardNavigatable'];","module.exports = flarum.core.compat['Component'];","module.exports = flarum.core.compat['components/UserPage'];","module.exports = flarum.core.compat['components/LinkButton'];","module.exports = flarum.core.compat['components/PostsUserPage'];","import DiscussionControls from 'flarum/utils/DiscussionControls';\n\nfunction insertMention(post, component, quote) {\n const user = post.user();\n const mention = '@' + (user ? user.username() : post.number()) + '#' + post.id() + ' ';\n\n // If the composer is empty, then assume we're starting a new reply.\n // In which case we don't want the user to have to confirm if they\n // close the composer straight away.\n if (!component.content()) {\n component.props.originalContent = mention;\n }\n\n const cursorPosition = component.editor.getSelectionRange()[0];\n const preceding = component.editor.value().slice(0, cursorPosition);\n const precedingNewlines = preceding.length == 0 ? 0 : 3 - preceding.match(/(\\n{0,2})$/)[0].length;\n\n component.editor.insertAtCursor(\n Array(precedingNewlines).join('\\n') + // Insert up to two newlines, depending on preceding whitespace\n (quote\n ? '> ' + mention + quote.trim().replace(/\\n/g, '\\n> ') + '\\n\\n'\n : mention)\n );\n}\n\nexport default function reply(post, quote) {\n const component = app.composer.component;\n if (component && component.props.post && component.props.post.discussion() === post.discussion()) {\n insertMention(post, component, quote);\n } else {\n DiscussionControls.replyAction.call(post.discussion())\n .then(newComponent => insertMention(post, newComponent, quote));\n }\n}\n","export default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}","import Button from 'flarum/components/Button';\nimport extract from 'flarum/utils/extract';\n\nimport reply from '../utils/reply';\n\nexport default class PostQuoteButton extends Button {\n view() {\n const post = extract(this.props, 'post');\n const content = extract(this.props, 'content');\n\n this.props.className = 'Button PostQuoteButton';\n this.props.icon = 'fas fa-quote-left';\n this.props.children = app.translator.trans('flarum-mentions.forum.post.quote_button');\n this.props.onclick = () => {\n this.hide();\n reply(post, content);\n };\n this.props.onmousedown = (e) => e.stopPropagation();\n\n return super.view();\n }\n\n config(isInitialized) {\n if (isInitialized) return;\n\n $(document).on('mousedown', this.hide.bind(this));\n }\n\n show(left, top) {\n const $this = this.$().show();\n const parentOffset = $this.offsetParent().offset();\n\n $this\n .css('left', left - parentOffset.left)\n .css('top', top - parentOffset.top);\n }\n\n showStart(left, top) {\n const $this = this.$();\n\n this.show(left, $(window).scrollTop() + top - $this.outerHeight() - 5);\n }\n\n showEnd(right, bottom) {\n const $this = this.$();\n\n this.show(right - $this.outerWidth(), $(window).scrollTop() + bottom + 5);\n }\n\n hide() {\n this.$().hide();\n }\n}\n","import { extend } from 'flarum/extend';\nimport CommentPost from 'flarum/components/CommentPost';\n\nimport PostQuoteButton from './components/PostQuoteButton';\nimport selectedText from './utils/selectedText';\n\nexport default function addPostQuoteButton() {\n extend(CommentPost.prototype, 'config', function(original, isInitialized) {\n const post = this.props.post;\n\n if (isInitialized || post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n const $postBody = this.$('.Post-body');\n\n // Wrap the quote button in a wrapper element so that we can render\n // button into it.\n const $container = $('');\n\n const handler = function(e) {\n setTimeout(() => {\n const content = selectedText($postBody);\n if (content) {\n const button = new PostQuoteButton({post, content});\n m.render($container[0], button.render());\n\n const rects = window.getSelection().getRangeAt(0).getClientRects();\n const firstRect = rects[0];\n\n if (e.clientY < firstRect.bottom && e.clientX - firstRect.right < firstRect.left - e.clientX) {\n button.showStart(firstRect.left, firstRect.top);\n } else {\n const lastRect = rects[rects.length - 1];\n button.showEnd(lastRect.right, lastRect.bottom);\n }\n }\n }, 1);\n };\n\n this.$().after($container).on('mouseup', handler);\n\n if ('ontouchstart' in window) {\n document.addEventListener('selectionchange', handler, false);\n }\n });\n}\n","export default function selectedText(body) {\n const selection = window.getSelection();\n if (selection.rangeCount) {\n const range = selection.getRangeAt(0);\n const parent = range.commonAncestorContainer;\n if (body[0] === parent || $.contains(body[0], parent)) {\n const clone = $(\"
\").append(range.cloneContents());\n\n // Replace emoji images with their shortcode (found in alt attribute)\n clone.find('img.emoji').replaceWith(function() {\n return this.alt;\n });\n\n // Replace all other images with a Markdown image\n clone.find('img').replaceWith(function() {\n return '';\n });\n\n // Replace all links with a Markdown link\n clone.find('a').replaceWith(function() {\n return '[' + this.innerText + '](' + this.href + ')';\n });\n\n return clone.text();\n }\n }\n return \"\";\n}\n","import Component from 'flarum/Component';\n\nexport default class AutocompleteDropdown extends Component {\n init() {\n this.active = false;\n this.index = 0;\n this.keyWasJustPressed = false;\n }\n\n view() {\n return (\n
\n {this.props.items.map(item =>
{item}
)}\n
\n );\n }\n\n show(left, top) {\n this.$().show().css({\n left: left + 'px',\n top: top + 'px'\n });\n this.active = true;\n }\n\n hide() {\n this.$().hide();\n this.active = false;\n }\n\n navigate(delta) {\n this.keyWasJustPressed = true;\n this.setIndex(this.index + delta, true);\n clearTimeout(this.keyWasJustPressedTimeout);\n this.keyWasJustPressedTimeout = setTimeout(() => this.keyWasJustPressed = false, 500);\n }\n\n complete() {\n this.$('li').eq(this.index).find('button').click();\n }\n\n setIndex(index, scrollToItem) {\n if (this.keyWasJustPressed && !scrollToItem) return;\n\n const $dropdown = this.$();\n const $items = $dropdown.find('li');\n let rangedIndex = index;\n\n if (rangedIndex < 0) {\n rangedIndex = $items.length - 1;\n } else if (rangedIndex >= $items.length) {\n rangedIndex = 0;\n }\n\n this.index = rangedIndex;\n\n const $item = $items.removeClass('active').eq(rangedIndex).addClass('active');\n\n if (scrollToItem) {\n const dropdownScroll = $dropdown.scrollTop();\n const dropdownTop = $dropdown.offset().top;\n const dropdownBottom = dropdownTop + $dropdown.outerHeight();\n const itemTop = $item.offset().top;\n const itemBottom = itemTop + $item.outerHeight();\n\n let scrollTop;\n if (itemTop < dropdownTop) {\n scrollTop = dropdownScroll - dropdownTop + itemTop - parseInt($dropdown.css('padding-top'), 10);\n } else if (itemBottom > dropdownBottom) {\n scrollTop = dropdownScroll - dropdownBottom + itemBottom + parseInt($dropdown.css('padding-bottom'), 10);\n }\n\n if (typeof scrollTop !== 'undefined') {\n $dropdown.stop(true).animate({scrollTop}, 100);\n }\n }\n }\n}\n","import getCaretCoordinates from 'textarea-caret';\n\nimport { extend } from 'flarum/extend';\nimport TextEditor from 'flarum/components/TextEditor';\nimport TextEditorButton from 'flarum/components/TextEditorButton';\nimport ReplyComposer from 'flarum/components/ReplyComposer';\nimport EditPostComposer from 'flarum/components/EditPostComposer';\nimport avatar from 'flarum/helpers/avatar';\nimport usernameHelper from 'flarum/helpers/username';\nimport highlight from 'flarum/helpers/highlight';\nimport KeyboardNavigatable from 'flarum/utils/KeyboardNavigatable';\nimport { truncate } from 'flarum/utils/string';\n\nimport AutocompleteDropdown from './components/AutocompleteDropdown';\n\nexport default function addComposerAutocomplete() {\n extend(TextEditor.prototype, 'config', function(original, isInitialized) {\n if (isInitialized) return;\n\n const $container = $('');\n const dropdown = new AutocompleteDropdown({items: []});\n const $textarea = this.$('textarea').wrap('');\n const searched = [];\n let mentionStart;\n let typed;\n let searchTimeout;\n\n // We store users returned from an API here to preserve order in which they are returned\n // This prevents the user list jumping around while users are returned.\n // We also use a hashset for user IDs to provide O(1) lookup for the users already in the list.\n const returnedUsers = Array.from(app.store.all('users'));\n const returnedUserIds = new Set(returnedUsers.map(u => u.id()));\n\n const applySuggestion = (replacement) => {\n app.composer.editor.replaceBeforeCursor(mentionStart - 1, replacement + ' ');\n\n dropdown.hide();\n };\n\n this.navigator = new KeyboardNavigatable();\n this.navigator\n .when(() => dropdown.active)\n .onUp(() => dropdown.navigate(-1))\n .onDown(() => dropdown.navigate(1))\n .onSelect(dropdown.complete.bind(dropdown))\n .onCancel(dropdown.hide.bind(dropdown))\n .bindTo($textarea);\n\n $textarea\n .after($container)\n .on('click keyup input', function(e) {\n // Up, down, enter, tab, escape, left, right.\n if ([9, 13, 27, 40, 38, 37, 39].indexOf(e.which) !== -1) return;\n\n const cursor = this.selectionStart;\n\n if (this.selectionEnd - cursor > 0) return;\n\n // Search backwards from the cursor for an '@' symbol. If we find one,\n // we will want to show the autocomplete dropdown!\n const value = this.value;\n mentionStart = 0;\n for (let i = cursor - 1; i >= cursor - 30; i--) {\n const character = value.substr(i, 1);\n if (character === '@') {\n mentionStart = i + 1;\n break;\n }\n }\n\n dropdown.hide();\n dropdown.active = false;\n\n if (mentionStart) {\n typed = value.substring(mentionStart, cursor).toLowerCase();\n\n const makeSuggestion = function(user, replacement, content, className = '') {\n const username = usernameHelper(user);\n if (typed) {\n username.children[0] = highlight(username.children[0], typed);\n }\n\n return (\n \n );\n };\n\n const userMatches = function(user) {\n const names = [\n user.username(),\n user.displayName()\n ];\n\n return names.some(value => value.toLowerCase().substr(0, typed.length) === typed);\n };\n\n const buildSuggestions = () => {\n const suggestions = [];\n\n // If the user has started to type a username, then suggest users\n // matching that username.\n if (typed) {\n returnedUsers.forEach(user => {\n if (!userMatches(user)) return;\n\n suggestions.push(\n makeSuggestion(user, '@' + user.username(), '', 'MentionsDropdown-user')\n );\n });\n }\n\n // If the user is replying to a discussion, or if they are editing a\n // post, then we can suggest other posts in the discussion to mention.\n // We will add the 5 most recent comments in the discussion which\n // match any username characters that have been typed.\n if (app.composer.bodyMatches(ReplyComposer) || app.composer.bodyMatches(EditPostComposer)) {\n const composerAttrs = app.composer.body.attrs;\n const composerPost = composerAttrs.post;\n const discussion = (composerPost && composerPost.discussion()) || composerAttrs.discussion;\n\n if (discussion) {\n discussion.posts()\n .filter(post => post && post.contentType() === 'comment' && (!composerPost || post.number() < composerPost.number()))\n .sort((a, b) => b.createdAt() - a.createdAt())\n .filter(post => {\n const user = post.user();\n return user && userMatches(user);\n })\n .splice(0, 5)\n .forEach(post => {\n const user = post.user();\n suggestions.push(\n makeSuggestion(user, '@' + user.username() + '#' + post.id(), [\n app.translator.trans('flarum-mentions.forum.composer.reply_to_post_text', {number: post.number()}), ' — ',\n truncate(post.contentPlain(), 200)\n ], 'MentionsDropdown-post')\n );\n });\n }\n }\n\n if (suggestions.length) {\n dropdown.props.items = suggestions;\n m.render($container[0], dropdown.render());\n\n dropdown.show();\n const coordinates = getCaretCoordinates(this, mentionStart);\n const width = dropdown.$().outerWidth();\n const height = dropdown.$().outerHeight();\n const parent = dropdown.$().offsetParent();\n let left = coordinates.left;\n let top = coordinates.top - this.scrollTop + 15;\n if (top + height > parent.height()) {\n top = coordinates.top - this.scrollTop - height - 15;\n }\n if (left + width > parent.width()) {\n left = parent.width() - width;\n }\n dropdown.show(left, top);\n } else {\n dropdown.active = false;\n dropdown.hide();\n }\n };\n\n dropdown.active = true;\n\n buildSuggestions();\n\n dropdown.setIndex(0);\n dropdown.$().scrollTop(0);\n\n clearTimeout(searchTimeout);\n // Don't send API calls searching for users until at least 2 characters have been typed.\n // This focuses the mention results on users and posts in the discussion.\n if (typed.length > 1) {\n searchTimeout = setTimeout(function() {\n const typedLower = typed.toLowerCase();\n if (searched.indexOf(typedLower) === -1) {\n app.store.find('users', { filter: { q: typed }, page: { limit: 5 } }).then(results => {\n results.forEach(u => {\n if (!returnedUserIds.has(u.id())) {\n returnedUserIds.add(u.id());\n returnedUsers.push(u);\n }\n })\n if (dropdown.active) buildSuggestions();\n });\n searched.push(typedLower);\n }\n }, 250);\n }\n }\n });\n });\n\n extend(TextEditor.prototype, 'toolbarItems', function(items) {\n items.add('mention', (\n this.props.composer.editor.insertAtCursor('@')} icon=\"fas fa-at\">\n {app.translator.trans('flarum-mentions.forum.composer.mention_tooltip')}\n \n ));\n });\n}\n","import Notification from 'flarum/components/Notification';\nimport { truncate } from 'flarum/utils/string';\n\nexport default class PostMentionedNotification extends Notification {\n icon() {\n return 'fas fa-reply';\n }\n\n href() {\n const notification = this.props.notification;\n const post = notification.subject();\n const content = notification.content();\n\n return app.route.discussion(post.discussion(), content && content.replyNumber);\n }\n\n content() {\n const notification = this.props.notification;\n const user = notification.fromUser();\n\n return app.translator.transChoice('flarum-mentions.forum.notifications.post_mentioned_text', 1, {user});\n }\n\n excerpt() {\n return truncate(this.props.notification.subject().contentPlain(), 200);\n }\n}\n","import Notification from 'flarum/components/Notification';\nimport { truncate } from 'flarum/utils/string';\n\nexport default class UserMentionedNotification extends Notification {\n icon() {\n return 'fas fa-at';\n }\n\n href() {\n const post = this.props.notification.subject();\n\n return app.route.discussion(post.discussion(), post.number());\n }\n\n content() {\n const user = this.props.notification.fromUser();\n\n return app.translator.trans('flarum-mentions.forum.notifications.user_mentioned_text', {user});\n }\n\n excerpt() {\n return truncate(this.props.notification.subject().contentPlain(), 200);\n }\n}\n","import PostsUserPage from 'flarum/components/PostsUserPage';\n\n/**\n * The `MentionsUserPage` component shows post which user Mentioned at\n */\nexport default class MentionsUserPage extends PostsUserPage {\n /**\n * Load a new page of the user's activity feed.\n *\n * @param {Integer} [offset] The position to start getting results from.\n * @return {Promise}\n * @protected\n */\n loadResults(offset) {\n return app.store.find('posts', {\n filter: {\n type: 'comment',\n mentioned: this.user.id()\n },\n page: {offset, limit: this.loadLimit},\n sort: '-createdAt'\n });\n }\n}\n","import username from 'flarum/helpers/username';\nimport extractText from 'flarum/utils/extractText';\n\nexport function filterUserMentions(tag) {\n const user = app.store.getBy('users', 'username', tag.getAttribute('username'));\n\n if (user) {\n tag.setAttribute('id', user.id());\n tag.setAttribute('displayname', extractText(username(user)));\n\n return true;\n }\n}\n\nexport function filterPostMentions(tag) {\n const post = app.store.getById('posts', tag.getAttribute('id'));\n\n if (post) {\n tag.setAttribute('discussionid', post.discussion().id());\n tag.setAttribute('number', post.number());\n tag.setAttribute('displayname', extractText(username(post.user())));\n\n return true;\n }\n}\n","import { extend } from 'flarum/extend';\nimport app from 'flarum/app';\nimport NotificationGrid from 'flarum/components/NotificationGrid';\nimport { getPlainContent } from 'flarum/utils/string';\n\nimport addPostMentionPreviews from './addPostMentionPreviews';\nimport addMentionedByList from './addMentionedByList';\nimport addPostReplyAction from './addPostReplyAction';\nimport addPostQuoteButton from './addPostQuoteButton';\nimport addComposerAutocomplete from './addComposerAutocomplete';\nimport PostMentionedNotification from './components/PostMentionedNotification';\nimport UserMentionedNotification from './components/UserMentionedNotification';\nimport UserPage from 'flarum/components/UserPage'\nimport LinkButton from 'flarum/components/LinkButton';\nimport MentionsUserPage from './components/MentionsUserPage';\n\napp.initializers.add('flarum-mentions', function() {\n // For every mention of a post inside a post's content, set up a hover handler\n // that shows a preview of the mentioned post.\n addPostMentionPreviews();\n\n // In the footer of each post, show information about who has replied (i.e.\n // who the post has been mentioned by).\n addMentionedByList();\n\n // Add a 'reply' control to the footer of each post. When clicked, it will\n // open up the composer and add a post mention to its contents.\n addPostReplyAction();\n\n // Show a Quote button when Post text is selected\n addPostQuoteButton();\n\n // After typing '@' in the composer, show a dropdown suggesting a bunch of\n // posts or users that the user could mention.\n addComposerAutocomplete();\n\n app.notificationComponents.postMentioned = PostMentionedNotification;\n app.notificationComponents.userMentioned = UserMentionedNotification;\n\n // Add notification preferences.\n extend(NotificationGrid.prototype, 'notificationTypes', function(items) {\n items.add('postMentioned', {\n name: 'postMentioned',\n icon: 'fas fa-reply',\n label: app.translator.trans('flarum-mentions.forum.settings.notify_post_mentioned_label')\n });\n\n items.add('userMentioned', {\n name: 'userMentioned',\n icon: 'fas fa-at',\n label: app.translator.trans('flarum-mentions.forum.settings.notify_user_mentioned_label')\n });\n });\n\n // Add mentions tab in user profile\n app.routes['user.mentions'] = {path: '/u/:username/mentions', component: MentionsUserPage.component()};\n extend(UserPage.prototype, 'navItems', function(items) {\n const user = this.user;\n items.add('mentions',\n LinkButton.component({\n href: app.route('user.mentions', {username: user.username()}),\n name: 'mentions',\n children: [app.translator.trans('flarum-mentions.forum.user.mentions_link')],\n icon: 'fas fa-at'\n }),\n 80\n );\n });\n\n // Remove post mentions when rendering post previews.\n getPlainContent.removeSelectors.push('a.PostMention');\n});\n\nexport * from './utils/textFormatter';\n","import { extend } from 'flarum/extend';\nimport CommentPost from 'flarum/components/CommentPost';\nimport PostPreview from 'flarum/components/PostPreview';\nimport LoadingIndicator from 'flarum/components/LoadingIndicator';\n\nexport default function addPostMentionPreviews() {\n extend(CommentPost.prototype, 'config', function() {\n const contentHtml = this.props.post.contentHtml();\n\n if (contentHtml === this.oldPostContentHtml || this.isEditing()) return;\n\n this.oldPostContentHtml = contentHtml;\n\n const parentPost = this.props.post;\n const $parentPost = this.$();\n\n this.$('.UserMention, .PostMention').each(function() {\n m.route.call(this, this, false, {}, {attrs: {href: this.getAttribute('href')}});\n });\n\n this.$('.PostMention').each(function() {\n const $this = $(this);\n const id = $this.data('id');\n let timeout;\n\n // Wrap the mention link in a wrapper element so that we can insert a\n // preview popup as its sibling and relatively position it.\n const $preview = $('
');\n $parentPost.append($preview);\n\n const getPostElement = () => {\n return $(`.PostStream-item[data-id=\"${id}\"]`);\n };\n\n const showPreview = () => {\n // When the user hovers their mouse over the mention, look for the\n // post that it's referring to in the stream, and determine if it's\n // in the viewport. If it is, we will \"pulsate\" it.\n const $post = getPostElement();\n let visible = false;\n if ($post.length) {\n const top = $post.offset().top;\n const scrollTop = window.pageYOffset;\n if (top > scrollTop && top + $post.height() < scrollTop + $(window).height()) {\n $post.addClass('pulsate');\n visible = true;\n }\n }\n\n // Otherwise, we will show a popup preview of the post. If the post\n // hasn't yet been loaded, we will need to do that.\n if (!visible) {\n // Position the preview so that it appears above the mention.\n // (The offsetParent should be .Post-body.)\n const positionPreview = () => {\n const previewHeight = $preview.outerHeight(true);\n let offset = 0;\n\n // If the preview goes off the top of the viewport, reposition it to\n // be below the mention.\n if ($this.offset().top - previewHeight < $(window).scrollTop() + $('#header').outerHeight()) {\n offset += $this.outerHeight(true);\n } else {\n offset -= previewHeight;\n }\n\n $preview.show()\n .css('top', $this.offset().top - $parentPost.offset().top + offset)\n .css('left', $this.offsetParent().offset().left - $parentPost.offset().left)\n .css('max-width', $this.offsetParent().width());\n };\n\n const showPost = post => {\n const discussion = post.discussion();\n\n m.render($preview[0], [\n discussion !== parentPost.discussion()\n ?
{discussion.title()}
\n : '',\n
{PostPreview.component({post})}
\n ]);\n positionPreview();\n };\n\n const post = app.store.getById('posts', id);\n if (post && post.discussion()) {\n showPost(post);\n } else {\n m.render($preview[0], LoadingIndicator.component());\n app.store.find('posts', id).then(showPost);\n positionPreview();\n }\n\n setTimeout(() => $preview.off('transitionend').addClass('in'));\n }\n };\n\n const hidePreview = () => {\n getPostElement().removeClass('pulsate');\n if ($preview.hasClass('in')) {\n $preview.removeClass('in').one('transitionend', () => $preview.hide());\n }\n };\n\n $this.on('touchstart', e => e.preventDefault());\n\n $this.add($preview).hover(\n () => {\n clearTimeout(timeout);\n timeout = setTimeout(showPreview, 250);\n },\n () => {\n clearTimeout(timeout);\n getPostElement().removeClass('pulsate');\n timeout = setTimeout(hidePreview, 250);\n }\n )\n .on('touchend', e => {\n showPreview();\n e.stopPropagation();\n });\n\n $(document).on('touchend', hidePreview);\n });\n });\n}\n","import { extend } from 'flarum/extend';\nimport Model from 'flarum/Model';\nimport Post from 'flarum/models/Post';\nimport CommentPost from 'flarum/components/CommentPost';\nimport PostPreview from 'flarum/components/PostPreview';\nimport punctuateSeries from 'flarum/helpers/punctuateSeries';\nimport username from 'flarum/helpers/username';\nimport icon from 'flarum/helpers/icon';\n\nexport default function addMentionedByList() {\n Post.prototype.mentionedBy = Model.hasMany('mentionedBy');\n\n extend(CommentPost.prototype, 'footerItems', function(items) {\n const post = this.props.post;\n const replies = post.mentionedBy();\n\n if (replies && replies.length) {\n const hidePreview = () => {\n this.$('.Post-mentionedBy-preview')\n .removeClass('in')\n .one('transitionend', function() { $(this).hide(); });\n };\n\n const config = function(element, isInitialized) {\n if (isInitialized) return;\n\n const $this = $(element);\n let timeout;\n\n const $preview = $('
');\n $this.append($preview);\n\n $this.children().hover(function() {\n clearTimeout(timeout);\n timeout = setTimeout(function() {\n if (!$preview.hasClass('in') && $preview.is(':visible')) return;\n\n // When the user hovers their mouse over the list of people who have\n // replied to the post, render a list of reply previews into a\n // popup.\n m.render($preview[0], replies.map(reply => (\n
\n )));\n $preview.show();\n setTimeout(() => $preview.off('transitionend').addClass('in'));\n }, 500);\n }, function() {\n clearTimeout(timeout);\n timeout = setTimeout(hidePreview, 250);\n });\n\n // Whenever the user hovers their mouse over a particular name in the\n // list of repliers, highlight the corresponding post in the preview\n // popup.\n $this.find('.Post-mentionedBy-summary a').hover(function() {\n $preview.find('[data-number=\"' + $(this).data('number') + '\"]').addClass('active');\n }, function() {\n $preview.find('[data-number]').removeClass('active');\n });\n };\n\n const users = [];\n const repliers = replies\n .sort(reply => reply.user() === app.session.user ? -1 : 0)\n .filter(reply => {\n const user = reply.user();\n if (users.indexOf(user) === -1) {\n users.push(user);\n return true;\n }\n });\n\n const limit = 4;\n const overLimit = repliers.length > limit;\n\n // Create a list of unique users who have replied. So even if a user has\n // replied twice, they will only be in this array once.\n const names = repliers\n .slice(0, overLimit ? limit - 1 : limit)\n .map(reply => {\n const user = reply.user();\n\n return (\n \n {app.session.user === user ? app.translator.trans('flarum-mentions.forum.post.you_text') : username(user)}\n \n );\n });\n\n // If there are more users that we've run out of room to display, add a \"x\n // others\" name to the end of the list. Clicking on it will display a modal\n // with a full list of names.\n if (overLimit) {\n const count = repliers.length - names.length;\n\n names.push(\n app.translator.transChoice('flarum-mentions.forum.post.others_text', count, {count})\n );\n }\n\n items.add('replies',\n
\n );\n }\n });\n}\n","import { extend } from 'flarum/extend';\nimport Button from 'flarum/components/Button';\nimport CommentPost from 'flarum/components/CommentPost';\n\nimport reply from './utils/reply';\n\nexport default function () {\n extend(CommentPost.prototype, 'actionItems', function (items) {\n\n const post = this.props.post;\n\n if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n items.add('reply',\n Button.component({\n className: 'Button Button--link',\n children: app.translator.trans('flarum-mentions.forum.post.reply_link'),\n onclick: () => reply(post)\n })\n );\n });\n}\n"],"sourceRoot":""}
\ No newline at end of file