{"version":3,"file":"useMessageFormatter-CoQTTzFX.js","sources":["../../../node_modules/.pnpm/markdown-it-link-attributes@4.0.1/node_modules/markdown-it-link-attributes/index.js","../../../app/javascript/shared/helpers/markdownIt/link.js","../../../app/javascript/shared/helpers/MessageFormatter.js","../../../app/javascript/shared/composables/useMessageFormatter.js"],"sourcesContent":["\"use strict\";\n\n// Adapted from https://github.com/markdown-it/markdown-it/blob/fbc6b0fed563ba7c00557ab638fd19752f8e759d/docs/architecture.md\n\nfunction findFirstMatchingConfig(link, configs) {\n var i, config;\n var href = link.attrs[link.attrIndex(\"href\")][1];\n\n for (i = 0; i < configs.length; ++i) {\n config = configs[i];\n\n // If there is a matcher function defined then call it\n // Matcher Function should return a boolean indicating\n // whether or not it matched. If it matched, use that\n // configuration, otherwise, try the next one.\n if (typeof config.matcher === \"function\") {\n if (config.matcher(href, config)) {\n return config;\n } else {\n continue;\n }\n }\n\n return config;\n }\n}\n\nfunction applyAttributes(idx, tokens, attributes) {\n Object.keys(attributes).forEach(function (attr) {\n var attrIndex;\n var value = attributes[attr];\n\n if (attr === \"className\") {\n // when dealing with applying classes\n // programatically, some programmers\n // may prefer to use the className syntax\n attr = \"class\";\n }\n\n attrIndex = tokens[idx].attrIndex(attr);\n\n if (attrIndex < 0) {\n // attr doesn't exist, add new attribute\n tokens[idx].attrPush([attr, value]);\n } else {\n // attr already exists, overwrite it\n tokens[idx].attrs[attrIndex][1] = value; // replace value of existing attr\n }\n });\n}\n\nfunction markdownitLinkAttributes(md, configs) {\n if (!configs) {\n configs = [];\n } else {\n configs = Array.isArray(configs) ? configs : [configs];\n }\n\n Object.freeze(configs);\n\n var defaultRender = md.renderer.rules.link_open || this.defaultRender;\n\n md.renderer.rules.link_open = function (tokens, idx, options, env, self) {\n var config = findFirstMatchingConfig(tokens[idx], configs);\n var attributes = config && config.attrs;\n\n if (attributes) {\n applyAttributes(idx, tokens, attributes);\n }\n\n // pass token to default renderer.\n return defaultRender(tokens, idx, options, env, self);\n };\n}\n\nmarkdownitLinkAttributes.defaultRender = function (\n tokens,\n idx,\n options,\n env,\n self\n) {\n return self.renderToken(tokens, idx, options);\n};\n\nmodule.exports = markdownitLinkAttributes;\n","// Process [@mention](mention://user/1/Pranav)\nconst USER_MENTIONS_REGEX = /mention:\\/\\/(user|team)\\/(\\d+)\\/(.+)/gm;\n\nconst buildMentionTokens = () => (state, silent) => {\n var label;\n var labelEnd;\n var labelStart;\n var pos;\n var res;\n var token;\n var href = '';\n var max = state.posMax;\n\n if (state.src.charCodeAt(state.pos) !== 0x5b /* [ */) {\n return false;\n }\n\n labelStart = state.pos + 1;\n labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true);\n\n // parser failed to find ']', so it's not a valid link\n if (labelEnd < 0) {\n return false;\n }\n\n label = state.src.slice(labelStart, labelEnd);\n pos = labelEnd + 1;\n\n if (pos < max && state.src.charCodeAt(pos) === 0x28 /* ( */) {\n pos += 1;\n res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);\n if (res.ok) {\n href = state.md.normalizeLink(res.str);\n if (state.md.validateLink(href)) {\n pos = res.pos;\n } else {\n href = '';\n }\n }\n pos += 1;\n }\n\n if (!href.match(new RegExp(USER_MENTIONS_REGEX))) {\n return false;\n }\n\n if (!silent) {\n state.pos = labelStart;\n state.posMax = labelEnd;\n\n token = state.push('mention', '');\n token.href = href;\n token.content = label;\n }\n\n state.pos = pos;\n state.posMax = max;\n\n return true;\n};\n\nconst renderMentions = () => (tokens, idx) => {\n return `${tokens[idx].content}`;\n};\n\nexport default function mentionPlugin(md) {\n md.renderer.rules.mention = renderMentions(md);\n md.inline.ruler.before('link', 'mention', buildMentionTokens(md));\n}\n","import mila from 'markdown-it-link-attributes';\nimport mentionPlugin from './markdownIt/link';\nimport MarkdownIt from 'markdown-it';\nconst setImageHeight = inlineToken => {\n const imgSrc = inlineToken.attrGet('src');\n if (!imgSrc) return;\n const url = new URL(imgSrc);\n const height = url.searchParams.get('cw_image_height');\n if (!height) return;\n inlineToken.attrSet('style', `height: ${height};`);\n};\n\nconst processInlineToken = blockToken => {\n blockToken.children.forEach(inlineToken => {\n if (inlineToken.type === 'image') {\n setImageHeight(inlineToken);\n }\n });\n};\n\nconst imgResizeManager = md => {\n // Custom rule for image resize in markdown\n // If the image url has a query param cw_image_height, then add a style attribute to the image\n md.core.ruler.after('inline', 'add-image-height', state => {\n state.tokens.forEach(blockToken => {\n if (blockToken.type === 'inline') {\n processInlineToken(blockToken);\n }\n });\n });\n};\n\nconst md = MarkdownIt({\n html: false,\n xhtmlOut: true,\n breaks: true,\n langPrefix: 'language-',\n linkify: true,\n typographer: true,\n quotes: '\\u201c\\u201d\\u2018\\u2019',\n maxNesting: 20,\n})\n .use(mentionPlugin)\n .use(imgResizeManager)\n .use(mila, {\n attrs: {\n class: 'link',\n rel: 'noreferrer noopener nofollow',\n target: '_blank',\n },\n });\n\nconst TWITTER_USERNAME_REGEX = /(^|[^@\\w])@(\\w{1,15})\\b/g;\nconst TWITTER_USERNAME_REPLACEMENT = '$1[@$2](http://twitter.com/$2)';\nconst TWITTER_HASH_REGEX = /(^|\\s)#(\\w+)/g;\nconst TWITTER_HASH_REPLACEMENT = '$1[#$2](https://twitter.com/hashtag/$2)';\n\nclass MessageFormatter {\n constructor(message, isATweet = false, isAPrivateNote = false) {\n this.message = message || '';\n this.isAPrivateNote = isAPrivateNote;\n this.isATweet = isATweet;\n }\n\n formatMessage() {\n let updatedMessage = this.message;\n if (this.isATweet && !this.isAPrivateNote) {\n updatedMessage = updatedMessage.replace(\n TWITTER_USERNAME_REGEX,\n TWITTER_USERNAME_REPLACEMENT\n );\n updatedMessage = updatedMessage.replace(\n TWITTER_HASH_REGEX,\n TWITTER_HASH_REPLACEMENT\n );\n }\n return md.render(updatedMessage);\n }\n\n get formattedMessage() {\n return this.formatMessage();\n }\n\n get plainText() {\n const strippedOutHtml = new DOMParser().parseFromString(\n this.formattedMessage,\n 'text/html'\n );\n return strippedOutHtml.body.textContent || '';\n }\n}\n\nexport default MessageFormatter;\n","import MessageFormatter from '../helpers/MessageFormatter';\n\n/**\n * A composable providing utility functions for message formatting.\n *\n * @returns {Object} A set of functions for message formatting.\n */\nexport const useMessageFormatter = () => {\n /**\n * Formats a message based on specified conditions.\n *\n * @param {string} message - The message to be formatted.\n * @param {boolean} isATweet - Whether the message is a tweet.\n * @param {boolean} isAPrivateNote - Whether the message is a private note.\n * @returns {string} - The formatted message.\n */\n const formatMessage = (message, isATweet, isAPrivateNote) => {\n const messageFormatter = new MessageFormatter(\n message,\n isATweet,\n isAPrivateNote\n );\n return messageFormatter.formattedMessage;\n };\n\n /**\n * Converts a message to plain text.\n *\n * @param {string} message - The message to be converted.\n * @param {boolean} isATweet - Whether the message is a tweet.\n * @returns {string} - The plain text message.\n */\n const getPlainText = (message, isATweet) => {\n const messageFormatter = new MessageFormatter(message, isATweet);\n return messageFormatter.plainText;\n };\n\n /**\n * Truncates a description to a maximum length of 100 characters.\n *\n * @param {string} [description=''] - The description to be truncated.\n * @returns {string} - The truncated description.\n */\n const truncateMessage = (description = '') => {\n if (description.length < 100) {\n return description;\n }\n\n return `${description.slice(0, 97)}...`;\n };\n\n /**\n * Highlights occurrences of a search term within given content.\n *\n * @param {string} [content=''] - The content in which to search.\n * @param {string} [searchTerm=''] - The term to search for.\n * @param {string} [highlightClass=''] - The CSS class to apply to the highlighted term.\n * @returns {string} - The content with highlighted terms.\n */\n const highlightContent = (\n content = '',\n searchTerm = '',\n highlightClass = ''\n ) => {\n const plainTextContent = getPlainText(content);\n\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping\n const escapedSearchTerm = searchTerm.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n return plainTextContent.replace(\n new RegExp(`(${escapedSearchTerm})`, 'ig'),\n `$1`\n );\n };\n\n return {\n formatMessage,\n getPlainText,\n truncateMessage,\n highlightContent,\n };\n};\n"],"names":["findFirstMatchingConfig","link","configs","i","config","href","applyAttributes","idx","tokens","attributes","attr","attrIndex","value","markdownitLinkAttributes","md","defaultRender","options","env","self","markdownItLinkAttributes","USER_MENTIONS_REGEX","buildMentionTokens","state","silent","label","labelEnd","labelStart","pos","res","token","max","renderMentions","mentionPlugin","setImageHeight","inlineToken","imgSrc","height","processInlineToken","blockToken","imgResizeManager","MarkdownIt","mila","TWITTER_USERNAME_REGEX","TWITTER_USERNAME_REPLACEMENT","TWITTER_HASH_REGEX","TWITTER_HASH_REPLACEMENT","MessageFormatter","message","isATweet","isAPrivateNote","updatedMessage","useMessageFormatter","formatMessage","getPlainText","description","content","searchTerm","highlightClass","plainTextContent","escapedSearchTerm"],"mappings":"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","x_google_ignoreList":[0]}