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

Open
opened 2023-10-30 22:46:26 +01:00 by xenohunter · 0 comments
xenohunter commented 2023-10-30 22:46:26 +01:00 (Migrated from github.com)

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>
);
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`: ```typescript 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](https://prosemirror.net/examples/basic/) has been used with the following changes: ```typescript 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> ); ```
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
prosemirror/prosemirror#1424
No description provided.