diff --git a/core/modules/big_pipe/js/big_pipe.es6.js b/core/modules/big_pipe/js/big_pipe.es6.js index b78eaa9c708233f67e0b190775dabe17e805fbf7..df72915a8ed674a6e73a505839d929421ecc2c01 100644 --- a/core/modules/big_pipe/js/big_pipe.es6.js +++ b/core/modules/big_pipe/js/big_pipe.es6.js @@ -20,16 +20,17 @@ // Ignore any placeholders that are not in the known placeholder list. Used // to avoid someone trying to XSS the site via the placeholdering mechanism. if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') { + const response = mapTextContentToAjaxResponse(content); // If we try to parse the content too early (when the JSON containing Ajax - // commands is still arriving), textContent will be empty which will cause - // JSON.parse() to fail. Remove once so that it can be processed again - // later. - // @see bigPipeProcessDocument() - if (content === '') { + // commands is still arriving), textContent will be empty or incomplete. + if (response === false) { + /** + * Mark as unprocessed so this will be retried later. + * @see bigPipeProcessDocument() + */ $(this).removeOnce('big-pipe'); } else { - const response = JSON.parse(content); // Create a Drupal.Ajax object without associating an element, a // progress indicator or a URL. const ajaxObject = Drupal.ajax({ @@ -45,6 +46,28 @@ } } + /** + * Maps textContent of <script type="application/vnd.drupal-ajax"> to an AJAX response. + * + * @param {string} content + * The text content of a <script type="application/vnd.drupal-ajax"> DOM node. + * @return {Array|boolean} + * The parsed Ajax response containing an array of Ajax commands, or false in + * case the DOM node hasn't fully arrived yet. + */ + function mapTextContentToAjaxResponse(content) { + if (content === '') { + return false; + } + + try { + return JSON.parse(content); + } + catch (e) { + return false; + } + } + /** * Processes a streamed HTML document receiving placeholder replacements. * diff --git a/core/modules/big_pipe/js/big_pipe.js b/core/modules/big_pipe/js/big_pipe.js index 1464fdd968202268b4a23be8e1004e4d1152fc3f..b8a25f77cc8987832ec660ba87dea22329419b83 100644 --- a/core/modules/big_pipe/js/big_pipe.js +++ b/core/modules/big_pipe/js/big_pipe.js @@ -11,11 +11,11 @@ var content = this.textContent.trim(); if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') { - if (content === '') { + var response = mapTextContentToAjaxResponse(content); + + if (response === false) { $(this).removeOnce('big-pipe'); } else { - var response = JSON.parse(content); - var ajaxObject = Drupal.ajax({ url: '', base: false, @@ -28,6 +28,18 @@ } } + function mapTextContentToAjaxResponse(content) { + if (content === '') { + return false; + } + + try { + return JSON.parse(content); + } catch (e) { + return false; + } + } + function bigPipeProcessDocument(context) { if (!context.querySelector('script[data-big-pipe-event="start"]')) { return false;