Issue #2535118 by longwave, Wim Leers, borisson_, effulgentsia: Toolbar subtrees not working on admin pages due to lack of theme negotiation on Toolbar's custom JSONP route
parent
2f8646a759
commit
0c810aa1a0
|
|
@ -79,7 +79,8 @@
|
||||||
// asynchronously.
|
// asynchronously.
|
||||||
Drupal.toolbar.setSubtrees.done(function (subtrees) {
|
Drupal.toolbar.setSubtrees.done(function (subtrees) {
|
||||||
menuModel.set('subtrees', subtrees);
|
menuModel.set('subtrees', subtrees);
|
||||||
localStorage.setItem('Drupal.toolbar.subtrees', JSON.stringify(subtrees));
|
var theme = drupalSettings.ajaxPageState.theme;
|
||||||
|
localStorage.setItem('Drupal.toolbar.subtrees.' + theme, JSON.stringify(subtrees));
|
||||||
// Indicate on the toolbarModel that subtrees are now loaded.
|
// Indicate on the toolbarModel that subtrees are now loaded.
|
||||||
model.set('areSubtreesLoaded', true);
|
model.set('areSubtreesLoaded', true);
|
||||||
});
|
});
|
||||||
|
|
@ -233,4 +234,15 @@
|
||||||
'</div></div>';
|
'</div></div>';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax command to set the toolbar subtrees.
|
||||||
|
*
|
||||||
|
* @param {Drupal.Ajax} ajax
|
||||||
|
* @param {object} response
|
||||||
|
* @param {number} [status]
|
||||||
|
*/
|
||||||
|
Drupal.AjaxCommands.prototype.setToolbarSubtrees = function (ajax, response, status) {
|
||||||
|
Drupal.toolbar.setSubtrees.resolve(response.subtrees);
|
||||||
|
};
|
||||||
|
|
||||||
}(jQuery, Drupal, drupalSettings));
|
}(jQuery, Drupal, drupalSettings));
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,8 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the endpoint URI that will return rendered subtrees with JSONP.
|
* Calls the endpoint URI that builds an AJAX command with the rendered
|
||||||
|
* subtrees.
|
||||||
*
|
*
|
||||||
* The rendered admin menu subtrees HTML is cached on the client in
|
* The rendered admin menu subtrees HTML is cached on the client in
|
||||||
* localStorage until the cache of the admin menu subtrees on the server-
|
* localStorage until the cache of the admin menu subtrees on the server-
|
||||||
|
|
@ -267,9 +268,10 @@
|
||||||
// (3) The orientation of the tray is vertical.
|
// (3) The orientation of the tray is vertical.
|
||||||
if (!this.model.get('areSubtreesLoaded') && typeof $activeTab.data('drupal-subtrees') !== 'undefined' && orientation === 'vertical') {
|
if (!this.model.get('areSubtreesLoaded') && typeof $activeTab.data('drupal-subtrees') !== 'undefined' && orientation === 'vertical') {
|
||||||
var subtreesHash = drupalSettings.toolbar.subtreesHash;
|
var subtreesHash = drupalSettings.toolbar.subtreesHash;
|
||||||
|
var theme = drupalSettings.ajaxPageState.theme;
|
||||||
var endpoint = Drupal.url('toolbar/subtrees/' + subtreesHash);
|
var endpoint = Drupal.url('toolbar/subtrees/' + subtreesHash);
|
||||||
var cachedSubtreesHash = localStorage.getItem('Drupal.toolbar.subtreesHash');
|
var cachedSubtreesHash = localStorage.getItem('Drupal.toolbar.subtreesHash.' + theme);
|
||||||
var cachedSubtrees = JSON.parse(localStorage.getItem('Drupal.toolbar.subtrees'));
|
var cachedSubtrees = JSON.parse(localStorage.getItem('Drupal.toolbar.subtrees.' + theme));
|
||||||
var isVertical = this.model.get('orientation') === 'vertical';
|
var isVertical = this.model.get('orientation') === 'vertical';
|
||||||
// If we have the subtrees in localStorage and the subtree hash has not
|
// If we have the subtrees in localStorage and the subtree hash has not
|
||||||
// changed, then use the cached data.
|
// changed, then use the cached data.
|
||||||
|
|
@ -280,13 +282,13 @@
|
||||||
// toolbar is vertical.
|
// toolbar is vertical.
|
||||||
else if (isVertical) {
|
else if (isVertical) {
|
||||||
// Remove the cached menu information.
|
// Remove the cached menu information.
|
||||||
localStorage.removeItem('Drupal.toolbar.subtreesHash');
|
localStorage.removeItem('Drupal.toolbar.subtreesHash.' + theme);
|
||||||
localStorage.removeItem('Drupal.toolbar.subtrees');
|
localStorage.removeItem('Drupal.toolbar.subtrees.' + theme);
|
||||||
// The response from the server will call the resolve method of the
|
// The AJAX response's command will trigger the resolve method of the
|
||||||
// Drupal.toolbar.setSubtrees Promise.
|
// Drupal.toolbar.setSubtrees Promise.
|
||||||
$.ajax(endpoint);
|
Drupal.ajax({url: endpoint}).execute();
|
||||||
// Cache the hash for the subtrees locally.
|
// Cache the hash for the subtrees locally.
|
||||||
localStorage.setItem('Drupal.toolbar.subtreesHash', subtreesHash);
|
localStorage.setItem('Drupal.toolbar.subtreesHash.' + theme, subtreesHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\toolbar\Ajax\SetSubtreesCommand.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\toolbar\Ajax;
|
||||||
|
|
||||||
|
use Drupal\Core\Ajax\CommandInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an AJAX command that sets the toolbar subtrees.
|
||||||
|
*/
|
||||||
|
class SetSubtreesCommand implements CommandInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The toolbar subtrees.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $subtrees;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a SetSubtreesCommand object.
|
||||||
|
*
|
||||||
|
* @param array $subtrees
|
||||||
|
* The toolbar subtrees that will be set.
|
||||||
|
*/
|
||||||
|
public function __construct($subtrees) {
|
||||||
|
$this->subtrees = $subtrees;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function render() {
|
||||||
|
return [
|
||||||
|
'command' => 'setToolbarSubtrees',
|
||||||
|
'subtrees' => array_map('strval', $this->subtrees),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -8,8 +8,9 @@
|
||||||
namespace Drupal\toolbar\Controller;
|
namespace Drupal\toolbar\Controller;
|
||||||
|
|
||||||
use Drupal\Core\Access\AccessResult;
|
use Drupal\Core\Access\AccessResult;
|
||||||
|
use Drupal\Core\Ajax\AjaxResponse;
|
||||||
use Drupal\Core\Controller\ControllerBase;
|
use Drupal\Core\Controller\ControllerBase;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Drupal\toolbar\Ajax\SetSubtreesCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a controller for the toolbar module.
|
* Defines a controller for the toolbar module.
|
||||||
|
|
@ -17,14 +18,14 @@ use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
class ToolbarController extends ControllerBase {
|
class ToolbarController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rendered subtree of each top-level toolbar link.
|
* Returns an AJAX response to render the toolbar subtrees.
|
||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\JsonResponse
|
* @return \Drupal\Core\Ajax\AjaxResponse
|
||||||
*/
|
*/
|
||||||
public function subtreesJsonp() {
|
public function subtreesAjax() {
|
||||||
list($subtrees, $cacheability) = toolbar_get_rendered_subtrees();
|
list($subtrees, $cacheability) = toolbar_get_rendered_subtrees();
|
||||||
$response = new JsonResponse($subtrees);
|
$response = new AjaxResponse();
|
||||||
$response->setCallback('Drupal.toolbar.setSubtrees.resolve');
|
$response->addCommand(new SetSubtreesCommand($subtrees));
|
||||||
|
|
||||||
// The Expires HTTP header is the heart of the client-side HTTP caching. The
|
// The Expires HTTP header is the heart of the client-side HTTP caching. The
|
||||||
// additional server-side page cache only takes effect when the client
|
// additional server-side page cache only takes effect when the client
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Drupal\toolbar\Tests;
|
namespace Drupal\toolbar\Tests;
|
||||||
|
|
||||||
use Drupal\Component\Serialization\Json;
|
|
||||||
use Drupal\Core\Cache\Cache;
|
use Drupal\Core\Cache\Cache;
|
||||||
use Drupal\Core\Language\LanguageInterface;
|
use Drupal\Core\Language\LanguageInterface;
|
||||||
use Drupal\Core\Url;
|
use Drupal\Core\Url;
|
||||||
|
|
@ -341,14 +340,10 @@ class ToolbarAdminMenuTest extends WebTestBase {
|
||||||
// Request a new page to refresh the drupalSettings object.
|
// Request a new page to refresh the drupalSettings object.
|
||||||
$subtrees_hash = $this->getSubtreesHash();
|
$subtrees_hash = $this->getSubtreesHash();
|
||||||
|
|
||||||
$this->drupalGetJSON('toolbar/subtrees/' . $subtrees_hash);
|
$ajax_result = $this->drupalGetAjax('toolbar/subtrees/' . $subtrees_hash);
|
||||||
$this->assertResponse('200');
|
$this->assertResponse('200');
|
||||||
$json_callback_start = substr($this->getRawContent(), 0, 39);
|
$this->assertEqual($ajax_result[0]['command'], 'setToolbarSubtrees', 'Subtrees response uses the correct command.');
|
||||||
$json_callback_end = substr($this->getRawContent(), -2, 2);
|
$this->assertEqual(array_keys($ajax_result[0]['subtrees']), ['system-admin_content', 'system-admin_structure', 'system-themes_page', 'system-modules_list', 'system-admin_config', 'entity-user-collection', 'front'], 'Correct subtrees returned.');
|
||||||
$json = substr($this->getRawContent(), 39, strlen($this->getRawContent()) - 41);
|
|
||||||
$this->assertTrue($json_callback_start === '/**/Drupal.toolbar.setSubtrees.resolve(' && $json_callback_end === ');', 'Subtrees response is wrapped in callback.');
|
|
||||||
$subtrees = Json::decode($json);
|
|
||||||
$this->assertEqual(array_keys($subtrees), ['system-admin_content', 'system-admin_structure', 'system-themes_page', 'system-modules_list', 'system-admin_config', 'entity-user-collection', 'front'], 'Correct subtrees JSON returned.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ toolbar:
|
||||||
- core/jquery
|
- core/jquery
|
||||||
- core/drupal
|
- core/drupal
|
||||||
- core/drupalSettings
|
- core/drupalSettings
|
||||||
|
- core/drupal.ajax
|
||||||
- core/drupal.announce
|
- core/drupal.announce
|
||||||
- core/backbone
|
- core/backbone
|
||||||
- core/matchmedia
|
- core/matchmedia
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
toolbar.subtrees:
|
toolbar.subtrees:
|
||||||
path: '/toolbar/subtrees/{hash}'
|
path: '/toolbar/subtrees/{hash}'
|
||||||
defaults:
|
defaults:
|
||||||
_controller: '\Drupal\toolbar\Controller\ToolbarController::subtreesJsonp'
|
_controller: '\Drupal\toolbar\Controller\ToolbarController::subtreesAjax'
|
||||||
langcode: null
|
options:
|
||||||
|
_theme: ajax_base_page
|
||||||
requirements:
|
requirements:
|
||||||
_custom_access: '\Drupal\toolbar\Controller\ToolbarController::checkSubTreeAccess'
|
_custom_access: '\Drupal\toolbar\Controller\ToolbarController::checkSubTreeAccess'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue