UX: when pasting a link use linkify rules

This commit is contained in:
Kerry Liu
2021-11-22 16:15:46 -08:00
committed by Robin Ward
parent 0009498901
commit f37bffdf6c
2 changed files with 32 additions and 10 deletions

View File

@@ -50,6 +50,13 @@ export function generateCookFunction(options) {
}); });
} }
export function generateLinkifyFunction(options) {
return loadMarkdownIt().then(() => {
const prettyText = createPrettyText(options);
return prettyText.opts.engine.linkify;
});
}
export function sanitize(text, options) { export function sanitize(text, options) {
return textSanitize(text, new AllowLister(options)); return textSanitize(text, new AllowLister(options));
} }

View File

@@ -1,5 +1,6 @@
import { bind } from "discourse-common/utils/decorators"; import { bind } from "discourse-common/utils/decorators";
import Mixin from "@ember/object/mixin"; import Mixin from "@ember/object/mixin";
import { generateLinkifyFunction } from "discourse/lib/text";
import toMarkdown from "discourse/lib/to-markdown"; import toMarkdown from "discourse/lib/to-markdown";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
@@ -17,6 +18,14 @@ const isInside = (text, regex) => {
}; };
export default Mixin.create({ export default Mixin.create({
init() {
this._super(...arguments);
generateLinkifyFunction(this.markdownOptions || {}).then((linkify) => {
// When pasting links, we should use the same rules to match links as we do when creating links for a cooked post.
this._cachedLinkify = linkify;
});
},
// ensures textarea scroll position is correct // ensures textarea scroll position is correct
_focusTextArea() { _focusTextArea() {
schedule("afterRender", () => { schedule("afterRender", () => {
@@ -273,18 +282,24 @@ export default Mixin.create({
} }
} }
if (plainText && !handled && selected.end > selected.start) { if (
let isURL; this._cachedLinkify &&
try { plainText &&
isURL = !!new URL(plainText); !handled &&
} catch { selected.end > selected.start
isURL = false; ) {
} if (this._cachedLinkify.test(plainText)) {
if (isURL) { const match = this._cachedLinkify.match(plainText)[0];
this._addText(selected, `[${selectedValue}](${plainText})`); if (
match &&
match.index === 0 &&
match.lastIndex === match.raw.length
) {
this._addText(selected, `[${selectedValue}](${match.url})`);
handled = true; handled = true;
} }
} }
}
if (canPasteHtml && !handled) { if (canPasteHtml && !handled) {
let markdown = toMarkdown(html); let markdown = toMarkdown(html);