فهرست منبع

Merge pull request #17786 from overleaf/ar-select-caption-in-inserted-figures

Select caption text when new figure inserted

GitOrigin-RevId: 443594ff03c5a5cd316623e60b231a6af4390d3c
Andrew Rumble 2 سال پیش
والد
کامیت
9fda813e20

+ 20 - 22
services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal.tsx

@@ -10,6 +10,7 @@ import { FigureModalFooter } from './figure-modal-footer'
 import { lazy, memo, Suspense, useCallback, useEffect } from 'react'
 import { useCodeMirrorViewContext } from '../codemirror-editor'
 import { ChangeSpec } from '@codemirror/state'
+import { snippet } from '@codemirror/autocomplete'
 import {
   FigureData,
   PastedImageData,
@@ -206,29 +207,26 @@ const FigureModalContent = () => {
         effects: editFigureDataEffect.of(null),
       })
     } else {
-      view.dispatch(
-        view.state.changeByRange(range => {
-          const { pos, suffix } = ensureEmptyLine(view.state, range)
-          const widthArgument =
-            width !== undefined ? `[width=${width}\\linewidth]` : ''
-          const changes: ChangeSpec = view.state.changes({
-            insert: prepareLines(
-              [
-                '\\begin{figure}',
-                '\t\\centering',
-                `\t\\includegraphics${widthArgument}{${path}}`,
-                `\t${captionCommand}`,
-                `\t${labelCommand}`,
-                `\\end{figure}${suffix}`,
-              ],
-              view.state,
-              pos
-            ),
-            from: pos,
-          })
+      const { pos, suffix } = ensureEmptyLine(
+        view.state,
+        view.state.selection.main
+      )
 
-          return { range: range.map(changes), changes }
-        })
+      const widthArgument =
+        width !== undefined ? `[width=${width}\\linewidth]` : ''
+      const caption = includeCaption ? `\n\t\\caption{\${Enter Caption}}` : ''
+      const label = includeLabel ? `\n\t\\label{\${fig:enter-label}}` : ''
+
+      snippet(
+        `\\begin{figure}
+\t\\centering
+\t\\includegraphics${widthArgument}{${path}}${caption}${label}
+\\end{figure}${suffix}\${}`
+      )(
+        { state: view.state, dispatch: view.dispatch },
+        { label: 'figure' },
+        pos,
+        pos
       )
     }
     hide()

+ 87 - 5
services/web/test/frontend/features/source-editor/components/codemirror-editor-figure-modal.spec.tsx

@@ -113,7 +113,7 @@ describe('<FigureModal />', function () {
 
       cy.get('.cm-content').should(
         'have.text',
-        '\\begin{figure}    \\centering    Enter Caption    🏷fig:enter-label\\end{figure}'
+        '\\begin{figure}    \\centering    \\caption{Enter Caption}    🏷fig:enter-label\\end{figure}'
       )
     })
 
@@ -159,7 +159,7 @@ describe('<FigureModal />', function () {
       cy.findByText('Insert figure').click()
       cy.get('.cm-content').should(
         'have.text',
-        '\\begin{figure}    \\centering    Enter Caption    🏷fig:enter-label\\end{figure}'
+        '\\begin{figure}    \\centering    \\caption{Enter Caption}    🏷fig:enter-label\\end{figure}'
       )
     })
   })
@@ -233,7 +233,7 @@ describe('<FigureModal />', function () {
 
       cy.get('.cm-content').should(
         'have.text',
-        '\\begin{figure}    \\centering    Enter Caption    🏷fig:enter-label\\end{figure}'
+        '\\begin{figure}    \\centering    \\caption{Enter Caption}    🏷fig:enter-label\\end{figure}'
       )
     })
 
@@ -261,7 +261,7 @@ describe('<FigureModal />', function () {
 
       cy.get('.cm-content').should(
         'have.text',
-        '\\begin{figure}    \\centering    Enter Caption    🏷fig:enter-label\\end{figure}'
+        '\\begin{figure}    \\centering    \\caption{Enter Caption}    🏷fig:enter-label\\end{figure}'
       )
     })
   })
@@ -403,7 +403,89 @@ describe('<FigureModal />', function () {
 
       cy.get('.cm-content').should(
         'have.text',
-        '\\begin{figure}    \\centering    Enter Caption    🏷fig:enter-label\\end{figure}'
+        '\\begin{figure}    \\centering    \\caption{Enter Caption}    🏷fig:enter-label\\end{figure}'
+      )
+    })
+
+    it('Selects the caption when the figure is inserted with a caption', function () {
+      cy.get('@image-url-input').type('https://my-fake-website.com/frog.jpg')
+      cy.findByText('Insert figure').click()
+
+      cy.get('@linked-file-request').should('have.been.calledWithMatch', {
+        body: {
+          provider: 'url',
+          data: {
+            url: 'https://my-fake-website.com/frog.jpg',
+          },
+        },
+      })
+
+      cy.get('.cm-selectionLayer .cm-selectionBackground').should(
+        'have.length',
+        1
+      )
+
+      // If caption is selected then typing will replace the whole caption
+      cy.focused().type('My caption')
+      cy.get('.cm-content').should(
+        'have.text',
+        '\\begin{figure}    \\centering    \\caption{My caption}    🏷fig:enter-label\\end{figure}'
+      )
+    })
+
+    it('Selects the label when the figure is inserted without a caption', function () {
+      cy.get('@image-url-input').type('https://my-fake-website.com/frog.jpg')
+      cy.get('@include-caption-checkbox').uncheck()
+      cy.findByText('Insert figure').click()
+
+      cy.get('@linked-file-request').should('have.been.calledWithMatch', {
+        body: {
+          provider: 'url',
+          data: {
+            url: 'https://my-fake-website.com/frog.jpg',
+          },
+        },
+      })
+
+      cy.get('.cm-selectionLayer .cm-selectionBackground').should(
+        'have.length',
+        1
+      )
+
+      // If label is selected then typing will replace the whole label
+      cy.focused().type('fig:my-label')
+      cy.get('.cm-content').should(
+        'have.text',
+        '\\begin{figure}    \\centering    \\label{fig:my-label}\\end{figure}'
+      )
+    })
+
+    it('Places the cursor after the figure if it is inserted without a caption or a label', function () {
+      cy.get('@image-url-input').type('https://my-fake-website.com/frog.jpg')
+      cy.get('@include-caption-checkbox').uncheck()
+      cy.get('@include-label-checkbox').uncheck()
+
+      cy.findByText('Insert figure').click()
+
+      cy.get('@linked-file-request').should('have.been.calledWithMatch', {
+        body: {
+          provider: 'url',
+          data: {
+            url: 'https://my-fake-website.com/frog.jpg',
+          },
+        },
+      })
+
+      cy.get('.cm-content').should(
+        'have.text',
+        '\\begin{figure}    \\centering\\end{figure}'
+      )
+
+      cy.focused().type('Some more text')
+
+      cy.get('.cm-content').should(
+        'have.text',
+        '\\begin{figure}    \\centering\\end{figure}Some more text'
       )
     })
   })