PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.0.1
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.0.1
3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 All 194 releases
convertkit / resources / backend / js / gutenberg.js

gutenberg.js in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 2.0.1, at resources/backend/js/gutenberg.js

319 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Registers blocks in the Gutenberg editor.
3 *
4 * @since 1.9.6.5
5 *
6 * @package ConvertKit
7 * @author ConvertKit
8 */
9
10 // Register Gutenberg Blocks if the Gutenberg Editor is loaded on screen.
11 // This prevents JS errors if this script is accidentally enqueued on a non-
12 // Gutenberg editor screen, or the Classic Editor Plugin is active.
13 if ( typeof wp !== 'undefined' &&
14 typeof wp.blocks !== 'undefined' ) {
15
16 // Register each ConvertKit Block in Gutenberg.
17 for ( const block in convertkit_blocks ) {
18 convertKitGutenbergRegisterBlock( convertkit_blocks[ block ] );
19 }
20
21 }
22
23 /**
24 * Registers the given block in Gutenberg.
25 *
26 * @since 1.9.6.5
27 *
28 * @param object block Block
29 */
30 function convertKitGutenbergRegisterBlock( block ) {
31
32 // Register Block.
33 ( function( blocks, editor, element, components, block ) {
34
35 // Define some constants for the various items we'll use.
36 const el = element.createElement;
37 const { registerBlockType } = blocks;
38 const { RichText, InspectorControls } = editor;
39 const { Fragment } = element;
40 const {
41 TextControl,
42 CheckboxControl,
43 RadioControl,
44 SelectControl,
45 TextareaControl,
46 ToggleControl,
47 RangeControl,
48 FormTokenField,
49 Panel,
50 PanelBody,
51 PanelRow,
52 SandBox,
53 ServerSideRender
54 } = components;
55
56 // Build Icon, if it's an object.
57 var icon = 'dashicons-tablet';
58 if ( typeof block.gutenberg_icon !== 'undefined' ) {
59 if ( block.gutenberg_icon.search( 'svg' ) >= 0 ) {
60 // SVG.
61 icon = element.RawHTML(
62 {
63 children: block.gutenberg_icon
64 }
65 );
66 } else {
67 // Dashicon.
68 icon = block.gutenberg_icon;
69 }
70 }
71
72 // Register Block.
73 registerBlockType(
74 'convertkit/' + block.name,
75 {
76 title: block.title,
77 description:block.description,
78 category: block.category,
79 icon: icon,
80 keywords: block.keywords,
81 attributes: block.attributes,
82 supports: block.supports,
83 example: {
84 attributes: {
85 is_gutenberg_example: true,
86 }
87 },
88
89 // Editor.
90 edit: function( props ) {
91
92 // If requesting an example of how this block looks (which is requested
93 // when the user adds a new block and hovers over this block's icon),
94 // show the preview image.
95 if ( props.attributes.is_gutenberg_example === true ) {
96 return (
97 Fragment,
98 {},
99 el(
100 'img',
101 {
102 src: block.gutenberg_example_image,
103 }
104 )
105 );
106 }
107
108 // Build Inspector Control Panels, which will appear in the Sidebar when editing the Block.
109 var panels = [],
110 initialOpen = true;
111 for ( const panel in block.panels ) {
112
113 // Build Inspector Control Panel Rows, one for each Field.
114 var rows = [];
115 for ( var i in block.panels[ panel ].fields ) {
116 const attribute = block.panels[ panel ].fields[ i ], // e.g. 'term'.
117 field = block.fields[ attribute ]; // field array.
118
119 // If this field doesn't exist as an attribute in the block's get_attributes(),
120 // this is a non-Gutenberg field (such as a color picker for shortcodes),
121 // which should be ignored.
122 if ( typeof block.attributes[ attribute ] === 'undefined' ) {
123 continue;
124 }
125
126 var fieldElement; // Holds the field element (select, textarea, text etc).
127
128 // Define Field's Properties.
129 var fieldProperties = {
130 id: 'convertkit_' + block.name + '_' + attribute,
131 label: field.label,
132 help: field.description,
133 value: props.attributes[ attribute ],
134 onChange: function( value ) {
135 if ( field.type == 'number' ) {
136 // If value is a blank string i.e. no attribute value was provided,
137 // cast it to the field's minimum number setting.
138 // This prevents WordPress' block renderer API returning a 400 error
139 // because a blank value will be passed as a string, when WordPress
140 // expects it to be a numerical value.
141 if ( value === '' ) {
142 value = field.min;
143 }
144
145 // Cast value to integer if a value exists.
146 if ( value.length > 0 ) {
147 value = Number( value );
148 }
149 }
150
151 var newValue = {};
152 newValue[ attribute ] = value;
153 props.setAttributes( newValue );
154 }
155 };
156
157 // Define additional Field Properties and the Field Element,
158 // depending on the Field Type (select, textarea, text etc).
159 switch ( field.type ) {
160
161 case 'select':
162 // Build options for <select> input.
163 var fieldOptions = [
164 {
165 label: '(None)',
166 value: '',
167 }
168 ];
169 for ( var value in field.values ) {
170 fieldOptions.push(
171 {
172 label: field.values[ value ],
173 value: value
174 }
175 );
176 }
177
178 // Sort field's options alphabetically by label.
179 fieldOptions.sort(
180 function ( x, y ) {
181
182 let a = x.label.toUpperCase(),
183 b = y.label.toUpperCase();
184 return a.localeCompare( b );
185
186 }
187 );
188
189 // Assign options to field.
190 fieldProperties.options = fieldOptions;
191
192 // Define field element.
193 fieldElement = el(
194 SelectControl,
195 fieldProperties
196 );
197 break;
198
199 case 'toggle':
200 // Define field properties.
201 fieldProperties.checked = props.attributes[ attribute ];
202
203 // Define field element.
204 fieldElement = el(
205 ToggleControl,
206 fieldProperties
207 );
208 break;
209
210 case 'number':
211 // Define field properties.
212 fieldProperties.type = field.type;
213 fieldProperties.min = field.min;
214 fieldProperties.max = field.max;
215 fieldProperties.step = field.step;
216
217 // Define field element.
218 fieldElement = el(
219 TextControl,
220 fieldProperties
221 );
222 break;
223
224 default:
225 // Define field element.
226 fieldElement = el(
227 TextControl,
228 fieldProperties
229 );
230 break;
231 }
232
233 // Add Field as a Row.
234 rows.push(
235 el(
236 PanelRow,
237 {
238 key: attribute
239 },
240 fieldElement
241 )
242 );
243 }
244
245 // Add the Panel Rows to a new Panel.
246 panels.push(
247 el(
248 PanelBody,
249 {
250 title: block.panels[ panel ].label,
251 key: panel,
252 initialOpen: initialOpen
253 },
254 rows
255 )
256 );
257
258 // Don't open any further panels.
259 initialOpen = false;
260 }
261
262 // Generate Block Preview.
263 var preview = '';
264 if ( typeof block.gutenberg_preview_render_callback !== 'undefined' ) {
265 // Use a custom callback function to render this block's preview in the Gutenberg Editor.
266 // This doesn't affect the output for this block on the frontend site, which will always
267 // use the block's PHP's render() function.
268 preview = window[ block.gutenberg_preview_render_callback ]( block, props );
269 } else {
270 // Use the block's PHP's render() function by calling the ServerSideRender component.
271 preview = el(
272 ServerSideRender,
273 {
274 block: 'convertkit/' + block.name,
275 attributes: props.attributes,
276 className: 'convertkit-' + block.name
277 }
278 );
279 }
280
281 // Return.
282 return (
283 el(
284 // Sidebar Panel with Fields.
285 Fragment,
286 {},
287 el(
288 InspectorControls,
289 {},
290 panels
291 ),
292 // Block Preview.
293 preview
294 )
295 );
296 },
297
298 // Output.
299 save: function( props ) {
300
301 // Deliberate; preview in the editor is determined by the return statement in `edit` above.
302 // On the frontend site, the block's render() PHP class is always called, so we dynamically
303 // fetch the content.
304 return null;
305
306 },
307 }
308 );
309
310 } (
311 window.wp.blocks,
312 window.wp.blockEditor,
313 window.wp.element,
314 window.wp.components,
315 block
316 ) );
317
318 }
319