Repository: prettier/prettier (JavaScript)

Issue:
Wrong cursorOffset with formatted JSX text
In a similar vein to #12491 (which I am still intending to fix), I found a misplaced cursorOffset issue with code like this

```jsx
<>a•
  <div>hi</div>
</>
```
(where `•` denotes the given cursor position)

When passed into prettier we get:
```jsx
<>•
  a<div>hi</div>
</>
```

Which is unexpected, because the a correctly moves down, but the cursor stays up.

Here is code for testing it:
```js
const prettier = require("prettier");
prettier.formatWithCursor(["<>a", "  <div>hi</div>", "</>"].join("\n"), { cursorOffset: 3, parser: 'babel' });
```
and the runkit to see it in the browser:
https://runkit.com/gregoor/prettier-jsx-cursor-offset-bug


Hints:

Patch:
diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js
--- a/src/language-js/print/jsx.js
+++ b/src/language-js/print/jsx.js
@@ -13,6 +13,7 @@ import {
   ifBreak,
   lineSuffixBoundary,
   join,
+  cursor,
 } from "../../document/builders.js";
 import { willBreak, replaceEndOfLine } from "../../document/utils.js";
 import UnexpectedNodeError from "../../utils/unexpected-node-error.js";
@@ -50,6 +51,7 @@ const isEmptyStringOrAnyLine = (doc) =>
  * @typedef {import("../../common/ast-path.js").default} AstPath
  * @typedef {import("../types/estree.js").Node} Node
  * @typedef {import("../types/estree.js").JSXElement} JSXElement
+ * @typedef {import("../../document/builders.js").Doc} Doc
  */
 
 // JSX expands children from the inside-out, instead of the outside-in.
@@ -236,10 +238,22 @@ function printJsxElementInternal(path, options, print) {
   // If there is text we use `fill` to fit as much onto each line as possible.
   // When there is no text (just tags and expressions) we use `group`
   // to output each on a separate line.
-  const content = containsText
+  /** @type {Doc} */
+  let content = containsText
     ? fill(multilineChildren)
     : group(multilineChildren, { shouldBreak: true });
 
+  /*
+  `printJsxChildren` won't call `print` on `JSXText`
+  When the cursorNode is inside `cursor` won't get print.
+  */
+  if (
+    options.cursorNode?.type === "JSXText" &&
+    node.children.includes(options.cursorNode)
+  ) {
+    content = [cursor, content, cursor];
+  }
+
   if (isMdxBlock) {
     return content;
   }


Test patch:
diff --git a/tests/format/jsx/cursor/__snapshots__/jsfmt.spec.js.snap b/tests/format/jsx/cursor/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
--- /dev/null
+++ b/tests/format/jsx/cursor/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`in-jsx-text.js format 1`] = `
+====================================options=====================================
+cursorOffset: 3
+parsers: ["babel", "typescript", "flow"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+<>a<|>
+  <div>hi</div>
+</>
+
+=====================================output=====================================
+<>
+  a<|><div>hi</div>
+</>;
+
+================================================================================
+`;
diff --git a/tests/format/jsx/cursor/in-jsx-text.js b/tests/format/jsx/cursor/in-jsx-text.js
new file mode 100644
--- /dev/null
+++ b/tests/format/jsx/cursor/in-jsx-text.js
@@ -0,0 +1,3 @@
+<>a<|>
+  <div>hi</div>
+</>
diff --git a/tests/format/jsx/cursor/jsfmt.spec.js b/tests/format/jsx/cursor/jsfmt.spec.js
new file mode 100644
--- /dev/null
+++ b/tests/format/jsx/cursor/jsfmt.spec.js
@@ -0,0 +1 @@
+run_spec(import.meta, ["babel", "typescript", "flow"]);