UNPKG

6.8 kBJavaScriptView Raw
1import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2import _objectSpread from "@babel/runtime/helpers/esm/objectSpread";
3import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
4import { createElement } from "@wordpress/element";
5
6/**
7 * Internal dependencies
8 */
9import { common, others } from './core-embeds';
10import { DEFAULT_EMBED_BLOCK, WORDPRESS_EMBED_BLOCK, ASPECT_RATIOS } from './constants';
11/**
12 * External dependencies
13 */
14
15import { includes } from 'lodash';
16import classnames from 'classnames/dedupe';
17/**
18 * WordPress dependencies
19 */
20
21import { renderToString } from '@wordpress/element';
22import { createBlock } from '@wordpress/blocks';
23/**
24 * Returns true if any of the regular expressions match the URL.
25 *
26 * @param {string} url The URL to test.
27 * @param {Array} patterns The list of regular expressions to test agains.
28 * @return {boolean} True if any of the regular expressions match the URL.
29 */
30
31export var matchesPatterns = function matchesPatterns(url) {
32 var patterns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
33 return patterns.some(function (pattern) {
34 return url.match(pattern);
35 });
36};
37/**
38 * Finds the block name that should be used for the URL, based on the
39 * structure of the URL.
40 *
41 * @param {string} url The URL to test.
42 * @return {string} The name of the block that should be used for this URL, e.g. core-embed/twitter
43 */
44
45export var findBlock = function findBlock(url) {
46 var _arr = [].concat(_toConsumableArray(common), _toConsumableArray(others));
47
48 for (var _i = 0; _i < _arr.length; _i++) {
49 var block = _arr[_i];
50
51 if (matchesPatterns(url, block.patterns)) {
52 return block.name;
53 }
54 }
55
56 return DEFAULT_EMBED_BLOCK;
57};
58export var isFromWordPress = function isFromWordPress(html) {
59 return includes(html, 'class="wp-embedded-content"');
60};
61export var getPhotoHtml = function getPhotoHtml(photo) {
62 // 100% width for the preview so it fits nicely into the document, some "thumbnails" are
63 // actually the full size photo. If thumbnails not found, use full image.
64 var imageUrl = photo.thumbnail_url ? photo.thumbnail_url : photo.url;
65 var photoPreview = createElement("p", null, createElement("img", {
66 src: imageUrl,
67 alt: photo.title,
68 width: "100%"
69 }));
70 return renderToString(photoPreview);
71};
72/***
73 * Creates a more suitable embed block based on the passed in props
74 * and attributes generated from an embed block's preview.
75 *
76 * We require `attributesFromPreview` to be generated from the latest attributes
77 * and preview, and because of the way the react lifecycle operates, we can't
78 * guarantee that the attributes contained in the block's props are the latest
79 * versions, so we require that these are generated separately.
80 * See `getAttributesFromPreview` in the generated embed edit component.
81 *
82 * @param {Object} props The block's props.
83 * @param {Object} attributesFromPreview Attributes generated from the block's most up to date preview.
84 * @return {Object|undefined} A more suitable embed block if one exists.
85 */
86
87export var createUpgradedEmbedBlock = function createUpgradedEmbedBlock(props, attributesFromPreview) {
88 var preview = props.preview,
89 name = props.name;
90 var url = props.attributes.url;
91
92 if (!url) {
93 return;
94 }
95
96 var matchingBlock = findBlock(url); // WordPress blocks can work on multiple sites, and so don't have patterns,
97 // so if we're in a WordPress block, assume the user has chosen it for a WordPress URL.
98
99 if (WORDPRESS_EMBED_BLOCK !== name && DEFAULT_EMBED_BLOCK !== matchingBlock) {
100 // At this point, we have discovered a more suitable block for this url, so transform it.
101 if (name !== matchingBlock) {
102 return createBlock(matchingBlock, {
103 url: url
104 });
105 }
106 }
107
108 if (preview) {
109 var html = preview.html; // We can't match the URL for WordPress embeds, we have to check the HTML instead.
110
111 if (isFromWordPress(html)) {
112 // If this is not the WordPress embed block, transform it into one.
113 if (WORDPRESS_EMBED_BLOCK !== name) {
114 return createBlock(WORDPRESS_EMBED_BLOCK, _objectSpread({
115 url: url
116 }, attributesFromPreview));
117 }
118 }
119 }
120};
121/**
122 * Returns class names with any relevant responsive aspect ratio names.
123 *
124 * @param {string} html The preview HTML that possibly contains an iframe with width and height set.
125 * @param {string} existingClassNames Any existing class names.
126 * @param {boolean} allowResponsive If the responsive class names should be added, or removed.
127 * @return {string} Deduped class names.
128 */
129
130export function getClassNames(html) {
131 var existingClassNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
132 var allowResponsive = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
133
134 if (!allowResponsive) {
135 // Remove all of the aspect ratio related class names.
136 var aspectRatioClassNames = {
137 'wp-has-aspect-ratio': false
138 };
139
140 for (var ratioIndex = 0; ratioIndex < ASPECT_RATIOS.length; ratioIndex++) {
141 var aspectRatioToRemove = ASPECT_RATIOS[ratioIndex];
142 aspectRatioClassNames[aspectRatioToRemove.className] = false;
143 }
144
145 return classnames(existingClassNames, aspectRatioClassNames);
146 }
147
148 var previewDocument = document.implementation.createHTMLDocument('');
149 previewDocument.body.innerHTML = html;
150 var iframe = previewDocument.body.querySelector('iframe'); // If we have a fixed aspect iframe, and it's a responsive embed block.
151
152 if (iframe && iframe.height && iframe.width) {
153 var aspectRatio = (iframe.width / iframe.height).toFixed(2); // Given the actual aspect ratio, find the widest ratio to support it.
154
155 for (var _ratioIndex = 0; _ratioIndex < ASPECT_RATIOS.length; _ratioIndex++) {
156 var potentialRatio = ASPECT_RATIOS[_ratioIndex];
157
158 if (aspectRatio >= potentialRatio.ratio) {
159 var _classnames;
160
161 return classnames(existingClassNames, (_classnames = {}, _defineProperty(_classnames, potentialRatio.className, allowResponsive), _defineProperty(_classnames, 'wp-has-aspect-ratio', allowResponsive), _classnames));
162 }
163 }
164 }
165
166 return existingClassNames;
167}
168/**
169 * Fallback behaviour for unembeddable URLs.
170 * Creates a paragraph block containing a link to the URL, and calls `onReplace`.
171 *
172 * @param {string} url The URL that could not be embedded.
173 * @param {function} onReplace Function to call with the created fallback block.
174 */
175
176export function fallback(url, onReplace) {
177 var link = createElement("a", {
178 href: url
179 }, url);
180 onReplace(createBlock('core/paragraph', {
181 content: renderToString(link)
182 }));
183}
184//# sourceMappingURL=util.js.map
\No newline at end of file