From 84ebb1c8f2ca18200234ca6250e368dff9e2a3d0 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Fri, 5 Jan 2024 10:03:57 +0000 Subject: [PATCH] Merge pull request #16378 from overleaf/ae-upgrade-codemirror-3 Upgrade `@codemirror` dependencies GitOrigin-RevId: 242b1dbcf2878869957f40a5522dabcbcc181b5b --- package-lock.json | 92 +++++++++---------- .../extensions/visual/list-item-marker.ts | 9 +- services/web/package.json | 10 +- .../codemirror-editor-visual-list.spec.tsx | 10 +- 4 files changed, 63 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index e67ddc110b..c90ed209e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3428,13 +3428,13 @@ } }, "node_modules/@codemirror/commands": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.0.tgz", - "integrity": "sha512-tFfcxRIlOWiQDFhjBSWJ10MxcvbCIsRr6V64SgrcaY0MwNk32cUOcCuNlWo8VjV4qRQCgNgUAnIeo0svkk4R5Q==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz", + "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==", "dev": true, "dependencies": { "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.2.0", + "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.1.0" } @@ -3482,9 +3482,9 @@ } }, "node_modules/@codemirror/lang-markdown": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.1.tgz", - "integrity": "sha512-Tpk1+CllQ/KU27AYixsxvtqqQS2xYfLEUiBEyyzO+Y9/0LfI2oB1qM2cMhy0D7oRnG0ZSAy9qcYniZc9VtlIxg==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.3.tgz", + "integrity": "sha512-wCewRLWpdefWi7uVkHIDiE8+45Fe4buvMDZkihqEom5uRUQrl76Zb13emjeK3W+8pcRgRfAmwelURBbxNEKCIg==", "dev": true, "dependencies": { "@codemirror/autocomplete": "^6.7.1", @@ -3497,13 +3497,13 @@ } }, "node_modules/@codemirror/language": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.9.1.tgz", - "integrity": "sha512-lWRP3Y9IUdOms6DXuBpoWwjkR7yRmnS0hKYCbSfPz9v6Em1A1UCRujAkDiCrdYfs1Z0Eu4dGtwovNPStIfkgNA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.0.tgz", + "integrity": "sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==", "dev": true, "dependencies": { "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", + "@codemirror/view": "^6.23.0", "@lezer/common": "^1.1.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", @@ -3534,18 +3534,18 @@ } }, "node_modules/@codemirror/state": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.1.tgz", - "integrity": "sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz", + "integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==", "dev": true }, "node_modules/@codemirror/view": { - "version": "6.21.2", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.21.2.tgz", - "integrity": "sha512-EZ/Q1WeMWVarWiZHcy4E2aOjjDySeipVkPawOIu2iViZ1YNaZXPBqJBd9/2zLJtN/MrXKm0V1mHB8Cxn50t91A==", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.23.0.tgz", + "integrity": "sha512-/51px9N4uW8NpuWkyUX+iam5+PM6io2fm+QmRnzwqBy5v/pwGg9T0kILFtYeum8hjuvENtgsGNKluOfqIICmeQ==", "dev": true, "dependencies": { - "@codemirror/state": "^6.1.4", + "@codemirror/state": "^6.4.0", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } @@ -46491,13 +46491,13 @@ "@babel/preset-typescript": "^7.23.2", "@babel/register": "^7.22.15", "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#v6.10.2-overleaf-1", - "@codemirror/commands": "^6.3.0", - "@codemirror/lang-markdown": "^6.2.1", - "@codemirror/language": "^6.9.1", + "@codemirror/commands": "^6.3.3", + "@codemirror/lang-markdown": "^6.2.3", + "@codemirror/language": "^6.10.0", "@codemirror/lint": "^6.4.2", "@codemirror/search": "github:overleaf/codemirror-search#29f7a871969ad64b89341bacbe5d46dda02eee12", - "@codemirror/state": "^6.2.1", - "@codemirror/view": "^6.21.2", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.23.0", "@juggle/resize-observer": "^3.3.1", "@lezer/common": "^1.1.0", "@lezer/generator": "^1.5.1", @@ -49986,13 +49986,13 @@ } }, "@codemirror/commands": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.0.tgz", - "integrity": "sha512-tFfcxRIlOWiQDFhjBSWJ10MxcvbCIsRr6V64SgrcaY0MwNk32cUOcCuNlWo8VjV4qRQCgNgUAnIeo0svkk4R5Q==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz", + "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==", "dev": true, "requires": { "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.2.0", + "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.1.0" } @@ -50040,9 +50040,9 @@ } }, "@codemirror/lang-markdown": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.1.tgz", - "integrity": "sha512-Tpk1+CllQ/KU27AYixsxvtqqQS2xYfLEUiBEyyzO+Y9/0LfI2oB1qM2cMhy0D7oRnG0ZSAy9qcYniZc9VtlIxg==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.3.tgz", + "integrity": "sha512-wCewRLWpdefWi7uVkHIDiE8+45Fe4buvMDZkihqEom5uRUQrl76Zb13emjeK3W+8pcRgRfAmwelURBbxNEKCIg==", "dev": true, "requires": { "@codemirror/autocomplete": "^6.7.1", @@ -50055,13 +50055,13 @@ } }, "@codemirror/language": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.9.1.tgz", - "integrity": "sha512-lWRP3Y9IUdOms6DXuBpoWwjkR7yRmnS0hKYCbSfPz9v6Em1A1UCRujAkDiCrdYfs1Z0Eu4dGtwovNPStIfkgNA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.0.tgz", + "integrity": "sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==", "dev": true, "requires": { "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", + "@codemirror/view": "^6.23.0", "@lezer/common": "^1.1.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", @@ -50091,18 +50091,18 @@ } }, "@codemirror/state": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.1.tgz", - "integrity": "sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz", + "integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==", "dev": true }, "@codemirror/view": { - "version": "6.21.2", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.21.2.tgz", - "integrity": "sha512-EZ/Q1WeMWVarWiZHcy4E2aOjjDySeipVkPawOIu2iViZ1YNaZXPBqJBd9/2zLJtN/MrXKm0V1mHB8Cxn50t91A==", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.23.0.tgz", + "integrity": "sha512-/51px9N4uW8NpuWkyUX+iam5+PM6io2fm+QmRnzwqBy5v/pwGg9T0kILFtYeum8hjuvENtgsGNKluOfqIICmeQ==", "dev": true, "requires": { - "@codemirror/state": "^6.1.4", + "@codemirror/state": "^6.4.0", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } @@ -55177,13 +55177,13 @@ "@babel/preset-typescript": "^7.23.2", "@babel/register": "^7.22.15", "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#v6.10.2-overleaf-1", - "@codemirror/commands": "^6.3.0", - "@codemirror/lang-markdown": "^6.2.1", - "@codemirror/language": "^6.9.1", + "@codemirror/commands": "^6.3.3", + "@codemirror/lang-markdown": "^6.2.3", + "@codemirror/language": "^6.10.0", "@codemirror/lint": "^6.4.2", "@codemirror/search": "github:overleaf/codemirror-search#29f7a871969ad64b89341bacbe5d46dda02eee12", - "@codemirror/state": "^6.2.1", - "@codemirror/view": "^6.21.2", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.23.0", "@contentful/rich-text-html-renderer": "^16.0.2", "@contentful/rich-text-types": "^16.0.2", "@google-cloud/bigquery": "^6.0.1", diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/list-item-marker.ts b/services/web/frontend/js/features/source-editor/extensions/visual/list-item-marker.ts index e9bbfcb35d..e0be2c307a 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/list-item-marker.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/list-item-marker.ts @@ -17,7 +17,7 @@ export const listItemMarker = EditorState.transactionFilter.of(tr => { for (const [index, range] of tr.selection.ranges.entries()) { if (range.empty) { const node = syntaxTree(tr.state).resolveInner(range.anchor, 1) - const pos = chooseTargetPosition(node, tr, range) + const pos = chooseTargetPosition(node, tr, range, index) if (pos !== null) { selection = selection.replaceRange( EditorSelection.cursor( @@ -41,7 +41,8 @@ export const listItemMarker = EditorState.transactionFilter.of(tr => { const chooseTargetPosition = ( node: SyntaxNode, tr: Transaction, - range: SelectionRange + range: SelectionRange, + index: number ) => { let targetNode if (node.type.is('Item')) { @@ -62,8 +63,10 @@ const chooseTargetPosition = ( return targetNode.to } + const previousHead = tr.startState.selection.ranges[index]?.head + // keyboard navigation - if (range.assoc === 1 && !range.goalColumn) { + if (range.head < previousHead) { // moving backwards: jump to end of the previous line return Math.max(tr.state.doc.lineAt(range.anchor).from - 1, 1) } else { diff --git a/services/web/package.json b/services/web/package.json index 4e7a2018ae..be044e4fb4 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -177,13 +177,13 @@ "@babel/preset-typescript": "^7.23.2", "@babel/register": "^7.22.15", "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#v6.10.2-overleaf-1", - "@codemirror/commands": "^6.3.0", - "@codemirror/lang-markdown": "^6.2.1", - "@codemirror/language": "^6.9.1", + "@codemirror/commands": "^6.3.3", + "@codemirror/lang-markdown": "^6.2.3", + "@codemirror/language": "^6.10.0", "@codemirror/lint": "^6.4.2", "@codemirror/search": "github:overleaf/codemirror-search#29f7a871969ad64b89341bacbe5d46dda02eee12", - "@codemirror/state": "^6.2.1", - "@codemirror/view": "^6.21.2", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.23.0", "@juggle/resize-observer": "^3.3.1", "@lezer/common": "^1.1.0", "@lezer/generator": "^1.5.1", diff --git a/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual-list.spec.tsx b/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual-list.spec.tsx index 07000041c0..e29fd313a3 100644 --- a/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual-list.spec.tsx +++ b/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual-list.spec.tsx @@ -191,20 +191,22 @@ describe(' lists in Rich Text mode', function () { it('handles keyboard navigation around a list', function () { const content = [ + '', '\\begin{itemize}', '\\item One', '\\item Two', '\\end{itemize}', + '', ].join('\n') mountEditor(content) cy.get('.cm-line').eq(0).as('line') cy.get('@line').click('left') cy.get('@line').type( - '{downArrow}'.repeat(4) + // down to the end line - '{rightArrow}'.repeat(3) + // along a few characters - '{upArrow}'.repeat(2) + // up to the first list item - '{rightArrow}'.repeat(4) + // along to the start of the second list item + '{downArrow}'.repeat(2) + // down to the second list item + '{rightArrow}'.repeat(2) + // along a few characters + '{upArrow}'.repeat(1) + // up to the first list item + '{rightArrow}'.repeat(2) + // along to the start of the second list item '{shift}' + // start extending the selection '{rightArrow}'.repeat(3) // cover the word )