PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.1.2
GenerateBlocks v2.1.2
2.4.1 2.4.0 trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / src / blocks / media / edit.js
generateblocks / src / blocks / media Last commit date
components 1 year ago hooks 1 year ago block.json 1 year ago edit.js 1 year ago editor.scss 1 year ago image-utils.js 1 year ago index.js 1 year ago save.js 1 year ago toolbar-appenders.js 1 year ago transforms.js 1 year ago
edit.js
230 lines
1 import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
2 import { useEffect, useState } from '@wordpress/element';
3 import { compose } from '@wordpress/compose';
4 import { isBlobURL, getBlobByURL, revokeBlobURL } from '@wordpress/blob';
5 import { useSelect } from '@wordpress/data';
6
7 import { BlockStyles, withUniqueId } from '@edge22/block-styles';
8
9 import { useImageFunctions } from './hooks/useImageFunctions.js';
10 import { Image } from './components/Image.jsx';
11 import { withDynamicTag } from '../../hoc/withDynamicTag.js';
12 import RootElement from '../../components/root-element/index.js';
13 import { BlockSettings } from './components/BlockSettings';
14 import { withStyles } from '@hoc/withStyles';
15 import { BlockStylesBuilder, StylesOnboarder } from '@components/index';
16 import { withHtmlAttributes } from '@hoc/withHtmlAttributes.js';
17 import { getBlockClasses } from '@utils/getBlockClasses.js';
18
19 function EditBlock( props ) {
20 const {
21 attributes,
22 setAttributes,
23 isSelected,
24 name,
25 clientId,
26 onStyleChange,
27 editorHtmlAttributes,
28 htmlAttributes,
29 styles,
30 } = props;
31
32 const {
33 tagName,
34 linkHtmlAttributes = {},
35 } = attributes;
36
37 const [ temporaryURL, setTemporaryURL ] = useState();
38 const { isTemporaryImage, mediaUpload, onUploadError } = useImageFunctions();
39 const classNames = getBlockClasses(
40 'gb-media',
41 {
42 ...attributes,
43 styles,
44 }
45 );
46
47 useEffect( () => {
48 if ( ! tagName ) {
49 setAttributes( { tagName: 'img' } );
50 }
51 }, [ tagName ] );
52
53 const {
54 isBlockMultiSelected,
55 } = useSelect( ( select ) => select( 'core/block-editor' ), [] );
56
57 const blockProps = useBlockProps();
58 const shouldWrapBlock = isSelected || isBlockMultiSelected( clientId ) || ( 'img' === tagName && ! temporaryURL && ! htmlAttributes?.src );
59 const elementAttributes = {
60 className: classNames.join( ' ' ).trim(),
61 'data-block': clientId,
62 ...editorHtmlAttributes,
63 };
64 const TagName = tagName || 'img';
65
66 function onSelectImage( image, sizeSlug = null ) {
67 if ( ! image || ! image.url ) {
68 onResetImage();
69 return;
70 }
71
72 if ( isBlobURL( image.url ) ) {
73 setTemporaryURL( image.url );
74 }
75
76 setTemporaryURL();
77
78 if ( !! image ) {
79 const imageUrl = ( image?.sizes && image?.sizes[ sizeSlug ]?.url ) || image?.url;
80
81 const newAttributes = {
82 ...htmlAttributes,
83 src: imageUrl,
84 alt: image.alt,
85 title: image.title,
86 height: image.height,
87 width: image.width,
88 };
89
90 setAttributes( {
91 htmlAttributes: newAttributes,
92 mediaId: image.id ?? 0,
93 } );
94 }
95 }
96
97 function onSelectURL( newURL ) {
98 if ( newURL === htmlAttributes.src ) {
99 return;
100 }
101
102 const newAttributes = {
103 ...htmlAttributes,
104 src: newURL,
105 };
106
107 setAttributes( { htmlAttributes: newAttributes } );
108 }
109
110 function onResetImage() {
111 const newAttributes = { ...htmlAttributes };
112 delete newAttributes.src;
113 delete newAttributes.alt;
114 delete newAttributes.title;
115
116 setAttributes( {
117 htmlAttributes: newAttributes,
118 mediaId: 0,
119 } );
120 }
121
122 let isTemp = isTemporaryImage( htmlAttributes?.src );
123
124 useEffect( () => {
125 if ( ! isTemp ) {
126 return;
127 }
128
129 const file = getBlobByURL( htmlAttributes?.src );
130
131 if ( file ) {
132 mediaUpload( {
133 filesList: [ file ],
134 onFileChange: ( [ img ] ) => {
135 onSelectImage( img );
136 },
137 allowedTypes: [ 'image' ],
138 onError: ( message ) => {
139 isTemp = false;
140 onUploadError( message );
141 },
142 } );
143 }
144 }, [] );
145
146 // If an image is temporary, revoke the Blob url when it is uploaded (and is
147 // no longer temporary).
148 useEffect( () => {
149 if ( isTemp ) {
150 setTemporaryURL( htmlAttributes?.src );
151 return;
152 }
153 revokeBlobURL( temporaryURL );
154 }, [ isTemp, htmlAttributes?.src ] );
155
156 function elementRender() {
157 return (
158 <>
159 { 'img' === tagName ? (
160 <Image
161 { ...props }
162 elementAttributes={ elementAttributes }
163 temporaryURL={ temporaryURL }
164 onSelectImage={ onSelectImage }
165 onSelectURL={ onSelectURL }
166 onResetImage={ onResetImage }
167 onUploadError={ onUploadError }
168 linkHtmlAttributes={ linkHtmlAttributes }
169 />
170 ) : (
171 <TagName { ...elementAttributes } />
172 ) }
173 </>
174 );
175 }
176
177 return (
178 <>
179 <InspectorControls>
180 <StylesOnboarder />
181
182 <BlockStyles
183 settingsTab={ (
184 <BlockSettings
185 { ...props }
186 onSelectImage={ onSelectImage }
187 />
188 ) }
189 stylesTab={ (
190 <BlockStylesBuilder
191 attributes={ attributes }
192 setAttributes={ setAttributes }
193 shortcuts={ {} }
194 onStyleChange={ onStyleChange }
195 name={ name }
196 />
197 ) }
198 />
199 </InspectorControls>
200
201 <RootElement
202 name={ name }
203 clientId={ clientId }
204 >
205 <div
206 { ...blockProps }
207 data-block-wrapper
208 style={ {
209 display: ! shouldWrapBlock ? 'none' : undefined,
210 } }
211 >
212 { elementRender() }
213 </div>
214 <div style={ { display: shouldWrapBlock ? 'none' : 'contents' } }>
215 { elementRender() }
216 </div>
217 </RootElement>
218 </>
219 );
220 }
221
222 const Edit = compose(
223 withHtmlAttributes,
224 withStyles,
225 withDynamicTag,
226 withUniqueId
227 )( EditBlock );
228
229 export { Edit };
230