From 99941575e7be16bf8a76f7f60171830767b5613c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hasan=20=C3=96zbey?= Date: Wed, 30 Jun 2021 00:59:20 +0300 Subject: [PATCH] 0.3.7 release possibly fixes https://discuss.flarum.org/d/22439-mathren-tex-math-rendering/81 --- CHANGELOG.md | 3 +++ extend.php | 2 +- js/dist/forum.js | 2 +- js/dist/forum.js.map | 2 +- js/package.json | 2 +- js/src/forum/index.js | 2 +- 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe6a5e7..d71ed57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 0.3.7 +- Use `['oncreate', 'onupdate']` lifecycle hooks for `CommentPost` component instead of `onupdate` only. + ### 0.3.6 - **Fix** wrong KaTeX css version. diff --git a/extend.php b/extend.php index bf4e52e..ccf7fba 100644 --- a/extend.php +++ b/extend.php @@ -11,7 +11,7 @@ * @author Hasan Ă–zbey * @copyright 2020 * @license The MIT License - * @version Release: 0.3.5 + * @version Release: 0.3.7 * @link https://github.com/the-turk/flarum-mathren */ diff --git a/js/dist/forum.js b/js/dist/forum.js index 8b0a543..6ef68c8 100644 --- a/js/dist/forum.js +++ b/js/dist/forum.js @@ -1,2 +1,2 @@ -module.exports=function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=20)}([function(t,e){t.exports=flarum.core.compat["common/app"]},function(t,e){t.exports=flarum.core.compat["common/extend"]},function(t,e,n){"use strict";function o(t,e){return(o=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function r(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,o(t,e)}n.d(e,"a",(function(){return r}))},,function(t,e){t.exports=flarum.core.compat["common/components/Button"]},function(t,e){t.exports=flarum.core.compat["components/CommentPost"]},function(t,e){t.exports=flarum.core.compat["common/helpers/icon"]},,function(t,e){t.exports=flarum.core.compat["components/TextEditor"]},function(t,e){t.exports=flarum.core.compat["common/Component"]},function(t,e){t.exports=flarum.core.compat["common/components/Dropdown"]},function(t,e){t.exports=flarum.core.compat["common/utils/ItemList"]},function(t,e){t.exports=flarum.core.compat.Fragment},function(t,e){t.exports=flarum.core.compat["utils/DiscussionControls"]},function(t,e){t.exports=flarum.core.compat["components/EditPostComposer"]},function(t,e){t.exports=flarum.core.compat["components/DiscussionPage"]},,,,,function(t,e,n){"use strict";n.r(e);var o=n(1),r=n(0),i=n.n(r),a=n(5),c=n.n(a),s=n(8),u=n.n(s),l=n(2),p=n(9),f=n.n(p),d=n(10),h=n.n(d),v=n(4),b=n.n(v),x=n(11),g=n.n(x),y=n(6),w=n.n(y),k=function(t){function e(){return t.apply(this,arguments)||this}Object(l.a)(e,t);var n=e.prototype;return n.oninit=function(e){t.prototype.oninit.call(this,e),this.delimiters={inline:i.a.forum.attribute("mathRenMainInlineDelimiter"),block:i.a.forum.attribute("mathRenMainBlockDelimiter")}},n.oncreate=function(e){t.prototype.oncreate.call(this,e)},n.view=function(){return h.a.component({className:"MathRenDropdown",buttonClassName:"Button Button--flat",label:w()("fas fa-square-root-alt")},this.items().toArray())},n.items=function(){var t=this,e=new g.a;return e.add("mathBlock",b.a.component({icon:"fas fa-vector-square",onclick:function(){var e=t.delimiters.block.left,n=t.delimiters.block.right;t.wrapSelection(e,n)}},i.a.translator.trans("the-turk-mathren.forum.textEditor.blockExpression")),50),e.add("mathInline",b.a.component({icon:"fas fa-grip-lines",onclick:function(){var e=t.delimiters.inline.left,n=t.delimiters.inline.right;t.wrapSelection(e,n)}},i.a.translator.trans("the-turk-mathren.forum.textEditor.inlineExpression")),0),e},n.wrapSelection=function(t,e){var n=this.attrs.textEditor.getSelectionRange();n[0]!=n[1]?(this.attrs.textEditor.insertAt(n[0],t),this.attrs.textEditor.insertAt(n[1]+t.length,e)):(this.attrs.textEditor.replaceBeforeCursor(n[0],t+e),this.attrs.textEditor.moveCursorTo(n[0]+t.length))},e}(f.a);var j=n(12),S=n.n(j),C=n(13),E=n.n(C),R=n(14),M=n.n(R);function T(t,e,n){var o=t.user(),r='@"'+(o&&function(t){return t.displayName().replace(/"#[a-z]{0,3}[0-9]+/,"_")}(o)||app.translator.trans("core.lib.username.deleted_text"))+'"#p'+t.id()+" ";e.fields.content()||(e.body.attrs.originalContent=r);var i=e.editor.getSelectionRange()[0],a=e.fields.content().slice(0,i),c=0==a.length?0:3-a.match(/(\n{0,2})$/)[0].length;e.editor.insertAtCursor(Array(c).join("\n")+(n?"> "+r+n.trim().replace(/\n/g,"\n> ")+"\n\n":r),!1)}var O=function(t){function e(e){var n;return(n=t.call(this)||this).post=e,n}Object(l.a)(e,t);var n=e.prototype;return n.view=function(){var t=this;return m("button",{class:"Button PostQuoteButton",onclick:function(){var e,n;e=t.post,n=t.content,app.composer.bodyMatches(M.a)&&app.composer.body.attrs.post.discussion()===e.discussion()?T(e,app.composer,n):E.a.replyAction.call(e.discussion()).then((function(t){return T(e,t,n)}))}},w()("fas fa-quote-left",{className:"Button-icon"}),app.translator.trans("flarum-mentions.forum.post.quote_button"))},n.show=function(t,e){var n=this.$().show(),o=n.offsetParent().offset();n.css("left",t-o.left).css("top",e-o.top),this.hideHandler=this.hide.bind(this),$(document).on("mouseup",this.hideHandler)},n.showStart=function(t,e){var n=this.$();this.show(t,$(window).scrollTop()+e-n.outerHeight()-5)},n.showEnd=function(t,e){var n=this.$();this.show(t-n.outerWidth(),$(window).scrollTop()+e+5)},n.hide=function(){this.$().hide(),$(document).off("mouseup",this.hideHandler)},e}(S.a),A=function(t,e){for(var n=t.querySelectorAll(".katex-mathml + .katex-html"),o=0;o'),r=new O(t),i=function(t){setTimeout((function(){var i=function(t,e){var n=window.getSelection();if(n.rangeCount){var o=n.getRangeAt(0).commonAncestorContainer;if(t[0]===o||$.contains(t[0],o)){var r=n.getRangeAt(0).cloneContents();r.querySelector(".katex-mathml")&&(r=A(r,e));var i=$("
").append(r);return i.find("img.emoji").replaceWith((function(){return this.alt})),i.find("img").replaceWith((function(){return"![]("+this.src+")"})),i.find("a").replaceWith((function(){return"["+this.innerText+"]("+this.href+")"})),i.text()}}return""}(n,D(e));if(i){r.content=i,m.render(o[0],r.render());var a=window.getSelection().getRangeAt(0).getClientRects(),c=a[0];if(t.clientY "+r+n.trim().replace(/\n/g,"\n> ")+"\n\n":r),!1)}var O=function(t){function e(e){var n;return(n=t.call(this)||this).post=e,n}Object(l.a)(e,t);var n=e.prototype;return n.view=function(){var t=this;return m("button",{class:"Button PostQuoteButton",onclick:function(){var e,n;e=t.post,n=t.content,app.composer.bodyMatches(M.a)&&app.composer.body.attrs.post.discussion()===e.discussion()?T(e,app.composer,n):E.a.replyAction.call(e.discussion()).then((function(t){return T(e,t,n)}))}},w()("fas fa-quote-left",{className:"Button-icon"}),app.translator.trans("flarum-mentions.forum.post.quote_button"))},n.show=function(t,e){var n=this.$().show(),o=n.offsetParent().offset();n.css("left",t-o.left).css("top",e-o.top),this.hideHandler=this.hide.bind(this),$(document).on("mouseup",this.hideHandler)},n.showStart=function(t,e){var n=this.$();this.show(t,$(window).scrollTop()+e-n.outerHeight()-5)},n.showEnd=function(t,e){var n=this.$();this.show(t-n.outerWidth(),$(window).scrollTop()+e+5)},n.hide=function(){this.$().hide(),$(document).off("mouseup",this.hideHandler)},e}(S.a),A=function(t,e){for(var n=t.querySelectorAll(".katex-mathml + .katex-html"),o=0;o
'),r=new O(t),i=function(t){setTimeout((function(){var i=function(t,e){var n=window.getSelection();if(n.rangeCount){var o=n.getRangeAt(0).commonAncestorContainer;if(t[0]===o||$.contains(t[0],o)){var r=n.getRangeAt(0).cloneContents();r.querySelector(".katex-mathml")&&(r=A(r,e));var i=$("
").append(r);return i.find("img.emoji").replaceWith((function(){return this.alt})),i.find("img").replaceWith((function(){return"![]("+this.src+")"})),i.find("a").replaceWith((function(){return"["+this.innerText+"]("+this.href+")"})),i.text()}}return""}(n,D(e));if(i){r.content=i,m.render(o[0],r.render());var a=window.getSelection().getRangeAt(0).getClientRects(),c=a[0];if(t.clientY {\n // opening tag (left delimiter)\n const leftDelim = this.delimiters.block['left'];\n // closing tag (right delimiter)\n const rightDelim = this.delimiters.block['right'];\n\n this.wrapSelection(leftDelim, rightDelim);\n },\n },\n app.translator.trans(localePrefix + 'blockExpression')\n ),\n 50\n );\n\n items.add(\n 'mathInline',\n Button.component(\n {\n icon: 'fas fa-grip-lines',\n onclick: () => {\n // opening tag (left delimiter)\n const leftDelim = this.delimiters.inline['left'];\n // closing tag (right delimiter)\n const rightDelim = this.delimiters.inline['right'];\n\n this.wrapSelection(leftDelim, rightDelim);\n },\n },\n app.translator.trans(localePrefix + 'inlineExpression')\n ),\n 0\n );\n\n return items;\n }\n\n /**\n * Wrap the current selection with BBCode tags\n * If there's no selection, put them around the cursor\n *\n * @param string leftDelim\n * @param string rightDelim\n */\n wrapSelection(leftDelim, rightDelim) {\n const selectionRange = this.attrs.textEditor.getSelectionRange();\n\n if (selectionRange[0] != selectionRange[1]) {\n this.attrs.textEditor.insertAt(selectionRange[0], leftDelim);\n this.attrs.textEditor.insertAt(selectionRange[1] + leftDelim.length, rightDelim);\n } else {\n this.attrs.textEditor.replaceBeforeCursor(selectionRange[0], leftDelim + rightDelim);\n this.attrs.textEditor.moveCursorTo(selectionRange[0] + leftDelim.length);\n }\n }\n}\n","/**\n * Copied from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/utils/reply.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport DiscussionControls from 'flarum/utils/DiscussionControls';\nimport EditPostComposer from 'flarum/components/EditPostComposer';\nimport cleanDisplayName from './cleanDisplayName';\n\nfunction insertMention(post, composer, quote) {\n const user = post.user();\n const mention = `@\"${(user && cleanDisplayName(user)) || app.translator.trans('core.lib.username.deleted_text')}\"#p${post.id()} `;\n\n // If the composer is empty, then assume we're starting a new reply.\n // In which case we don't want the user to have to confirm if they\n // close the composer straight away.\n if (!composer.fields.content()) {\n composer.body.attrs.originalContent = mention;\n }\n\n const cursorPosition = composer.editor.getSelectionRange()[0];\n const preceding = composer.fields.content().slice(0, cursorPosition);\n const precedingNewlines = preceding.length == 0 ? 0 : 3 - preceding.match(/(\\n{0,2})$/)[0].length;\n\n composer.editor.insertAtCursor(\n Array(precedingNewlines).join('\\n') + // Insert up to two newlines, depending on preceding whitespace\n (quote ? '> ' + mention + quote.trim().replace(/\\n/g, '\\n> ') + '\\n\\n' : mention),\n false\n );\n}\n\nexport default function reply(post, quote) {\n if (app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {\n // If we're already editing a post in the discussion of post we're quoting,\n // insert the mention directly.\n insertMention(post, app.composer, quote);\n } else {\n // The default \"Reply\" action behavior will only open a new composer if\n // necessary, but it will always be a ReplyComposer, hence the exceptional\n // case above.\n DiscussionControls.replyAction.call(post.discussion()).then((composer) => insertMention(post, composer, quote));\n }\n}\n","/**\n * Copied from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/utils/cleanDisplayName.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nexport default function cleanDisplayName(user) {\n return user.displayName().replace(/\"#[a-z]{0,3}[0-9]+/, '_');\n}\n","/**\n * Copied & modified from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/fragments/PostQuoteButton.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport Fragment from 'flarum/Fragment';\nimport icon from 'flarum/common/helpers/icon';\n\nimport reply from '../utils/reply';\n\nexport default class PostQuoteButton extends Fragment {\n constructor(post) {\n super();\n\n this.post = post;\n }\n\n view() {\n return (\n {\n reply(this.post, this.content);\n }}\n >\n {icon('fas fa-quote-left', { className: 'Button-icon' })}\n {app.translator.trans('flarum-mentions.forum.post.quote_button')}\n \n );\n }\n\n show(left, top) {\n const $this = this.$().show();\n const parentOffset = $this.offsetParent().offset();\n\n $this.css('left', left - parentOffset.left).css('top', top - parentOffset.top);\n\n this.hideHandler = this.hide.bind(this);\n $(document).on('mouseup', this.hideHandler);\n }\n\n showStart(left, top) {\n const $this = this.$();\n\n this.show(left, $(window).scrollTop() + top - $this.outerHeight() - 5);\n }\n\n showEnd(right, bottom) {\n const $this = this.$();\n\n this.show(right - $this.outerWidth(), $(window).scrollTop() + bottom + 5);\n }\n\n hide() {\n this.$().hide();\n $(document).off('mouseup', this.hideHandler);\n }\n}\n","/**\n * Copied & modified from:\n * https://github.com/KaTeX/KaTeX/blob/master/contrib/copy-tex/katex2tex.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2013-2019 Khan Academy and other contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n// Replace .katex elements with their TeX source ( element).\n// Modifies fragment in-place. Useful for writing your own 'copy' handler,\n// as in copy-tex.js.\nexport const katexReplaceWithTex = function (fragment, copyDelimiters) {\n // Remove .katex-html blocks that are preceded by .katex-mathml blocks\n // (which will get replaced below).\n const katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html');\n for (let i = 0; i < katexHtml.length; i++) {\n const element = katexHtml[i];\n if (element.remove) {\n element.remove(null);\n } else {\n element.parentNode.removeChild(element);\n }\n }\n // Replace .katex-mathml elements with their annotation (TeX source)\n // descendant, with inline delimiters.\n const katexMathml = fragment.querySelectorAll('.katex-mathml');\n for (let i = 0; i < katexMathml.length; i++) {\n const element = katexMathml[i];\n const texSource = element.querySelector('annotation');\n if (texSource) {\n if (element.replaceWith) {\n element.replaceWith(texSource);\n } else {\n element.parentNode.replaceChild(texSource, element);\n }\n texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1];\n }\n }\n // Switch display math to display delimiters.\n const displays = fragment.querySelectorAll('.katex-display annotation');\n for (let i = 0; i < displays.length; i++) {\n const element = displays[i];\n element.innerHTML =\n copyDelimiters.display[0] +\n element.innerHTML.substr(\n copyDelimiters.inline[0].length,\n element.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length\n ) +\n copyDelimiters.display[1];\n }\n return fragment;\n};\n\nexport default katexReplaceWithTex;\n","/**\n * Define delimiters those will be used in Copy-tex plugin\n *\n * @see https://github.com/KaTeX/KaTeX/blob/master/contrib/copy-tex/katex2tex.js#L1-L5\n * @returns {object}\n */\n\nexport default function copyDelimiters(delimiters) {\n return {\n inline: [delimiters.inline.left, delimiters.inline.right],\n display: [delimiters.block.left, delimiters.block.right],\n };\n}\n","/**\n * Copied & modified from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/addPostQuoteButton.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { extend } from 'flarum/common/extend';\nimport CommentPost from 'flarum/components/CommentPost';\nimport PostQuoteButton from './fragments/PostQuoteButton';\nimport selectedText from './utils/selectedText';\nimport copyDelimiters from './utils/copyDelimiters';\n\nexport default function addPostQuoteButton() {\n extend(CommentPost.prototype, 'oncreate', function () {\n if (!app.forum.attribute('mathRenAddQuoteButton') || !app.forum.attribute('mathRenEnableCopyTeX')) return;\n\n const post = this.attrs.post;\n const delimiters = {\n inline: app.forum.attribute('mathRenMainInlineDelimiter'),\n block: app.forum.attribute('mathRenMainBlockDelimiter'),\n };\n\n if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n const $postBody = this.$('.Post-body');\n\n // Wrap the quote button in a wrapper element so that we can render\n // button into it.\n const $container = $('
');\n\n const button = new PostQuoteButton(post);\n\n const handler = function (e) {\n setTimeout(() => {\n const content = selectedText($postBody, copyDelimiters(delimiters));\n if (content) {\n button.content = content;\n m.render($container[0], button.render());\n\n const rects = window.getSelection().getRangeAt(0).getClientRects();\n const firstRect = rects[0];\n\n if (e.clientY < firstRect.bottom && e.clientX - firstRect.right < firstRect.left - e.clientX) {\n button.showStart(firstRect.left, firstRect.top);\n } else {\n const lastRect = rects[rects.length - 1];\n button.showEnd(lastRect.right, lastRect.bottom);\n }\n }\n }, 1);\n };\n\n this.$().after($container).on('mouseup', handler);\n\n if ('ontouchstart' in window) {\n document.addEventListener('selectionchange', handler, false);\n }\n });\n}\n","/**\n * Copied & modified from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/utils/selectedText.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport katexReplaceWithTex from './katex2tex';\n\nexport default function selectedText(body, copyDelimiters) {\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 let fragment = selection.getRangeAt(0).cloneContents();\n\n if (fragment.querySelector('.katex-mathml')) {\n fragment = katexReplaceWithTex(fragment, copyDelimiters);\n }\n\n const clone = $('
').append(fragment);\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 { extend } from 'flarum/common/extend';\nimport app from 'flarum/common/app';\nimport CommentPost from 'flarum/components/CommentPost';\nimport addTextEditorButton from './addTextEditorButton';\nimport addPostQuoteButton from './addPostQuoteButton';\nimport addCopyListener from './addCopyListener';\n\napp.initializers.add('the-turk-mathren', () => {\n let whenLoaded = {};\n let hasLoaded = false;\n let isLoading = false;\n\n const load = () => {\n isLoading = true;\n\n $.getScript('//cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js', () => {\n $.getScript('//cdn.jsdelivr.net/npm/katex@0.13.11/dist/contrib/auto-render.min.js', () => {\n for (const id in whenLoaded) {\n whenLoaded[id]();\n }\n\n whenLoaded = {};\n isLoading = false;\n hasLoaded = true;\n });\n });\n };\n\n // Add Text Editor buttons\n addTextEditorButton();\n\n /**\n * Show a Quote button when Post text is selected\n *\n * We have to run KaTeX's Copy-tex plugin on the selected post\n * and need to modify `selectedText` function which comes with\n * `flarum/mentions` extension.\n **/\n addPostQuoteButton();\n\n // Hook into global copy handler to modify behavior on `.katex` elements\n addCopyListener();\n\n var renderMath = function (element, id) {\n const render = () => renderMathInElement(element, app.forum.attribute('mathRenKatexOptions'));\n\n if (!hasLoaded) {\n whenLoaded[id] = render;\n\n if (isLoading) return;\n\n load();\n } else {\n render();\n }\n };\n\n /* Run KaTeX renderer on every post loading */\n extend(CommentPost.prototype, 'onupdate', function () {\n const postId = this.attrs.post.id();\n\n $.each($('.Post-body', this.element), function (i, p) {\n renderMath(p, postId + '_' + i);\n });\n });\n\n /**\n * Render the math in preview mode\n * Note: We also have this TextFormatter's Live preview attributes\n *\n * @see https://github.com/s9e/TextFormatter/blob/master/docs/JavaScript/Live_preview_attributes.md\n */\n if (s9e && s9e.TextFormatter) {\n extend(s9e.TextFormatter, 'preview', function (original, preview, element) {\n if (element.matches('.Post *')) renderMath(element, 0);\n });\n }\n});\n","import { extend } from 'flarum/common/extend';\nimport TextEditor from 'flarum/components/TextEditor';\nimport TextEditorButton from './components/TextEditorButton';\n\nexport default function addTextEditorButton() {\n extend(TextEditor.prototype, 'toolbarItems', function (items) {\n if (app.forum.attribute('mathRenEnableTextEditorButtons') === true) {\n items.add('the-turk-mathren', );\n }\n });\n}\n","/**\n * Copied & modified from:\n * https://github.com/KaTeX/KaTeX/blob/master/contrib/copy-tex/copy-tex.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2013-2020 Khan Academy and other contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { extend } from 'flarum/common/extend';\nimport DiscussionPage from 'flarum/components/DiscussionPage';\nimport katexReplaceWithTex from './utils/katex2tex';\nimport copyDelimiters from './utils/copyDelimiters';\n\nexport default function addCopyListener() {\n extend(DiscussionPage.prototype, 'oncreate', function () {\n if (!app.forum.attribute('mathRenEnableCopyTeX')) return;\n\n const delimiters = {\n inline: app.forum.attribute('mathRenMainInlineDelimiter'),\n block: app.forum.attribute('mathRenMainBlockDelimiter'),\n };\n\n // Global copy handler to modify behavior on .katex elements.\n document.addEventListener('copy', function (event) {\n const selection = window.getSelection();\n if (selection.isCollapsed) {\n return; // default action OK if selection is empty\n }\n const fragment = selection.getRangeAt(0).cloneContents();\n if (!fragment.querySelector('.katex-mathml')) {\n return; // default action OK if no .katex-mathml elements\n }\n // Preserve usual HTML copy/paste behavior.\n const html = [];\n for (let i = 0; i < fragment.childNodes.length; i++) {\n html.push(fragment.childNodes[i].outerHTML);\n }\n event.clipboardData.setData('text/html', html.join(''));\n // Rewrite plain-text version.\n event.clipboardData.setData('text/plain', katexReplaceWithTex(fragment, copyDelimiters(delimiters)).textContent);\n // Prevent normal copy handling.\n event.preventDefault();\n });\n });\n}\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://@the-turk/flarum-mathren/webpack/bootstrap","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/app']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/extend']\"","webpack://@the-turk/flarum-mathren/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://@the-turk/flarum-mathren/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/components/Button']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['components/CommentPost']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/helpers/icon']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['components/TextEditor']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/Component']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/components/Dropdown']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['common/utils/ItemList']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['Fragment']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['utils/DiscussionControls']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['components/EditPostComposer']\"","webpack://@the-turk/flarum-mathren/external \"flarum.core.compat['components/DiscussionPage']\"","webpack://@the-turk/flarum-mathren/./src/forum/components/TextEditorButton.js","webpack://@the-turk/flarum-mathren/./src/forum/utils/reply.js","webpack://@the-turk/flarum-mathren/./src/forum/utils/cleanDisplayName.js","webpack://@the-turk/flarum-mathren/./src/forum/fragments/PostQuoteButton.js","webpack://@the-turk/flarum-mathren/./src/forum/utils/katex2tex.js","webpack://@the-turk/flarum-mathren/./src/forum/utils/copyDelimiters.js","webpack://@the-turk/flarum-mathren/./src/forum/addPostQuoteButton.js","webpack://@the-turk/flarum-mathren/./src/forum/utils/selectedText.js","webpack://@the-turk/flarum-mathren/./src/forum/index.js","webpack://@the-turk/flarum-mathren/./src/forum/addTextEditorButton.js","webpack://@the-turk/flarum-mathren/./src/forum/addCopyListener.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","_setPrototypeOf","setPrototypeOf","__proto__","_inheritsLoose","subClass","superClass","constructor","oninit","vnode","this","delimiters","inline","app","forum","attribute","block","oncreate","view","Dropdown","component","className","buttonClassName","label","icon","items","toArray","ItemList","add","Button","onclick","leftDelim","rightDelim","wrapSelection","translator","trans","localePrefix","selectionRange","attrs","textEditor","getSelectionRange","insertAt","length","replaceBeforeCursor","moveCursorTo","Component","insertMention","post","composer","quote","user","mention","displayName","replace","cleanDisplayName","id","fields","content","body","originalContent","cursorPosition","editor","preceding","slice","precedingNewlines","match","insertAtCursor","Array","join","trim","PostQuoteButton","class","bodyMatches","EditPostComposer","discussion","DiscussionControls","replyAction","then","show","left","top","$this","$","parentOffset","offsetParent","offset","css","hideHandler","hide","document","on","showStart","window","scrollTop","outerHeight","showEnd","right","bottom","outerWidth","off","Fragment","katexReplaceWithTex","fragment","copyDelimiters","katexHtml","querySelectorAll","element","remove","parentNode","removeChild","katexMathml","texSource","querySelector","replaceWith","replaceChild","innerHTML","displays","display","substr","addPostQuoteButton","extend","CommentPost","isHidden","session","canReply","$postBody","$container","button","handler","e","setTimeout","selection","getSelection","rangeCount","parent","getRangeAt","commonAncestorContainer","contains","cloneContents","clone","append","find","alt","src","innerText","href","text","selectedText","render","rects","getClientRects","firstRect","clientY","clientX","lastRect","after","addEventListener","initializers","whenLoaded","hasLoaded","isLoading","TextEditor","DiscussionPage","event","isCollapsed","html","childNodes","push","outerHTML","clipboardData","setData","textContent","preventDefault","renderMath","renderMathInElement","getScript","postId","each","s9e","TextFormatter","original","preview","matches"],"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 = 20);\n","module.exports = flarum.core.compat['common/app'];","module.exports = flarum.core.compat['common/extend'];","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n setPrototypeOf(subClass, superClass);\n}","module.exports = flarum.core.compat['common/components/Button'];","module.exports = flarum.core.compat['components/CommentPost'];","module.exports = flarum.core.compat['common/helpers/icon'];","module.exports = flarum.core.compat['components/TextEditor'];","module.exports = flarum.core.compat['common/Component'];","module.exports = flarum.core.compat['common/components/Dropdown'];","module.exports = flarum.core.compat['common/utils/ItemList'];","module.exports = flarum.core.compat['Fragment'];","module.exports = flarum.core.compat['utils/DiscussionControls'];","module.exports = flarum.core.compat['components/EditPostComposer'];","module.exports = flarum.core.compat['components/DiscussionPage'];","import app from 'flarum/common/app';\nimport Component from 'flarum/common/Component';\nimport Dropdown from 'flarum/common/components/Dropdown';\nimport Button from 'flarum/common/components/Button';\nimport ItemList from 'flarum/common/utils/ItemList';\nimport icon from 'flarum/common/helpers/icon';\n\nconst localePrefix = 'the-turk-mathren.forum.textEditor.';\n\nexport default class extends Component {\n oninit(vnode) {\n super.oninit(vnode);\n\n this.delimiters = {\n inline: app.forum.attribute('mathRenMainInlineDelimiter'),\n block: app.forum.attribute('mathRenMainBlockDelimiter'),\n };\n }\n\n oncreate(vnode) {\n super.oncreate(vnode);\n }\n\n view() {\n return Dropdown.component(\n {\n className: 'MathRenDropdown',\n buttonClassName: 'Button Button--flat',\n label: icon('fas fa-square-root-alt'),\n },\n this.items().toArray()\n );\n }\n\n /**\n * Build an item list for the contents of the dropdown menu.\n *\n * @return {ItemList}\n */\n items() {\n const items = new ItemList();\n\n items.add(\n 'mathBlock',\n Button.component(\n {\n icon: 'fas fa-vector-square',\n onclick: () => {\n // opening tag (left delimiter)\n const leftDelim = this.delimiters.block['left'];\n // closing tag (right delimiter)\n const rightDelim = this.delimiters.block['right'];\n\n this.wrapSelection(leftDelim, rightDelim);\n },\n },\n app.translator.trans(localePrefix + 'blockExpression')\n ),\n 50\n );\n\n items.add(\n 'mathInline',\n Button.component(\n {\n icon: 'fas fa-grip-lines',\n onclick: () => {\n // opening tag (left delimiter)\n const leftDelim = this.delimiters.inline['left'];\n // closing tag (right delimiter)\n const rightDelim = this.delimiters.inline['right'];\n\n this.wrapSelection(leftDelim, rightDelim);\n },\n },\n app.translator.trans(localePrefix + 'inlineExpression')\n ),\n 0\n );\n\n return items;\n }\n\n /**\n * Wrap the current selection with BBCode tags\n * If there's no selection, put them around the cursor\n *\n * @param string leftDelim\n * @param string rightDelim\n */\n wrapSelection(leftDelim, rightDelim) {\n const selectionRange = this.attrs.textEditor.getSelectionRange();\n\n if (selectionRange[0] != selectionRange[1]) {\n this.attrs.textEditor.insertAt(selectionRange[0], leftDelim);\n this.attrs.textEditor.insertAt(selectionRange[1] + leftDelim.length, rightDelim);\n } else {\n this.attrs.textEditor.replaceBeforeCursor(selectionRange[0], leftDelim + rightDelim);\n this.attrs.textEditor.moveCursorTo(selectionRange[0] + leftDelim.length);\n }\n }\n}\n","/**\n * Copied from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/utils/reply.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport DiscussionControls from 'flarum/utils/DiscussionControls';\nimport EditPostComposer from 'flarum/components/EditPostComposer';\nimport cleanDisplayName from './cleanDisplayName';\n\nfunction insertMention(post, composer, quote) {\n const user = post.user();\n const mention = `@\"${(user && cleanDisplayName(user)) || app.translator.trans('core.lib.username.deleted_text')}\"#p${post.id()} `;\n\n // If the composer is empty, then assume we're starting a new reply.\n // In which case we don't want the user to have to confirm if they\n // close the composer straight away.\n if (!composer.fields.content()) {\n composer.body.attrs.originalContent = mention;\n }\n\n const cursorPosition = composer.editor.getSelectionRange()[0];\n const preceding = composer.fields.content().slice(0, cursorPosition);\n const precedingNewlines = preceding.length == 0 ? 0 : 3 - preceding.match(/(\\n{0,2})$/)[0].length;\n\n composer.editor.insertAtCursor(\n Array(precedingNewlines).join('\\n') + // Insert up to two newlines, depending on preceding whitespace\n (quote ? '> ' + mention + quote.trim().replace(/\\n/g, '\\n> ') + '\\n\\n' : mention),\n false\n );\n}\n\nexport default function reply(post, quote) {\n if (app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {\n // If we're already editing a post in the discussion of post we're quoting,\n // insert the mention directly.\n insertMention(post, app.composer, quote);\n } else {\n // The default \"Reply\" action behavior will only open a new composer if\n // necessary, but it will always be a ReplyComposer, hence the exceptional\n // case above.\n DiscussionControls.replyAction.call(post.discussion()).then((composer) => insertMention(post, composer, quote));\n }\n}\n","/**\n * Copied from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/utils/cleanDisplayName.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nexport default function cleanDisplayName(user) {\n return user.displayName().replace(/\"#[a-z]{0,3}[0-9]+/, '_');\n}\n","/**\n * Copied & modified from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/fragments/PostQuoteButton.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport Fragment from 'flarum/Fragment';\nimport icon from 'flarum/common/helpers/icon';\n\nimport reply from '../utils/reply';\n\nexport default class PostQuoteButton extends Fragment {\n constructor(post) {\n super();\n\n this.post = post;\n }\n\n view() {\n return (\n {\n reply(this.post, this.content);\n }}\n >\n {icon('fas fa-quote-left', { className: 'Button-icon' })}\n {app.translator.trans('flarum-mentions.forum.post.quote_button')}\n \n );\n }\n\n show(left, top) {\n const $this = this.$().show();\n const parentOffset = $this.offsetParent().offset();\n\n $this.css('left', left - parentOffset.left).css('top', top - parentOffset.top);\n\n this.hideHandler = this.hide.bind(this);\n $(document).on('mouseup', this.hideHandler);\n }\n\n showStart(left, top) {\n const $this = this.$();\n\n this.show(left, $(window).scrollTop() + top - $this.outerHeight() - 5);\n }\n\n showEnd(right, bottom) {\n const $this = this.$();\n\n this.show(right - $this.outerWidth(), $(window).scrollTop() + bottom + 5);\n }\n\n hide() {\n this.$().hide();\n $(document).off('mouseup', this.hideHandler);\n }\n}\n","/**\n * Copied & modified from:\n * https://github.com/KaTeX/KaTeX/blob/master/contrib/copy-tex/katex2tex.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2013-2019 Khan Academy and other contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n// Replace .katex elements with their TeX source ( element).\n// Modifies fragment in-place. Useful for writing your own 'copy' handler,\n// as in copy-tex.js.\nexport const katexReplaceWithTex = function (fragment, copyDelimiters) {\n // Remove .katex-html blocks that are preceded by .katex-mathml blocks\n // (which will get replaced below).\n const katexHtml = fragment.querySelectorAll('.katex-mathml + .katex-html');\n for (let i = 0; i < katexHtml.length; i++) {\n const element = katexHtml[i];\n if (element.remove) {\n element.remove(null);\n } else {\n element.parentNode.removeChild(element);\n }\n }\n // Replace .katex-mathml elements with their annotation (TeX source)\n // descendant, with inline delimiters.\n const katexMathml = fragment.querySelectorAll('.katex-mathml');\n for (let i = 0; i < katexMathml.length; i++) {\n const element = katexMathml[i];\n const texSource = element.querySelector('annotation');\n if (texSource) {\n if (element.replaceWith) {\n element.replaceWith(texSource);\n } else {\n element.parentNode.replaceChild(texSource, element);\n }\n texSource.innerHTML = copyDelimiters.inline[0] + texSource.innerHTML + copyDelimiters.inline[1];\n }\n }\n // Switch display math to display delimiters.\n const displays = fragment.querySelectorAll('.katex-display annotation');\n for (let i = 0; i < displays.length; i++) {\n const element = displays[i];\n element.innerHTML =\n copyDelimiters.display[0] +\n element.innerHTML.substr(\n copyDelimiters.inline[0].length,\n element.innerHTML.length - copyDelimiters.inline[0].length - copyDelimiters.inline[1].length\n ) +\n copyDelimiters.display[1];\n }\n return fragment;\n};\n\nexport default katexReplaceWithTex;\n","/**\n * Define delimiters those will be used in Copy-tex plugin\n *\n * @see https://github.com/KaTeX/KaTeX/blob/master/contrib/copy-tex/katex2tex.js#L1-L5\n * @returns {object}\n */\n\nexport default function copyDelimiters(delimiters) {\n return {\n inline: [delimiters.inline.left, delimiters.inline.right],\n display: [delimiters.block.left, delimiters.block.right],\n };\n}\n","/**\n * Copied & modified from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/addPostQuoteButton.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { extend } from 'flarum/common/extend';\nimport CommentPost from 'flarum/components/CommentPost';\nimport PostQuoteButton from './fragments/PostQuoteButton';\nimport selectedText from './utils/selectedText';\nimport copyDelimiters from './utils/copyDelimiters';\n\nexport default function addPostQuoteButton() {\n extend(CommentPost.prototype, 'oncreate', function () {\n if (!app.forum.attribute('mathRenAddQuoteButton') || !app.forum.attribute('mathRenEnableCopyTeX')) return;\n\n const post = this.attrs.post;\n const delimiters = {\n inline: app.forum.attribute('mathRenMainInlineDelimiter'),\n block: app.forum.attribute('mathRenMainBlockDelimiter'),\n };\n\n if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;\n\n const $postBody = this.$('.Post-body');\n\n // Wrap the quote button in a wrapper element so that we can render\n // button into it.\n const $container = $('
');\n\n const button = new PostQuoteButton(post);\n\n const handler = function (e) {\n setTimeout(() => {\n const content = selectedText($postBody, copyDelimiters(delimiters));\n if (content) {\n button.content = content;\n m.render($container[0], button.render());\n\n const rects = window.getSelection().getRangeAt(0).getClientRects();\n const firstRect = rects[0];\n\n if (e.clientY < firstRect.bottom && e.clientX - firstRect.right < firstRect.left - e.clientX) {\n button.showStart(firstRect.left, firstRect.top);\n } else {\n const lastRect = rects[rects.length - 1];\n button.showEnd(lastRect.right, lastRect.bottom);\n }\n }\n }, 1);\n };\n\n this.$().after($container).on('mouseup', handler);\n\n if ('ontouchstart' in window) {\n document.addEventListener('selectionchange', handler, false);\n }\n });\n}\n","/**\n * Copied & modified from:\n * https://github.com/flarum/mentions/blob/master/js/src/forum/utils/selectedText.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)\n * Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport katexReplaceWithTex from './katex2tex';\n\nexport default function selectedText(body, copyDelimiters) {\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 let fragment = selection.getRangeAt(0).cloneContents();\n\n if (fragment.querySelector('.katex-mathml')) {\n fragment = katexReplaceWithTex(fragment, copyDelimiters);\n }\n\n const clone = $('
').append(fragment);\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 { extend } from 'flarum/common/extend';\nimport app from 'flarum/common/app';\nimport CommentPost from 'flarum/components/CommentPost';\nimport addTextEditorButton from './addTextEditorButton';\nimport addPostQuoteButton from './addPostQuoteButton';\nimport addCopyListener from './addCopyListener';\n\napp.initializers.add('the-turk-mathren', () => {\n let whenLoaded = {};\n let hasLoaded = false;\n let isLoading = false;\n\n const load = () => {\n isLoading = true;\n\n $.getScript('//cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js', () => {\n $.getScript('//cdn.jsdelivr.net/npm/katex@0.13.11/dist/contrib/auto-render.min.js', () => {\n for (const id in whenLoaded) {\n whenLoaded[id]();\n }\n\n whenLoaded = {};\n isLoading = false;\n hasLoaded = true;\n });\n });\n };\n\n // Add Text Editor buttons\n addTextEditorButton();\n\n /**\n * Show a Quote button when Post text is selected\n *\n * We have to run KaTeX's Copy-tex plugin on the selected post\n * and need to modify `selectedText` function which comes with\n * `flarum/mentions` extension.\n **/\n addPostQuoteButton();\n\n // Hook into global copy handler to modify behavior on `.katex` elements\n addCopyListener();\n\n var renderMath = function (element, id) {\n const render = () => renderMathInElement(element, app.forum.attribute('mathRenKatexOptions'));\n\n if (!hasLoaded) {\n whenLoaded[id] = render;\n\n if (isLoading) return;\n\n load();\n } else {\n render();\n }\n };\n\n /* Run KaTeX renderer on every post loading */\n extend(CommentPost.prototype, ['oncreate', 'onupdate'], function () {\n const postId = this.attrs.post.id();\n\n $.each($('.Post-body', this.element), function (i, p) {\n renderMath(p, postId + '_' + i);\n });\n });\n\n /**\n * Render the math in preview mode\n * Note: We also have this TextFormatter's Live preview attributes\n *\n * @see https://github.com/s9e/TextFormatter/blob/master/docs/JavaScript/Live_preview_attributes.md\n */\n if (s9e && s9e.TextFormatter) {\n extend(s9e.TextFormatter, 'preview', function (original, preview, element) {\n if (element.matches('.Post *')) renderMath(element, 0);\n });\n }\n});\n","import { extend } from 'flarum/common/extend';\nimport TextEditor from 'flarum/components/TextEditor';\nimport TextEditorButton from './components/TextEditorButton';\n\nexport default function addTextEditorButton() {\n extend(TextEditor.prototype, 'toolbarItems', function (items) {\n if (app.forum.attribute('mathRenEnableTextEditorButtons') === true) {\n items.add('the-turk-mathren', );\n }\n });\n}\n","/**\n * Copied & modified from:\n * https://github.com/KaTeX/KaTeX/blob/master/contrib/copy-tex/copy-tex.js\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2013-2020 Khan Academy and other contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { extend } from 'flarum/common/extend';\nimport DiscussionPage from 'flarum/components/DiscussionPage';\nimport katexReplaceWithTex from './utils/katex2tex';\nimport copyDelimiters from './utils/copyDelimiters';\n\nexport default function addCopyListener() {\n extend(DiscussionPage.prototype, 'oncreate', function () {\n if (!app.forum.attribute('mathRenEnableCopyTeX')) return;\n\n const delimiters = {\n inline: app.forum.attribute('mathRenMainInlineDelimiter'),\n block: app.forum.attribute('mathRenMainBlockDelimiter'),\n };\n\n // Global copy handler to modify behavior on .katex elements.\n document.addEventListener('copy', function (event) {\n const selection = window.getSelection();\n if (selection.isCollapsed) {\n return; // default action OK if selection is empty\n }\n const fragment = selection.getRangeAt(0).cloneContents();\n if (!fragment.querySelector('.katex-mathml')) {\n return; // default action OK if no .katex-mathml elements\n }\n // Preserve usual HTML copy/paste behavior.\n const html = [];\n for (let i = 0; i < fragment.childNodes.length; i++) {\n html.push(fragment.childNodes[i].outerHTML);\n }\n event.clipboardData.setData('text/html', html.join(''));\n // Rewrite plain-text version.\n event.clipboardData.setData('text/plain', katexReplaceWithTex(fragment, copyDelimiters(delimiters)).textContent);\n // Prevent normal copy handling.\n event.preventDefault();\n });\n });\n}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/js/package.json b/js/package.json index c613e13..866fc58 100644 --- a/js/package.json +++ b/js/package.json @@ -2,7 +2,7 @@ "name": "@the-turk/flarum-mathren", "description": "TeX math rendering for your forum.", "license": "MIT", - "version": "0.3.5", + "version": "0.3.7", "dependencies": { "flarum-webpack-config": "0.1.0-beta.16.2", "webpack": "^4.46.0", diff --git a/js/src/forum/index.js b/js/src/forum/index.js index 5513c19..e2a5dcb 100644 --- a/js/src/forum/index.js +++ b/js/src/forum/index.js @@ -56,7 +56,7 @@ app.initializers.add('the-turk-mathren', () => { }; /* Run KaTeX renderer on every post loading */ - extend(CommentPost.prototype, 'onupdate', function () { + extend(CommentPost.prototype, ['oncreate', 'onupdate'], function () { const postId = this.attrs.post.id(); $.each($('.Post-body', this.element), function (i, p) {