ProseMirror / prosemirror

The ProseMirror WYSIWYM editor

Home Page:http://prosemirror.net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tap to the left of a checkbox in iOS browsers results in the caret moving to the end of the document

xenohunter opened this issue · comments

In iOS browsers, if you add a single checkbox to a line (nothing to the right of it, not even spaces) and tap directly to the left of the checkbox, the caret position moves to the end of the last line in the editor.

Happens in: Safari iOS, Chrome iOS. (Android seems to be unaffected, couldn't reproduce.)

Code needed to reproduce

Checkbox NodeSpec:

const checkbox = {
  group: "inline",
  selectable: false,
  inline: true,
  attrs: { isChecked: { default: false } },
  toDOM(node) {
    return [
      "label",
      { class: "checkbox-wrapper", contenteditable: "false" },
      [
        "input",
        {
          type: "checkbox",
          ...(node.attrs.isChecked ? { checked: "true" } : undefined),
        },
      ],
    ];
  },
  parseDOM: [
    {
      tag: "input",
      getAttrs: (dom) => {
        if (typeof dom != "string")
          return {
            isChecked: (dom as any).getAttribute("checked") === "true",
          };
        else return {};
      },
    },
  ],
};

To run it, the ProseMirror basic example has been used with the following changes:

const nodes = schema.spec.nodes.addToEnd("checkbox", checkbox);

const mySchema = new Schema({
  nodes: addListNodes(nodes, "paragraph block*", "block"),
  marks: schema.spec.marks,
});

function App() {
  const view = useRef<EditorView>();
  const editorDiv = useRef<HTMLDivElement>(null);
  useEffect(() => {
    view.current = new EditorView(editorDiv.current, {
      state: EditorState.create({
        doc: mySchema.nodeFromJSON({ type: "doc", content: [{ type: "paragraph" }] }),
        plugins: [...exampleSetup({ schema: mySchema })],
      }),
    });
    return () => {
      view.current?.destroy();
    };
  }, []);

  return (
    <div className="App">
      <h1>Prosemirror Basic Example</h1>
      <div style={{
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
      }}>
        <div
          id="editor"
          ref={editorDiv}
          style={{
            width: 600,
            height: 300,
            textAlign: "left"
          }}
        />
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);