mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat(editor): add embed iframe provider google docs (#10998)
Related [BS-2835](https://linear.app/affine-design/issue/BS-2835/支持更多-embed-iframe-providers)
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { EmbedIframeConfigExtension } from '../../extension/embed-iframe-config';
|
||||
import {
|
||||
type EmbedIframeUrlValidationOptions,
|
||||
validateEmbedIframeUrl,
|
||||
} from '../../utils';
|
||||
|
||||
const GOOGLE_DOCS_DEFAULT_WIDTH_IN_SURFACE = 800;
|
||||
const GOOGLE_DOCS_DEFAULT_HEIGHT_IN_SURFACE = 600;
|
||||
const GOOGLE_DOCS_DEFAULT_WIDTH_PERCENT = 100;
|
||||
const GOOGLE_DOCS_DEFAULT_HEIGHT_IN_NOTE = 600;
|
||||
|
||||
const googleDocsUrlValidationOptions: EmbedIframeUrlValidationOptions = {
|
||||
protocols: ['https:'],
|
||||
hostnames: ['docs.google.com'],
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the URL has a valid sharing parameter
|
||||
* @param parsedUrl Parsed URL object
|
||||
* @returns Boolean indicating if the URL has a valid sharing parameter
|
||||
*/
|
||||
function hasValidSharingParam(parsedUrl: URL): boolean {
|
||||
const usp = parsedUrl.searchParams.get('usp');
|
||||
return usp === 'sharing';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if a URL is a valid Google Docs URL
|
||||
* Valid format: https://docs.google.com/document/d/doc-id/edit?usp=sharing
|
||||
* @param url The URL to validate
|
||||
* @param strictMode Whether to strictly validate sharing parameters
|
||||
* @returns Boolean indicating if the URL is a valid Google Docs URL
|
||||
*/
|
||||
function isValidGoogleDocsUrl(url: string, strictMode = true): boolean {
|
||||
try {
|
||||
if (!validateEmbedIframeUrl(url, googleDocsUrlValidationOptions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parsedUrl = new URL(url);
|
||||
|
||||
if (strictMode && !hasValidSharingParam(parsedUrl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const pathSegments = parsedUrl.pathname.split('/').filter(Boolean);
|
||||
return (
|
||||
pathSegments[0] === 'document' &&
|
||||
pathSegments[1] === 'd' &&
|
||||
pathSegments.length >= 3 &&
|
||||
!!pathSegments[2]
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn('Invalid Google Docs URL:', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const googleDocsConfig = {
|
||||
name: 'google-docs',
|
||||
match: (url: string) => isValidGoogleDocsUrl(url),
|
||||
buildOEmbedUrl: (url: string) => {
|
||||
if (!isValidGoogleDocsUrl(url)) {
|
||||
return undefined;
|
||||
}
|
||||
return url;
|
||||
},
|
||||
useOEmbedUrlDirectly: true,
|
||||
options: {
|
||||
widthInSurface: GOOGLE_DOCS_DEFAULT_WIDTH_IN_SURFACE,
|
||||
heightInSurface: GOOGLE_DOCS_DEFAULT_HEIGHT_IN_SURFACE,
|
||||
widthPercent: GOOGLE_DOCS_DEFAULT_WIDTH_PERCENT,
|
||||
heightInNote: GOOGLE_DOCS_DEFAULT_HEIGHT_IN_NOTE,
|
||||
allowFullscreen: true,
|
||||
style: 'border: none; border-radius: 8px;',
|
||||
},
|
||||
};
|
||||
|
||||
export const GoogleDocsEmbedConfig =
|
||||
EmbedIframeConfigExtension(googleDocsConfig);
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ExcalidrawEmbedConfig } from './excalidraw';
|
||||
import { GoogleDocsEmbedConfig } from './google-docs';
|
||||
import { GoogleDriveEmbedConfig } from './google-drive';
|
||||
import { MiroEmbedConfig } from './miro';
|
||||
import { SpotifyEmbedConfig } from './spotify';
|
||||
@@ -8,4 +9,5 @@ export const EmbedIframeConfigExtensions = [
|
||||
GoogleDriveEmbedConfig,
|
||||
MiroEmbedConfig,
|
||||
ExcalidrawEmbedConfig,
|
||||
GoogleDocsEmbedConfig,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user