diff sites/all/modules/admin_menu/admin_menu.js @ 4:ce11bbd8f642

added modules
author danieleb <danielebarchiesi@me.com>
date Thu, 19 Sep 2013 10:38:44 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/modules/admin_menu/admin_menu.js	Thu Sep 19 10:38:44 2013 +0100
@@ -0,0 +1,397 @@
+(function($) {
+
+Drupal.admin = Drupal.admin || {};
+Drupal.admin.behaviors = Drupal.admin.behaviors || {};
+Drupal.admin.hashes = Drupal.admin.hashes || {};
+
+/**
+ * Core behavior for Administration menu.
+ *
+ * Test whether there is an administration menu is in the output and execute all
+ * registered behaviors.
+ */
+Drupal.behaviors.adminMenu = {
+  attach: function (context, settings) {
+    // Initialize settings.
+    settings.admin_menu = $.extend({
+      suppress: false,
+      margin_top: false,
+      position_fixed: false,
+      tweak_modules: false,
+      tweak_permissions: false,
+      tweak_tabs: false,
+      destination: '',
+      basePath: settings.basePath,
+      hash: 0,
+      replacements: {}
+    }, settings.admin_menu || {});
+    // Check whether administration menu should be suppressed.
+    if (settings.admin_menu.suppress) {
+      return;
+    }
+    var $adminMenu = $('#admin-menu:not(.admin-menu-processed)', context);
+    // Client-side caching; if administration menu is not in the output, it is
+    // fetched from the server and cached in the browser.
+    if (!$adminMenu.length && settings.admin_menu.hash) {
+      Drupal.admin.getCache(settings.admin_menu.hash, function (response) {
+          if (typeof response == 'string' && response.length > 0) {
+            $('body', context).append(response);
+          }
+          var $adminMenu = $('#admin-menu:not(.admin-menu-processed)', context);
+          // Apply our behaviors.
+          Drupal.admin.attachBehaviors(context, settings, $adminMenu);
+          // Allow resize event handlers to recalculate sizes/positions.
+          $(window).triggerHandler('resize');
+      });
+    }
+    // If the menu is in the output already, this means there is a new version.
+    else {
+      // Apply our behaviors.
+      Drupal.admin.attachBehaviors(context, settings, $adminMenu);
+    }
+  }
+};
+
+/**
+ * Collapse fieldsets on Modules page.
+ */
+Drupal.behaviors.adminMenuCollapseModules = {
+  attach: function (context, settings) {
+    if (settings.admin_menu.tweak_modules) {
+      $('#system-modules fieldset:not(.collapsed)', context).addClass('collapsed');
+    }
+  }
+};
+
+/**
+ * Collapse modules on Permissions page.
+ */
+Drupal.behaviors.adminMenuCollapsePermissions = {
+  attach: function (context, settings) {
+    if (settings.admin_menu.tweak_permissions) {
+      // Freeze width of first column to prevent jumping.
+      $('#permissions th:first', context).css({ width: $('#permissions th:first', context).width() });
+      // Attach click handler.
+      $modules = $('#permissions tr:has(td.module)', context).once('admin-menu-tweak-permissions', function () {
+        var $module = $(this);
+        $module.bind('click.admin-menu', function () {
+          // @todo Replace with .nextUntil() in jQuery 1.4.
+          $module.nextAll().each(function () {
+            var $row = $(this);
+            if ($row.is(':has(td.module)')) {
+              return false;
+            }
+            $row.toggleClass('element-hidden');
+          });
+        });
+      });
+      // Collapse all but the targeted permission rows set.
+      if (window.location.hash.length) {
+        $modules = $modules.not(':has(' + window.location.hash + ')');
+      }
+      $modules.trigger('click.admin-menu');
+    }
+  }
+};
+
+/**
+ * Apply margin to page.
+ *
+ * Note that directly applying marginTop does not work in IE. To prevent
+ * flickering/jumping page content with client-side caching, this is a regular
+ * Drupal behavior.
+ */
+Drupal.behaviors.adminMenuMarginTop = {
+  attach: function (context, settings) {
+    if (!settings.admin_menu.suppress && settings.admin_menu.margin_top) {
+      $('body:not(.admin-menu)', context).addClass('admin-menu');
+    }
+  }
+};
+
+/**
+ * Retrieve content from client-side cache.
+ *
+ * @param hash
+ *   The md5 hash of the content to retrieve.
+ * @param onSuccess
+ *   A callback function invoked when the cache request was successful.
+ */
+Drupal.admin.getCache = function (hash, onSuccess) {
+  if (Drupal.admin.hashes.hash !== undefined) {
+    return Drupal.admin.hashes.hash;
+  }
+  $.ajax({
+    cache: true,
+    type: 'GET',
+    dataType: 'text', // Prevent auto-evaluation of response.
+    global: false, // Do not trigger global AJAX events.
+    url: Drupal.settings.admin_menu.basePath.replace(/admin_menu/, 'js/admin_menu/cache/' + hash),
+    success: onSuccess,
+    complete: function (XMLHttpRequest, status) {
+      Drupal.admin.hashes.hash = status;
+    }
+  });
+};
+
+/**
+ * TableHeader callback to determine top viewport offset.
+ *
+ * @see toolbar.js
+ */
+Drupal.admin.height = function() {
+  var $adminMenu = $('#admin-menu');
+  var height = $adminMenu.outerHeight();
+  // In IE, Shadow filter adds some extra height, so we need to remove it from
+  // the returned height.
+  if ($adminMenu.css('filter') && $adminMenu.css('filter').match(/DXImageTransform\.Microsoft\.Shadow/)) {
+    height -= $adminMenu.get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength;
+  }
+  return height;
+};
+
+/**
+ * @defgroup admin_behaviors Administration behaviors.
+ * @{
+ */
+
+/**
+ * Attach administrative behaviors.
+ */
+Drupal.admin.attachBehaviors = function (context, settings, $adminMenu) {
+  if ($adminMenu.length) {
+    $adminMenu.addClass('admin-menu-processed');
+    $.each(Drupal.admin.behaviors, function() {
+      this(context, settings, $adminMenu);
+    });
+  }
+};
+
+/**
+ * Apply 'position: fixed'.
+ */
+Drupal.admin.behaviors.positionFixed = function (context, settings, $adminMenu) {
+  if (settings.admin_menu.position_fixed) {
+    $adminMenu.addClass('admin-menu-position-fixed');
+    $adminMenu.css('position', 'fixed');
+  }
+};
+
+/**
+ * Move page tabs into administration menu.
+ */
+Drupal.admin.behaviors.pageTabs = function (context, settings, $adminMenu) {
+  if (settings.admin_menu.tweak_tabs) {
+    var $tabs = $(context).find('ul.tabs.primary');
+    $adminMenu.find('#admin-menu-wrapper > ul').eq(1)
+      .append($tabs.find('li').addClass('admin-menu-tab'));
+    $(context).find('ul.tabs.secondary')
+      .appendTo('#admin-menu-wrapper > ul > li.admin-menu-tab.active')
+      .removeClass('secondary');
+    $tabs.remove();
+  }
+};
+
+/**
+ * Perform dynamic replacements in cached menu.
+ */
+Drupal.admin.behaviors.replacements = function (context, settings, $adminMenu) {
+  for (var item in settings.admin_menu.replacements) {
+    $(item, $adminMenu).html(settings.admin_menu.replacements[item]);
+  }
+};
+
+/**
+ * Inject destination query strings for current page.
+ */
+Drupal.admin.behaviors.destination = function (context, settings, $adminMenu) {
+  if (settings.admin_menu.destination) {
+    $('a.admin-menu-destination', $adminMenu).each(function() {
+      this.search += (!this.search.length ? '?' : '&') + Drupal.settings.admin_menu.destination;
+    });
+  }
+};
+
+/**
+ * Apply JavaScript-based hovering behaviors.
+ *
+ * @todo This has to run last.  If another script registers additional behaviors
+ *   it will not run last.
+ */
+Drupal.admin.behaviors.hover = function (context, settings, $adminMenu) {
+  // Hover emulation for IE 6.
+  if ($.browser.msie && parseInt(jQuery.browser.version) == 6) {
+    $('li', $adminMenu).hover(
+      function () {
+        $(this).addClass('iehover');
+      },
+      function () {
+        $(this).removeClass('iehover');
+      }
+    );
+  }
+
+  // Delayed mouseout.
+  $('li.expandable', $adminMenu).hover(
+    function () {
+      // Stop the timer.
+      clearTimeout(this.sfTimer);
+      // Display child lists.
+      $('> ul', this)
+        .css({left: 'auto', display: 'block'})
+        // Immediately hide nephew lists.
+        .parent().siblings('li').children('ul').css({left: '-999em', display: 'none'});
+    },
+    function () {
+      // Start the timer.
+      var uls = $('> ul', this);
+      this.sfTimer = setTimeout(function () {
+        uls.css({left: '-999em', display: 'none'});
+      }, 400);
+    }
+  );
+};
+
+/**
+ * Apply the search bar functionality.
+ */
+Drupal.admin.behaviors.search = function (context, settings, $adminMenu) {
+  // @todo Add a HTML ID.
+  var $input = $('input.admin-menu-search', $adminMenu);
+  // Initialize the current search needle.
+  var needle = $input.val();
+  // Cache of all links that can be matched in the menu.
+  var links;
+  // Minimum search needle length.
+  var needleMinLength = 2;
+  // Append the results container.
+  var $results = $('<div />').insertAfter($input);
+
+  /**
+   * Executes the search upon user input.
+   */
+  function keyupHandler() {
+    var matches, $html, value = $(this).val();
+    // Only proceed if the search needle has changed.
+    if (value !== needle) {
+      needle = value;
+      // Initialize the cache of menu links upon first search.
+      if (!links && needle.length >= needleMinLength) {
+        // @todo Limit to links in dropdown menus; i.e., skip menu additions.
+        links = buildSearchIndex($adminMenu.find('li:not(.admin-menu-action, .admin-menu-action li) > a'));
+      }
+      // Empty results container when deleting search text.
+      if (needle.length < needleMinLength) {
+        $results.empty();
+      }
+      // Only search if the needle is long enough.
+      if (needle.length >= needleMinLength && links) {
+        matches = findMatches(needle, links);
+        // Build the list in a detached DOM node.
+        $html = buildResultsList(matches);
+        // Display results.
+        $results.empty().append($html);
+      }
+    }
+  }
+
+  /**
+   * Builds the search index.
+   */
+  function buildSearchIndex($links) {
+    return $links
+      .map(function () {
+        var text = (this.textContent || this.innerText);
+        // Skip menu entries that do not contain any text (e.g., the icon).
+        if (typeof text === 'undefined') {
+          return;
+        }
+        return {
+          text: text,
+          textMatch: text.toLowerCase(),
+          element: this
+        };
+      });
+  }
+
+  /**
+   * Searches the index for a given needle and returns matching entries.
+   */
+  function findMatches(needle, links) {
+    var needleMatch = needle.toLowerCase();
+    // Select matching links from the cache.
+    return $.grep(links, function (link) {
+      return link.textMatch.indexOf(needleMatch) !== -1;
+    });
+  }
+
+  /**
+   * Builds the search result list in a detached DOM node.
+   */
+  function buildResultsList(matches) {
+    var $html = $('<ul class="dropdown admin-menu-search-results" />');
+    $.each(matches, function () {
+      var result = this.text;
+      var $element = $(this.element);
+
+      // Check whether there is a top-level category that can be prepended.
+      var $category = $element.closest('#admin-menu-wrapper > ul > li');
+      var categoryText = $category.find('> a').text()
+      if ($category.length && categoryText) {
+        result = categoryText + ': ' + result;
+      }
+
+      var $result = $('<li><a href="' + $element.attr('href') + '">' + result + '</a></li>');
+      $result.data('original-link', $(this.element).parent());
+      $html.append($result);
+    });
+    return $html;
+  }
+
+  /**
+   * Highlights selected result.
+   */
+  function resultsHandler(e) {
+    var $this = $(this);
+    var show = e.type === 'mouseenter' || e.type === 'focusin';
+    $this.trigger(show ? 'showPath' : 'hidePath', [this]);
+  }
+
+  /**
+   * Closes the search results and clears the search input.
+   */
+  function resultsClickHandler(e, link) {
+    var $original = $(this).data('original-link');
+    $original.trigger('mouseleave');
+    $input.val('').trigger('keyup');
+  }
+
+  /**
+   * Shows the link in the menu that corresponds to a search result.
+   */
+  function highlightPathHandler(e, link) {
+    if (link) {
+      var $original = $(link).data('original-link');
+      var show = e.type === 'showPath';
+      // Toggle an additional CSS class to visually highlight the matching link.
+      // @todo Consider using same visual appearance as regular hover.
+      $original.toggleClass('highlight', show);
+      $original.trigger(show ? 'mouseenter' : 'mouseleave');
+    }
+  }
+
+  // Attach showPath/hidePath handler to search result entries.
+  $results.delegate('li', 'mouseenter mouseleave focus blur', resultsHandler);
+  // Hide the result list after a link has been clicked, useful for overlay.
+  $results.delegate('li', 'click', resultsClickHandler);
+  // Attach hover/active highlight behavior to search result entries.
+  $adminMenu.delegate('.admin-menu-search-results li', 'showPath hidePath', highlightPathHandler);
+  // Attach the search input event handler.
+  $input.bind('keyup search', keyupHandler);
+};
+
+/**
+ * @} End of "defgroup admin_behaviors".
+ */
+
+})(jQuery);