839 lines
25 KiB
Plaintext
839 lines
25 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Main module file for Modernizr
|
|
*/
|
|
|
|
// Regular expression to determine which version of Modernizr is installed.
|
|
define('MODERNIZR_VERSION_REGEX', '/([23]\.\d\.\d)/');
|
|
|
|
// Regular expression to detect valid Modernizr filenames.
|
|
define('MODERNIZR_FILENAME_REGEX', '/^modernizr[A-Za-z0-9\.-]*\.js$/');
|
|
|
|
// Our drupal_add_js() and libraries_load() calls use this value to maintain
|
|
// consistency between the position of the library and its inline settings.
|
|
define('MODERNIZR_SCRIPT_GROUP', JS_LIBRARY - 10);
|
|
define('MODERNIZR_SCRIPT_WEIGHT', -100);
|
|
|
|
// As of 7.x-3.3 we support footer scope, inlining, and defer.
|
|
define('MODERNIZR_TYPE_DEFAULT', 'sync');
|
|
define('MODERNIZR_SCOPE_DEFAULT', 'header');
|
|
|
|
// Determines the severity of administrative errors.
|
|
// As of 7.x-3.7 we switched the default to TRUE since yepnope is now included
|
|
// automatically, so a custom build is no longer absolutely necessary in order
|
|
// to begin using hook_modernizr_load() functionality.
|
|
define('MODERNIZR_QUIET_DEFAULT', TRUE);
|
|
|
|
// As of 7.x-3.5 we support Modernizr v3, which cannot include yepnope.js in a
|
|
// custom build. For backward compat purposes, we will enable this flag in an
|
|
// update hook automatically, but the default it to not include it.
|
|
define('MODERNIZR_YEPNOPE_DEFAULT', FALSE);
|
|
|
|
/**
|
|
* Default drupal_add_js settings. Used in multiple places.
|
|
*
|
|
* @return array An array of settings for drupal_add_js.
|
|
*/
|
|
function _modernizr_js_settings() {
|
|
return array(
|
|
'type' => (variable_get('modernizr_type', MODERNIZR_TYPE_DEFAULT) != 'inline') ? 'file' : 'inline',
|
|
'scope' => variable_get('modernizr_scope', MODERNIZR_SCOPE_DEFAULT),
|
|
'group' => MODERNIZR_SCRIPT_GROUP,
|
|
'weight' => MODERNIZR_SCRIPT_WEIGHT,
|
|
'every_page' => TRUE,
|
|
'preprocess' => 0,
|
|
'defer' => (variable_get('modernizr_type', MODERNIZR_TYPE_DEFAULT) == 'defer') ? TRUE : FALSE,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Implements hook_page_build().
|
|
*
|
|
* We used to use hook_init(), but that loads the JS files needlessly
|
|
* on AJAX requests, private file requests, etc.
|
|
*/
|
|
function modernizr_page_build(&$page) {
|
|
global $base_url;
|
|
$modernizr_js_settings = _modernizr_js_settings();
|
|
|
|
// Load Modernizr on the page by invoking our implementation of
|
|
// hook_libraries_info().
|
|
//
|
|
// We can only use this method when Libraries API 2.0 is installed. Since Libraries 1.0
|
|
// did not contain a function called libraries_load(), we must explicitly check for a
|
|
// valid function to avoid fatal errors.
|
|
//
|
|
// @see http://drupal.org/node/1919796
|
|
if (module_exists('libraries') && function_exists('libraries_load')) {
|
|
libraries_load('modernizr');
|
|
}
|
|
else {
|
|
// First, figure out if we're inlining.
|
|
if (in_array(variable_get('modernizr_type', MODERNIZR_TYPE_DEFAULT), array('sync', 'defer'))) {
|
|
// We are loading external script. Load file path.
|
|
$modernizr_file = modernizr_get_path();
|
|
}
|
|
else {
|
|
// We are inlining. Load contents of file instead of path.
|
|
$modernizr_file = file_get_contents(modernizr_get_path());
|
|
}
|
|
|
|
// With no Libraries API, load the regular way.
|
|
drupal_add_js(
|
|
$modernizr_file,
|
|
$modernizr_js_settings
|
|
);
|
|
}
|
|
|
|
// We want yepnope() commands to be issued immediately after the call
|
|
// to Modernizr so that they download while the page renders. The overrides
|
|
// to $inline_js_settings will format the output as inline JS.
|
|
if ($output = _modernizr_load_generate()) {
|
|
|
|
// Modernizr v3 removed the ability to include yepnope.js directly in the
|
|
// custom builds. To ensure that previous users of this module can continue
|
|
// without breaking changes, we need to load a copy of yepnope manually,
|
|
// which Modernizr detects and aliases to yepnope().
|
|
if ($output && variable_get('modernizr_cb_load', MODERNIZR_YEPNOPE_DEFAULT)) {
|
|
$yepnope_settings = $modernizr_js_settings;
|
|
$yepnope_settings['type'] = 'inline';
|
|
$yepnope_settings['weight'] = MODERNIZR_SCRIPT_WEIGHT - 1;
|
|
|
|
// yepnope.js
|
|
drupal_add_js(
|
|
file_get_contents(drupal_get_path('module', 'modernizr') . '/js/yepnope.js'),
|
|
$yepnope_settings
|
|
);
|
|
|
|
$inline_js_settings = $modernizr_js_settings;
|
|
$inline_js_settings['type'] = 'inline';
|
|
$inline_js_settings['weight'] = MODERNIZR_SCRIPT_WEIGHT + 1;
|
|
|
|
// yepnope() statements
|
|
drupal_add_js(
|
|
$output,
|
|
$inline_js_settings
|
|
);
|
|
}
|
|
// If there are yepnope commands being requested, but the module does not
|
|
// have yepnope enabled, warn the user in the console.
|
|
else if ($output && !variable_get('modernizr_cb_load', MODERNIZR_YEPNOPE_DEFAULT)) {
|
|
drupal_add_js('console.warn("The Modernizr module is receiving requests to use yepnope.js but that option is currently disabled. Please enable yepnope.js by loading ' . $base_url . '/admin/config/development/modernizr/settings' . '");', array('type' => 'inline'));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_permission().
|
|
*/
|
|
function modernizr_permission() {
|
|
return array(
|
|
'administer modernizr' => array(
|
|
'title' => t('Administer Modernizr'),
|
|
'description' => t('Perform administration tasks for Modernizr.'),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Implements hook_menu().
|
|
*/
|
|
function modernizr_menu() {
|
|
$items = array();
|
|
|
|
// Rebuild Modernizr
|
|
$items['admin/config/development/modernizr/rebuild'] = array(
|
|
'title' => 'Rebuild Modernizr',
|
|
'description' => 'Queries Drupal for Modernizr dependencies and generates a custom link to the Modernizr builder.',
|
|
'page callback' => 'modernizr_generate_url',
|
|
'file' => 'modernizr.admin.inc',
|
|
'type' => MENU_DEFAULT_LOCAL_TASK,
|
|
'access arguments' => array('administer modernizr'),
|
|
);
|
|
|
|
// Module settings
|
|
$items['admin/config/development/modernizr/settings'] = array(
|
|
'title' => 'Modernizr settings',
|
|
'description' => 'Administrative settings for Modernizr module.',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('modernizr_admin'),
|
|
'file' => 'modernizr.admin.inc',
|
|
'type' => MENU_LOCAL_TASK,
|
|
'access arguments' => array('administer modernizr'),
|
|
);
|
|
|
|
// Admin menu item (duplicate of "Rebuild Modernizr")
|
|
$items['admin/config/development/modernizr'] = array(
|
|
'title' => 'Modernizr',
|
|
'description' => 'Queries Drupal for Modernizr dependencies and generates a custom link to the Modernizr builder.',
|
|
'page callback' => 'modernizr_generate_url',
|
|
'file' => 'modernizr.admin.inc',
|
|
'type' => MENU_NORMAL_ITEM,
|
|
'access arguments' => array('administer modernizr'),
|
|
);
|
|
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_libraries_info().
|
|
*
|
|
* @return array
|
|
*/
|
|
function modernizr_libraries_info() {
|
|
$modernizr_js_settings = _modernizr_js_settings();
|
|
$libraries = array();
|
|
$file_name = modernizr_get_filename();
|
|
|
|
// Define Modernizr within Libraries API
|
|
$libraries['modernizr'] = array(
|
|
'name' => t('Modernizr'),
|
|
'vendor url' => 'http://modernizr.com',
|
|
'download url' => 'http://modernizr.com/download/',
|
|
'version arguments' => array(
|
|
'file' => $file_name,
|
|
'pattern' => MODERNIZR_VERSION_REGEX,
|
|
),
|
|
'files' => array(
|
|
'js' => array(
|
|
$file_name => $modernizr_js_settings,
|
|
),
|
|
),
|
|
);
|
|
|
|
return $libraries;
|
|
}
|
|
|
|
/**
|
|
* Returns the full path of modernizr, along with the filename.
|
|
*
|
|
* @return string
|
|
*/
|
|
function modernizr_get_path() {
|
|
$path = &drupal_static(__FUNCTION__);
|
|
|
|
if ($path === NULL) {
|
|
// Get possible paths for the file.
|
|
$paths = _modernizr_get_paths();
|
|
|
|
// Scan directories for files
|
|
$path = _modernizr_scan_for_library($paths);
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
/**
|
|
* Helper function to scan for acceptably named libraries
|
|
*/
|
|
function _modernizr_get_paths() {
|
|
$paths = &drupal_static(__FUNCTION__);
|
|
|
|
if ($paths === NULL) {
|
|
$paths = array();
|
|
foreach (_modernizr_library_search_paths() as $search_path) {
|
|
$library_path = $search_path . '/modernizr';
|
|
if (file_exists($library_path)) {
|
|
$paths[] = $library_path;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $paths;
|
|
}
|
|
|
|
/**
|
|
* Get library search paths.
|
|
*
|
|
* Original logic was taken from Libraries 7.x-2.3 since it doesn't provide a
|
|
* way to look up its search paths.
|
|
*
|
|
* @see libraries_get_libraries()
|
|
*/
|
|
function _modernizr_library_search_paths() {
|
|
$searchdir = array();
|
|
$profile = drupal_get_path('profile', drupal_get_profile());
|
|
$config = conf_path();
|
|
|
|
// Similar to 'modules' and 'themes' directories in the root directory,
|
|
// certain distributions may want to place libraries into a 'libraries'
|
|
// directory in Drupal's root directory.
|
|
$searchdir[] = 'libraries';
|
|
|
|
// Always search sites/all/libraries.
|
|
$searchdir[] = 'sites/all/libraries';
|
|
|
|
// $profile should never be empty in a proper Drupal setup. Check to make sure
|
|
// it exists before adding path.
|
|
if ($profile) {
|
|
// Similar to 'modules' and 'themes' directories inside an installation
|
|
// profile, installation profiles may want to place libraries into a
|
|
// 'libraries' directory.
|
|
$searchdir[] = $profile . '/libraries';
|
|
}
|
|
|
|
// $config should never be empty in a proper Drupal setup. Check to make sure
|
|
// it exists before adding path.
|
|
if ($config) {
|
|
// Also search sites/<domain>/*.
|
|
$searchdir[] = $config . '/libraries';
|
|
}
|
|
|
|
return $searchdir;
|
|
}
|
|
|
|
/**
|
|
* Helper function to scan for acceptably named libraries
|
|
*/
|
|
function _modernizr_scan_for_library($paths) {
|
|
$path = '';
|
|
|
|
if (is_array($paths) && !empty($paths)) {
|
|
foreach ($paths as $p) {
|
|
if ($files = file_scan_directory($p, MODERNIZR_FILENAME_REGEX)) {
|
|
$path = reset($files)->uri;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
/**
|
|
* Helper function to fetch the active Modernizr library.
|
|
*/
|
|
function modernizr_get_filename() {
|
|
// Get the full path to the library,
|
|
$full_path = modernizr_get_path();
|
|
// Break it up into its directories and file
|
|
$file_parts = explode('/', $full_path);
|
|
// Isolate the filename
|
|
$file_name = $file_parts[count($file_parts)-1];
|
|
|
|
return $file_name;
|
|
}
|
|
|
|
|
|
/**
|
|
* Guesses the modernizr library version.
|
|
*
|
|
* This function is using a regex, which assumes that the format of the version
|
|
* string won't change. If it changes, feel free to submit a bug report.
|
|
*
|
|
* @return mixed The version number if exists, or a boolean FALSE if it can't be
|
|
* determined.
|
|
*/
|
|
function modernizr_get_version($reset = FALSE) {
|
|
$version = &drupal_static(__FUNCTION__);
|
|
|
|
if ($version === NULL || $reset == TRUE) {
|
|
if ($cached = cache_get('modernizr_version') && isset($cached->data) && $reset != TRUE) {
|
|
$version = $cached->data;
|
|
}
|
|
else {
|
|
$version = FALSE;
|
|
$modernizr_path = modernizr_get_path();
|
|
if (file_exists($modernizr_path)) {
|
|
$modernizr = file_get_contents($modernizr_path);
|
|
|
|
$matches = array();
|
|
preg_match(MODERNIZR_VERSION_REGEX, $modernizr, $matches);
|
|
|
|
if (isset($matches[0])) {
|
|
$version = $matches[0];
|
|
if ($version) {
|
|
cache_set('modernizr_version', $version);
|
|
}
|
|
}
|
|
|
|
unset($modernizr);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $version;
|
|
}
|
|
|
|
|
|
/**
|
|
* Implements MODULE_preprocess_html().
|
|
*/
|
|
function modernizr_preprocess_html(&$vars, $hook) {
|
|
// This will set up all of our tests for Modernizr.
|
|
modernizr_load_data();
|
|
}
|
|
|
|
/**
|
|
* A function to generate the load data from the current themes.
|
|
*
|
|
* Reads async-loaded CSS/JS from theme .info files. Stores info in variable.
|
|
* Prints yepnope() calls into drupal_add_js() as inline settings.
|
|
*
|
|
* @return array
|
|
*/
|
|
function modernizr_load_data() {
|
|
$load = &drupal_static(__FUNCTION__);
|
|
|
|
if (!isset($load)) {
|
|
// This is the first time this is called.
|
|
global $base_url, $base_theme_info, $theme_info;
|
|
$load = array();
|
|
$num_tests = 0;
|
|
|
|
// Make a list of base themes and the current theme.
|
|
$themes = $base_theme_info;
|
|
$themes[] = $theme_info;
|
|
|
|
foreach (array_keys($themes) as $key) {
|
|
$theme_path = dirname($themes[$key]->filename) . '/';
|
|
if (isset($themes[$key]->info['modernizr'])) {
|
|
// Loop through Modernizr calls and assemble Load variable.
|
|
foreach (array_keys($themes[$key]->info['modernizr']) as $test_key => $test) {
|
|
// If no tests are defined, simply add them as resources for loading them unconditionally.
|
|
if (is_numeric($test)) {
|
|
$load[] = array(_modernizr_sanitize_resource($themes[$key]->info['modernizr'][$test_key], $theme_path));
|
|
}
|
|
// Skip the ['tests'] variable because it is reserved for selecting
|
|
// specific tests that Modernizr must include.
|
|
elseif ($test != 'tests') {
|
|
// All other entries inside a theme's modernizr[] settings should be scanned
|
|
$load[$num_tests]['test'] = $test;
|
|
foreach (array_keys($themes[$key]->info['modernizr'][$test]) as $action) {
|
|
foreach ($themes[$key]->info['modernizr'][$test][$action] as $asset) {
|
|
|
|
// First figure out which property we're reading.
|
|
// callback/complete need different processing than yep/nope/both/load
|
|
$functions = array('callback', 'complete');
|
|
|
|
// Is this a function or a resource?
|
|
if (in_array($action, $functions)) {
|
|
// It's a function
|
|
$load[$num_tests][$action][] = _modernizr_sanitize_callback($asset);
|
|
}
|
|
else {
|
|
// It's a resource
|
|
$load[$num_tests][$action][] = _modernizr_sanitize_resource($asset, $theme_path);
|
|
}
|
|
}
|
|
}
|
|
|
|
$num_tests++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $load;
|
|
}
|
|
|
|
/**
|
|
* Helper function to render the yepnope() calls.
|
|
*/
|
|
function _modernizr_load_generate() {
|
|
$output = FALSE;
|
|
|
|
// Get yepnope() calls from the active theme.
|
|
$theme = modernizr_load_data();
|
|
|
|
// Collect data from modules that implement hook_modernizr_load().
|
|
$modules = modernizr_load_list();
|
|
|
|
// Combine the data from the .info file and the Drupal modules.
|
|
// Themes go first because they are more visual and in most cases
|
|
// it's probably best to load them first. Modules whose assets
|
|
// truly need to be loaded first have hook_modernizr_load_alter()
|
|
// at their disposal.
|
|
$test_objects = array_merge($theme, $modules);
|
|
|
|
// Build the yepnope() commands.
|
|
if (count($test_objects)) {
|
|
$num_tests = 0;
|
|
$items = array();
|
|
|
|
foreach ($test_objects as $load) {
|
|
// If test is defined, this entry will be an object.
|
|
if (isset($load['test'])) {
|
|
$item = '{' . "\n";
|
|
$item .= ' test: ' . $load['test'] . ',' . "\n";
|
|
|
|
// Print each action and its resources
|
|
$actions = array('yep', 'nope', 'both', 'load');
|
|
foreach ($actions as $action) {
|
|
if (isset($load[$action])) {
|
|
|
|
// Begin output for this action
|
|
$item .= ' ' . sprintf('%-4s', $action) . ': ';
|
|
|
|
// How many resources for this action?
|
|
if (count($load[$action]) == 1) {
|
|
// Single resource
|
|
$item .= "'" . $load[$action][0] . "',\n";
|
|
}
|
|
else {
|
|
// Multiple resources
|
|
$item .= '[';
|
|
foreach ($load[$action] as $resource) {
|
|
$item .= "'" . $resource . "',";
|
|
}
|
|
// Truncate last comma
|
|
$item = substr($item, 0, -1);
|
|
$item .= "],\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Output these two properties without quotes around the output
|
|
$callbacks = array('callback', 'complete');
|
|
foreach ($callbacks as $action) {
|
|
if (isset($load[$action])) {
|
|
|
|
// Begin output for this action
|
|
$item .= ' ' . sprintf('%-4s', $action) . ': ';
|
|
|
|
// How many callbacks for this action?
|
|
if (count($load[$action]) == 1) {
|
|
// Single resource
|
|
$item .= $load[$action][0] . ",\n";
|
|
}
|
|
else {
|
|
// Multiple resources
|
|
$item .= '[';
|
|
foreach ($load[$action] as $callback) {
|
|
$item .= $callback . ",";
|
|
}
|
|
// Truncate last comma
|
|
$item = substr($item, 0, -1);
|
|
$item .= "],\n";
|
|
}
|
|
}
|
|
}
|
|
// Truncate last comma and newline
|
|
$item = substr($item, 0, -2);
|
|
$item .= "\n}";
|
|
$num_tests++;
|
|
}
|
|
// No test is defined, add the resource(s) to the loader unconditionally.
|
|
else {
|
|
$resources = array();
|
|
foreach ($load as $resource) {
|
|
$resources[] = "'" . $resource . "'";
|
|
}
|
|
$item = implode(",\n", $resources);
|
|
$num_tests++;
|
|
}
|
|
|
|
$items[] = $item;
|
|
}
|
|
|
|
$output .= 'yepnope(';
|
|
// Issue commands as array if there is more than resource to load.
|
|
$output .= ($num_tests > 1) ? '[' : '';
|
|
// Add commands.
|
|
$output .= implode(",\n", $items);
|
|
// Finally, close the yepnope() function parenthesis.
|
|
$output .= ($num_tests > 1) ? ']' : '';
|
|
$output .= ');';
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Implements MODULE_preprocess_maintenance_page().
|
|
*/
|
|
function modernizr_preprocess_maintenance_page(&$vars, $hook) {
|
|
modernizr_preprocess_html($vars, $hook);
|
|
}
|
|
|
|
/**
|
|
* Helper function to sanitize yepnope() callbacks
|
|
*/
|
|
function _modernizr_sanitize_callback($callback) {
|
|
global $base_url;
|
|
$output = '';
|
|
$function_regex = '/^function(\s)*\(\)(\s)*\{(.*)\}$/';
|
|
|
|
// Save the people who don't wrap their code in anonymous functions.
|
|
// Yes, an extra semi-colon has been added for safety :)
|
|
$output = (preg_match($function_regex, $callback)) ? $callback : 'function(){' . $callback . ';}';
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Helper function to sanitize yepnope() assets
|
|
*/
|
|
function _modernizr_sanitize_resource($resource, $theme_path) {
|
|
global $base_path, $base_url;
|
|
$output = '';
|
|
|
|
// If a path starts with 'sites/' or 'profiles/' we assume they know exactly
|
|
// where they're going. Otherwise, they seem like relative URLs so append
|
|
// theme path.
|
|
$output = (strpos($resource, 'sites/') === 0 || strpos($resource, 'profiles/') === 0) ? $base_path . $resource : $base_url . '/' . $theme_path . $resource;
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Helper function for hook_modernizr_info().
|
|
* Returns a Modernizr argument's type.
|
|
*/
|
|
function _modernizr_get_type($arg) {
|
|
$data = _modernizr_get_arg_info($arg, 'type');
|
|
|
|
// Since community-created detects are by far the most likely unknown entry,
|
|
// we assume that a value not found in modernizr.args.inc is a community detect.
|
|
// Note: 'tests' does NOT need t() because it is a machine value.
|
|
return $data ? $data : 'tests';
|
|
}
|
|
|
|
/**
|
|
* Helper function for hook_modernizr_info().
|
|
* Returns a Modernizr argument's description.
|
|
*/
|
|
function _modernizr_get_desc($arg) {
|
|
$data = _modernizr_get_arg_info($arg, 'desc');
|
|
|
|
// If we can't find a description, just admit it.
|
|
return $data ? $data : '<em>' . t('No description available.') . '</em>';
|
|
}
|
|
|
|
|
|
/**
|
|
* A helper function to get the information stored in modernizr.args.inc.
|
|
*
|
|
* @param string $arg
|
|
* The test machine name.
|
|
* @param string $type (default: 'desc')
|
|
* The data wanted, currently just 'desc' or 'type'.
|
|
* @return
|
|
* The data in the field, or FALSE if it doesn't exist.
|
|
*/
|
|
function _modernizr_get_arg_info($arg, $type = 'desc') {
|
|
static $loaded = FALSE;
|
|
|
|
if (!$loaded) {
|
|
$loaded = module_load_include('inc', 'modernizr', 'modernizr.args');
|
|
}
|
|
|
|
$data = _modernizr_args_return($arg);
|
|
|
|
// This data doesnt exist.
|
|
return ($data && isset($data[$type])) ? $data[$type] : FALSE;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Helper function to pulls all tests from the current modernizr.js
|
|
*/
|
|
function _modernizr_current_build() {
|
|
$tests = &drupal_static(__FUNCTION__);
|
|
|
|
if (!isset($tests)) {
|
|
|
|
$path = modernizr_get_path();
|
|
$path_parts = explode('/', $path);
|
|
$file = ($path) ? file_get_contents($path) : NULL;
|
|
$filename = $path_parts[count($path_parts)-1];
|
|
$tests = array();
|
|
|
|
// $matches holds two items:
|
|
// - [0] the full URL
|
|
// - [1] a string containing the args captured in the parens vvvv
|
|
$build_url = preg_match('/https?:\/\/modernizr.com\/download\/[#?]-(.*) /', $file, $matches);
|
|
|
|
// Turn URL args into test entries for Drupal module
|
|
if (isset($matches[1])) {
|
|
$args_and_prefix = explode(':', $matches[1]);
|
|
$build_args = explode('-', $args_and_prefix[0]);
|
|
|
|
foreach ($build_args as $arg) {
|
|
$tests[] = $arg;
|
|
}
|
|
}
|
|
else {
|
|
// Modernizr must not be downloaded, return null.
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return $tests;
|
|
}
|
|
|
|
/**
|
|
* Asks other Drupal modules which Modernizr tests they need.
|
|
*
|
|
* @return array
|
|
*/
|
|
function modernizr_api_list() {
|
|
$tests = &drupal_static(__FUNCTION__);
|
|
|
|
if (!isset($tests)) {
|
|
// Grab all module implementations
|
|
// Note: this is a slightly augmented version of module_invoke_all(), so
|
|
// that we can know which module is providing which test.
|
|
$hook = 'modernizr_info';
|
|
|
|
foreach (module_implements($hook) as $module) {
|
|
$function = $module . '_' . $hook;
|
|
if (function_exists($function)) {
|
|
$result = call_user_func($function);
|
|
if (isset($result) && is_array($result)) {
|
|
$tests[$module] = $result;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Grabbing the information with an hook_alter is not enough for themes
|
|
// because they will not all be active, nor their code added into the session.
|
|
$themes = list_themes();
|
|
$active_themes = array();
|
|
foreach ($themes as $theme_name => $theme) {
|
|
if ($theme->status == 1) {
|
|
$active_themes[$theme_name] = $theme;
|
|
if (isset($theme->base_themes)) {
|
|
foreach ($theme->base_themes as $base_theme_name => $base_theme) {
|
|
$active_themes[$base_theme_name] = $themes[$base_theme_name];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// We now go into every active theme and pull from the .info file the tests.
|
|
foreach ($active_themes as $active_theme) {
|
|
$data = drupal_parse_info_file($active_theme->filename);
|
|
|
|
if (isset($data['modernizr']) && isset($data['modernizr']['tests'])) {
|
|
// There are modernizr tests within this theme.
|
|
$theme_name = $data['name'];
|
|
$tests[$theme_name] = $data['modernizr']['tests'];
|
|
}
|
|
}
|
|
|
|
// The last thing we do is send it to have its data cleaned and organized.
|
|
$tests = _modernizr_api_list_clean($tests);
|
|
}
|
|
|
|
return $tests;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Cleans up the array of tests to be unified.
|
|
*
|
|
* @param $raw_tests array
|
|
* An array of tests provided by hook_modernizr_info.
|
|
* @return array
|
|
*/
|
|
function _modernizr_api_list_clean($raw_tests) {
|
|
$clean_tests = array();
|
|
|
|
foreach ($raw_tests as $module => $tests) {
|
|
|
|
foreach ($tests as $name => $data) {
|
|
// First, we check and correct if the tests have been added using indexed
|
|
// arrays, fixing the name variable.
|
|
if (is_int($name) && !is_array($data)) {
|
|
// The test is stored as a simple array, therefore the data is the name.
|
|
$name = $data;
|
|
$data = array();
|
|
}
|
|
elseif (is_int($name) && is_array($data)) {
|
|
// Still stored as a indexed array, but the data is an array.
|
|
$name = $data['name'];
|
|
}
|
|
|
|
// Now, we add these tests to our array of cleaned up data.
|
|
if (isset($clean_tests[$name])) {
|
|
// We already have the test, we are just going to add our module name.
|
|
$clean_tests[$name]['source'][] = $module;
|
|
}
|
|
else {
|
|
// The test has not been marked, we are adding it to the array.
|
|
$clean_tests[$name] = $data;
|
|
$clean_tests[$name]['source'] = array($module);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Cleaning up the data to ensure all data we need is present.
|
|
foreach ($clean_tests as $name => $clean_test) {
|
|
$data = array(
|
|
'name' => $name,
|
|
'desc' => _modernizr_get_desc($name),
|
|
'docs' => '',
|
|
'camiuse' => '',
|
|
);
|
|
|
|
$clean_tests[$name] = array_merge($data, $clean_test);
|
|
}
|
|
|
|
return $clean_tests;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_modernizr_info().
|
|
*
|
|
* This function implements our own hook to ensure that any custom Modernizr
|
|
* builds downloaded from either the settings screen or drush commands contain
|
|
* the essential components needed to support the module's functionality.
|
|
*
|
|
* html5shiv w/ printshiv
|
|
* - Includes some utility JS that allows IE to recognize HTML5 elements.
|
|
*/
|
|
function modernizr_modernizr_info() {
|
|
$items = array();
|
|
|
|
// If a site admin has chosen to require printshiv, add it to dependencies.
|
|
if (variable_get('modernizr_cb_printshiv', FALSE)) {
|
|
$items[] = 'printshiv';
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Asks other Drupal modules for yepnope() commands.
|
|
*
|
|
* @return array
|
|
*/
|
|
function modernizr_load_list($reset = FALSE) {
|
|
$load = &drupal_static(__FUNCTION__);
|
|
if (!isset($load) || $reset) {
|
|
$load = module_invoke_all('modernizr_load');
|
|
drupal_alter('modernizr_load', $load);
|
|
}
|
|
|
|
return $load;
|
|
}
|
|
|
|
/**
|
|
* Private function to look for missing Modernizr tests.
|
|
*/
|
|
function _modernizr_info_missing_tests() {
|
|
$requested_tests = modernizr_api_list();
|
|
$current_build = _modernizr_current_build();
|
|
$missing_tests = array();
|
|
|
|
if (is_null($current_build)) {
|
|
// There is no installed version of Modernizr. Return all tests.
|
|
return $requested_tests;
|
|
}
|
|
|
|
foreach($requested_tests as $test => $test_info) {
|
|
if (!in_array($test, $current_build)) {
|
|
$missing_tests[$test] = $test_info;
|
|
}
|
|
}
|
|
|
|
return $missing_tests;
|
|
}
|