core/lib/Drupal/Core/Ajax/AddJsCommand.php | 44 ++++++++++++++++++ .../Core/Ajax/AjaxResponseAttachmentsProcessor.php | 6 ++- core/misc/ajax.js | 53 +++++++++++++++++++++- core/misc/dialog/dialog.ajax.js | 3 ++ 4 files changed, 103 insertions(+), 3 deletions(-) diff --git a/core/lib/Drupal/Core/Ajax/AddJsCommand.php b/core/lib/Drupal/Core/Ajax/AddJsCommand.php new file mode 100644 index 0000000..f7c0a8a --- /dev/null +++ b/core/lib/Drupal/Core/Ajax/AddJsCommand.php @@ -0,0 +1,44 @@ +styles = $scripts; + } + + /** + * {@inheritdoc} + */ + public function render() { + + return [ + 'command' => 'add_js', + 'data' => $this->styles, + ]; + } + +} diff --git a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php index 45aa45e..6cb9f3e 100644 --- a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php +++ b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php @@ -174,11 +174,13 @@ protected function buildAttachmentsCommands(AjaxResponse $response, Request $req } if ($js_assets_header) { $js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header); - $resource_commands[] = new PrependCommand('head', $this->renderer->renderPlain($js_header_render_array)); + $scripts_attributes = array_map(function ($render_array) { return $render_array['#attributes']; }, $js_header_render_array); + $resource_commands[] = new AddJsCommand($scripts_attributes); } if ($js_assets_footer) { $js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer); - $resource_commands[] = new AppendCommand('body', $this->renderer->renderPlain($js_footer_render_array)); + $scripts_attributes = array_map(function ($render_array) { return $render_array['#attributes']; }, $js_footer_render_array); + $resource_commands[] = new AddJsCommand($scripts_attributes); } foreach (array_reverse($resource_commands) as $resource_command) { $response->addCommand($resource_command, TRUE); diff --git a/core/misc/ajax.js b/core/misc/ajax.js index fefe9f3..74d1502 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -860,6 +860,7 @@ // focus set by the Ajax command. var focusChanged = false; for (var i in response) { + console.log('[ajax.js] command to execute: ' + response[i].command, this.commands[response[i].command] ? 'command exists, executing' : 'command does NOT exist, SKIPPING!'); if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) { this.commands[response[i].command](this, response[i], status); if (response[i].command === 'invoke' && response[i].method === 'focus') { @@ -1019,6 +1020,7 @@ // our presets. var $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); var method = response.method || ajax.method; + console.log(method); var effect = ajax.getEffect(response); var settings; @@ -1338,7 +1340,56 @@ document.styleSheets[0].addImport(match[1]); } while (match); } - } + }, + + add_js: function (ajax, response, status) { + var head = document.getElementsByTagName('head')[0]; + window.loaded = {}; + for (var i in response.data) { + if (!response.data.hasOwnProperty(i)) { + continue; + } + + // Prepare to load script. + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.setAttribute('data-ajax', true); + for (var attributeName in response.data[i]) { + if (response.data[i].hasOwnProperty(attributeName)) { + script.setAttribute(attributeName, response.data[i][attributeName]); + } + } + + // Track loading of script. + var src = response.data[i].src; + window.loaded[src] = false; + (function(src) { + script.onload = function () { + return function () { + console.log(src + ' finished loading!'); + delete window.loaded[src]; + }; + }(); + })(response.data[i].src); + + // Start loading script. + head.appendChild(script); + } + + console.log(Object.keys(window.loaded)); + console.log('started loading'); + + function allJsIsLoaded() { + console.log(Object.keys(window.loaded).length); + return Object.keys(window.loaded).length === 0; + } + var maxIterations = 10000; + var c = 0; + while (!allJsIsLoaded() && c < maxIterations) { + c++; // This is evil, I know. But this MUST be blocking because the caller (Drupal.Ajax.prototype.success) is blocking. We can make this non-blocking if we can make the caller non-blocking too. + } + console.log('finished loading'); + }, }; })(jQuery, window, Drupal, drupalSettings); diff --git a/core/misc/dialog/dialog.ajax.js b/core/misc/dialog/dialog.ajax.js index 3f1b0c2..6b8f89d 100644 --- a/core/misc/dialog/dialog.ajax.js +++ b/core/misc/dialog/dialog.ajax.js @@ -5,6 +5,8 @@ (function ($, Drupal) { + console.log('dialog.ajax.js loaded'); + 'use strict'; /** @@ -111,6 +113,7 @@ * Returns false if there was no selector property in the response object. */ Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) { + console.log('openDialog() ajax command called'); if (!response.selector) { return false; }