feat: support multi-embed pasting & x.com domain (#7516)

This commit is contained in:
David Luzar 2024-01-04 13:27:52 +01:00 committed by GitHub
parent 4249b7dec8
commit 43ccc875fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 27 deletions

View file

@ -182,6 +182,7 @@ import {
ExcalidrawIframeLikeElement,
IframeData,
ExcalidrawIframeElement,
ExcalidrawEmbeddableElement,
} from "../element/types";
import { getCenter, getDistance } from "../gesture";
import {
@ -271,11 +272,12 @@ import {
easeOut,
updateStable,
addEventListener,
normalizeEOL,
} from "../utils";
import {
createSrcDoc,
embeddableURLValidator,
extractSrc,
maybeParseEmbedSrc,
getEmbedLink,
} from "../element/embeddable";
import {
@ -2924,21 +2926,49 @@ class App extends React.Component<AppProps, AppState> {
retainSeed: isPlainPaste,
});
} else if (data.text) {
const maybeUrl = extractSrc(data.text);
const nonEmptyLines = normalizeEOL(data.text)
.split(/\n+/)
.map((s) => s.trim())
.filter(Boolean);
const embbeddableUrls = nonEmptyLines
.map((str) => maybeParseEmbedSrc(str))
.filter((string) => {
return (
embeddableURLValidator(string, this.props.validateEmbeddable) &&
(/^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(string) ||
getEmbedLink(string)?.type === "video")
);
});
if (
!isPlainPaste &&
embeddableURLValidator(maybeUrl, this.props.validateEmbeddable) &&
(/^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(maybeUrl) ||
getEmbedLink(maybeUrl)?.type === "video")
!IS_PLAIN_PASTE &&
embbeddableUrls.length > 0 &&
// if there were non-embeddable text (lines) mixed in with embeddable
// urls, ignore and paste as text
embbeddableUrls.length === nonEmptyLines.length
) {
const embeddable = this.insertEmbeddableElement({
sceneX,
sceneY,
link: normalizeLink(maybeUrl),
});
if (embeddable) {
this.setState({ selectedElementIds: { [embeddable.id]: true } });
const embeddables: NonDeleted<ExcalidrawEmbeddableElement>[] = [];
for (const url of embbeddableUrls) {
const prevEmbeddable: ExcalidrawEmbeddableElement | undefined =
embeddables[embeddables.length - 1];
const embeddable = this.insertEmbeddableElement({
sceneX: prevEmbeddable
? prevEmbeddable.x + prevEmbeddable.width + 20
: sceneX,
sceneY,
link: normalizeLink(url),
});
if (embeddable) {
embeddables.push(embeddable);
}
}
if (embeddables.length) {
this.setState({
selectedElementIds: Object.fromEntries(
embeddables.map((embeddable) => [embeddable.id, true]),
),
});
}
return;
}