PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.17.0
GiveWP – Donation Plugin and Fundraising Platform v4.17.0
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 All 256 releases
← All changes | src/DonationForms/ViewModels/DonationFormViewModel.php +49 -1 4.16.74.17.0 View file →
@@ -6,10 +6,13 @@
6 6 use Give\Campaigns\ValueObjects\CampaignGoalType;
7 7 use Give\DonationForms\Actions\GenerateAuthUrl;
8 8 use Give\DonationForms\Actions\GenerateDonateRouteUrl;
9 9 use Give\DonationForms\Actions\GenerateDonationFormValidationRouteUrl;
10 +use Give\DonationForms\Actions\GetFormSkeletonData;
10 11 use Give\DonationForms\Actions\IsolateEnqueuedFormViewAssets;
12 +use Give\DonationForms\Actions\RenderFormSkeleton;
11 13 use Give\DonationForms\DataTransferObjects\DonationFormGoalData;
14 +use Give\DonationForms\Models\DonationForm;
12 15 use Give\DonationForms\Properties\FormSettings;
13 16 use Give\DonationForms\Repositories\DonationFormRepository;
14 17 use Give\DonationForms\ValueObjects\GoalType;
15 18 use Give\Framework\Blocks\BlockCollection;
@@ -47,9 +50,18 @@
47 50 /**
48 51 * @var bool
49 52 */
50 53 private $previewMode;
54 +
51 55 /**
56 + * The skeleton markup for this render, or empty when there is none to show.
57 + *
58 + * @since 4.17.0
59 + *
60 + * @var string
61 + */
62 + private $skeleton = '';
63 + /**
52 64 * @since 4.1.0
53 65 */
54 66 private DonationFormGoalData $donationFormGoalData;
55 67
@@ -145,8 +157,15 @@
145 157 wp_strip_all_tags(give_get_option('custom_form_styles', ''))
146 158 );
147 159
148 160 wp_enqueue_style('givewp-base-form-styles');
161 +
162 + // The skeleton prints in the body before the app bundles load, so its styles go in the head with the rest.
163 + if ($this->skeleton) {
164 + wp_register_style('givewp-form-skeleton-styles', false);
165 + wp_add_inline_style('givewp-form-skeleton-styles', (new RenderFormSkeleton())->css());
166 + wp_enqueue_style('givewp-form-skeleton-styles');
167 + }
149 168 }
150 169
151 170 /**
152 171 * @since 3.0.0
@@ -275,8 +294,9 @@
275 294 ];
276 295 }
277 296
278 297 /**
298 + * @since 4.17.0 print the form's skeleton inside the root and announce the shell to the embedding page.
279 299 * This is the order of loading:
280 300 * 1. Enqueue global styles from WP.
281 301 * - This ensures template compatability with global WP css variables as needed. Loads before our templates, so they can use things like global font-family, etc.
282 302 * 2. Enqueue our donation form specific scripts & styles.
@@ -297,8 +317,10 @@
297 317 * @since 3.0.0
298 318 */
299 319 public function render(): string
300 320 {
321 + $this->skeleton = $this->previewMode ? '' : $this->renderSkeleton();
322 +
301 323 $this->enqueueGlobalStyles();
302 324
303 325 $this->enqueueFormScripts(
304 326 $this->donationFormId,
@@ -328,10 +350,14 @@
328 350 ?>
329 351
330 352 <div data-theme="light" id="root-givewp-donation-form"
331 353 data-iframe-height
332 - class="<?= esc_attr(implode(' ', $classNames)) ?>"></div>
354 + class="<?= esc_attr(implode(' ', $classNames)) ?>"><?= $this->skeleton ?></div>
333 355
356 + <?php if ($this->skeleton): ?>
357 + <script>parent.postMessage({type: 'givewp-embed-shell', height: document.documentElement.scrollHeight}, '*');</script>
358 + <?php endif; ?>
359 +
334 360 <?php
335 361 wp_print_footer_scripts();
336 362
337 363 echo ob_get_clean();
@@ -336,8 +362,30 @@
336 362
337 363 echo ob_get_clean();
338 364
339 365 exit();
366 + }
367 +
368 + /**
369 + * The skeleton RenderFormSkeleton draws, printed inside the root so the iframe shows the form's
370 + * shape as soon as its HTML and head styles arrive, before the app bundles load. createRoot()
371 + * replaces it with the form. The inline script that follows the root tells the embedding page
372 + * the shell has painted and how tall it is; the payload is that height and nothing else, so it
373 + * is addressed to any origin and the embed authenticates the message by its origin and source
374 + * instead. Both are skipped for an unknown design, where there is nothing to show, and in the
375 + * builder preview.
376 + *
377 + * @since 4.17.0
378 + */
379 + private function renderSkeleton(): string
380 + {
381 + $form = DonationForm::find($this->donationFormId);
382 +
383 + if (!$form) {
384 + return '';
385 + }
386 +
387 + return (new RenderFormSkeleton())((new GetFormSkeletonData())($form));
340 388 }
341 389
342 390 /**
343 391 * Loads scripts in order: [Registrars, Designs, Gateways, Block]