');i.append(s),i.children().hover((function(){clearTimeout(n),n=setTimeout((function(){!s.hasClass("in")&&s.is(":visible")||(m.render(s[0],o.map((function(t){return m("li",{"data-number":t.number()},l.a.component({post:t,onclick:r}))}))),s.show(),setTimeout((function(){return s.off("transitionend").addClass("in")})))}),500)}),(function(){clearTimeout(n),n=setTimeout(r,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"+(s[0].user()===app.session.user?"_self":"")+"_text",u.length,{count:u.length,users:x()(u)}))))}})),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(),tt(),i.a.notificationComponents.postMentioned=ot,i.a.notificationComponents.userMentioned=rt,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:pt.component()},Object(o.extend)(st.a.prototype,"navItems",(function(t){var e=this.user;t.add("mentions",ut.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")})),n.d(e,"filterUserMentions",(function(){return dt})),n.d(e,"filterPostMentions",(function(){return mt}))}]);
//# 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 0f633f5e7..f1b5947fa 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['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/ComposerBody']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditor']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditorButton']\"","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","webpack://@flarum/mentions/./forum.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","_this","this","extract","className","icon","children","translator","trans","onclick","hide","onmousedown","e","stopPropagation","_Button","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","ComposerBody","mentionStart","typed","searchTimeout","dropdown","$textarea","wrap","searched","navigator","KeyboardNavigatable","when","onUp","onDown","onSelect","onCancel","bindTo","indexOf","which","cursor","selectionStart","selectionEnd","substr","toLowerCase","makeSuggestion","replacement","usernameHelper","highlight","insert","setValue","setSelectionRange","applySuggestion","onmouseenter","avatar","userMatches","displayName","some","buildSuggestions","suggestions","store","all","push","composerPost","posts","filter","contentType","sort","a","b","createdAt","splice","truncate","contentPlain","width","typedLower","q","page","limit","TextEditor","_this2","add","TextEditorButton_default","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","attrs","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","__webpack_exports__"],"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['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['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/ComposerBody'];","module.exports = flarum.core.compat['components/TextEditor'];","module.exports = flarum.core.compat['components/TextEditorButton'];","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 '![](' + 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","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 ComposerBody from 'flarum/components/ComposerBody';\nimport TextEditor from 'flarum/components/TextEditor';\nimport TextEditorButton from 'flarum/components/TextEditorButton';\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(ComposerBody.prototype, 'config', function(original, isInitialized) {\n if (isInitialized) return;\n\n const composer = this;\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 const applySuggestion = function(replacement) {\n const insert = replacement + ' ';\n\n // When calling setValue(), mentionStart will be set back to 0 so we need to compute this beforehand\n const index = mentionStart - 1 + insert.length;\n\n const content = composer.content();\n composer.editor.setValue(content.substring(0, mentionStart - 1) + insert + content.substr($textarea[0].selectionStart));\n\n composer.editor.setSelectionRange(index, index);\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 app.store.all('users').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 const composerPost = composer.props.post;\n const discussion = (composerPost && composerPost.discussion()) || composer.props.discussion;\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 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 if (typed) {\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(() => {\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 // If there is only one reply, and it's adjacent to this post, we don't\n // really need to show the list.\n if (replies.length === 1 && replies[0].number() === post.number() + 1) {\n return;\n }\n\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","/*\n * This file is part of Flarum.\n *\n * (c) Toby Zerner \n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nexport * from './src/forum';\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['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/ComposerBody']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditor']\"","webpack://@flarum/mentions/external \"flarum.core.compat['components/TextEditorButton']\"","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","webpack://@flarum/mentions/./forum.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","ComposerBody","mentionStart","typed","searchTimeout","dropdown","$textarea","wrap","searched","navigator","KeyboardNavigatable","when","onUp","onDown","onSelect","onCancel","bindTo","indexOf","which","cursor","selectionStart","selectionEnd","substr","toLowerCase","makeSuggestion","replacement","usernameHelper","highlight","insert","setValue","setSelectionRange","applySuggestion","onmouseenter","avatar","userMatches","displayName","some","buildSuggestions","suggestions","store","all","push","composerPost","posts","filter","contentType","sort","a","b","createdAt","splice","truncate","contentPlain","width","typedLower","q","page","limit","TextEditor","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","attrs","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 = 28);\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['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/ComposerBody'];","module.exports = flarum.core.compat['components/TextEditor'];","module.exports = flarum.core.compat['components/TextEditorButton'];","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 '![](' + 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","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 ComposerBody from 'flarum/components/ComposerBody';\nimport TextEditor from 'flarum/components/TextEditor';\nimport TextEditorButton from 'flarum/components/TextEditorButton';\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(ComposerBody.prototype, 'config', function(original, isInitialized) {\n if (isInitialized) return;\n\n const composer = this;\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 const applySuggestion = function(replacement) {\n const insert = replacement + ' ';\n\n // When calling setValue(), mentionStart will be set back to 0 so we need to compute this beforehand\n const index = mentionStart - 1 + insert.length;\n\n const content = composer.content();\n composer.editor.setValue(content.substring(0, mentionStart - 1) + insert + content.substr($textarea[0].selectionStart));\n\n composer.editor.setSelectionRange(index, index);\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 app.store.all('users').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 const composerPost = composer.props.post;\n const discussion = (composerPost && composerPost.discussion()) || composer.props.discussion;\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 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 if (typed) {\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(() => {\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 // If there is only one reply, and it's adjacent to this post, we don't\n // really need to show the list.\n if (replies.length === 1 && replies[0].number() === post.number() + 1) {\n return;\n }\n\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","/*\n * This file is part of Flarum.\n *\n * (c) Toby Zerner \n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nexport * from './src/forum';\n"],"sourceRoot":""}
\ No newline at end of file