Issue #2407859 by vaplas, lauriii, vprocessor, drpal, jwilson3, sidharthap, aprogs, finnsky: Allow theming throbber element
parent
3663ab6bc0
commit
bae2ff8761
|
|
@ -811,6 +811,40 @@
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An animated progress throbber and container element for AJAX operations.
|
||||
*
|
||||
* @param {string} [message]
|
||||
* (optional) The message shown on the UI.
|
||||
* @return {string}
|
||||
* The HTML markup for the throbber.
|
||||
*/
|
||||
Drupal.theme.ajaxProgressThrobber = (message) => {
|
||||
// Build markup without adding extra white space since it affects rendering.
|
||||
const messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : '';
|
||||
const throbber = '<div class="throbber"> </div>';
|
||||
|
||||
return `<div class="ajax-progress ajax-progress-throbber">${throbber}${messageMarkup}</div>`;
|
||||
};
|
||||
|
||||
/**
|
||||
* An animated progress throbber and container element for AJAX operations.
|
||||
*
|
||||
* @return {string}
|
||||
* The HTML markup for the throbber.
|
||||
*/
|
||||
Drupal.theme.ajaxProgressIndicatorFullscreen = () => '<div class="ajax-progress ajax-progress-fullscreen"> </div>';
|
||||
|
||||
/**
|
||||
* Formats text accompanying the AJAX progress throbber.
|
||||
*
|
||||
* @param {string} message
|
||||
* The message shown on the UI.
|
||||
* @return {string}
|
||||
* The HTML markup for the throbber.
|
||||
*/
|
||||
Drupal.theme.ajaxProgressMessage = message => `<div class="message">${message}</div>`;
|
||||
|
||||
/**
|
||||
* Sets the progress bar progress indicator.
|
||||
*/
|
||||
|
|
@ -831,10 +865,7 @@
|
|||
* Sets the throbber progress indicator.
|
||||
*/
|
||||
Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () {
|
||||
this.progress.element = $('<div class="ajax-progress ajax-progress-throbber"><div class="throbber"> </div></div>');
|
||||
if (this.progress.message) {
|
||||
this.progress.element.find('.throbber').after(`<div class="message">${this.progress.message}</div>`);
|
||||
}
|
||||
this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message));
|
||||
$(this.element).after(this.progress.element);
|
||||
};
|
||||
|
||||
|
|
@ -842,7 +873,7 @@
|
|||
* Sets the fullscreen progress indicator.
|
||||
*/
|
||||
Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () {
|
||||
this.progress.element = $('<div class="ajax-progress ajax-progress-fullscreen"> </div>');
|
||||
this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen'));
|
||||
$('body').after(this.progress.element);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -368,6 +368,21 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
|
|||
}
|
||||
};
|
||||
|
||||
Drupal.theme.ajaxProgressThrobber = function (message) {
|
||||
var messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : '';
|
||||
var throbber = '<div class="throbber"> </div>';
|
||||
|
||||
return '<div class="ajax-progress ajax-progress-throbber">' + throbber + messageMarkup + '</div>';
|
||||
};
|
||||
|
||||
Drupal.theme.ajaxProgressIndicatorFullscreen = function () {
|
||||
return '<div class="ajax-progress ajax-progress-fullscreen"> </div>';
|
||||
};
|
||||
|
||||
Drupal.theme.ajaxProgressMessage = function (message) {
|
||||
return '<div class="message">' + message + '</div>';
|
||||
};
|
||||
|
||||
Drupal.Ajax.prototype.setProgressIndicatorBar = function () {
|
||||
var progressBar = new Drupal.ProgressBar('ajax-progress-' + this.element.id, $.noop, this.progress.method, $.noop);
|
||||
if (this.progress.message) {
|
||||
|
|
@ -382,15 +397,12 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
|
|||
};
|
||||
|
||||
Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () {
|
||||
this.progress.element = $('<div class="ajax-progress ajax-progress-throbber"><div class="throbber"> </div></div>');
|
||||
if (this.progress.message) {
|
||||
this.progress.element.find('.throbber').after('<div class="message">' + this.progress.message + '</div>');
|
||||
}
|
||||
this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message));
|
||||
$(this.element).after(this.progress.element);
|
||||
};
|
||||
|
||||
Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () {
|
||||
this.progress.element = $('<div class="ajax-progress ajax-progress-fullscreen"> </div>');
|
||||
this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen'));
|
||||
$('body').after(this.progress.element);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@
|
|||
|
||||
if (rowNames.length) {
|
||||
// Add a throbber next each of the ajaxElements.
|
||||
$(ajaxElements).after('<div class="ajax-progress ajax-progress-throbber"><div class="throbber"> </div></div>');
|
||||
$(ajaxElements).after(Drupal.theme.ajaxProgressThrobber());
|
||||
|
||||
// Fire the Ajax update.
|
||||
$('input[name=refresh_rows]').val(rowNames.join(' '));
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@
|
|||
});
|
||||
|
||||
if (rowNames.length) {
|
||||
$(ajaxElements).after('<div class="ajax-progress ajax-progress-throbber"><div class="throbber"> </div></div>');
|
||||
$(ajaxElements).after(Drupal.theme.ajaxProgressThrobber());
|
||||
|
||||
$('input[name=refresh_rows]').val(rowNames.join(' '));
|
||||
$('input[data-drupal-selector="edit-refresh"]').trigger('mousedown');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
name: Hold test
|
||||
type: module
|
||||
description: 'Support testing with request/response hold.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the hold_test module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function hold_test_install() {
|
||||
hold_test_request(FALSE);
|
||||
hold_test_response(FALSE);
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains functions for testing hold request/response.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Request hold.
|
||||
*
|
||||
* @param bool $status
|
||||
* TRUE - enable hold, FALSE - disable hold.
|
||||
*/
|
||||
function hold_test_request($status) {
|
||||
file_put_contents(\Drupal::root() . '/sites/default/files/simpletest/hold_test_request.txt', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Response hold.
|
||||
*
|
||||
* @param bool $status
|
||||
* TRUE - enable hold, FALSE - disable hold.
|
||||
*/
|
||||
function hold_test_response($status) {
|
||||
file_put_contents(\Drupal::root() . '/sites/default/files/simpletest/hold_test_response.txt', $status);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
services:
|
||||
hold_test.response:
|
||||
class: Drupal\hold_test\EventSubscriber\HoldTestSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\hold_test\EventSubscriber;
|
||||
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Response subscriber to test hold.
|
||||
*/
|
||||
class HoldTestSubscriber implements EventSubscriberInterface {
|
||||
|
||||
const HOLD_REQUEST = 'request';
|
||||
const HOLD_RESPONSE = 'response';
|
||||
|
||||
/**
|
||||
* Request hold.
|
||||
*/
|
||||
public function onRequest() {
|
||||
$this->hold(static::HOLD_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Response hold.
|
||||
*/
|
||||
public function onRespond() {
|
||||
$this->hold(static::HOLD_RESPONSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hold process by type.
|
||||
*
|
||||
* @param string $type
|
||||
* Type of hold.
|
||||
*/
|
||||
protected function hold($type) {
|
||||
$path = \Drupal::root() . "/sites/default/files/simpletest/hold_test_$type.txt";
|
||||
do {
|
||||
$status = (bool) file_get_contents($path);
|
||||
} while ($status && (NULL === usleep(100000)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events[KernelEvents::REQUEST][] = ['onRequest'];
|
||||
$events[KernelEvents::RESPONSE][] = ['onRespond'];
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests\Ajax;
|
||||
|
||||
use Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
|
||||
/**
|
||||
* Tests the throbber.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class ThrobberTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $minkDefaultDriverClass = DrupalSelenium2Driver::class;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'node',
|
||||
'views',
|
||||
'views_ui',
|
||||
'views_ui_test_field',
|
||||
'hold_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer views',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests theming throbber element.
|
||||
*/
|
||||
public function testThemingThrobberElement() {
|
||||
$session = $this->getSession();
|
||||
$web_assert = $this->assertSession();
|
||||
$page = $session->getPage();
|
||||
|
||||
$custom_ajax_progress_indicator_fullscreen = <<<JS
|
||||
Drupal.theme.ajaxProgressIndicatorFullscreen = function () {
|
||||
return '<div class="custom-ajax-progress-fullscreen"></div>';
|
||||
};
|
||||
JS;
|
||||
$custom_ajax_progress_throbber = <<<JS
|
||||
Drupal.theme.ajaxProgressThrobber = function (message) {
|
||||
return '<div class="custom-ajax-progress-throbber"></div>';
|
||||
};
|
||||
JS;
|
||||
$custom_ajax_progress_message = <<<JS
|
||||
Drupal.theme.ajaxProgressMessage = function (message) {
|
||||
return '<div class="custom-ajax-progress-message">Hold door!</div>';
|
||||
};
|
||||
JS;
|
||||
|
||||
$this->drupalGet('admin/structure/views/view/content');
|
||||
$this->waitForNoElement('.ajax-progress-fullscreen');
|
||||
|
||||
// Test theming fullscreen throbber.
|
||||
$session->executeScript($custom_ajax_progress_indicator_fullscreen);
|
||||
hold_test_response(TRUE);
|
||||
$page->clickLink('Content: Published (grouped)');
|
||||
$this->assertNotNull($web_assert->waitForElement('css', '.custom-ajax-progress-fullscreen'), 'Custom ajaxProgressIndicatorFullscreen.');
|
||||
hold_test_response(FALSE);
|
||||
$this->waitForNoElement('.custom-ajax-progress-fullscreen');
|
||||
|
||||
// Test theming throbber message.
|
||||
$web_assert->waitForElementVisible('css', '[data-drupal-selector="edit-options-group-info-add-group"]');
|
||||
$session->executeScript($custom_ajax_progress_message);
|
||||
hold_test_response(TRUE);
|
||||
$page->pressButton('Add another item');
|
||||
$this->assertNotNull($web_assert->waitForElement('css', '.ajax-progress-throbber .custom-ajax-progress-message'), 'Custom ajaxProgressMessage.');
|
||||
hold_test_response(FALSE);
|
||||
$this->waitForNoElement('.ajax-progress-throbber');
|
||||
|
||||
// Test theming throbber.
|
||||
$web_assert->waitForElementVisible('css', '[data-drupal-selector="edit-options-group-info-group-items-3-title"]');
|
||||
$session->executeScript($custom_ajax_progress_throbber);
|
||||
hold_test_response(TRUE);
|
||||
$page->pressButton('Add another item');
|
||||
$this->assertNotNull($web_assert->waitForElement('css', '.custom-ajax-progress-throbber'), 'Custom ajaxProgressThrobber.');
|
||||
hold_test_response(FALSE);
|
||||
$this->waitForNoElement('.custom-ajax-progress-throbber');
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for an element to be removed from the page.
|
||||
*
|
||||
* @param string $selector
|
||||
* CSS selector.
|
||||
* @param int $timeout
|
||||
* (optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @todo Remove in https://www.drupal.org/node/2892440.
|
||||
*/
|
||||
protected function waitForNoElement($selector, $timeout = 10000) {
|
||||
$condition = "(typeof jQuery !== 'undefined' && jQuery('$selector').length === 0)";
|
||||
$this->assertJsCondition($condition, $timeout);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue