Fix md pasting inside of incomplete html block (#203476)

Fix pasting inside of incomplete html block

Fixes #188868
This commit is contained in:
Matt Bierner
2024-01-29 07:55:19 +00:00
committed by GitHub
parent 0d22ba354b
commit 98d55333b9
2 changed files with 42 additions and 5 deletions
@@ -124,6 +124,8 @@ export async function shouldInsertMarkdownLinkByDefault(
}
}
const textTokenTypes = new Set(['paragraph_open', 'inline', 'heading_open', 'ordered_list_open', 'bullet_list_open', 'list_item_open', 'blockquote_open']);
async function shouldSmartPasteForSelection(
parser: IMdParser,
document: ITextDocument,
@@ -150,9 +152,29 @@ async function shouldSmartPasteForSelection(
if (token.isCancellationRequested) {
return false;
}
for (const token of tokens) {
if (token.map && token.map[0] <= selectedRange.start.line && token.map[1] > selectedRange.start.line) {
if (!['paragraph_open', 'inline', 'heading_open', 'ordered_list_open', 'bullet_list_open', 'list_item_open', 'blockquote_open'].includes(token.type)) {
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (!token.map) {
continue;
}
if (token.map[0] <= selectedRange.start.line && token.map[1] > selectedRange.start.line) {
if (!textTokenTypes.has(token.type)) {
return false;
}
}
// Special case for html such as:
//
// <b>
// |
// </b>
//
// In this case pasting will cause the html block to be created even though the cursor is not currently inside a block
if (token.type === 'html_block' && token.map[1] === selectedRange.start.line) {
const nextToken = tokens.at(i + 1);
// The next token does not need to be a html_block, but it must be on the next line
if (nextToken?.map?.[0] === selectedRange.end.line + 1) {
return false;
}
}
@@ -203,6 +203,23 @@ suite('createEditAddingLinksForUriList', () => {
false);
});
test('Smart should be disabled in html blocks where paste creates the block', async () => {
assert.strictEqual(
await shouldInsertMarkdownLinkByDefault(createNewMarkdownEngine(), makeTestDoc('<p>\n\n</p>'), PasteUrlAsMarkdownLink.Smart, [new vscode.Range(1, 0, 1, 0)], noopToken),
false,
'Between two html tags should be treated as html block');
assert.strictEqual(
await shouldInsertMarkdownLinkByDefault(createNewMarkdownEngine(), makeTestDoc('<p>\n\ntext'), PasteUrlAsMarkdownLink.Smart, [new vscode.Range(1, 0, 1, 0)], noopToken),
false,
'Between opening html tag and text should be treated as html block');
assert.strictEqual(
await shouldInsertMarkdownLinkByDefault(createNewMarkdownEngine(), makeTestDoc('<p>\n\n\n</p>'), PasteUrlAsMarkdownLink.Smart, [new vscode.Range(1, 0, 1, 0)], noopToken),
true,
'Extra new line after paste should not be treated as html block');
});
test('Smart should be disabled in Markdown links', async () => {
assert.strictEqual(
await shouldInsertMarkdownLinkByDefault(createNewMarkdownEngine(), makeTestDoc('[a](bcdef)'), PasteUrlAsMarkdownLink.Smart, [new vscode.Range(0, 4, 0, 6)], noopToken),
@@ -266,7 +283,5 @@ suite('createEditAddingLinksForUriList', () => {
await shouldInsertMarkdownLinkByDefault(createNewMarkdownEngine(), makeTestDoc(' \r\n\r\n'), PasteUrlAsMarkdownLink.SmartWithSelection, [new vscode.Range(0, 0, 0, 7)], noopToken),
false);
});
});
});