fix(editor): should add HTTP protocol into link automatically (#11934)

Closes: [BS-3291](https://linear.app/affine-design/issue/BS-3291/工具栏展开时报错,链接无法点击打开)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - URLs entered without a protocol (e.g., "github.com/...") are now automatically normalized to use "https://", ensuring links are secure and consistently formatted.

- **Bug Fixes**
  - Improved handling and validation of links to prevent issues with missing or invalid protocols in bookmarks and inline links.
  - Simplified URL validation logic by leveraging native URL parsing, removing complex regex and email-specific checks.
  - Streamlined toolbar link actions to operate only on valid normalized URLs.
  - Refined URL detection in markdown preprocessing to exclude lines containing spaces from being treated as URLs.

- **Tests**
  - Added tests to verify that links without a protocol are correctly normalized and displayed across different views.
  - Updated URL validation tests to better reflect valid and invalid URL formats, including IP addresses and domain variants.

- **Style**
  - Updated snapshots to reflect the use of "https://" in links.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
fundon
2025-05-19 17:05:06 +00:00
parent 4d6a3731a3
commit fd838d4e2d
10 changed files with 160 additions and 120 deletions

View File

@@ -74,23 +74,34 @@ export const resolveRouteLinkMeta = (
}
};
export const isLink = (href: string) => {
const toURL = (str: string) => {
try {
const hasScheme = href.match(/^https?:\/\//);
if (!URL.canParse(str)) return null;
if (!hasScheme) {
const dotIdx = href.indexOf('.');
if (dotIdx > 0 && dotIdx < href.length - 1) {
href = `https://${href}`;
}
}
return Boolean(URL.canParse?.(href) ?? new URL(href));
return new URL(str);
} catch {
return null;
}
};
export const isLink = (str: string) => {
str = str.trim();
let url = toURL(str);
if (!url) {
const hasScheme = str.match(/^https?:\/\//);
if (!hasScheme) {
const dotIdx = str.indexOf('.');
if (dotIdx > 0 && dotIdx < str.length - 1) {
url = toURL(`https://${str}`);
}
}
}
return Boolean(url);
};
/**
* @see /packages/frontend/core/src/router.tsx
*/