Commit 989116ec authored by Phil Hughes's avatar Phil Hughes

Fixes suggestions with new line characters not working

Fixes a bug where new lines in the suggestions content
would insert a new line instead of the new line character.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/333351
parent 80e26dbe
...@@ -232,7 +232,9 @@ export function insertMarkdownText({ ...@@ -232,7 +232,9 @@ export function insertMarkdownText({
.join('\n'); .join('\n');
} }
} else if (tag.indexOf(textPlaceholder) > -1) { } else if (tag.indexOf(textPlaceholder) > -1) {
textToInsert = tag.replace(textPlaceholder, () => selected.replace(/\\n/g, '\n')); textToInsert = tag.replace(textPlaceholder, () =>
selected.replace(/\\n/g, '\n').replace(/\/(n|t|r)/g, '\\$1'),
);
} else { } else {
textToInsert = String(startChar) + tag + selected + (wrap ? tag : ''); textToInsert = String(startChar) + tag + selected + (wrap ? tag : '');
} }
......
...@@ -15,6 +15,14 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; ...@@ -15,6 +15,14 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MarkdownHeader from './header.vue'; import MarkdownHeader from './header.vue';
import MarkdownToolbar from './toolbar.vue'; import MarkdownToolbar from './toolbar.vue';
function cleanUpLine(content) {
return unescape(
stripHtml(content)
.replace(/\\(n|t|r)/g, '/$1')
.replace(/\n/g, ''),
);
}
export default { export default {
components: { components: {
GfmAutocomplete, GfmAutocomplete,
...@@ -129,7 +137,7 @@ export default { ...@@ -129,7 +137,7 @@ export default {
return text; return text;
} }
return unescape(stripHtml(richText).replace(/\n/g, '')); return cleanUpLine(richText);
}) })
.join('\\n'); .join('\\n');
} }
...@@ -141,7 +149,7 @@ export default { ...@@ -141,7 +149,7 @@ export default {
return text; return text;
} }
return unescape(stripHtml(richText).replace(/\n/g, '')); return cleanUpLine(richText);
} }
return ''; return '';
...@@ -272,6 +280,7 @@ export default { ...@@ -272,6 +280,7 @@ export default {
:can-suggest="canSuggest" :can-suggest="canSuggest"
:show-suggest-popover="showSuggestPopover" :show-suggest-popover="showSuggestPopover"
:suggestion-start-index="suggestionsStartIndex" :suggestion-start-index="suggestionsStartIndex"
data-testid="markdownHeader"
@preview-markdown="showPreviewTab" @preview-markdown="showPreviewTab"
@write-markdown="showWriteTab" @write-markdown="showWriteTab"
@handleSuggestDismissed="() => $emit('handleSuggestDismissed')" @handleSuggestDismissed="() => $emit('handleSuggestDismissed')"
......
...@@ -88,6 +88,25 @@ describe('init markdown', () => { ...@@ -88,6 +88,25 @@ describe('init markdown', () => {
expect(textArea.value).toEqual(`${initialValue}\n- `); expect(textArea.value).toEqual(`${initialValue}\n- `);
}); });
it('unescapes new line characters', () => {
const initialValue = '';
textArea.value = initialValue;
textArea.selectionStart = 0;
textArea.selectionEnd = 0;
insertMarkdownText({
textArea,
text: textArea.value,
tag: '```suggestion:-0+0\n{text}\n```',
blockTag: true,
selected: '# Does not parse the /n currently.',
wrap: false,
});
expect(textArea.value).toContain('# Does not parse the \\n currently.');
});
it('inserts the tag on the same line if the current line only contains spaces', () => { it('inserts the tag on the same line if the current line only contains spaces', () => {
const initialValue = ' '; const initialValue = ' ';
......
...@@ -28,6 +28,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] = ...@@ -28,6 +28,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
data-uploads-path="" data-uploads-path=""
> >
<markdown-header-stub <markdown-header-stub
data-testid="markdownHeader"
linecontent="" linecontent=""
suggestionstartindex="0" suggestionstartindex="0"
/> />
......
...@@ -32,7 +32,7 @@ describe('Markdown field component', () => { ...@@ -32,7 +32,7 @@ describe('Markdown field component', () => {
axiosMock.restore(); axiosMock.restore();
}); });
function createSubject() { function createSubject(lines = []) {
// We actually mount a wrapper component so that we can force Vue to rerender classes in order to test a regression // We actually mount a wrapper component so that we can force Vue to rerender classes in order to test a regression
// caused by mixing Vanilla JS and Vue. // caused by mixing Vanilla JS and Vue.
subject = mount( subject = mount(
...@@ -60,6 +60,7 @@ describe('Markdown field component', () => { ...@@ -60,6 +60,7 @@ describe('Markdown field component', () => {
markdownPreviewPath, markdownPreviewPath,
isSubmitting: false, isSubmitting: false,
textareaValue, textareaValue,
lines,
}, },
}, },
); );
...@@ -243,4 +244,14 @@ describe('Markdown field component', () => { ...@@ -243,4 +244,14 @@ describe('Markdown field component', () => {
}); });
}); });
}); });
describe('suggestions', () => {
it('escapes new line characters', () => {
createSubject([{ rich_text: 'hello world\\n' }]);
expect(subject.find('[data-testid="markdownHeader"]').props('lineContent')).toBe(
'hello world/n',
);
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment