PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 1.9.8.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v1.9.8.0
3.4.3 3.4.2 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 All 196 releases
convertkit / resources / backend / js / gutenberg.js

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

312 lines 7.7 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 var fieldElement; // Holds the field element (select, textarea, text etc).
120
121 // Define Field's Properties.
122 var fieldProperties = {
123 id: 'convertkit_' + block.name + '_' + attribute,
124 label: field.label,
125 help: field.description,
126 value: props.attributes[ attribute ],
127 onChange: function( value ) {
128 if ( field.type == 'number' ) {
129 // If value is a blank string i.e. no attribute value was provided,
130 // cast it to the field's minimum number setting.
131 // This prevents WordPress' block renderer API returning a 400 error
132 // because a blank value will be passed as a string, when WordPress
133 // expects it to be a numerical value.
134 if ( value === '' ) {
135 value = field.min;
136 }
137
138 // Cast value to integer if a value exists.
139 if ( value.length > 0 ) {
140 value = Number( value );
141 }
142 }
143
144 var newValue = {};
145 newValue[ attribute ] = value;
146 props.setAttributes( newValue );
147 }
148 };
149
150 // Define additional Field Properties and the Field Element,
151 // depending on the Field Type (select, textarea, text etc).
152 switch ( field.type ) {
153
154 case 'select':
155 // Build options for <select> input.
156 var fieldOptions = [
157 {
158 label: '(None)',
159 value: '',
160 }
161 ];
162 for ( var value in field.values ) {
163 fieldOptions.push(
164 {
165 label: field.values[ value ],
166 value: value
167 }
168 );
169 }
170
171 // Sort field's options alphabetically by label.
172 fieldOptions.sort(
173 function ( x, y ) {
174
175 let a = x.label.toUpperCase(),
176 b = y.label.toUpperCase();
177 return a.localeCompare( b );
178
179 }
180 );
181
182 // Assign options to field.
183 fieldProperties.options = fieldOptions;
184
185 // Define field element.
186 fieldElement = el(
187 SelectControl,
188 fieldProperties
189 );
190 break;
191
192 case 'toggle':
193 // Define field properties.
194 fieldProperties.checked = props.attributes[ attribute ];
195
196 // Define field element.
197 fieldElement = el(
198 ToggleControl,
199 fieldProperties
200 );
201 break;
202
203 case 'number':
204 // Define field properties.
205 fieldProperties.type = field.type;
206 fieldProperties.min = field.min;
207 fieldProperties.max = field.max;
208 fieldProperties.step = field.step;
209
210 // Define field element.
211 fieldElement = el(
212 TextControl,
213 fieldProperties
214 );
215 break;
216
217 default:
218 // Define field element.
219 fieldElement = el(
220 TextControl,
221 fieldProperties
222 );
223 break;
224 }
225
226 // Add Field as a Row.
227 rows.push(
228 el(
229 PanelRow,
230 {
231 key: attribute
232 },
233 fieldElement
234 )
235 );
236 }
237
238 // Add the Panel Rows to a new Panel.
239 panels.push(
240 el(
241 PanelBody,
242 {
243 title: block.panels[ panel ].label,
244 key: panel,
245 initialOpen: initialOpen
246 },
247 rows
248 )
249 );
250
251 // Don't open any further panels.
252 initialOpen = false;
253 }
254
255 // Generate Block Preview.
256 var preview = '';
257 if ( typeof block.gutenberg_preview_render_callback !== 'undefined' ) {
258 // Use a custom callback function to render this block's preview in the Gutenberg Editor.
259 // This doesn't affect the output for this block on the frontend site, which will always
260 // use the block's PHP's render() function.
261 preview = window[ block.gutenberg_preview_render_callback ]( block, props );
262 } else {
263 // Use the block's PHP's render() function by calling the ServerSideRender component.
264 preview = el(
265 ServerSideRender,
266 {
267 block: 'convertkit/' + block.name,
268 attributes: props.attributes,
269 className: 'convertkit-' + block.name,
270 }
271 );
272 }
273
274 // Return.
275 return (
276 el(
277 // Sidebar Panel with Fields.
278 Fragment,
279 {},
280 el(
281 InspectorControls,
282 {},
283 panels
284 ),
285 // Block Preview.
286 preview
287 )
288 );
289 },
290
291 // Output.
292 save: function( props ) {
293
294 // Deliberate; preview in the editor is determined by the return statement in `edit` above.
295 // On the frontend site, the block's render() PHP class is always called, so we dynamically
296 // fetch the content.
297 return null;
298
299 },
300 }
301 );
302
303 } (
304 window.wp.blocks,
305 window.wp.blockEditor,
306 window.wp.element,
307 window.wp.components,
308 block
309 ) );
310
311 }
312