@wordpress/block-library
Version:
Block library for the WordPress editor.
247 lines (246 loc) • 7.21 kB
JavaScript
// packages/block-library/src/embed/edit.js
import {
createUpgradedEmbedBlock,
getClassNames,
removeAspectRatioClasses,
fallback,
getEmbedInfoByProvider,
getMergedAttributesWithPreview
} from "./util";
import EmbedControls from "./embed-controls";
import { embedContentIcon } from "./icons";
import EmbedLoading from "./embed-loading";
import EmbedPlaceholder from "./embed-placeholder";
import EmbedPreview from "./embed-preview";
import clsx from "clsx";
import { __, _x, sprintf } from "@wordpress/i18n";
import { useState, useEffect } from "@wordpress/element";
import { useDispatch, useSelect } from "@wordpress/data";
import { useBlockProps } from "@wordpress/block-editor";
import { store as coreStore } from "@wordpress/core-data";
import { View } from "@wordpress/primitives";
import { getAuthority } from "@wordpress/url";
import { Caption } from "../utils/caption";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var EmbedEdit = (props) => {
const {
attributes: {
providerNameSlug,
previewable,
responsive,
url: attributesUrl
},
attributes,
isSelected,
onReplace,
setAttributes,
insertBlocksAfter,
onFocus
} = props;
const defaultEmbedInfo = {
title: _x("Embed", "block title"),
icon: embedContentIcon
};
const { icon, title } = getEmbedInfoByProvider(providerNameSlug) || defaultEmbedInfo;
const [url, setURL] = useState(attributesUrl);
const [isEditingURL, setIsEditingURL] = useState(false);
const { invalidateResolution } = useDispatch(coreStore);
const {
preview,
fetching,
themeSupportsResponsive,
cannotEmbed,
hasResolved
} = useSelect(
(select) => {
const {
getEmbedPreview,
isPreviewEmbedFallback,
isRequestingEmbedPreview,
getThemeSupports,
hasFinishedResolution
} = select(coreStore);
if (!attributesUrl) {
return { fetching: false, cannotEmbed: false };
}
const embedPreview = getEmbedPreview(attributesUrl);
const previewIsFallback = isPreviewEmbedFallback(attributesUrl);
const badEmbedProvider = embedPreview?.html === false && embedPreview?.type === void 0;
const wordpressCantEmbed = embedPreview?.data?.status === 404;
const validPreview = !!embedPreview && !badEmbedProvider && !wordpressCantEmbed;
return {
preview: validPreview ? embedPreview : void 0,
fetching: isRequestingEmbedPreview(attributesUrl),
themeSupportsResponsive: getThemeSupports()["responsive-embeds"],
cannotEmbed: !validPreview || previewIsFallback,
hasResolved: hasFinishedResolution("getEmbedPreview", [
attributesUrl
])
};
},
[attributesUrl]
);
const getMergedAttributes = () => getMergedAttributesWithPreview(
attributes,
preview,
title,
responsive
);
function toggleResponsive(newAllowResponsive) {
const { className: className2 } = attributes;
const { html } = preview;
setAttributes({
allowResponsive: newAllowResponsive,
className: getClassNames(
html,
className2,
responsive && newAllowResponsive
)
});
}
useEffect(() => {
if (preview?.html || !cannotEmbed || !hasResolved) {
return;
}
const newURL = attributesUrl.replace(/\/$/, "");
setURL(newURL);
setIsEditingURL(false);
setAttributes({ url: newURL });
}, [
preview?.html,
attributesUrl,
cannotEmbed,
hasResolved,
setAttributes
]);
useEffect(() => {
if (!cannotEmbed || fetching || !url) {
return;
}
if (getAuthority(url) === "x.com") {
const newURL = new URL(url);
newURL.host = "twitter.com";
setAttributes({ url: newURL.toString() });
}
}, [url, cannotEmbed, fetching, setAttributes]);
useEffect(() => {
if (preview && !isEditingURL) {
const mergedAttributes = getMergedAttributes();
const hasChanges = Object.keys(mergedAttributes).some(
(key) => mergedAttributes[key] !== attributes[key]
);
if (hasChanges) {
setAttributes(mergedAttributes);
}
if (onReplace) {
const upgradedBlock = createUpgradedEmbedBlock(
props,
mergedAttributes
);
if (upgradedBlock) {
onReplace(upgradedBlock);
}
}
}
}, [preview, isEditingURL]);
const blockProps = useBlockProps();
if (fetching) {
return /* @__PURE__ */ jsx(View, { ...blockProps, children: /* @__PURE__ */ jsx(EmbedLoading, {}) });
}
const label = sprintf(__("%s URL"), title);
const showEmbedPlaceholder = !preview || cannotEmbed || isEditingURL;
if (showEmbedPlaceholder) {
return /* @__PURE__ */ jsx(View, { ...blockProps, children: /* @__PURE__ */ jsx(
EmbedPlaceholder,
{
icon,
label,
onFocus,
onSubmit: (event) => {
if (event) {
event.preventDefault();
}
const blockClass = removeAspectRatioClasses(
attributes.className
);
setIsEditingURL(false);
setAttributes({ url, className: blockClass });
},
value: url,
cannotEmbed,
onChange: (value) => setURL(value),
fallback: () => fallback(url, onReplace),
tryAgain: () => {
invalidateResolution("getEmbedPreview", [url]);
}
}
) });
}
const {
caption,
type,
allowResponsive,
className: classFromPreview
} = getMergedAttributes();
const className = clsx(classFromPreview, props.className);
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(
EmbedControls,
{
showEditButton: preview && !cannotEmbed,
themeSupportsResponsive,
blockSupportsResponsive: responsive,
allowResponsive,
toggleResponsive,
switchBackToURLInput: () => setIsEditingURL(true)
}
),
/* @__PURE__ */ jsxs(
"figure",
{
...blockProps,
className: clsx(blockProps.className, className, {
[`is-type-${type}`]: type,
[`is-provider-${providerNameSlug}`]: providerNameSlug,
[`wp-block-embed-${providerNameSlug}`]: providerNameSlug
}),
children: [
/* @__PURE__ */ jsx(
EmbedPreview,
{
preview,
previewable,
className,
url,
type,
caption,
onCaptionChange: (value) => setAttributes({ caption: value }),
isSelected,
icon,
label,
insertBlocksAfter,
attributes,
setAttributes
}
),
/* @__PURE__ */ jsx(
Caption,
{
attributes,
setAttributes,
isSelected,
insertBlocksAfter,
label: __("Embed caption text"),
showToolbarButton: isSelected
}
)
]
}
)
] });
};
var edit_default = EmbedEdit;
export {
edit_default as default
};
//# sourceMappingURL=edit.js.map