From db26446d76e32295085ad25b2ffd3ad8dd2323cc Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Thu, 29 Jun 2023 09:51:57 +0100 Subject: [PATCH] [visual] Avoid showing braces around section headings when editing the section title (#13464) GitOrigin-RevId: 050663e752720993ccf1ab745a8b4250d54198fc --- .../extensions/visual/atomic-decorations.ts | 25 +++++++++++++------ .../codemirror-editor-visual.spec.tsx | 10 +++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts b/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts index c71173b0af..29223434d5 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/atomic-decorations.ts @@ -45,6 +45,7 @@ import { InlineGraphicsWidget } from './visual-widgets/inline-graphics' import getMeta from '../../../../utils/meta' import { EditableGraphicsWidget } from './visual-widgets/editable-graphics' import { EditableInlineGraphicsWidget } from './visual-widgets/editable-inline-graphics' +import { CloseBrace, OpenBrace } from '../../lezer-latex/latex.terms.mjs' type Options = { fileTreeManager: { @@ -449,12 +450,16 @@ export const atomicDecorations = (options: Options) => { 'SectioningCommand' ) if (ancestorNode) { - const shouldShowBraces = !shouldDecorate(state, ancestorNode) // a section (or subsection, etc) command const argumentNode = ancestorNode.getChild('SectioningArgument') if (argumentNode) { - const braces = argumentNode.getChildren('$Brace') - if (braces.length !== 2) { + const openBrace = argumentNode.getChild(OpenBrace) + const closeBrace = argumentNode.getChild(CloseBrace) + if (!openBrace || !closeBrace) { + return false + } + const sectionCtrlSeqNode = ancestorNode.getChild('$CtrlSeq') + if (!sectionCtrlSeqNode) { return false } const titleNode = argumentNode.getChild('LongArg') @@ -466,17 +471,23 @@ export const atomicDecorations = (options: Options) => { return false } + const showBraces = + selectionIntersects(state.selection, sectionCtrlSeqNode) || + selectionIntersects(state.selection, openBrace) || + selectionIntersects(state.selection, closeBrace) + decorations.push( Decoration.replace({ - widget: new BraceWidget(shouldShowBraces ? '}' : ''), - }).range(braces[1].from, braces[1].to) + widget: new BraceWidget(showBraces ? '{' : ''), + }).range(nodeRef.from, titleNode.from) ) decorations.push( Decoration.replace({ - widget: new BraceWidget(shouldShowBraces ? '{' : ''), - }).range(nodeRef.from, titleNode.from) + widget: new BraceWidget(showBraces ? '}' : ''), + }).range(closeBrace.from, closeBrace.to) ) + return false } } diff --git a/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx b/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx index b01b2bd53a..4b4a035754 100644 --- a/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx +++ b/services/web/test/frontend/features/source-editor/components/codemirror-editor-visual.spec.tsx @@ -151,9 +151,13 @@ describe(' in Rich Text mode', function () { cy.get('@first-line').should('have.text', `\\${command}{}`) cy.get('@first-line').type('{rightArrow} ') cy.get('@first-line').should('have.text', `\\${command}{} `) - // Press enter before closing brace - cy.get('@first-line').type('{Backspace}{leftArrow}title{leftArrow}{Enter}') - cy.get('@first-line').should('have.text', 'title') + // Type a section heading + cy.get('@first-line').type('{Backspace}{leftArrow}title') + cy.get('@first-line').should('have.text', '{title}') // braces are visible as cursor is adjacent + cy.get('@first-line').type('{leftArrow}') + cy.get('@first-line').should('have.text', 'title') // braces are hidden as cursor is not adjacent + cy.get('@first-line').type('{Enter}') + cy.get('@first-line').should('have.text', 'title') // braces are hidden as cursor is on the next line cy.get('@first-line').find(`.ol-cm-heading.ol-cm-command-${command}`) })