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/getScrollFraction.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
packages/editor/CodeMirror/markdown/decoratorExtension.js packages/editor/CodeMirror/markdown/decoratorExtension.js
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/markdown/markdownCommands.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/getScrollFraction.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
packages/editor/CodeMirror/markdown/decoratorExtension.js packages/editor/CodeMirror/markdown/decoratorExtension.js
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
packages/editor/CodeMirror/markdown/markdownCommands.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' }, 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 // Returns a set of [Decoration]s, associated with block syntax groups that require
// full-line styling. // full-line styling.
@ -87,6 +87,7 @@ const computeDecorations = (view: EditorView) => {
const line = view.state.doc.lineAt(pos); const line = view.state.doc.lineAt(pos);
decorations.push({ decorations.push({
pos: line.from, pos: line.from,
length: 0,
decoration, 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>(); const decorationBuilder = new RangeSetBuilder<Decoration>();
for (const { pos, length, decoration } of decorations) { for (const { pos, length, decoration } of decorations) {
// Null length => entire line // Zero length => entire line
decorationBuilder.add(pos, pos + (length ?? 0), decoration); decorationBuilder.add(pos, pos + length, decoration);
} }
return decorationBuilder.finish(); return decorationBuilder.finish();
}; };

View File

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