1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Mobile: Fixes #9477: Fix inline code at beginning of line in table breaks formatting (#9478)

This commit is contained in:
Henry Heino 2023-12-13 11:45:17 -08:00 committed by GitHub
parent 1bbec445d5
commit 815a0a5db4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 7 deletions

View File

@ -542,6 +542,7 @@ packages/editor/CodeMirror/editorCommands/swapLine.js
packages/editor/CodeMirror/getScrollFraction.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
packages/editor/CodeMirror/markdown/decoratorExtension.js
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/markdown/markdownCommands.test.js

1
.gitignore vendored
View File

@ -524,6 +524,7 @@ packages/editor/CodeMirror/editorCommands/swapLine.js
packages/editor/CodeMirror/getScrollFraction.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
packages/editor/CodeMirror/markdown/decoratorExtension.js
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/markdown/markdownCommands.test.js

View File

@ -0,0 +1,30 @@
import { EditorSelection } from '@codemirror/state';
import createTestEditor from '../testUtil/createTestEditor';
import decoratorExtension from './decoratorExtension';
jest.retryTimes(2);
describe('decoratorExtension', () => {
it('should highlight code blocks within tables', async () => {
// Regression test for https://github.com/laurent22/joplin/issues/9477
const editorText = `
left | right
--------|-------
\`foo\` | bar
`;
const editor = await createTestEditor(
editorText,
// Put the initial cursor at the start of "foo"
EditorSelection.cursor(editorText.indexOf('foo')),
['TableRow', 'InlineCode'],
[decoratorExtension],
);
const codeBlock = editor.contentDOM.querySelector('.cm-inlineCode');
expect(codeBlock.textContent).toBe('`foo`');
expect(codeBlock.parentElement.classList.contains('.cm-tableRow'));
});
});

View File

@ -72,7 +72,7 @@ const taskMarkerDecoration = Decoration.mark({
attributes: { class: 'cm-taskMarker' },
});
type DecorationDescription = { pos: number; length?: number; decoration: Decoration };
type DecorationDescription = { pos: number; length: number; decoration: Decoration };
// Returns a set of [Decoration]s, associated with block syntax groups that require
// full-line styling.
@ -87,6 +87,7 @@ const computeDecorations = (view: EditorView) => {
const line = view.state.doc.lineAt(pos);
decorations.push({
pos: line.from,
length: 0,
decoration,
});
@ -185,13 +186,23 @@ const computeDecorations = (view: EditorView) => {
});
}
decorations.sort((a, b) => a.pos - b.pos);
// Decorations need to be sorted in ascending order first by start position,
// then by length. Adding items to the RangeSetBuilder in an incorrect order
// causes an exception to be thrown.
decorations.sort((a, b) => {
const posComparison = a.pos - b.pos;
if (posComparison !== 0) {
return posComparison;
}
const lengthComparison = a.length - b.length;
return lengthComparison;
});
// Items need to be added to a RangeSetBuilder in ascending order
const decorationBuilder = new RangeSetBuilder<Decoration>();
for (const { pos, length, decoration } of decorations) {
// Null length => entire line
decorationBuilder.add(pos, pos + (length ?? 0), decoration);
// Zero length => entire line
decorationBuilder.add(pos, pos + length, decoration);
}
return decorationBuilder.finish();
};

View File

@ -1,7 +1,7 @@
import { markdown } from '@codemirror/lang-markdown';
import { GFM as GithubFlavoredMarkdownExt } from '@lezer/markdown';
import { indentUnit, syntaxTree } from '@codemirror/language';
import { SelectionRange, EditorSelection, EditorState } from '@codemirror/state';
import { SelectionRange, EditorSelection, EditorState, Extension } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { MarkdownMathExtension } from '../markdown/markdownMathParser';
import forceFullParse from './forceFullParse';
@ -10,7 +10,10 @@ import loadLangauges from './loadLanguages';
// Creates and returns a minimal editor with markdown extensions. Waits to return the editor
// until all syntax tree tags in `expectedSyntaxTreeTags` exist.
const createTestEditor = async (
initialText: string, initialSelection: SelectionRange, expectedSyntaxTreeTags: string[],
initialText: string,
initialSelection: SelectionRange,
expectedSyntaxTreeTags: string[],
extraExtensions: Extension[] = [],
): Promise<EditorView> => {
await loadLangauges();
@ -23,6 +26,7 @@ const createTestEditor = async (
}),
indentUnit.of('\t'),
EditorState.tabSize.of(4),
extraExtensions,
],
});