PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.0.2
GenerateBlocks v2.0.2
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
228 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 ) {
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 newAttributes = {
80 ...htmlAttributes,
81 src: image.url,
82 alt: image.alt,
83 title: image.title,
84 height: image.height,
85 width: image.width,
86 };
87
88 setAttributes( {
89 htmlAttributes: newAttributes,
90 mediaId: image.id ?? 0,
91 } );
92 }
93 }
94
95 function onSelectURL( newURL ) {
96 if ( newURL === htmlAttributes.src ) {
97 return;
98 }
99
100 const newAttributes = {
101 ...htmlAttributes,
102 src: newURL,
103 };
104
105 setAttributes( { htmlAttributes: newAttributes } );
106 }
107
108 function onResetImage() {
109 const newAttributes = { ...htmlAttributes };
110 delete newAttributes.src;
111 delete newAttributes.alt;
112 delete newAttributes.title;
113
114 setAttributes( {
115 htmlAttributes: newAttributes,
116 mediaId: 0,
117 } );
118 }
119
120 let isTemp = isTemporaryImage( htmlAttributes?.src );
121
122 useEffect( () => {
123 if ( ! isTemp ) {
124 return;
125 }
126
127 const file = getBlobByURL( htmlAttributes?.src );
128
129 if ( file ) {
130 mediaUpload( {
131 filesList: [ file ],
132 onFileChange: ( [ img ] ) => {
133 onSelectImage( img );
134 },
135 allowedTypes: [ 'image' ],
136 onError: ( message ) => {
137 isTemp = false;
138 onUploadError( message );
139 },
140 } );
141 }
142 }, [] );
143
144 // If an image is temporary, revoke the Blob url when it is uploaded (and is
145 // no longer temporary).
146 useEffect( () => {
147 if ( isTemp ) {
148 setTemporaryURL( htmlAttributes?.src );
149 return;
150 }
151 revokeBlobURL( temporaryURL );
152 }, [ isTemp, htmlAttributes?.src ] );
153
154 function elementRender() {
155 return (
156 <>
157 { 'img' === tagName ? (
158 <Image
159 { ...props }
160 elementAttributes={ elementAttributes }
161 temporaryURL={ temporaryURL }
162 onSelectImage={ onSelectImage }
163 onSelectURL={ onSelectURL }
164 onResetImage={ onResetImage }
165 onUploadError={ onUploadError }
166 linkHtmlAttributes={ linkHtmlAttributes }
167 />
168 ) : (
169 <TagName { ...elementAttributes } />
170 ) }
171 </>
172 );
173 }
174
175 return (
176 <>
177 <InspectorControls>
178 <StylesOnboarder />
179
180 <BlockStyles
181 settingsTab={ (
182 <BlockSettings
183 { ...props }
184 onSelectImage={ onSelectImage }
185 />
186 ) }
187 stylesTab={ (
188 <BlockStylesBuilder
189 attributes={ attributes }
190 setAttributes={ setAttributes }
191 shortcuts={ {} }
192 onStyleChange={ onStyleChange }
193 name={ name }
194 />
195 ) }
196 />
197 </InspectorControls>
198
199 <RootElement
200 name={ name }
201 clientId={ clientId }
202 >
203 <div
204 { ...blockProps }
205 data-block-wrapper
206 style={ {
207 display: ! shouldWrapBlock ? 'none' : undefined,
208 } }
209 >
210 { elementRender() }
211 </div>
212 <div style={ { display: shouldWrapBlock ? 'none' : 'contents' } }>
213 { elementRender() }
214 </div>
215 </RootElement>
216 </>
217 );
218 }
219
220 const Edit = compose(
221 withHtmlAttributes,
222 withStyles,
223 withDynamicTag,
224 withUniqueId
225 )( EditBlock );
226
227 export { Edit };
228