Quantcast
Viewing all articles
Browse latest Browse all 294680

Complete the work to make the Toolbar administration menu sub tree rendering more efficient

Problem/Motivation

These are the components of the administration menu subtree rendering flow

Subtrees toolbar menu item

/**
* Implements hook_menu().
*/
function toolbar_menu() {
  $items['toolbar/subtrees/%'] = array(
    'page callback' => 'toolbar_subtrees_jsonp',
    'page arguments' => array(2),
    'access callback' => '_toolbar_subtrees_access',
    'access arguments' => array(2),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

Inject an inlined JS call to the subtree item retrieval menu item when the page renders.

// To conserve bandwidth, we only include the top-level links in the HTML.
// The subtrees are included in a JSONP script, cached by the browser. Here we
// add that JSONP script. We add it as an external script, because it's a
// Drupal path, not a file available via a stream wrapper.
// @see toolbar_subtrees_jsonp()
$menu['toolbar_administration']['#attached']['js'][url('toolbar/subtrees/' . _toolbar_get_subtree_hash())] = array('type' => 'external');

Retrieve the subtrees through a client-side AJAX call and return as JSON

/**
* Page callback: Returns the rendered subtree of each top-level toolbar link.
*
* @see toolbar_menu().
*/
function toolbar_subtrees_jsonp($hash) {
  _toolbar_initialize_page_cache();
  $subtrees = toolbar_get_rendered_subtrees();
  $response = new JsonResponse($subtrees);
  $response->setCallback('Drupal.toolbar.setSubtrees');
  return $response;
}

The JS callback for the AJAX call is defined by toolbar.js under the Drupal object so it is available on the page to be invoked.

/**
* Set subtrees.
*
* JSONP callback.
* @see toolbar_subtrees_jsonp().
*/
Drupal.toolbar.setSubtrees = function(subtrees) {
  Drupal.toolbar.subtrees = subtrees;
};

If, at the time that the attach method of Drupal.behaviors.toolbar is invoked, the AJAX call to get the subtrees has returned and populated Drupal.toolbar.subtrees, then render the HTML to the DOM.

// Add subtrees.
// @todo Optimize this to delay adding each subtree to the DOM until it is
//   needed; however, take into account screen readers for determining
//   when the DOM elements are needed.
if (Drupal.toolbar.subtrees) {
  for (var id in Drupal.toolbar.subtrees) {
    $('#toolbar-link-' + id).after(Drupal.toolbar.subtrees[id]);
  }
}

The code flow above was always meant to be temporary improvement to simply hard-coding the submenu items into the HTML on the initial page request. But the flow can be further refined so that sub-menus items are retrieved on a needs basis, when the menu tree parent for the sub items is toggled open, rather than simply on page load.

Proposed resolution

(description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch)

Remaining tasks

Propose the changes in a patch.

User interface changes

Loading menu sub items may incur a spinner as the AJAX request is processed.

API changes

None.


Viewing all articles
Browse latest Browse all 294680

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>