UX: pasting links on a selection will apply a link format

This commit is contained in:
Kerry Liu 2021-11-18 08:54:26 -08:00 committed by Robin Ward
parent c75224e3d9
commit 0009498901
2 changed files with 58 additions and 2 deletions

View File

@ -242,7 +242,8 @@ export default Mixin.create({
let html = clipboard.getData("text/html"); let html = clipboard.getData("text/html");
let handled = false; let handled = false;
const { pre, lineVal } = this._getSelected(null, { lineVal: true }); const selected = this._getSelected(null, { lineVal: true });
const { pre, value: selectedValue, lineVal } = selected;
const isInlinePasting = pre.match(/[^\n]$/); const isInlinePasting = pre.match(/[^\n]$/);
const isCodeBlock = isInside(pre, /(^|\n)```/g); const isCodeBlock = isInside(pre, /(^|\n)```/g);
@ -272,6 +273,19 @@ export default Mixin.create({
} }
} }
if (plainText && !handled && selected.end > selected.start) {
let isURL;
try {
isURL = !!new URL(plainText);
} catch {
isURL = false;
}
if (isURL) {
this._addText(selected, `[${selectedValue}](${plainText})`);
handled = true;
}
}
if (canPasteHtml && !handled) { if (canPasteHtml && !handled) {
let markdown = toMarkdown(html); let markdown = toMarkdown(html);

View File

@ -729,10 +729,11 @@ third line`
}); });
async function paste(element, text) { async function paste(element, text) {
let e = new Event("paste"); let e = new Event("paste", { cancelable: true });
e.clipboardData = { getData: () => text }; e.clipboardData = { getData: () => text };
element.dispatchEvent(e); element.dispatchEvent(e);
await settled(); await settled();
return e;
} }
componentTest("paste table", { componentTest("paste table", {
@ -763,6 +764,47 @@ third line`
}, },
}); });
testCase(
`pasting a link into a selection applies a link format`,
async function (assert, textarea) {
this.set("value", "See discourse in action");
setTextareaSelection(textarea, 4, 13);
const element = query(".d-editor");
const event = await paste(element, "https://www.discourse.org/");
assert.strictEqual(
this.value,
"See [discourse](https://www.discourse.org/) in action"
);
assert.strictEqual(event.defaultPrevented, true);
}
);
testCase(
`pasting other text into a selection will replace text value`,
async function (assert, textarea) {
this.set("value", "good morning");
setTextareaSelection(textarea, 5, 12);
const element = query(".d-editor");
const event = await paste(element, "evening");
// Synthetic paste events do not manipulate document content.
assert.strictEqual(this.value, "good morning");
assert.strictEqual(event.defaultPrevented, false);
}
);
testCase(
`pasting a url without a selection will insert the url`,
async function (assert, textarea) {
this.set("value", "a link example:");
jumpEnd(textarea);
const element = query(".d-editor");
const event = await paste(element, "https://www.discourse.org/");
// Synthetic paste events do not manipulate document content.
assert.strictEqual(this.value, "a link example:");
assert.strictEqual(event.defaultPrevented, false);
}
);
(() => { (() => {
// Tests to check cursor/selection after replace-text event. // Tests to check cursor/selection after replace-text event.
const BEFORE = "red green blue"; const BEFORE = "red green blue";