View source
<?php
define('MINIFYHTML_PLACEHOLDER', 'MINIFYHTML_' . md5(REQUEST_TIME));
function minifyhtml_permission() {
return array(
'administer minifyhtml' => array(
'title' => t('Administer Minify HTML Module'),
'description' => t('Perform administration tasks for Minify HTML module.'),
),
);
}
function minifyhtml_menu() {
$items['admin/config/development/performance/default'] = array(
'title' => 'Performance',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/config/development/performance/minifyhtml'] = array(
'access arguments' => array(
'administer minifyhtml',
),
'file' => 'minifyhtml.admin.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'minifyhtml_settings_form',
),
'title' => 'Minify Source HTML settings',
'description' => 'Settings that control how the HTML is minified',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
return $items;
}
function minifyhtml_help($path, $arg) {
switch ($path) {
case 'admin/help#minifyhtml':
$filepath = dirname(__FILE__) . '/README.md';
if (file_exists($filepath)) {
$readme = file_get_contents($filepath);
}
else {
$filepath = dirname(__FILE__) . '/README.txt';
if (file_exists($filepath)) {
$readme = file_get_contents($filepath);
}
}
if (!isset($readme)) {
return NULL;
}
if (module_exists('markdown')) {
$filters = module_invoke('markdown', 'filter_info');
$info = $filters['filter_markdown'];
if (function_exists($info['process callback'])) {
$output = $info['process callback']($readme, NULL);
}
else {
$output = '<pre>' . $readme . '</pre>';
}
}
else {
$output = '<pre>' . $readme . '</pre>';
}
return $output;
}
}
function minifyhtml_form_system_performance_settings_alter(&$form, &$form_state, $form_id) {
if (user_access('administer minifyhtml')) {
$form['bandwidth_optimization']['minifyhtml_minify'] = array(
'#type' => 'checkbox',
'#title' => t('Minified Source HTML.'),
'#description' => t('Toggle minified HTML on or off.'),
'#default_value' => variable_get('minifyhtml_minify', 0),
);
}
}
function minifyhtml_exit() {
if (variable_get('minifyhtml_minify', 0)) {
$current_path = function_exists('current_path') ? current_path() : $_GET['q'];
if (stripos(drupal_get_http_header('content-type'), 'text/html') !== FALSE && !is_file($current_path) && ob_get_length()) {
$page = ob_get_contents();
$decoded = FALSE;
if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
$decoded = @gzinflate(substr(substr($page, 10), 0, -8));
if ($decoded) {
$page = $decoded;
}
}
minifyhtml_minify($page);
if (variable_get('page_compression', TRUE) && extension_loaded('zlib') && $decoded) {
$page = gzencode($page, 9, FORCE_GZIP);
}
if (strpos($page, '%' . MINIFYHTML_PLACEHOLDER)) {
$page = ob_get_contents();
watchdog('minifyhtml', 'Minifyhtml failed on %path', array(
'%path' => $current_path,
), WATCHDOG_WARNING, $current_path);
}
ob_clean();
print $page;
}
}
}
function minifyhtml_module_implements_alter(&$implementations, $hook) {
if ($hook == 'exit' && isset($implementations['minifyhtml'])) {
$group = $implementations['minifyhtml'];
unset($implementations['minifyhtml']);
$implementations['minifyhtml'] = $group;
}
}
function minifyhtml_minify(&$page) {
$callbacks = array(
'minifyhtml_placeholder_callback_textarea' => '/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i',
'minifyhtml_placeholder_callback_pre' => '/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i',
'minifyhtml_placeholder_callback_iframe' => '/\\s*<iframe(\\b[^>]*?>[\\s\\S]*?<\\/iframe>)\\s*/i',
'minifyhtml_placeholder_callback_script' => '/\\s*<script(\\b[^>]*?>[\\s\\S]*?<\\/script>)\\s*/i',
'minifyhtml_placeholder_callback_style' => '/\\s*<style(\\b[^>]*?>[\\s\\S]*?<\\/style>)\\s*/i',
);
if (variable_get('minifyhtml_strip_comments', TRUE)) {
$callbacks['minifyhtml_remove_html_comment'] = '/<!--([\\s\\S]*?)-->/';
}
foreach ($callbacks as $callback => $pattern) {
$content = minifyhtml_minify_callback($pattern, $callback, $page);
if (!is_null($content)) {
$page = $content;
}
}
minifyhtml_minify_html($page);
global $_minifyhtml_placeholders;
if (!empty($_minifyhtml_placeholders)) {
$page = str_replace(array_keys($_minifyhtml_placeholders), array_values($_minifyhtml_placeholders), $page);
}
}
function minifyhtml_minify_callback($pattern, $callback, $content) {
$content = preg_replace_callback($pattern, $callback, $content);
$error = preg_last_error();
if ($error > PREG_NO_ERROR) {
watchdog('minifyhtml', 'Preg error. The error code is %error. You can view what this error code is by viewing http://php.net/manual/en/function.preg-last-error.php', array(
'%error' => $error,
));
}
return $content;
}
function minifyhtml_placeholder_callback_textarea(array $matches) {
return minifyhtml_placeholder_replace(trim($matches[0]));
}
function minifyhtml_placeholder_callback_pre(array $matches) {
return minifyhtml_placeholder_replace(trim($matches[0]));
}
function minifyhtml_placeholder_callback_iframe(array $matches) {
$iframe = preg_replace('/^\\s+|\\s+$/m', '', $matches[0]);
return minifyhtml_placeholder_replace(trim($iframe));
}
function minifyhtml_placeholder_callback_script(array $matches) {
$search = array();
$replace = array();
if (variable_get('minifyhtml_strip_comments', TRUE)) {
$search[] = '!/\\*.*?\\*/!s';
$replace[] = '';
}
$search[] = '/^\\s+|\\s+$/m';
$replace[] = "\n";
$search[] = '/\\n(\\s*\\n)+/';
$replace[] = "\n";
$script = preg_replace($search, $replace, $matches[0]);
return minifyhtml_placeholder_replace(trim($script));
}
function minifyhtml_placeholder_callback_style(array $matches) {
$search = array();
$replace = array();
if (variable_get('minifyhtml_strip_comments', TRUE)) {
$search[] = '!/\\*.*?\\*/!s';
$replace[] = '';
}
$search[] = '/^\\s+|\\s+$/m';
$replace[] = '';
$style = preg_replace($search, $replace, $matches[0]);
return minifyhtml_placeholder_replace(trim($style));
}
function minifyhtml_placeholder_replace($content) {
global $_minifyhtml_placeholders;
if (!isset($_minifyhtml_placeholders)) {
$_minifyhtml_placeholders = array();
}
$placeholder = '%' . MINIFYHTML_PLACEHOLDER . count($_minifyhtml_placeholders) . '%';
$_minifyhtml_placeholders[$placeholder] = $content;
return $placeholder;
}
function minifyhtml_remove_html_comment(array $matches) {
return 0 === strpos($matches[1], '[') || FALSE !== strpos($matches[1], '<![') ? $matches[0] : '';
}
function minifyhtml_minify_html(&$page) {
$search = array();
$replace = array();
$search[] = '/\\>[^\\S ]+/s';
$replace[] = '>';
$search[] = '/[^\\S ]+\\</s';
$replace[] = '<';
$search[] = '/(\\s)+/s';
$replace[] = '\\1';
$search[] = '/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body' . '|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' . '|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta' . '|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)' . '|ul)\\b[^>]*>)/i';
$replace[] = '$1';
$search[] = '/^\\s+|\\s+$/m';
$replace[] = '';
$page = preg_replace($search, $replace, $page);
}