mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-54474] Fixed behaviour of markdown code button (#24816)
* update webapp/../apply_markdown.ts to support codeblock and inline block markdown correctly & added corresponding unit tests to apply_markdown.test.tsx * refactor apply_markdown.ts * refactor applyMarkdownToSelection to support different starting/ending delimiter && delete applyCodeBlockToSelection * updated apply_markdown.test.tsx --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
3e6cce5ab5
commit
d2d820cb31
@ -441,4 +441,100 @@ describe('applyMarkdown', () => {
|
||||
selectionEnd: 14,
|
||||
});
|
||||
});
|
||||
|
||||
/* ***************
|
||||
* CODE (inline code and code block)
|
||||
* ************** */
|
||||
test('should apply inline code markdown to the selection', () => {
|
||||
// "Fafda" is selected with ctrl + alt + C hotkey
|
||||
const result = applyMarkdown({
|
||||
message: 'Jalebi Fafda & Sambharo',
|
||||
selectionStart: 7,
|
||||
selectionEnd: 12,
|
||||
markdownMode: 'code',
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
message: 'Jalebi `Fafda` & Sambharo',
|
||||
selectionStart: 8,
|
||||
selectionEnd: 13,
|
||||
});
|
||||
});
|
||||
|
||||
test('should remove inline code markdown to the selection', () => {
|
||||
// "Fafda" is selected with ctrl + alt + C hotkey
|
||||
const result = applyMarkdown({
|
||||
message: 'Jalebi `Fafda` & Sambharo',
|
||||
selectionStart: 8,
|
||||
selectionEnd: 13,
|
||||
markdownMode: 'code',
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
message: 'Jalebi Fafda & Sambharo',
|
||||
selectionStart: 7,
|
||||
selectionEnd: 12,
|
||||
});
|
||||
});
|
||||
|
||||
test('should apply code block markdown to the full message (multi-lines)', () => {
|
||||
// all message is selected with ctrl + alt + C hotkey
|
||||
const result = applyMarkdown({
|
||||
message: 'Jalebi\nFafda\nSambharo',
|
||||
selectionStart: 0,
|
||||
selectionEnd: 21,
|
||||
markdownMode: 'code',
|
||||
});
|
||||
expect(result).toEqual({
|
||||
message: '```\nJalebi\nFafda\nSambharo\n```',
|
||||
selectionStart: 4,
|
||||
selectionEnd: 25,
|
||||
});
|
||||
});
|
||||
|
||||
test('should remove code block markdown to the full message', () => {
|
||||
// all message is selected with ctrl + alt + C hotkey
|
||||
const result = applyMarkdown({
|
||||
message: '```\nJalebi\nFafda\nSambharo\n```',
|
||||
selectionStart: 4,
|
||||
selectionEnd: 25,
|
||||
markdownMode: 'code',
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
message: 'Jalebi\nFafda\nSambharo',
|
||||
selectionStart: 0,
|
||||
selectionEnd: 21,
|
||||
});
|
||||
});
|
||||
|
||||
test('should apply code block markdown to the sub-message (multi-lines)', () => {
|
||||
// "bi\nFaf" is selected with ctrl + alt + C hotkey
|
||||
const result = applyMarkdown({
|
||||
message: 'Jalebi\nFafda\nSambharo',
|
||||
selectionStart: 4,
|
||||
selectionEnd: 10,
|
||||
markdownMode: 'code',
|
||||
});
|
||||
expect(result).toEqual({
|
||||
message: 'Jale```\nbi\nFaf\n```da\nSambharo',
|
||||
selectionStart: 8,
|
||||
selectionEnd: 14,
|
||||
});
|
||||
});
|
||||
|
||||
test('should remove code block markdown to the sub-message', () => {
|
||||
// "bi\nFaf" is selected with ctrl + alt + C hotkey
|
||||
const result = applyMarkdown({
|
||||
message: 'Jale```\nbi\nFaf\n```da\nSambharo',
|
||||
selectionStart: 8,
|
||||
selectionEnd: 14,
|
||||
markdownMode: 'code',
|
||||
});
|
||||
expect(result).toEqual({
|
||||
message: 'Jalebi\nFafda\nSambharo',
|
||||
selectionStart: 4,
|
||||
selectionEnd: 10,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -18,6 +18,8 @@ type ApplyMarkdownReturnValue = {
|
||||
|
||||
type ApplySpecificMarkdownOptions = ApplyMarkdownReturnValue & {
|
||||
delimiter?: string;
|
||||
delimiterStart?: string;
|
||||
delimiterEnd?: string;
|
||||
}
|
||||
|
||||
export type ApplyLinkMarkdownOptions = ApplySpecificMarkdownOptions & {
|
||||
@ -73,8 +75,7 @@ export function applyMarkdown(options: ApplyMarkdownOptions): ApplyMarkdownRetur
|
||||
delimiter = '~~';
|
||||
return applyMarkdownToSelection({selectionEnd, selectionStart, message, delimiter});
|
||||
case 'code':
|
||||
delimiter = '```';
|
||||
return applyMarkdownToSelection({selectionEnd, selectionStart, message, delimiter});
|
||||
return applyCodeMarkdown({selectionEnd, selectionStart, message});
|
||||
}
|
||||
|
||||
throw Error('Unsupported markdown mode: ' + markdownMode);
|
||||
@ -271,8 +272,12 @@ const applyMarkdownToSelection = ({
|
||||
selectionStart,
|
||||
message,
|
||||
delimiter,
|
||||
delimiterStart,
|
||||
delimiterEnd,
|
||||
}: ApplySpecificMarkdownOptions) => {
|
||||
if (!delimiter) {
|
||||
const openingDelimiter = delimiterStart ?? delimiter;
|
||||
const closingDelimiter = delimiterEnd ?? delimiter;
|
||||
if (!openingDelimiter || !closingDelimiter) {
|
||||
/**
|
||||
* in case no delimiter is set return the values without changing anything
|
||||
*/
|
||||
@ -293,7 +298,7 @@ const applyMarkdownToSelection = ({
|
||||
let suffix = message.slice(selectionEnd);
|
||||
|
||||
// Does the selection have current hotkey's markdown?
|
||||
const hasCurrentMarkdown = prefix.endsWith(delimiter) && suffix.startsWith(delimiter);
|
||||
const hasCurrentMarkdown = prefix.endsWith(openingDelimiter) && suffix.startsWith(closingDelimiter);
|
||||
|
||||
let newValue: string;
|
||||
let newStart = selectionStart;
|
||||
@ -313,14 +318,14 @@ const applyMarkdownToSelection = ({
|
||||
|
||||
if (hasCurrentMarkdown) {
|
||||
// selection already has the markdown, so we remove it here
|
||||
newValue = prefix.slice(0, prefix.length - delimiter.length) + selection + suffix.slice(delimiter.length);
|
||||
newStart -= delimiter.length;
|
||||
newEnd -= delimiter.length;
|
||||
newValue = prefix.slice(0, prefix.length - openingDelimiter.length) + selection + suffix.slice(closingDelimiter.length);
|
||||
newStart -= openingDelimiter.length;
|
||||
newEnd -= closingDelimiter.length;
|
||||
} else {
|
||||
// add markdown to the selection
|
||||
newValue = prefix + delimiter + selection + delimiter + suffix;
|
||||
newStart += delimiter.length;
|
||||
newEnd += delimiter.length;
|
||||
newValue = prefix + openingDelimiter + selection + closingDelimiter + suffix;
|
||||
newStart += openingDelimiter.length;
|
||||
newEnd += closingDelimiter.length;
|
||||
}
|
||||
|
||||
return {
|
||||
@ -492,6 +497,13 @@ export function applyLinkMarkdown({selectionEnd, selectionStart, message, url =
|
||||
};
|
||||
}
|
||||
|
||||
function applyCodeMarkdown({selectionEnd, selectionStart, message}: ApplySpecificMarkdownOptions) {
|
||||
if (isSelectionMultiline(message, selectionStart, selectionEnd)) {
|
||||
return applyMarkdownToSelection({selectionEnd, selectionStart, message, delimiterStart: '```\n', delimiterEnd: '\n```'});
|
||||
}
|
||||
return applyMarkdownToSelection({selectionEnd, selectionStart, message, delimiter: '`'});
|
||||
}
|
||||
|
||||
function findWordEnd(text: string, start: number) {
|
||||
const wordEnd = text.indexOf(' ', start);
|
||||
return wordEnd === -1 ? text.length : wordEnd;
|
||||
@ -501,3 +513,7 @@ function findWordStart(text: string, start: number) {
|
||||
const wordStart = text.lastIndexOf(' ', start - 1) + 1;
|
||||
return wordStart === -1 ? 0 : wordStart;
|
||||
}
|
||||
|
||||
function isSelectionMultiline(message: string, selectionStart: number, selectionEnd: number) {
|
||||
return message.slice(selectionStart, selectionEnd).includes('\n');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user