Backup of db before drupal security update
[yaffs-website] / web / core / modules / big_pipe / js / big_pipe.js
1 /**
2  * @file
3  * Renders BigPipe placeholders using Drupal's Ajax system.
4  */
5
6 (function ($, Drupal, drupalSettings) {
7
8   'use strict';
9
10   /**
11    * Executes Ajax commands in <script type="application/vnd.drupal-ajax"> tag.
12    *
13    * These Ajax commands replace placeholders with HTML and load missing CSS/JS.
14    *
15    * @param {number} index
16    *   Current index.
17    * @param {HTMLScriptElement} placeholderReplacement
18    *   Script tag created by BigPipe.
19    */
20   function bigPipeProcessPlaceholderReplacement(index, placeholderReplacement) {
21     var placeholderId = placeholderReplacement.getAttribute('data-big-pipe-replacement-for-placeholder-with-id');
22     var content = this.textContent.trim();
23     // Ignore any placeholders that are not in the known placeholder list. Used
24     // to avoid someone trying to XSS the site via the placeholdering mechanism.
25     if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') {
26       // If we try to parse the content too early (when the JSON containing Ajax
27       // commands is still arriving), textContent will be empty which will cause
28       // JSON.parse() to fail. Remove once so that it can be processed again
29       // later.
30       // @see bigPipeProcessDocument()
31       if (content === '') {
32         $(this).removeOnce('big-pipe');
33       }
34       else {
35         var response = JSON.parse(content);
36         // Create a Drupal.Ajax object without associating an element, a
37         // progress indicator or a URL.
38         var ajaxObject = Drupal.ajax({
39           url: '',
40           base: false,
41           element: false,
42           progress: false
43         });
44         // Then, simulate an AJAX response having arrived, and let the Ajax
45         // system handle it.
46         ajaxObject.success(response, 'success');
47       }
48     }
49   }
50
51   /**
52    * Processes a streamed HTML document receiving placeholder replacements.
53    *
54    * @param {HTMLDocument} context
55    *   The HTML document containing <script type="application/vnd.drupal-ajax">
56    *   tags generated by BigPipe.
57    *
58    * @return {bool}
59    *   Returns true when processing has been finished and a stop signal has been
60    *   found.
61    */
62   function bigPipeProcessDocument(context) {
63     // Make sure we have BigPipe-related scripts before processing further.
64     if (!context.querySelector('script[data-big-pipe-event="start"]')) {
65       return false;
66     }
67
68     $(context).find('script[data-big-pipe-replacement-for-placeholder-with-id]')
69       .once('big-pipe')
70       .each(bigPipeProcessPlaceholderReplacement);
71
72     // If we see the stop signal, clear the timeout: all placeholder
73     // replacements are guaranteed to be received and processed.
74     if (context.querySelector('script[data-big-pipe-event="stop"]')) {
75       if (timeoutID) {
76         clearTimeout(timeoutID);
77       }
78       return true;
79     }
80
81     return false;
82   }
83
84   function bigPipeProcess() {
85     timeoutID = setTimeout(function () {
86       if (!bigPipeProcessDocument(document)) {
87         bigPipeProcess();
88       }
89     }, interval);
90   }
91
92   // The frequency with which to check for newly arrived BigPipe placeholders.
93   // Hence 50 ms means we check 20 times per second. Setting this to 100 ms or
94   // more would cause the user to see content appear noticeably slower.
95   var interval = drupalSettings.bigPipeInterval || 50;
96   // The internal ID to contain the watcher service.
97   var timeoutID;
98
99   bigPipeProcess();
100
101   // If something goes wrong, make sure everything is cleaned up and has had a
102   // chance to be processed with everything loaded.
103   $(window).on('load', function () {
104     if (timeoutID) {
105       clearTimeout(timeoutID);
106     }
107     bigPipeProcessDocument(document);
108   });
109
110 })(jQuery, Drupal, drupalSettings);