feat: remove ExcalidrawEmbeddableElement.validated flag (#7539)

This commit is contained in:
David Luzar 2024-01-11 17:42:51 +01:00 committed by GitHub
parent 86cfeb714c
commit 0c24a7042f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 94 additions and 39 deletions

View file

@ -246,6 +246,7 @@ import {
ToolType,
OnUserFollowedPayload,
UnsubscribeCallback,
EmbedsValidationStatus,
ElementsPendingErasure,
} from "../types";
import {
@ -529,6 +530,15 @@ class App extends React.Component<AppProps, AppState> {
public files: BinaryFiles = {};
public imageCache: AppClassProperties["imageCache"] = new Map();
private iFrameRefs = new Map<ExcalidrawElement["id"], HTMLIFrameElement>();
/**
* Indicates whether the embeddable's url has been validated for rendering.
* If value not set, indicates that the validation is pending.
* Initially or on url change the flag is not reset so that we can guarantee
* the validation came from a trusted source (the editor).
**/
private embedsValidationStatus: EmbedsValidationStatus = new Map();
/** embeds that have been inserted to DOM (as a perf optim, we don't want to
* insert to DOM before user initially scrolls to them) */
private initializedEmbeds = new Set<ExcalidrawIframeLikeElement["id"]>();
private elementsPendingErasure: ElementsPendingErasure = new Set();
@ -869,6 +879,14 @@ class App extends React.Component<AppProps, AppState> {
);
}
private updateEmbedValidationStatus = (
element: ExcalidrawEmbeddableElement,
status: boolean,
) => {
this.embedsValidationStatus.set(element.id, status);
ShapeCache.delete(element);
};
private updateEmbeddables = () => {
const iframeLikes = new Set<ExcalidrawIframeLikeElement["id"]>();
@ -876,7 +894,7 @@ class App extends React.Component<AppProps, AppState> {
this.scene.getNonDeletedElements().filter((element) => {
if (isEmbeddableElement(element)) {
iframeLikes.add(element.id);
if (element.validated == null) {
if (!this.embedsValidationStatus.has(element.id)) {
updated = true;
const validated = embeddableURLValidator(
@ -884,8 +902,7 @@ class App extends React.Component<AppProps, AppState> {
this.props.validateEmbeddable,
);
mutateElement(element, { validated }, false);
ShapeCache.delete(element);
this.updateEmbedValidationStatus(element, validated);
}
} else if (isIframeElement(element)) {
iframeLikes.add(element.id);
@ -914,7 +931,9 @@ class App extends React.Component<AppProps, AppState> {
.getNonDeletedElements()
.filter(
(el): el is NonDeleted<ExcalidrawIframeLikeElement> =>
(isEmbeddableElement(el) && !!el.validated) || isIframeElement(el),
(isEmbeddableElement(el) &&
this.embedsValidationStatus.get(el.id) === true) ||
isIframeElement(el),
);
return (
@ -1507,6 +1526,9 @@ class App extends React.Component<AppProps, AppState> {
setAppState={this.setAppState}
onLinkOpen={this.props.onLinkOpen}
setToast={this.setToast}
updateEmbedValidationStatus={
this.updateEmbedValidationStatus
}
/>
)}
{this.props.aiEnabled !== false &&
@ -1617,6 +1639,7 @@ class App extends React.Component<AppProps, AppState> {
renderGrid: true,
canvasBackgroundColor:
this.state.viewBackgroundColor,
embedsValidationStatus: this.embedsValidationStatus,
elementsPendingErasure: this.elementsPendingErasure,
}}
/>
@ -6425,7 +6448,6 @@ class App extends React.Component<AppProps, AppState> {
width: embedLink.intrinsicSize.w,
height: embedLink.intrinsicSize.h,
link,
validated: null,
});
this.scene.replaceAllElements([
@ -6659,7 +6681,6 @@ class App extends React.Component<AppProps, AppState> {
if (elementType === "embeddable") {
element = newEmbeddableElement({
type: "embeddable",
validated: null,
...baseElementAttributes,
});
} else {