fix(editor): markdown url preprocessor should fully encode partial encoded url (#12091)

Closes: [BS-3369](https://linear.app/affine-design/issue/BS-3369/昨天发现-footnote-中的引用,和实际渲染出来的对不上)

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

## Summary by CodeRabbit

- **Bug Fixes**
	- Improved handling of URLs in footnote definitions to ensure all URLs are fully percent-encoded, including those that were only partially encoded before.

- **Tests**
	- Added a new test case to verify that partially encoded URLs in footnotes are now fully encoded as expected.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
donteatfriedrice
2025-04-30 12:08:45 +00:00
parent 8ac3257f73
commit 83e55fad1e
2 changed files with 24 additions and 7 deletions
@@ -23,12 +23,17 @@ type FootnoteDefinition = {
content: FootNoteReferenceParams;
};
// Check if a URL is already encoded with encodeURIComponent
function isEncoded(uri: string): boolean {
/**
* Check if a URL is already encoded with encodeURIComponent to avoid markdown link parsing
* @example
* https://example.com/path%20with%20spaces should return false
* https://example.com/ should return false
* https%3A%2F%2Fexample.com%2F should return true
*/
function isFullyEncoded(uri: string): boolean {
try {
// If decoding produces a different result than the original,
// then the URI contains encoded characters
return uri !== decodeURIComponent(uri);
// Should check if the components of the URI are fully encoded
return uri === encodeURIComponent(decodeURIComponent(uri));
} catch {
// If decoding fails, the URI contains invalid percent-encoding
return true;
@@ -194,10 +199,10 @@ class FootnoteParser {
// Process URLs in footnote content
private processUrls(footnote: FootnoteDefinition): FootnoteDefinition {
const content = footnote.content;
if (content.url && !isEncoded(content.url)) {
if (content.url && !isFullyEncoded(content.url)) {
content.url = encodeURIComponent(content.url);
}
if (content.favicon && !isEncoded(content.favicon)) {
if (content.favicon && !isFullyEncoded(content.favicon)) {
content.favicon = encodeURIComponent(content.favicon);
}
return footnote;