UNPKG

@wordpress/block-library

Version:
249 lines (209 loc) 8.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@wordpress/element"); var _util = require("./util"); var _embedControls = _interopRequireDefault(require("./embed-controls")); var _icons = require("./icons"); var _embedLoading = _interopRequireDefault(require("./embed-loading")); var _embedPlaceholder = _interopRequireDefault(require("./embed-placeholder")); var _embedPreview = _interopRequireDefault(require("./embed-preview")); var _classnames = _interopRequireDefault(require("classnames")); var _i18n = require("@wordpress/i18n"); var _data = require("@wordpress/data"); var _blockEditor = require("@wordpress/block-editor"); var _coreData = require("@wordpress/core-data"); var _primitives = require("@wordpress/primitives"); /** * Internal dependencies */ /** * External dependencies */ /** * WordPress dependencies */ const EmbedEdit = props => { const { attributes: { providerNameSlug, previewable, responsive, url: attributesUrl }, attributes, isSelected, onReplace, setAttributes, insertBlocksAfter, onFocus } = props; const defaultEmbedInfo = { title: (0, _i18n._x)('Embed', 'block title'), icon: _icons.embedContentIcon }; const { icon, title } = (0, _util.getEmbedInfoByProvider)(providerNameSlug) || defaultEmbedInfo; const [url, setURL] = (0, _element.useState)(attributesUrl); const [isEditingURL, setIsEditingURL] = (0, _element.useState)(false); const { invalidateResolution } = (0, _data.useDispatch)(_coreData.store); const { preview, fetching, themeSupportsResponsive, cannotEmbed } = (0, _data.useSelect)(select => { var _embedPreview$data; const { getEmbedPreview, isPreviewEmbedFallback, isRequestingEmbedPreview, getThemeSupports } = select(_coreData.store); if (!attributesUrl) { return { fetching: false, cannotEmbed: false }; } const embedPreview = getEmbedPreview(attributesUrl); const previewIsFallback = isPreviewEmbedFallback(attributesUrl); // The external oEmbed provider does not exist. We got no type info and no html. const badEmbedProvider = (embedPreview === null || embedPreview === void 0 ? void 0 : embedPreview.html) === false && (embedPreview === null || embedPreview === void 0 ? void 0 : embedPreview.type) === undefined; // Some WordPress URLs that can't be embedded will cause the API to return // a valid JSON response with no HTML and `data.status` set to 404, rather // than generating a fallback response as other embeds do. const wordpressCantEmbed = (embedPreview === null || embedPreview === void 0 ? void 0 : (_embedPreview$data = embedPreview.data) === null || _embedPreview$data === void 0 ? void 0 : _embedPreview$data.status) === 404; const validPreview = !!embedPreview && !badEmbedProvider && !wordpressCantEmbed; return { preview: validPreview ? embedPreview : undefined, fetching: isRequestingEmbedPreview(attributesUrl), themeSupportsResponsive: getThemeSupports()['responsive-embeds'], cannotEmbed: !validPreview || previewIsFallback }; }, [attributesUrl]); /** * Returns the attributes derived from the preview, merged with the current attributes. * * @param {boolean} ignorePreviousClassName Determines if the previous className attribute should be ignored when merging. * @return {Object} Merged attributes. */ const getMergedAttributes = function () { let ignorePreviousClassName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; return (0, _util.getMergedAttributesWithPreview)(attributes, preview, title, responsive, ignorePreviousClassName); }; const toggleResponsive = () => { const { allowResponsive, className } = attributes; const { html } = preview; const newAllowResponsive = !allowResponsive; setAttributes({ allowResponsive: newAllowResponsive, className: (0, _util.getClassNames)(html, className, responsive && newAllowResponsive) }); }; (0, _element.useEffect)(() => { if (!(preview !== null && preview !== void 0 && preview.html) || !cannotEmbed || fetching) { return; } // At this stage, we're not fetching the preview and know it can't be embedded, // so try removing any trailing slash, and resubmit. const newURL = attributesUrl.replace(/\/$/, ''); setURL(newURL); setIsEditingURL(false); setAttributes({ url: newURL }); }, [preview === null || preview === void 0 ? void 0 : preview.html, attributesUrl]); // Handle incoming preview. (0, _element.useEffect)(() => { if (preview && !isEditingURL) { // When obtaining an incoming preview, we set the attributes derived from // the preview data. In this case when getting the merged attributes, // we ignore the previous classname because it might not match the expected // classes by the new preview. setAttributes(getMergedAttributes(true)); if (onReplace) { const upgradedBlock = (0, _util.createUpgradedEmbedBlock)(props, getMergedAttributes()); if (upgradedBlock) { onReplace(upgradedBlock); } } } }, [preview, isEditingURL]); const blockProps = (0, _blockEditor.useBlockProps)(); if (fetching) { return (0, _element.createElement)(_primitives.View, blockProps, (0, _element.createElement)(_embedLoading.default, null)); } // translators: %s: type of embed e.g: "YouTube", "Twitter", etc. "Embed" is used when no specific type exists const label = (0, _i18n.sprintf)((0, _i18n.__)('%s URL'), title); // No preview, or we can't embed the current URL, or we've clicked the edit button. const showEmbedPlaceholder = !preview || cannotEmbed || isEditingURL; if (showEmbedPlaceholder) { return (0, _element.createElement)(_primitives.View, blockProps, (0, _element.createElement)(_embedPlaceholder.default, { icon: icon, label: label, onFocus: onFocus, onSubmit: event => { if (event) { event.preventDefault(); } setIsEditingURL(false); setAttributes({ url }); }, value: url, cannotEmbed: cannotEmbed, onChange: event => setURL(event.target.value), fallback: () => (0, _util.fallback)(url, onReplace), tryAgain: () => { invalidateResolution('getEmbedPreview', [url]); } })); } // Even though we set attributes that get derived from the preview, // we don't access them directly because for the initial render, // the `setAttributes` call will not have taken effect. If we're // rendering responsive content, setting the responsive classes // after the preview has been rendered can result in unwanted // clipping or scrollbars. The `getAttributesFromPreview` function // that `getMergedAttributes` uses is memoized so that we're not // calculating them on every render. const { caption, type, allowResponsive, className: classFromPreview } = getMergedAttributes(); const className = (0, _classnames.default)(classFromPreview, props.className); return (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_embedControls.default, { showEditButton: preview && !cannotEmbed, themeSupportsResponsive: themeSupportsResponsive, blockSupportsResponsive: responsive, allowResponsive: allowResponsive, toggleResponsive: toggleResponsive, switchBackToURLInput: () => setIsEditingURL(true) }), (0, _element.createElement)(_primitives.View, blockProps, (0, _element.createElement)(_embedPreview.default, { preview: preview, previewable: previewable, className: className, url: url, type: type, caption: caption, onCaptionChange: value => setAttributes({ caption: value }), isSelected: isSelected, icon: icon, label: label, insertBlocksAfter: insertBlocksAfter }))); }; var _default = EmbedEdit; exports.default = _default; //# sourceMappingURL=edit.js.map