Added JS+CSS+HTML compiler
This commit is contained in:
parent
e6ebac8277
commit
51c0fa2636
4 changed files with 140 additions and 1 deletions
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"mnapoli/php-di": "~4.0"
|
"mnapoli/php-di": "~4.0",
|
||||||
|
"linkorb/jsmin-php": "1.*",
|
||||||
|
"natxet/CssMin": "3.*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
public_html/.gitignore
vendored
Normal file
1
public_html/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
index-compiled.html
|
|
@ -1,3 +1,6 @@
|
||||||
|
DirectoryIndex index-compiled.html
|
||||||
|
DirectoryIndex index.html
|
||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
RewriteRule ^/?api/(.*) api-dispatch.php?q=$1 [L]
|
RewriteRule ^/?api/(.*) api-dispatch.php?q=$1 [L]
|
||||||
|
|
||||||
|
|
133
public_html/compile.php
Normal file
133
public_html/compile.php
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<?php
|
||||||
|
define('DS', DIRECTORY_SEPARATOR);
|
||||||
|
require_once __DIR__ . DS . '..' . DS . 'vendor' . DS . 'autoload.php';
|
||||||
|
|
||||||
|
class Compressor
|
||||||
|
{
|
||||||
|
public static function css($content)
|
||||||
|
{
|
||||||
|
return CssMin::minify($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function js($content)
|
||||||
|
{
|
||||||
|
return JSMin::minify($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function html($html)
|
||||||
|
{
|
||||||
|
$illegalTags = ['script', 'link', 'textarea', 'pre'];
|
||||||
|
$chunks = preg_split( '/(<(' . join('|', $illegalTags) . ')(?:\/|.*?\/\2)>)/ms', $html, -1,
|
||||||
|
PREG_SPLIT_DELIM_CAPTURE);
|
||||||
|
$buffer = '';
|
||||||
|
foreach ($chunks as $chunk)
|
||||||
|
{
|
||||||
|
if (in_array($chunk, $illegalTags))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (preg_match('/^<(' . join('|', $illegalTags) . ')/', $chunk))
|
||||||
|
{
|
||||||
|
$buffer .= $chunk;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove new lines & tabs
|
||||||
|
$chunk = preg_replace( '/[\\n\\r\\t]+/', ' ', $chunk);
|
||||||
|
# remove extra whitespace
|
||||||
|
$chunk = preg_replace( '/\\s{2,}/', ' ', $chunk);
|
||||||
|
# remove inter-tag whitespace
|
||||||
|
$chunk = preg_replace( '/>\\s</', '><', $chunk);
|
||||||
|
# remove CSS & JS comments
|
||||||
|
$chunk = preg_replace( '/\\/\\*.*?\\*\\//i', '', $chunk);
|
||||||
|
$buffer .= $chunk;
|
||||||
|
}
|
||||||
|
return $buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IndexBuilder
|
||||||
|
{
|
||||||
|
public static function build()
|
||||||
|
{
|
||||||
|
$html = file_get_contents(__DIR__ . DS . 'index.html');
|
||||||
|
self::includeTemplates($html);
|
||||||
|
self::minifyScripts($html);
|
||||||
|
self::minifyStylesheets($html);
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function injectBody(&$html, $text)
|
||||||
|
{
|
||||||
|
$html = str_replace('</body>', $text . '</body>', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function injectHead(&$html, $text)
|
||||||
|
{
|
||||||
|
$html = str_replace('</head>', $text . '</head>', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function minifyScripts(&$html)
|
||||||
|
{
|
||||||
|
$scriptsToMinify = [];
|
||||||
|
|
||||||
|
$html = preg_replace_callback(
|
||||||
|
'/<script[^>]*src="([^"]+)"[^>]*><\/script>/',
|
||||||
|
function($matches) use (&$scriptsToMinify)
|
||||||
|
{
|
||||||
|
$scriptPath = $matches[1];
|
||||||
|
if (substr($scriptPath, 0, 2) == '//' or strpos($scriptPath, 'http') !== false)
|
||||||
|
return $matches[0];
|
||||||
|
$scriptsToMinify []= __DIR__ . DS . $scriptPath;
|
||||||
|
return '';
|
||||||
|
}, $html);
|
||||||
|
|
||||||
|
$out = '<script type="text/javascript">';
|
||||||
|
foreach ($scriptsToMinify as $scriptPath)
|
||||||
|
$out .= Compressor::js(file_get_contents($scriptPath));
|
||||||
|
$out .= '</script>';
|
||||||
|
self::injectBody($html, $out);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function minifyStylesheets(&$html)
|
||||||
|
{
|
||||||
|
$html = preg_replace_callback(
|
||||||
|
'/<link[^>]*href="([^"]+)"[^>]*>/',
|
||||||
|
function($matches) use (&$stylesToMinify)
|
||||||
|
{
|
||||||
|
$stylePath = $matches[1];
|
||||||
|
if (substr($stylePath, 0, 2) == '//' or strpos($stylePath, 'http') !== false)
|
||||||
|
return $matches[0];
|
||||||
|
if (strpos($matches[0], 'css') === false)
|
||||||
|
return $matches[0];
|
||||||
|
$stylesToMinify []= __DIR__ . DS . $stylePath;
|
||||||
|
return '';
|
||||||
|
}, $html);
|
||||||
|
|
||||||
|
$out = '<style type="text/css">';
|
||||||
|
foreach ($stylesToMinify as $stylePath)
|
||||||
|
$out .= Compressor::css(file_get_contents($stylePath));
|
||||||
|
$out .= '</style>';
|
||||||
|
self::injectHead($html, $out);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function includeTemplates(&$html)
|
||||||
|
{
|
||||||
|
$templatesToInclude = [];
|
||||||
|
foreach (glob(__DIR__ . DS . 'templates' . DS . '*.tpl') as $templatePath)
|
||||||
|
$templatesToInclude []= $templatePath;
|
||||||
|
|
||||||
|
$out = '';
|
||||||
|
foreach ($templatesToInclude as $templatePath)
|
||||||
|
{
|
||||||
|
$out .= '<script type="text/template" id="' . str_replace('.tpl', '-template', basename($templatePath)) . '">';
|
||||||
|
$out .= Compressor::html(file_get_contents($templatePath));
|
||||||
|
$out .= '</script>';
|
||||||
|
}
|
||||||
|
self::injectBody($html, $out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$compiledPath = __DIR__ . DS . 'index-compiled.html';
|
||||||
|
$html = IndexBuilder::build();
|
||||||
|
$html = Compressor::html($html);
|
||||||
|
file_put_contents($compiledPath, $html);
|
Loading…
Reference in a new issue