');r.append(i),r.children().hover((function(){clearTimeout(e),e=setTimeout((function(){!i.hasClass("in")&&i.is(":visible")||(m.render(i[0],n.map((function(t){return m("li",{"data-number":t.number()},l.a.component({post:t,onclick:o}))}))),i.show(),setTimeout((function(){return i.off("transitionend").addClass("in")})))}),500)}),(function(){clearTimeout(e),e=setTimeout(o,250)})),r.find(".Post-mentionedBy-summary a").hover((function(){i.find('[data-number="'+$(this).data("number")+'"]').addClass("active")}),(function(){i.find("[data-number]").removeClass("active")}))}},m("span",{className:"Post-mentionedBy-summary"},j()("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:P()(a)}))))}})),Object(o.extend)(p.a.prototype,"actionItems",(function(t){var e=this.attrs.post;e.isHidden()||app.session.user&&!e.discussion().canReply()||t.add("reply",m(B.a,{className:"Button Button--link",onclick:function(){return W(e)}},app.translator.trans("flarum-mentions.forum.post.reply_link")))})),R(),it(),i.a.notificationComponents.postMentioned=ut,i.a.notificationComponents.userMentioned=ct,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:ht},Object(o.extend)(ft.a.prototype,"navItems",(function(t){var e=this.user;t.add("mentions",dt.a.component({href:i.a.route("user.mentions",{username:e.username()}),name:"mentions",icon:"fas fa-at"},i.a.translator.trans("flarum-mentions.forum.user.mentions_link")),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 787961f81..7566a8c2b 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['components/CommentPost']\"","webpack://@flarum/mentions/external \"flarum.core.compat['app']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/string']\"","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['helpers/icon']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/EditPostComposer']\"","webpack://@flarum/mentions/external \"flarum.core.compat['Fragment']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Notification']\"","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['components/Button']\"","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['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['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/fragments/PostQuoteButton.js","webpack://@flarum/mentions/./src/forum/addPostQuoteButton.js","webpack://@flarum/mentions/./src/forum/utils/selectedText.js","webpack://@flarum/mentions/./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack://@flarum/mentions/./node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://@flarum/mentions/./src/forum/fragments/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","composer","quote","user","mention","username","number","fields","content","attrs","originalContent","cursorPosition","editor","getSelectionRange","preceding","slice","precedingNewlines","length","match","insertAtCursor","Array","join","trim","reply","app","bodyMatches","EditPostComposer","discussion","DiscussionControls","replyAction","then","_inheritsLoose","subClass","superClass","constructor","__proto__","PostQuoteButton","view","class","onclick","icon","className","translator","trans","show","$this","this","$","parentOffset","offsetParent","offset","css","hideHandler","hide","on","showStart","scrollTop","outerHeight","showEnd","right","bottom","outerWidth","off","Fragment","addPostQuoteButton","extend","CommentPost","isHidden","session","canReply","$postBody","$container","button","handler","e","setTimeout","selection","getSelection","rangeCount","range","getRangeAt","parent","commonAncestorContainer","contains","clone","append","cloneContents","find","replaceWith","alt","src","innerText","href","text","selectedText","render","rects","getClientRects","firstRect","clientY","clientX","lastRect","after","addEventListener","_assertThisInitialized","self","ReferenceError","_defineProperty","obj","configurable","writable","AutocompleteDropdown","items","map","item","active","navigate","delta","keyWasJustPressed","setIndex","index","clearTimeout","keyWasJustPressedTimeout","complete","eq","click","scrollToItem","$dropdown","$items","rangedIndex","$item","removeClass","addClass","dropdownScroll","dropdownTop","dropdownBottom","itemTop","itemBottom","stop","animate","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","children","highlight","replaceBeforeCursor","applySuggestion","onmouseenter","avatar","userMatches","displayName","some","buildSuggestions","suggestions","push","ReplyComposer","composerAttrs","composerPost","posts","filter","contentType","sort","a","b","createdAt","splice","truncate","contentPlain","width","typedLower","q","page","limit","results","has","add","props","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","addPreviews","contentHtml","oldPostContentHtml","isEditing","parentPost","$parentPost","set","preventDefault","each","timeout","data","$preview","getPostElement","showPreview","$post","visible","pageYOffset","positionPreview","previewHeight","showPost","title","PostPreview","component","LoadingIndicator","hidePreview","hasClass","one","hover","stopPropagation","addPostMentionPreviews","Post","mentionedBy","Model","hasMany","replies","users","repliers","overLimit","names","data-number","count","oncreate","vnode","dom","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 = 28);\n","module.exports = flarum.core.compat['extend'];","module.exports = flarum.core.compat['components/CommentPost'];","module.exports = flarum.core.compat['app'];","module.exports = flarum.core.compat['utils/string'];","module.exports = flarum.core.compat['helpers/username'];","module.exports = flarum.core.compat['components/PostPreview'];","module.exports = flarum.core.compat['helpers/icon'];","module.exports = flarum.core.compat['components/EditPostComposer'];","module.exports = flarum.core.compat['Fragment'];","module.exports = flarum.core.compat['components/Notification'];","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['components/Button'];","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['helpers/avatar'];","module.exports = flarum.core.compat['helpers/highlight'];","module.exports = flarum.core.compat['utils/KeyboardNavigatable'];","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';\nimport EditPostComposer from 'flarum/components/EditPostComposer';\n\nfunction insertMention(post, composer, 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 (!composer.fields.content()) {\n composer.body.attrs.originalContent = mention;\n }\n\n const cursorPosition = composer.editor.getSelectionRange()[0];\n const preceding = composer.fields.content().slice(0, cursorPosition);\n const precedingNewlines = preceding.length == 0 ? 0 : 3 - preceding.match(/(\\n{0,2})$/)[0].length;\n\n composer.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 if (app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {\n // If we're already editing a post in the discussion of post we're quoting,\n // insert the mention directly.\n insertMention(post, app.composer, quote);\n } else {\n // The default \"Reply\" action behavior will only open a new composer if\n // necessary, but it will always be a ReplyComposer, hence the exceptional\n // case above.\n DiscussionControls.replyAction.call(post.discussion())\n .then(composer => insertMention(post, composer, 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 Fragment from 'flarum/Fragment';\nimport icon from 'flarum/helpers/icon';\n\nimport reply from '../utils/reply';\n\nexport default class PostQuoteButton extends Fragment {\n constructor(post) {\n super();\n\n this.post = post;\n }\n\n view() {\n return (\n \n );\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 this.hideHandler = this.hide.bind(this);\n $(document).on('mouseup', this.hideHandler);\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 $(document).off('mouseup', this.hideHandler);\n }\n}\n","import { extend } from 'flarum/extend';\nimport CommentPost from 'flarum/components/CommentPost';\n\nimport PostQuoteButton from './fragments/PostQuoteButton';\nimport selectedText from './utils/selectedText';\n\nexport default function addPostQuoteButton() {\n extend(CommentPost.prototype, 'oncreate', function() {\n const post = this.attrs.post;\n\n if (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 button = new PostQuoteButton(post);\n\n const handler = function(e) {\n setTimeout(() => {\n const content = selectedText($postBody);\n if (content) {\n button.content = 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 '![](' + this.src + ')';\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","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import Fragment from 'flarum/Fragment';\n\nexport default class AutocompleteDropdown extends Fragment {\n items = [];\n active = false;\n index = 0;\n keyWasJustPressed = false;\n\n view() {\n return (\n
\n {this.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 './fragments/AutocompleteDropdown';\n\nexport default function addComposerAutocomplete() {\n extend(TextEditor.prototype, 'oncreate', function () {\n const $container = $('');\n const dropdown = new AutocompleteDropdown();\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 = [highlight(username.text, typed)];\n delete username.text;\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.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.attrs.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.attrs.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.attrs.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.attrs.notification.subject();\n\n return app.route.discussion(post.discussion(), post.number());\n }\n\n content() {\n const user = this.attrs.notification.fromUser();\n\n return app.translator.trans('flarum-mentions.forum.notifications.user_mentioned_text', {user});\n }\n\n excerpt() {\n return truncate(this.attrs.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};\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 icon: 'fas fa-at'\n }, app.translator.trans('flarum-mentions.forum.user.mentions_link')),\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 function addPreviews() {\n const contentHtml = this.attrs.post.contentHtml();\n\n if (contentHtml === this.oldPostContentHtml || this.isEditing()) return;\n\n this.oldPostContentHtml = contentHtml;\n\n const parentPost = this.attrs.post;\n const $parentPost = this.$();\n\n this.$().on('click', '.UserMention, .PostMention', function (e) {\n m.route.set(this.getAttribute('href'));\n e.preventDefault();\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 extend(CommentPost.prototype, 'oncreate', addPreviews);\n extend(CommentPost.prototype, 'onupdate', addPreviews);\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.attrs.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 oncreate = function(vnode) {\n const $this = $(vnode.dom);\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.attrs.post;\n\n if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n items.add('reply',\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['components/CommentPost']\"","webpack://@flarum/mentions/external \"flarum.core.compat['app']\"","webpack://@flarum/mentions/external \"flarum.core.compat['utils/string']\"","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['helpers/icon']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/EditPostComposer']\"","webpack://@flarum/mentions/external \"flarum.core.compat['Fragment']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Notification']\"","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['components/Link']\"","webpack://@flarum/mentions/external \"flarum.core.compat['helpers/punctuateSeries']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/Button']\"","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['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['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/fragments/PostQuoteButton.js","webpack://@flarum/mentions/./src/forum/addPostQuoteButton.js","webpack://@flarum/mentions/./src/forum/utils/selectedText.js","webpack://@flarum/mentions/./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack://@flarum/mentions/./node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://@flarum/mentions/./src/forum/fragments/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","composer","quote","user","mention","username","number","fields","content","attrs","originalContent","cursorPosition","editor","getSelectionRange","preceding","slice","precedingNewlines","length","match","insertAtCursor","Array","join","trim","reply","app","bodyMatches","EditPostComposer","discussion","DiscussionControls","replyAction","then","_inheritsLoose","subClass","superClass","constructor","__proto__","PostQuoteButton","view","class","onclick","icon","className","translator","trans","show","$this","this","$","parentOffset","offsetParent","offset","css","hideHandler","hide","on","showStart","scrollTop","outerHeight","showEnd","right","bottom","outerWidth","off","Fragment","addPostQuoteButton","extend","CommentPost","isHidden","session","canReply","$postBody","$container","button","handler","e","setTimeout","selection","getSelection","rangeCount","range","getRangeAt","parent","commonAncestorContainer","contains","clone","append","cloneContents","find","replaceWith","alt","src","innerText","href","text","selectedText","render","rects","getClientRects","firstRect","clientY","clientX","lastRect","after","addEventListener","_assertThisInitialized","self","ReferenceError","_defineProperty","obj","configurable","writable","AutocompleteDropdown","items","map","item","active","navigate","delta","keyWasJustPressed","setIndex","index","clearTimeout","keyWasJustPressedTimeout","complete","eq","click","scrollToItem","$dropdown","$items","rangedIndex","$item","removeClass","addClass","dropdownScroll","dropdownTop","dropdownBottom","itemTop","itemBottom","stop","animate","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","children","highlight","replaceBeforeCursor","applySuggestion","onmouseenter","avatar","userMatches","displayName","some","buildSuggestions","suggestions","push","ReplyComposer","composerAttrs","composerPost","posts","filter","contentType","sort","a","b","createdAt","splice","truncate","contentPlain","width","typedLower","q","page","limit","results","has","add","props","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","addPreviews","contentHtml","oldPostContentHtml","isEditing","parentPost","$parentPost","set","preventDefault","each","timeout","data","$preview","getPostElement","showPreview","$post","visible","pageYOffset","positionPreview","previewHeight","showPost","title","PostPreview","component","LoadingIndicator","hidePreview","hasClass","one","hover","stopPropagation","addPostMentionPreviews","Post","mentionedBy","Model","hasMany","replies","users","repliers","overLimit","names","data-number","count","oncreate","vnode","dom","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['components/CommentPost'];","module.exports = flarum.core.compat['app'];","module.exports = flarum.core.compat['utils/string'];","module.exports = flarum.core.compat['helpers/username'];","module.exports = flarum.core.compat['components/PostPreview'];","module.exports = flarum.core.compat['helpers/icon'];","module.exports = flarum.core.compat['components/EditPostComposer'];","module.exports = flarum.core.compat['Fragment'];","module.exports = flarum.core.compat['components/Notification'];","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['components/Link'];","module.exports = flarum.core.compat['helpers/punctuateSeries'];","module.exports = flarum.core.compat['components/Button'];","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['helpers/avatar'];","module.exports = flarum.core.compat['helpers/highlight'];","module.exports = flarum.core.compat['utils/KeyboardNavigatable'];","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';\nimport EditPostComposer from 'flarum/components/EditPostComposer';\n\nfunction insertMention(post, composer, 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 (!composer.fields.content()) {\n composer.body.attrs.originalContent = mention;\n }\n\n const cursorPosition = composer.editor.getSelectionRange()[0];\n const preceding = composer.fields.content().slice(0, cursorPosition);\n const precedingNewlines = preceding.length == 0 ? 0 : 3 - preceding.match(/(\\n{0,2})$/)[0].length;\n\n composer.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 if (app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {\n // If we're already editing a post in the discussion of post we're quoting,\n // insert the mention directly.\n insertMention(post, app.composer, quote);\n } else {\n // The default \"Reply\" action behavior will only open a new composer if\n // necessary, but it will always be a ReplyComposer, hence the exceptional\n // case above.\n DiscussionControls.replyAction.call(post.discussion())\n .then(composer => insertMention(post, composer, 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 Fragment from 'flarum/Fragment';\nimport icon from 'flarum/helpers/icon';\n\nimport reply from '../utils/reply';\n\nexport default class PostQuoteButton extends Fragment {\n constructor(post) {\n super();\n\n this.post = post;\n }\n\n view() {\n return (\n \n );\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 this.hideHandler = this.hide.bind(this);\n $(document).on('mouseup', this.hideHandler);\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 $(document).off('mouseup', this.hideHandler);\n }\n}\n","import { extend } from 'flarum/extend';\nimport CommentPost from 'flarum/components/CommentPost';\n\nimport PostQuoteButton from './fragments/PostQuoteButton';\nimport selectedText from './utils/selectedText';\n\nexport default function addPostQuoteButton() {\n extend(CommentPost.prototype, 'oncreate', function() {\n const post = this.attrs.post;\n\n if (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 button = new PostQuoteButton(post);\n\n const handler = function(e) {\n setTimeout(() => {\n const content = selectedText($postBody);\n if (content) {\n button.content = 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 '![](' + this.src + ')';\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","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import Fragment from 'flarum/Fragment';\n\nexport default class AutocompleteDropdown extends Fragment {\n items = [];\n active = false;\n index = 0;\n keyWasJustPressed = false;\n\n view() {\n return (\n
\n {this.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 './fragments/AutocompleteDropdown';\n\nexport default function addComposerAutocomplete() {\n extend(TextEditor.prototype, 'oncreate', function () {\n const $container = $('');\n const dropdown = new AutocompleteDropdown();\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 = [highlight(username.text, typed)];\n delete username.text;\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.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.attrs.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.attrs.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.attrs.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.attrs.notification.subject();\n\n return app.route.discussion(post.discussion(), post.number());\n }\n\n content() {\n const user = this.attrs.notification.fromUser();\n\n return app.translator.trans('flarum-mentions.forum.notifications.user_mentioned_text', {user});\n }\n\n excerpt() {\n return truncate(this.attrs.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};\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 icon: 'fas fa-at'\n }, app.translator.trans('flarum-mentions.forum.user.mentions_link')),\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 function addPreviews() {\n const contentHtml = this.attrs.post.contentHtml();\n\n if (contentHtml === this.oldPostContentHtml || this.isEditing()) return;\n\n this.oldPostContentHtml = contentHtml;\n\n const parentPost = this.attrs.post;\n const $parentPost = this.$();\n\n this.$().on('click', '.UserMention, .PostMention', function (e) {\n m.route.set(this.getAttribute('href'));\n e.preventDefault();\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 extend(CommentPost.prototype, 'oncreate', addPreviews);\n extend(CommentPost.prototype, 'onupdate', addPreviews);\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 Link from 'flarum/components/Link';\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.attrs.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 oncreate = function(vnode) {\n const $this = $(vnode.dom);\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.attrs.post;\n\n if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n items.add('reply',\n \n );\n });\n}\n"],"sourceRoot":""}
\ No newline at end of file