facebook / lexical

Lexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.
https://lexical.dev
MIT License
17.5k stars 1.45k forks source link

Bug: AutoLinkPlugin fails simple examples like https://www.google.com #4692

Open cranium opened 10 months ago

cranium commented 10 months ago

Lexical version: 0.11.1

Steps To Reproduce

  1. Go to https://playground.lexical.dev/
  2. Type https://www.google.com
  3. https://www.google is linked but not .com

I have an example here which appears to match the problem in the playground:

import { AutoLinkNode } from "@lexical/link";
import { AutoLinkPlugin } from "@lexical/react/LexicalAutoLinkPlugin";
import {
  InitialConfigType,
  LexicalComposer,
} from "@lexical/react/LexicalComposer";
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
import { PlainTextPlugin } from "@lexical/react/LexicalPlainTextPlugin";
import { $getRoot, $getSelection, EditorState, ParagraphNode } from "lexical";

// When the editor changes, you can get notified via the
// LexicalOnChangePlugin!
function onChange(editorState: EditorState) {
  editorState.read(() => {
    // Read the contents of the EditorState here.
    const root = $getRoot();
    const selection = $getSelection();

    console.log(root, selection);
  });
}

// Catch any errors that occur during Lexical updates and log them
// or throw them as needed. If you don't throw them, Lexical will
// try to recover gracefully without losing user data.
function onError(error) {
  throw error;
}

const domainList = [
    "com",
    "google",
]

const Editor = () => {
  const URL_MATCHER = new RegExp(
    `(?:https?:\\/\\/)?[-a-zA-Z0-9@:%\\._\\+~#=]{1,256}\\.(?:${domainList.join(
      "|"
    )})\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&//=]*)`,
    "gi"
  );

  const MATCHERS = [
    (text: string) => {
      const match = URL_MATCHER.exec(text);

      console.log(text, match);

      if (match === null) {
        return null;
      }
      const fullMatch = match[0];
      return {
        index: match.index,
        length: fullMatch.length,
        text: fullMatch,
        url: fullMatch.startsWith("http") ? fullMatch : `https://${fullMatch}`,
        attributes: { rel: "noreferrer", target: "_blank" }, // Optional link attributes
      };
    },
  ];

  const initialConfig: InitialConfigType = {
    namespace: "MyEditor",
    onError,
    nodes: [AutoLinkNode],
  };

  return (
    <LexicalComposer initialConfig={initialConfig}>
      <PlainTextPlugin
        contentEditable={
          <ContentEditable />
        }
      />
      <LexicalClickableLinkPlugin />
      <AutoLinkPlugin matchers={MATCHERS} />
      <OnChangePlugin onChange={onChange} />
      <HistoryPlugin />
    </LexicalComposer>
  );
};

The current behavior

When typing https://www.google.com -> https://www.google is linked and .com is not.

The expected behavior

https://www.google.com would be linked.

Seems like in the autolink plugin there is a need to check existing links that are not separated by a whitespace.

rex-iotum commented 5 months ago

My observation from this is that it doesn't properly autolink unless the domain is 7 characters long. The link also has to be manually typed instead of pasted at once.

In the playground, https://www.123456.com skips the .com as part of the link, but https://1234567.com properly links fine.

larrygotto commented 1 month ago

Is there any progress on this? As in the mention above, this bug completely ruins the experience with urls that have a subdomain, such as .co.uk

linchen1987 commented 2 weeks ago

in https://playground.lexical.dev/

action working as expected
manually type https://www.google.com NOT working as expected
manually type https://google.com working as expected
copy & paste https://www.google.com working as expected
manually type google.com NOT working as expected
copy & paste google.com NOT working as expected
manually type www.google.com working as expected
copy & paste www.google.com working as expected
image