'JS Compression', 'description' => 'Adjust JS Compression settings.', 'page callback' => 'drupal_get_form', 'page arguments' => array('advagg_js_compress_admin_settings_form'), 'type' => MENU_LOCAL_TASK, 'access arguments' => array('administer site configuration'), 'file path' => $file_path, 'file' => 'advagg_js_compress.admin.inc', 'weight' => 10, ); return $items; } /** * Implements hook_module_implements_alter(). */ function advagg_js_compress_module_implements_alter(&$implementations, $hook) { // Move advagg_js_compress below advagg. if ($hook === 'advagg_save_aggregate_alter' && array_key_exists('advagg_js_compress', $implementations)) { $advagg_key = ''; $advagg_js_compress_key = ''; $counter = 0; foreach ($implementations as $key => $value) { if ($key == 'advagg') { $advagg_key = $counter; } if ($key == 'advagg_js_compress') { $advagg_js_compress_key = $counter; } $counter++; } if ($advagg_js_compress_key > $advagg_key) { // Move advagg_js_compress to the top. $item = array('advagg_js_compress' => $implementations['advagg_js_compress']); unset($implementations['advagg_js_compress']); $implementations = array_merge($item, $implementations); // Move advagg to the very top. $item = array('advagg' => $implementations['advagg']); unset($implementations['advagg']); $implementations = array_merge($item, $implementations); } } } /** * @} End of "addtogroup hooks". */ /** * @addtogroup advagg_hooks * @{ */ /** * Implements hook_advagg_current_hooks_hash_array_alter(). */ function advagg_js_compress_advagg_current_hooks_hash_array_alter(&$aggregate_settings) { $aggregate_settings['variables']['advagg_js_compressor'] = variable_get('advagg_js_compressor', ADVAGG_JS_COMPRESSOR); $aggregate_settings['variables']['advagg_js_compress_packer'] = variable_get('advagg_js_compress_packer', ADVAGG_JS_COMPRESS_PACKER); $aggregate_settings['variables']['advagg_js_compress_max_ratio'] = variable_get('advagg_js_compress_max_ratio', ADVAGG_JS_COMPRESS_MAX_RATIO); $aggregate_settings['variables']['advagg_js_compressor_file_settings'] = variable_get('advagg_js_compressor_file_settings', array()); $aggregate_settings['variables']['advagg_js_compress_add_license'] = variable_get('advagg_js_compress_add_license', ADVAGG_JS_COMPRESS_ADD_LICENSE); } /** * Implements hook_advagg_modify_js_pre_render_alter(). * * Used compress inline js. */ function advagg_js_compress_advagg_modify_js_pre_render_alter(&$children, &$elements) { // Get variables. $aggregate_settings['variables']['advagg_js_compressor'] = variable_get('advagg_js_compress_inline', ADVAGG_JS_COMPRESS_INLINE); $aggregate_settings['variables']['advagg_js_compress_max_ratio'] = variable_get('advagg_js_compress_max_ratio', ADVAGG_JS_COMPRESS_MAX_RATIO); // Do nothing if the compressor is disabled. if (empty($aggregate_settings['variables']['advagg_js_compressor'])) { return; } // Do nothing if the page is not cacheable and inline compress if not // cacheable is not checked. if (!variable_get('advagg_js_compress_inline_if_not_cacheable', ADVAGG_JS_COMPRESS_INLINE_IF_NOT_CACHEABLE) && !drupal_page_is_cacheable()) { return; } // Compress any inline JS. module_load_include('inc', 'advagg_js_compress', 'advagg_js_compress.advagg'); foreach ($children as &$values) { // Compress onload. if (!empty($values['#attributes']['onload'])) { $contents = $values['#attributes']['onload']; $filename = drupal_hash_base64($contents); advagg_js_compress_prep($contents, $filename, $aggregate_settings, FALSE); $values['#attributes']['onload'] = $contents; } // Compress onerror. if (!empty($values['#attributes']['onerror'])) { $contents = $values['#attributes']['onerror']; $filename = drupal_hash_base64($contents); advagg_js_compress_prep($contents, $filename, $aggregate_settings, FALSE); $values['#attributes']['onerror'] = $contents; } // Compress inline. if (!empty($values['#value'])) { $contents = $values['#value']; $filename = drupal_hash_base64($contents); advagg_js_compress_prep($contents, $filename, $aggregate_settings, FALSE); $values['#value'] = $contents; } } unset($values); } /** * @} End of "addtogroup advagg_hooks". */ /** * @addtogroup 3rd_party_hooks * @{ */ /** * Implements hook_libraries_info(). */ function advagg_js_compress_libraries_info() { $libraries['JShrink'] = array( 'name' => 'JShrink', 'vendor url' => 'https://github.com/tedious/JShrink', 'download url' => 'https://github.com/tedious/JShrink/archive/master.zip', 'local version' => '1.2.0', 'files' => array( 'php' => array( 'src/JShrink/Minifier.php', ), ), ); $libraries['jsqueeze'] = array( 'name' => 'JSqueeze', 'vendor url' => 'https://github.com/tchwork/jsqueeze', 'download url' => 'https://github.com/tchwork/jsqueeze/archive/master.zip', 'local version' => '2.0.5', 'files' => array( 'php' => array( 'src/JSqueeze.php', ), ), ); $libraries['jsminplus'] = array( 'name' => 'JSMinPlus', 'local version' => '1.4', 'files' => array( 'php' => array( 'jsminplus.php', ), ), ); $libraries['jspacker'] = array( 'name' => 'JSPacker', 'local version' => '1.1', 'files' => array( 'php' => array( 'jspacker.php', ), ), ); return $libraries; } /** * @} End of "addtogroup 3rd_party_hooks". */ /** * Test a file, making sure it is compressible. * * @param string $filename * Path and filename of the js file to test. * @param array $compressors * List of compressors to test. * @param string $cache_id * The cache ID for this file. * * @return array * Array showing the results of the compression tests. */ function advagg_js_compress_test_file($filename, array $compressors, $cache_id) { $contents = (string) @advagg_file_get_contents($filename); // Get the JS string length before the compression operation. $contents_before = $contents; $before = strlen($contents); module_load_include('inc', 'advagg_js_compress', 'advagg_js_compress.advagg'); $results = array(); foreach ($compressors as $key => $name) { $contents = $contents_before; $aggregate_settings['variables']['advagg_js_compressor'] = $key; $aggregate_settings['variables']['advagg_js_compress_max_ratio'] = variable_get('advagg_js_compress_max_ratio', ADVAGG_JS_COMPRESS_MAX_RATIO); // Compress it. advagg_js_compress_prep($contents, $filename, $aggregate_settings, FALSE, FALSE, FALSE, TRUE); $after = strlen($contents); $ratio = 0; if ($before != 0) { $ratio = ($before - $after) / $before; } // Set to "-2" if compression ratio sucks (it's already compressed). if ($ratio < variable_get('advagg_js_compress_ratio', ADVAGG_JS_COMPRESS_RATIO)) { $results[$key] = array( 'code' => -2, 'ratio' => round($ratio, 5), 'name' => $name, ); } // Set to "-3" if the compression ratio is way too good (bad js output). elseif ($ratio > variable_get('advagg_js_compress_max_ratio', ADVAGG_JS_COMPRESS_MAX_RATIO)) { $results[$key] = array( 'code' => -3, 'ratio' => round($ratio, 5), 'name' => $name, ); } // Set to "1". Everything worked, mark this file as compressible. else { $results[$key] = array( 'code' => 1, 'ratio' => round($ratio, 5), 'name' => $name, ); } } $cache = cache_get($cache_id, 'cache_advagg_info'); // Merge in old cached data. if (!empty($cache->data)) { // Do not merge in -1 code. foreach ($cache->data as $key => $value) { if ($value['code'] == -1) { unset($cache->data[$key]); } } $results += $cache->data; } // CACHE_PERMANENT isn't good here. Use 2 weeks from now + 0-45 days. // The random 0 to 45 day addition is to prevent a cache stampeed. cache_set($cache_id, $results, 'cache_advagg_info', round(REQUEST_TIME + 1209600 + mt_rand(0, 3888000), -3)); return $results; } /** * Generate the js compress configuration. * * @return array * Array($options, $description, $compressors, $functions). */ function advagg_js_compress_configuration() { // Set the defaults. $description = ''; $options = array( 0 => t('Disabled'), 1 => t('JSMin+ ~1300ms'), // 2 => t('Packer ~500ms'), // 3 is JSMin c extension. // 4 is JShrink. // 5 is JSqueeze. ); if (function_exists('jsmin')) { $options[3] = t('JSMin ~2ms'); $description .= t('JSMin is the very fast C complied version. Recommend using it.'); } else { if (!defined('PHP_VERSION_ID') || constant('PHP_VERSION_ID') < 50310) { $link = 'http://www.ypass.net/software/php_jsmin/'; } else { $link = 'https://github.com/sqmk/pecl-jsmin/'; } $description .= t('You can use the much faster C version of JSMin (~2ms) by installing the JSMin PHP Extension on this server.', array('@php_jsmin' => $link)); } // Add in JShrink and JSqueeze if using php 5.3 or higher. if (defined('PHP_VERSION_ID') && constant('PHP_VERSION_ID') >= 50300) { $options += array( 4 => t('JShrink ~1000ms'), 5 => t('JSqueeze ~600ms'), ); } $compressors = array( 1 => 'jsminplus', 2 => 'packer', ); if (function_exists('jsmin')) { $compressors[3] = 'jsmin'; } if (defined('PHP_VERSION_ID') && constant('PHP_VERSION_ID') >= 50300) { $compressors += array( 4 => 'jshrink', 5 => 'jsqueeze', ); } $functions = array( 1 => 'advagg_js_compress_jsminplus', 2 => 'advagg_js_compress_jspacker', 3 => 'advagg_js_compress_jsmin', 4 => 'advagg_js_compress_jshrink', 5 => 'advagg_js_compress_jsqueeze', ); // Allow for other modules to alter this list. $options_desc = array($options, $description); // Call hook_advagg_js_compress_configuration_alter(). drupal_alter('advagg_js_compress_configuration', $options_desc, $compressors, $functions); list($options, $description) = $options_desc; return array($options, $description, $compressors, $functions); }