You are here

lazyloader.module in Image Lazyloader 7

Same filename and directory in other branches
  1. 8 lazyloader.module
  2. 7.2 lazyloader.module

Lazyloader Module

@author: Daniel Honrade http://drupal.org/user/351112

Note: Obviously, this will not work unless the javascript is on.

File

lazyloader.module
View source
<?php

/**
 * @file
 * Lazyloader Module
 *
 * @author: Daniel Honrade http://drupal.org/user/351112
 *
 * Note: Obviously, this will not work unless the javascript is on.
 *
 */
define("LAZYLOADER_ENABLED", TRUE);
define("LAZYLOADER_DISTANCE", 0);
define("LAZYLOADER_ICON", 7);
define("LAZYLOADER_PLACEHOLDER", '');
define("LAZYLOADER_PATHS", "media/*/format-form\nadmin/*\nnode/add/*\nnode/*/edit");
define("LAZYLOADER_EXCLUDE_OPTION", 'exclude');
define("LAZYLOADER_LOAD_IMAGE_DELAY", 50);

/**
 * Implements hook_menu().
 *
 */
function lazyloader_menu() {
  $items = array();
  $items['admin/config/media/lazyloader'] = array(
    'title' => 'Image Lazyloader',
    'page callback' => 'drupal_get_form',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer lazyloader',
    ),
    'page arguments' => array(
      'lazyloader_admin',
      NULL,
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'lazyloader.admin.inc',
    'description' => 'Configure Lazyloader',
  );
  return $items;
}

/**
 * Implements hook_perm().
 *
 */
function lazyloader_permission() {
  return array(
    'administer lazyloader' => array(
      'title' => t('Administer Lazyloader'),
      'description' => t('Perform administration tasks for Lazyloader.'),
    ),
  );
}

/**
 * Implements hook_theme_registry_alter().
 */
function lazyloader_theme_registry_alter(&$theme_registry) {
  if (variable_get('lazyloader_enabled', LAZYLOADER_ENABLED)) {
    $theme_registry['image']['function'] = 'lazyloader_image';
  }
  return $theme_registry;
}

/**
 * Returns HTML for an image.
 *
 * @param $variables
 *   An associative array containing:
 *   - path: Either the path of the image file (relative to base_path()) or a
 *     full URL.
 *   - width: The width of the image (if known).
 *   - height: The height of the image (if known).
 *   - alt: The alternative text for text-based browsers. HTML 4 and XHTML 1.0
 *     always require an alt attribute. The HTML 5 draft allows the alt
 *     attribute to be omitted in some cases. Therefore, this variable defaults
 *     to an empty string, but can be set to NULL for the attribute to be
 *     omitted. Usually, neither omission nor an empty string satisfies
 *     accessibility requirements, so it is strongly encouraged for code calling
 *     theme('image') to pass a meaningful value for this variable.
 *     - http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
 *     - http://www.w3.org/TR/xhtml1/dtds.html
 *     - http://dev.w3.org/html5/spec/Overview.html#alt
 *   - title: The title text is displayed when the image is hovered in some
 *     popular browsers.
 *   - attributes: Associative array of attributes to be placed in the img tag.
 * @return string
 *  HTML for a lazyloaded image
 */
function lazyloader_image($variables) {
  static $rdwimages_enabled, $image_placeholder_src;
  $attributes = $variables['attributes'];
  $noscript_attributes = $variables['attributes'];
  $src = file_create_url($variables['path']);
  if (_lazy_loader_enabled()) {
    $attributes['data-src'] = $src;
    if (!isset($image_placeholder_src)) {

      // Path to dummy placeholder image, to be replaced by actual image.
      $image_placeholder = trim(variable_get('lazyloader_placeholder', LAZYLOADER_PLACEHOLDER));
      $image_placeholder_src = $image_placeholder ? base_path() . $image_placeholder : file_create_url(drupal_get_path('module', 'lazyloader') . '/image_placeholder.gif');
    }
    $attributes['src'] = $image_placeholder_src;
    $noscript_attributes['src'] = $src;

    // Integrate with Responsive Webdesign module.
    if (!isset($rdwimages_enabled)) {
      global $_rwdimages_set;
      $rdwimages_enabled = module_exists('rdwimages') && $_rwdimages_set['enabled'];
    }
    if ($rdwimages_enabled) {
      $attributes['class'] = array(
        'rwdimage',
      );
    }
  }
  else {
    $attributes['src'] = $src;
  }
  foreach (array(
    'width',
    'height',
    'alt',
    'title',
  ) as $key) {
    if (isset($variables[$key])) {
      $attributes[$key] = $variables[$key];
    }
    if (isset($variables[$key])) {
      $noscript_attributes[$key] = $variables[$key];
    }
  }
  $noscript = '';
  if (!empty($attributes['data-src'])) {
    $noscript = '<noscript><img' . drupal_attributes($noscript_attributes) . ' /></noscript>';
  }
  return '<img' . drupal_attributes($attributes) . ' />' . $noscript;
}

/**
 * Implements hook_page_build().
 *
 * Initialize the trigger for lazyloader.
 */
function lazyloader_page_build(&$vars) {
  if (_lazy_loader_enabled()) {

    // add noscript markup as a fallback
    $vars['page_bottom']['lazyload']['#markup'] = <<<'NOSCRIPT'
      <noscript>
        <style type="text/css" media="all">
          img[data-src] { display: none !important; }
        </style>
      </noscript>
NOSCRIPT;

    // inline load this js with ajax / page compatibility in mind
    $distance = trim(variable_get('lazyloader_distance', LAZYLOADER_DISTANCE));
    $icon = _lazyloader_icon_path();
    $lazyloader_init = <<<Script
      (function (\$) {
        Drupal.behaviors.lazyloader = {
          attach: function (context, settings) {
            \$("img[data-src]").lazyloader({distance: {<span class="php-variable">$distance</span>}, icon: "{<span class="php-variable">$icon</span>}" });
          }
        };
      }(jQuery));
Script;
    $vars['page_bottom']['lazyload']['#attached']['js'][] = array(
      'data' => $lazyloader_init,
      'type' => 'inline',
      'scope' => 'footer',
    );
    $settings = array(
      'lazyloader' => array(
        'loadImageDelay' => variable_get('lazyloader_load_image_delay', LAZYLOADER_LOAD_IMAGE_DELAY),
      ),
    );
    $vars['page_bottom']['lazyload']['#attached']['js'][] = array(
      'data' => $settings,
      'type' => 'setting',
    );
  }
}

/**
 * Helper function to determine whether the lazyloader is enabled in a page.
 *
 * @return bool
 */
function _lazy_loader_enabled() {

  // Bail if lazyloader is disabled entirely.
  if (!variable_get('lazyloader_enabled', LAZYLOADER_ENABLED)) {
    return FALSE;
  }

  // Convert path to lowercase. This allows comparison of the same path
  // with different case. Ex: /Page, /page, /PAGE.
  $pages = drupal_strtolower(variable_get('lazyloader_paths', LAZYLOADER_PATHS));

  // Convert the Drupal path to lowercase
  $path = drupal_strtolower(drupal_get_path_alias($_GET['q']));

  // Compare the lowercase internal and lowercase path alias (if any).
  $path_match = drupal_match_path($path, $pages);
  if ($path != $_GET['q']) {
    $path_match = $path_match || drupal_match_path($_GET['q'], $pages);
  }
  if (variable_get('lazyloader_exclude_option', LAZYLOADER_EXCLUDE_OPTION) === 'exclude') {
    return !$path_match;
  }
  else {
    return $path_match;
  }
}

/**
 * Helper function to get the loading icon.
 */
function _lazyloader_icon_path() {
  $icon = variable_get('lazyloader_icon', LAZYLOADER_ICON);
  if (!empty($icon)) {
    $base = base_path();
    $path = drupal_get_path('module', 'lazyloader');
    return "{$base}{$path}/loader/loader-{$icon}.gif";
  }
  return '';
}

Functions

Namesort descending Description
lazyloader_image Returns HTML for an image.
lazyloader_menu Implements hook_menu().
lazyloader_page_build Implements hook_page_build().
lazyloader_permission Implements hook_perm().
lazyloader_theme_registry_alter Implements hook_theme_registry_alter().
_lazyloader_icon_path Helper function to get the loading icon.
_lazy_loader_enabled Helper function to determine whether the lazyloader is enabled in a page.

Constants