Skip to content

Commit 4c28031

Browse files
author
Nick Goris
committed
initial commit
0 parents  commit 4c28031

File tree

10 files changed

+260
-0
lines changed

10 files changed

+260
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
composer.lock
3+
vendor

composer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "nckg/laravel-minify-html",
3+
"description": "Minify your responses in Laravel 5.x",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "Nick Goris",
8+
"email": "nickgoris@gmail.com"
9+
}
10+
],
11+
"require": {
12+
"php" : "^7.0"
13+
},
14+
"require-dev": {
15+
"illuminate/support": "~5.1.0|~5.2.0|~5.3.0",
16+
"phpunit/phpunit": "5.*",
17+
"orchestra/testbench": "^3.2",
18+
"mockery/mockery": "^0.9.4"
19+
},
20+
"autoload": {
21+
"psr-4": {
22+
"Nckg\\Minify\\": "src/Nckg/Minify/"
23+
}
24+
},
25+
"autoload-dev": {
26+
"psr-4": {
27+
"Nckg\\Minify\\Test\\": "tests"
28+
}
29+
},
30+
"scripts": {
31+
"test": "vendor/bin/phpunit"
32+
}
33+
}

phpunit.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
colors="true"
5+
convertErrorsToExceptions="true"
6+
convertNoticesToExceptions="true"
7+
convertWarningsToExceptions="true"
8+
processIsolation="false"
9+
stopOnFailure="false">
10+
<testsuites>
11+
<testsuite name="Application Test Suite">
12+
<directory suffix="Test.php">./tests</directory>
13+
</testsuite>
14+
</testsuites>
15+
</phpunit>

readme.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# HTML minifier
2+
3+
## Introduction
4+
5+
Very, very simple html minifier with Laravel 5.x support.
6+
7+
## Code Samples
8+
9+
```php
10+
$input = "<a href="/foo" class="bar moo ">Hello World</a>";
11+
$minifier = new Minifier();
12+
$output = $minifier->html($string); // <a href="/foo" class="bar moo ">Hello World</a>
13+
```
14+
15+
## Installation
16+
17+
You can install the package via composer:
18+
19+
``` bash
20+
composer require nckg/laravel-html-minifier
21+
```
22+
If you are using Laravel you can add the middleware to your middleware providers
23+
24+
```php
25+
// app/Http/Kernel.php
26+
/**
27+
* The application's global HTTP middleware stack.
28+
*
29+
* @var array
30+
*/
31+
protected $middleware = [
32+
...
33+
\Nckg\Minify\Middleware\MinifyResponse::class,
34+
];
35+
```
36+
37+
## Testing
38+
39+
``` bash
40+
composer test
41+
```
42+
43+
## License
44+
45+
The MIT License (MIT).
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
4+
namespace Nckg\Minify\Middleware;
5+
6+
use Closure;
7+
use Nckg\Minify\Minifier;
8+
9+
class MinifyResponse
10+
{
11+
/**
12+
* Handle an incoming request.
13+
*
14+
* @param \Illuminate\Http\Request $request
15+
* @param \Closure $next
16+
* @return mixed
17+
*/
18+
public function handle($request, Closure $next)
19+
{
20+
/** @var Response $response */
21+
$response = $next($request);
22+
23+
if (app()->isLocal()) {
24+
$response->setContent((new Minifier)->html($response->getContent()));
25+
}
26+
27+
return $response;
28+
}
29+
}

src/Nckg/Minify/Minifier.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Nckg\Minify;
4+
5+
class Minifier
6+
{
7+
public $htmlFilters = [
8+
//Remove HTML comments except IE conditions
9+
'/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s' => '',
10+
// Remove comments in the form /* */
11+
'/(?<!\S)\/\/\s*[^\r\n]*/' => '',
12+
// Shorten multiple white spaces
13+
'/\s{2,}/' => ' ',
14+
// Collapse new lines
15+
'/(\r?\n)/' => '',
16+
];
17+
18+
/**
19+
* @param string $html
20+
* @return string
21+
*/
22+
public function html(string $html): string
23+
{
24+
$output = preg_replace(array_keys($this->htmlFilters), array_values($this->htmlFilters), $html);
25+
26+
return $output;
27+
}
28+
}

tests/MinifierTest.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
4+
namespace Nckg\Minify\Test;
5+
6+
7+
use Nckg\Minify\Minifier;
8+
9+
class MinifierTest extends TestCase
10+
{
11+
/** @test */
12+
public function it_shortens_multiple_white_spaces()
13+
{
14+
$string = '<a href="/foo" class="bar moo ">Hello World</a>';
15+
$expected = '<a href="/foo" class="bar moo ">Hello World</a>';
16+
$this->assertMinifiedString($expected, $string);
17+
}
18+
19+
/** @test */
20+
public function it_removes_comments_except_ie_conditions()
21+
{
22+
$string = [
23+
'<!-- Hello World -->',
24+
'<!--[if lt IE 9]>',
25+
'Hello IE',
26+
'<![endif]-->',
27+
];
28+
$expected = '<!--[if lt IE 9]>Hello IE<![endif]-->';
29+
$this->assertMinifiedString($expected, implode('', $string));
30+
}
31+
32+
/** @test */
33+
public function it_collapses_new_lines()
34+
{
35+
$string = 'Hello
36+
World';
37+
$expected = 'Hello World';
38+
$this->assertMinifiedString($expected, $string);
39+
}
40+
41+
/** @test */
42+
public function it_removes_comments()
43+
{
44+
$string = '// Hello World
45+
Batman';
46+
$expected = ' Batman';
47+
$this->assertMinifiedString($expected, $string);
48+
}
49+
50+
/** @test */
51+
public function it_minifies_an_entire_page_correct()
52+
{
53+
$string = file_get_contents(__DIR__ . '/_data/page.html');
54+
$expected = file_get_contents(__DIR__ . '/_data/page-minified.html');
55+
$this->assertMinifiedString($expected, $string);
56+
}
57+
58+
/**
59+
* @param $expected
60+
* @param $string
61+
*/
62+
protected function assertMinifiedString($expected, $string)
63+
{
64+
$minifier = new Minifier();
65+
$this->assertSame($expected, $minifier->html($string));
66+
}
67+
}

tests/TestCase.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
4+
namespace Nckg\Minify\Test;
5+
6+
use Orchestra\Testbench\TestCase as Orchestra;
7+
8+
abstract class TestCase extends Orchestra
9+
{
10+
11+
}

tests/_data/page-minified.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Bootstrap 101 Template</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--></head><body><h1>Hello, world!</h1> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="js/bootstrap.min.js"></script></body></html>

tests/_data/page.html

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
8+
<title>Bootstrap 101 Template</title>
9+
10+
<!-- Bootstrap -->
11+
<link href="css/bootstrap.min.css" rel="stylesheet">
12+
13+
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
14+
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
15+
<!--[if lt IE 9]>
16+
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
17+
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
18+
<![endif]-->
19+
</head>
20+
<body>
21+
<h1>Hello, world!</h1>
22+
23+
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
24+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
25+
<!-- Include all compiled plugins (below), or include individual files as needed -->
26+
<script src="js/bootstrap.min.js"></script>
27+
</body>
28+
</html>

0 commit comments

Comments
 (0)