1
0
mirror of https://github.com/mrclay/minify.git synced 2025-09-12 23:12:03 +02:00

113 Commits
3.0.1 ... 4.0.0

Author SHA1 Message Date
Steve Clay
45463786f8 Merge pull request #709 from mrclay/docker
Updates
2024-01-04 01:08:48 -05:00
Steve Clay
00e5e20abe Changelog update 2024-01-04 01:08:31 -05:00
Steve Clay
9e182a6255 Use scssphp/scssphp 2024-01-04 01:00:44 -05:00
Steve Clay
bc1ffdc5fc Test fixes 2024-01-04 01:00:44 -05:00
Steve Clay
aa3721156e Require PHP 8.1. Fixes #708 2024-01-04 01:00:35 -05:00
Steve Clay
3047f5c48f Add docker-compose setup 2024-01-03 21:41:47 -05:00
Elan Ruusamäe
104ccd2bfe Update .semver file 2023-05-05 15:03:33 +03:00
Elan Ruusamäe
dc02cdfba7 Fill changelog for 3.0.14 2023-05-05 15:03:06 +03:00
Elan Ruusamäe
23f055d3f5 Merge pull request #705 from rossbearman/monolog-v3 2023-04-13 23:03:05 +03:00
Ross Bearman
4970127e91 Support monolog v3 2023-04-12 16:11:35 +01:00
Elan Ruusamäe
39c37bdd8c Merge pull request #700 from turbulent/feat/allow-invalidation 2022-12-15 12:42:05 +02:00
Adrien Poupa
4a9d0595e3 feat: Allow invalidation from manual invocation 2022-12-14 15:21:52 -05:00
Elan Ruusamäe
ca8fdc6fdd Merge pull request #699 from tamakianimalife/php8.2
Add property declaration
2022-12-14 20:52:27 +02:00
tamakianimalife
8c69866874 Add property declaration 2022-12-14 17:30:53 +09:00
Elan Ruusamäe
ae5b9f0bfb Add changelog for #688 2022-10-03 00:12:43 +03:00
Elan Ruusamäe
e74adc4f6b Add changelog for 3.0.13 release 2022-10-03 00:11:04 +03:00
Elan Ruusamäe
5dee6538be Merge pull request #697 from croensch/apcu 2022-10-03 00:09:24 +03:00
Christoph Rönsch
455084b284 Minify_Cache_APCu replaces APC 2022-10-01 22:23:52 +02:00
Elan Ruusamäe
5112bb50f4 Merge pull request #688 from mrclay/lesserphp 2022-05-14 14:15:55 +03:00
Elan Ruusamäe
1962d3614c Fill changelog for 3.0.12 2022-05-14 14:11:27 +03:00
Elan Ruusamäe
2226a6add1 Merge pull request #696 from 0m3r/patch-1
Fix null argument to preg_split
2022-05-14 14:11:22 +03:00
Oleksandr Krasko
8b91de51c3 Fix null argument to preg_split
Deprecated Functionality: preg_split(): Passing null to parameter #3 ($limit) of type int is deprecated

https://www.php.net/manual/en/function.preg-split.php#refsect1-function.preg-split-parameters

limit:

If specified, then only substrings up to limit are returned with the
rest of the string being placed in the last substring. A limit of -1 or
0 means "no limit".

Refs:
- https://www.drupal.org/project/geshifilter/issues/3262325

Signed-off-by: Elan Ruusamäe <glen@pld-linux.org>
2022-05-14 14:01:14 +03:00
Elan Ruusamäe
1c000f9d05 Merge pull request #692 from venkatraj/dev-master 2022-01-04 10:14:13 +02:00
N. Venkat Raj
cbda49556e updated jquery version to avoid xss attacks 2022-01-04 13:36:07 +05:30
Elan Ruusamäe
b314554a0f Remove php 7.4 block for LessSourceTest 2021-03-11 17:54:46 +02:00
Elan Ruusamäe
9dac0ac873 Require marcusschwarz/lesserphp ^0.5.5
This resolves php 7.4 compatibility
2021-03-11 17:54:29 +02:00
Elan Ruusamäe
c80add80a2 Merge pull request #687 from mrclay/php-8-testing 2021-03-11 17:51:57 +02:00
Elan Ruusamäe
ad732493b8 Remove php 7.4 from allow failures 2021-03-11 14:04:50 +02:00
Elan Ruusamäe
ad0fb95556 Disable less tests on php 7.4+ 2021-03-11 14:04:45 +02:00
Elan Ruusamäe
f1572a580a Prepare for 3.0.11 release 2021-03-11 13:58:14 +02:00
Elan Ruusamäe
40f9dafe5f Merge pull request #685 from mrclay/php-8
Disable less tests on php 7.4+
2021-03-11 13:48:29 +02:00
Elan Ruusamäe
c814ff4bae Merge pull request #682 from angrybrad/master
Add PHP 8 support in composer.json
2021-03-11 13:47:59 +02:00
Elan Ruusamäe
8382fb85d8 Disable less tests on php 7.4+ 2020-12-01 16:16:43 +02:00
Elan Ruusamäe
efec97278f Merge pull request #677 from mrclay/php-7.4 2020-10-24 20:29:56 +03:00
Elan Ruusamäe
e9d4db41ac Add php nightly test
This adds php 8.0 to the test matrix
2020-10-24 18:52:22 +03:00
Elan Ruusamäe
b89bc57164 Fix Array and string offset access syntax with curly braces is deprecated 2020-10-24 18:52:22 +03:00
Brad Bell
69e3eb241f Add PHP 8 support in composer.json 2020-10-23 12:53:19 -07:00
Elan Ruusamäe
b17c00c05c Make code symmetric: Check on ConditionalGet as well
This partly reverts 5705fc9d89
2020-07-12 10:34:01 +03:00
Elan Ruusamäe
e3fe3001c3 Avoid calling get_magic_quotes_gpc() in tests for php >= 5.4 2020-07-12 10:33:58 +03:00
Elan Ruusamäe
8600312ed1 Merge pull request #672 from mrclay/fixer-psr2
Setup php-cs-fixer (@PSR2 rules only); Enable running in CI
2020-04-03 11:59:24 +03:00
Elan Ruusamäe
070c6c0349 Allow failures for php-cs-fixer 2020-04-03 10:48:29 +03:00
Elan Ruusamäe
b31855f6b8 Apply php-cs-fixer fixers
- braces
- function_declaration
- lowercase_keywords
- method_argument_space
- no_spaces_inside_parenthesis
- no_trailing_whitespace
- no_trailing_whitespace_in_comment
- single_blank_line_at_eof
2020-04-03 10:47:27 +03:00
Elan Ruusamäe
031e804d08 Run php-cs-fixer in Travis CI 2020-04-03 10:42:46 +03:00
Elan Ruusamäe
263381a23f Setup php-cs-fixer
Setup only to apply @PSR2 rules
2020-04-03 10:42:46 +03:00
Elan Ruusamäe
a36bfd50b0 Minor changelog fixes 2020-04-03 10:30:36 +03:00
Elan Ruusamäe
8dba84a2d2 Prepare for 3.0.10 release 2020-04-02 22:47:26 +03:00
Andrew Welch
0f607be23a Exclude SSI Comments (#670)
* Exclude SSI comments

Exclude Nginx & Apache Server Side Include (SSI) comments from being stripped via minification, the same way IE directives are not stripped.

Both Nginx & Apache SSI directives begin with:

<!—#

So we can just look for the # and don’t strip the comment in that case.

Nginx SSI: http://nginx.org/en/docs/http/ngx_http_ssi_module.html

Apache SSI: https://httpd.apache.org/docs/2.4/howto/ssi.html

* Add tests for Nginx/Apache SSI directives

Co-authored-by: Andrew Welch <andrew@keluli.local>
2020-04-02 22:45:11 +03:00
Elan Ruusamäe
d2a3e8c1d2 Setup .semver (gem install semver or gem install semver2) 2020-03-24 21:30:43 +02:00
Elan Ruusamäe
e59454bed5 Add 3.0.9 release notes 2020-03-24 21:28:47 +02:00
Elan Ruusamäe
eb5197f9d4 Update phpunit.xml deprecated options, exclude vendor from code-coverage 2020-03-24 21:26:16 +02:00
Elan Ruusamäe
20f336f598 Travis: use 7.4 instead of 7.4snapshot 2020-03-24 21:26:16 +02:00
Elan Ruusamäe
94829874f9 Allow intervention/httpauth 3.x 2020-03-24 21:26:16 +02:00
Elan Ruusamäe
f0aa0aa7d7 Add changelog for 3.0.8 2020-03-19 18:42:53 +02:00
robbykrlos
5705fc9d89 Function get_magic_quotes_gpc() is now deprecated in PHP 7.4 #661
- removed deprecated function that since PHP 5.4.0 returns FALSE always, and since PHP 7.4 is deprecated.
2020-03-06 19:20:17 +02:00
Elan Ruusamäe
3036ee9f55 Add more reflinks to changelog 2020-01-30 13:19:52 +02:00
Elan Ruusamäe
6e3ae8417a Allow marcusschwarz/lesserphp updates again 2020-01-30 13:09:30 +02:00
Elan Ruusamäe
d39fdd9e6b Update changelog for 3.0.7 2020-01-30 13:08:06 +02:00
Elan Ruusamäe
d35e780865 Force lesserphp to v0.5.2 because v0.5.3 changed namespace 2019-12-31 11:59:27 +02:00
Elan Ruusamäe
7378a0efe8 Composer: sort packages, set platform version 2019-12-10 08:31:58 +02:00
Jason Varga
c0dd8f50a1 Upgrade mrclay/props-dic (#658)
* Upgrade mrclay/props-dic
* Also support existing version
2019-12-08 22:38:04 +02:00
Elan Ruusamäe
63a812af8d Update changelog for 3.0.6 2019-10-28 13:39:13 +02:00
Elan Ruusamäe
8836df06d2 Bugfix for option sanitizer (#655) 2019-10-28 13:38:13 +02:00
Matthias Zronek
2f33b69786 Bugfix for option sanitizer 2019-10-28 11:03:44 +01:00
Elan Ruusamäe
8e4b0ceb86 Update changelog to format similar to keepachangelog.com 2019-10-01 13:09:59 +03:00
Elan Ruusamäe
266ddd7d54 Update changelog for 3.0.5 2019-10-01 13:04:39 +03:00
Elan Ruusamäe
07ed67aa77 Fix syntax error in composer.json (#653) 2019-10-01 13:03:36 +03:00
Elan Ruusamäe
2bbcce054d travis: add php 7.3, 7.4, 8.0; remove hhvm 2019-10-01 12:52:50 +03:00
Elan Ruusamäe
9040437901 Fix unit test for bd7d1077 2019-10-01 11:40:04 +03:00
Elan Ruusamäe
f954e1bd58 Fix syntax error in composer.json 2019-10-01 10:35:33 +03:00
Elan Ruusamäe
a8a77e6054 Set 3.0.4 release date 2019-09-24 08:12:01 +03:00
Elan Ruusamäe
25065b1559 Merge pull request #634 from dpauli/#633-Move-lesserphp-to-require
#633 move lesserphp to require
2019-09-19 10:31:19 +03:00
Elan Ruusamäe
807f41903e Merge pull request #642 from csabahete/master
Set "Vary: Accept-Encoding" header only if encoding is set and not empty
2019-09-19 10:30:56 +03:00
Elan Ruusamäe
b81ad2289a Merge pull request #646 from dli7319/master
Do not pass undefined variables into compact() for PHP 7.3
2019-09-19 10:30:25 +03:00
Elan Ruusamäe
fecf395de3 Allow monolog v2 (#650) 2019-09-19 10:29:27 +03:00
Jason Varga
2bd66ae3f9 use phpunit from vendor 2019-09-18 15:02:27 -04:00
Jason Varga
4453f3a4cb Allow monolog v2 2019-09-18 14:18:55 -04:00
David Li
f50353a952 Check if each variable is in the symbol table.
Delete if not before passing into compact.
2019-02-27 14:39:56 -05:00
Csaba Hete
bd7d1077b3 set "Vary: Accept-Encoding" header only if encoding is set and not empty 2018-11-06 19:24:25 +01:00
David Pauli
40f89b528c #633 Remove from suggest 2018-05-16 16:15:07 +02:00
David Pauli
b1bbdccef0 #633 Move marcusschwarz/lesserphp from require-dev to require 2018-05-16 16:13:44 +02:00
Elan Ruusamäe
258e495451 Revert "simplify substr third param"
This reverts commit 5659799c42.

the change actually broken MinifyImportProcessorTest
2018-01-05 19:13:28 +02:00
Elan Ruusamäe
b97a1db01d cleanup unneeded import 2018-01-05 19:09:42 +02:00
Elan Ruusamäe
3081a88dbd Merge pull request #623 from glensc/cs2
Code Quality fixes
2018-01-05 18:32:57 +02:00
Elan Ruusamäe
df7fddfa09 import classes instead of manual qualify 2018-01-05 14:35:57 +02:00
Elan Ruusamäe
c580d24e1b simplify return statement 2018-01-05 14:35:09 +02:00
Elan Ruusamäe
f9c96b6a3c use in_array instead of array_search (clearer intent) 2018-01-05 14:34:43 +02:00
Elan Ruusamäe
d3decb27e1 strict comparison 2018-01-05 14:34:06 +02:00
Elan Ruusamäe
0038cdb5de use empty string comparison instead of strlen 2018-01-05 14:34:06 +02:00
Elan Ruusamäe
5659799c42 simplify substr third param 2018-01-05 14:34:06 +02:00
Elan Ruusamäe
57be61586e use origin function instead of alias 2018-01-05 14:33:52 +02:00
Elan Ruusamäe
2198482600 drop useless return phpdoc annotation for constructor 2018-01-05 14:30:01 +02:00
Elan Ruusamäe
c2f40feb0c split workflows (no else after return) 2018-01-05 14:29:16 +02:00
Elan Ruusamäe
5c300aca97 do not define default value 2018-01-05 14:28:28 +02:00
Elan Ruusamäe
76c1edc6ff drop stale version comment 2018-01-05 14:27:22 +02:00
Elan Ruusamäe
919fc10139 Merge pull request #622 from glensc/travis-php-versions
travis: test php 5.3..7.3
2018-01-05 14:12:04 +02:00
Elan Ruusamäe
bb7fc74330 tests: rename dataproviders not to be picked up as tests 2018-01-05 13:13:20 +02:00
Elan Ruusamäe
eb4c0f6541 leafo/scssphp: allow 0.3/0.6/0.7
tests/ScssSourceTest.php passed with all versions

refs:
- commit ddf3a4e57f
- PR #562
2018-01-05 13:03:30 +02:00
Elan Ruusamäe
b6ef6fa397 travis: test php 5.3..7.3 2017-12-26 02:30:50 +02:00
Elan Ruusamäe
00b9f28630 Merge pull request #621 from glensc/phpunit
tests: move tests to Minify\Test namespace
2017-12-26 02:28:55 +02:00
Elan Ruusamäe
be40d4f9b2 fix namespaced _gzdecode 2017-12-22 18:18:07 +02:00
Elan Ruusamäe
9ee5fb7701 moved tests to minify\test namespace 2017-12-22 18:05:33 +02:00
Elan Ruusamäe
7d60fb9d0f use Minify\Test namespace for tests 2017-12-22 17:58:01 +02:00
Elan Ruusamäe
6236431c8f use forward-compatible phpunit testcase 2017-12-22 17:54:17 +02:00
Elan Ruusamäe
404664509c fill 3.0.3 release notes 2017-11-03 23:00:15 +02:00
Elan Ruusamäe
9ed7f9dc24 Fix closure-compiler's error "redirection limit reached". fixes #618, #619 2017-11-03 22:58:09 +02:00
Emanuele "ToX" Toscano
d9b392c474 Fix closure-compiler's "redirection limit reached"
Since a few days, the js minification was complaining about a redirection limit in the closure-compiler call. This was generating an error each time I have tried to use this tool.

After a bit of investigation I have found out that it was missing some parameters that are now mandatory. Plus, it now works in https only.
2017-11-03 10:24:25 +01:00
Steve Clay
004f6bf730 3.0.2 release notes 2017-09-14 18:13:04 -04:00
Steve Clay
72ece76cdf Fixes syntax error in Groups controller
Fixes #613
2017-09-14 18:03:49 -04:00
Elan Ruusamäe
bde7a41021 Merge pull request #610 from glensc/lesserphp
replace leafo/lessphp with marcusschwarz/lesserphp
2017-08-17 09:38:36 +03:00
Elan Ruusamäe
88aca4019d replace leafo/lessphp with marcusschwarz/lesserphp
This is a better maintained fork of lessphp. It seems to be fully
compatible, so this is more or less a drop in replacement.

Dokuwiki switched to this fork:
https://github.com/splitbrain/dokuwiki/pull/1969
2017-08-17 09:33:05 +03:00
Steve Clay
70952d88f9 Merge pull request #608 from benface/patch-1
Fix issue where minify() would corrupt some characters such as &nbsp; in some environments
2017-08-10 12:22:30 -04:00
Benoît Rouleau
6b274afd0b unicode flag everywhere to fix more issues with &nbsp; and MAMP 2017-08-09 17:22:32 -04:00
Benoît Rouleau
449f009b39 Fix issue where minify() would corrupt Unicode characters (such as &nbsp;) in some environments
Adding the `u` flag there fixes an issue in my environment (MAMP 4.1.1 with PHP 7.1.5) where `minify()` would corrupt the `&nbsp;` character (it would get replaced by the replacement character).
2017-07-20 20:34:49 -04:00
80 changed files with 989 additions and 438 deletions

44
.php_cs
View File

@@ -1,27 +1,23 @@
<?php <?php
$finder = Symfony\CS\Finder\DefaultFinder::create() $rules = array(
->in(__DIR__ . '/lib') '@PSR2' => true,
; );
return Symfony\CS\Config\Config::create() $config = PhpCsFixer\Config::create();
->level(Symfony\CS\FixerInterface::PSR2_LEVEL) $finder = $config->getFinder();
->setUsingCache(true)
->fixers(array( $finder
'linefeed', ->in(array('.', 'builder/', 'lib/', 'tests/', 'min_extras/', 'static/'))
'trailing_spaces', ->name('*.php')
'unused_use', ->ignoreDotFiles(true)
'short_tag', ->ignoreVCS(true);
'return',
'visibility', return $config
'php_closing_tag', ->setUsingCache(true)
'extra_empty_lines', ->setRiskyAllowed(true)
'function_declaration', ->setRules($rules)
'include', ->setIndent(' ')
'controls_spaces', ->setLineEnding("\n");
'elseif',
'-eof_ending', // vim:ft=php
'-method_argument_space',
))
->finder($finder)
;

6
.semver Normal file
View File

@@ -0,0 +1,6 @@
---
:major: 3
:minor: 0
:patch: 14
:special: ''
:metadata: ''

View File

@@ -1,21 +1,32 @@
language: php language: php
sudo: false sudo: false
dist: trusty
php: jobs:
- 7.0 fast_finish: true
- 5.6 allow_failures:
- 5.5 - php: "nightly"
- 5.4 - name: "Php CS Fixer"
- hhvm include:
- php: "5.3"
dist: precise
- php: "5.4"
- php: "5.5"
- php: "5.6"
- php: "7.0"
- php: "7.1"
- php: "7.2"
- php: "7.3"
- php: "7.4"
- php: "nightly"
- name: "Php CS Fixer"
php: "7.3"
env:
- PHP_CS_FIXER=1
env: env:
- CLOSURE_VERSION: 20161024 - CLOSURE_VERSION: 20161024
matrix:
allow_failures:
- php: hhvm
- php: 7.0
services: services:
- memcached - memcached
@@ -31,7 +42,14 @@ before_script:
- tests/dl-closure.sh - tests/dl-closure.sh
script: script:
- PATH=vendor/bin:$PATH
- composer validate - composer validate
- phpunit --verbose - |
if [ "$PHP_CS_FIXER" ]; then
composer config --unset platform.php
composer require --dev friendsofphp/php-cs-fixer:2.16
php-cs-fixer fix --verbose --diff --dry-run --ansi
fi
- vendor/bin/phpunit --verbose
# vim:ts=2:sw=2:et # vim:ts=2:sw=2:et

View File

@@ -1,8 +1,139 @@
## Version 3.0.1 (2017-06-09) # Changelog
* Update CSSmin to v4, #599, #590 All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## [4.0.0] - 2024-01-04
- Support PHP 8.1+
- Update PHPUnit to 8.x
- Replace `leafo/scssphp` with `scssphp/scssphp`
## [3.0.14] - 2023-05-05
- Support monolog v3, [#705]
- Allow invalidation from manual invocation, [#700]
- Add property declaration, [#699]
[3.0.14]: https://github.com/mrclay/minify/compare/3.0.13...3.0.14
[#705]: https://github.com/mrclay/minify/pull/705
[#700]: https://github.com/mrclay/minify/pull/700
[#699]: https://github.com/mrclay/minify/pull/699
## [3.0.13] - 2022-10-03
- Add `Minify_Cache_APCu` to replace `Minify_Cache_APC`, [#697]
- Require `marcusschwarz/lesserphp:^0.5.5` to fix php 7.4 compatibility, [#688]
[3.0.13]: https://github.com/mrclay/minify/compare/3.0.12...3.0.13
[#697]: https://github.com/mrclay/minify/pull/697
[#688]: https://github.com/mrclay/minify/pull/688
## [3.0.12] - 2022-05-14
- Update jquery to 1.12.4 to avoid xss attacks, [#692]
- Fix null argument to preg_split, [#696], [#695]
[3.0.12]: https://github.com/mrclay/minify/compare/3.0.11...3.0.12
[#692]: https://github.com/mrclay/minify/pull/692
[#696]: https://github.com/mrclay/minify/pull/696
[#695]: https://github.com/mrclay/minify/issues/695
## [3.0.11] - 2021-03-11
- PHP 8.0 support, [#685], [#682], [#677]
[3.0.11]: https://github.com/mrclay/minify/compare/3.0.10...3.0.11
[#685]: https://github.com/mrclay/minify/pull/685
[#682]: https://github.com/mrclay/minify/pull/682
[#677]: https://github.com/mrclay/minify/pull/677
## [3.0.10] - 2020-04-02
- Exclude SSI Comments from HTML minify, [#670], [#671]
[3.0.10]: https://github.com/mrclay/minify/compare/3.0.9...3.0.10
[#671]: https://github.com/mrclay/minify/issues/671
[#670]: https://github.com/mrclay/minify/pull/670
## [3.0.9] - 2020-03-24
- Allow `intervention/httpauth` 3.x, [#667], [#666], [#664]
[3.0.9]: https://github.com/mrclay/minify/compare/3.0.8...3.0.9
[#664]: https://github.com/mrclay/minify/issues/664
[#666]: https://github.com/mrclay/minify/pull/666
[#667]: https://github.com/mrclay/minify/pull/667
## [3.0.8] - 2020-03-19
- Removed deprecated get_magic_quotes_gpc() function that since PHP 5.4.0 returns FALSE always, and since PHP 7.4 is deprecated, [#661]
[3.0.8]: https://github.com/mrclay/minify/compare/3.0.7...3.0.8
[#661]: https://github.com/mrclay/minify/pull/661
## [3.0.7] - 2019-12-10
- Allow mrclay/props-dic ^3.0, [#658]
[3.0.7]: https://github.com/mrclay/minify/compare/3.0.6...3.0.7
[#658]: https://github.com/mrclay/minify/pull/658
## [3.0.6] - 2019-10-28
- Bugfix for option sanitizer, [#654], [#655]
[3.0.6]: https://github.com/mrclay/minify/compare/3.0.5...3.0.6
[#654]: https://github.com/mrclay/minify/issues/654
[#655]: https://github.com/mrclay/minify/pull/655
## [3.0.5] - 2019-10-01
- Fix syntax error in composer.json, [#653]
[3.0.5]: https://github.com/mrclay/minify/compare/3.0.4...3.0.5
[#653]: https://github.com/mrclay/minify/pull/653
## 3.0.4 - 2019-09-24
- Fix PHP 7.3 compatibility issues, [#648]
[3.0.4]: https://github.com/mrclay/minify/compare/3.0.3...3.0.4
[#648]: https://github.com/mrclay/minify/issues/648
## [3.0.3] - 2017-11-03
- Fix closure-compiler's error "redirection limit reached". [#618], [#619]
[3.0.3]: https://github.com/mrclay/minify/compare/3.0.2...3.0.3
[#618]: https://github.com/mrclay/minify/pull/618
[#619]: https://github.com/mrclay/minify/issues/619
## [3.0.2] - 2017-09-14
- Fixes syntax error in Groups controller, [#613]
- Better-maintained lessphp fork, [#610]
- No longer corrupts some chars in some environments, [#608]
[3.0.2]: https://github.com/mrclay/minify/compare/3.0.1...3.0.2
[#608]: https://github.com/mrclay/minify/pull/608
[#610]: https://github.com/mrclay/minify/pull/610
[#613]: https://github.com/mrclay/minify/issues/613
## [3.0.1] - 2017-06-09
- Update CSSmin to v4, [#599], [#590]
[3.0.1]: https://github.com/mrclay/minify/compare/3.0.0...3.0.1
[#590]: https://github.com/mrclay/minify/issues/590
[#599]: https://github.com/mrclay/minify/pull/599
## 3.0.0 - 2017-04-03
## Version 3.0.0 (2017-04-03)
* Improved CSS minification via Túbal Martín's CSSMin * Improved CSS minification via Túbal Martín's CSSMin
* Easier error identification (just see error_log) * Easier error identification (just see error_log)
* Adds feature to serve static files directly * Adds feature to serve static files directly
@@ -20,7 +151,8 @@
* BREAKING: Removes `$min_libPath` option * BREAKING: Removes `$min_libPath` option
* BREAKING: The Minify, source, and controller components have changed APIs * BREAKING: The Minify, source, and controller components have changed APIs
## Version 2.3.0 (2016-03-11) ## 2.3.0 - 2016-03-11
* Adds `$min_concatOnly` option to just concatenate files * Adds `$min_concatOnly` option to just concatenate files
* Deprecates use of Minify_Loader * Deprecates use of Minify_Loader
* Deprecates use of Minify_Logger * Deprecates use of Minify_Logger
@@ -28,13 +160,15 @@
* Deprecates use of FirePHP * Deprecates use of FirePHP
* Deprecates use of DooDigestAuth * Deprecates use of DooDigestAuth
## Version 2.2.1 (2014-10-30) ## 2.2.1 - 2014-10-30
* Builder styled with Bootstrap (thanks to help from acidvertigo) * Builder styled with Bootstrap (thanks to help from acidvertigo)
* Update CSSmin to v.2.4.8 * Update CSSmin to v.2.4.8
* Added WinCache * Added WinCache
* URLs with spaces properly rewritten * URLs with spaces properly rewritten
## Version 2.2.0 (2014-03-12) ## 2.2.0 - 2014-03-12
* Fix handling of RegEx in certain situations in JSMin * Fix handling of RegEx in certain situations in JSMin
* Thanks to Vovan-VE for reporting this * Thanks to Vovan-VE for reporting this
* Update composer.json with support info * Update composer.json with support info
@@ -56,11 +190,13 @@
* Allow far-future expiration and file versioning with the "v" querystirng parameter in addition to existing method * Allow far-future expiration and file versioning with the "v" querystirng parameter in addition to existing method
* Lots of general code tidy ups * Lots of general code tidy ups
## Version 2.1.7 (2013-07-23) ## 2.1.7 - 2013-07-23
* Fixes arbitrary file inclusion vulnerability on some systems * Fixes arbitrary file inclusion vulnerability on some systems
* Thanks to Matt Mecham for reporting this * Thanks to Matt Mecham for reporting this
## Version 2.1.6 (2013-07-19) ## 2.1.6 - 2013-07-19
* JSMin fixes * JSMin fixes
* Prevents some Closure Compiler API failures * Prevents some Closure Compiler API failures
* Uses autoloading for all class loading * Uses autoloading for all class loading
@@ -72,7 +208,8 @@
* CLI script more portable * CLI script more portable
* Adds composer.json * Adds composer.json
## Version 2.1.5 (2012-03-10) ## 2.1.5 - 2012-03-10
* Removed XSS vulnerability * Removed XSS vulnerability
* Disabled builder by default * Disabled builder by default
* command line tools to minify and rewrite URIs in CSS * command line tools to minify and rewrite URIs in CSS
@@ -81,7 +218,8 @@
* Closure Compiler uses cURL when allow\_url\_fopen is off * Closure Compiler uses cURL when allow\_url\_fopen is off
* Missing file notices when using groups * Missing file notices when using groups
## Version 2.1.4b (2010-07-10) ## 2.1.4b - 2010-07-10
* Option to minify JS with Closure Compiler API w/ JSMin failover * Option to minify JS with Closure Compiler API w/ JSMin failover
* Cookie/bookmarklet-based debug mode. No HTML editing! * Cookie/bookmarklet-based debug mode. No HTML editing!
* Allows 1 file to be missing w/o complete failure * Allows 1 file to be missing w/o complete failure
@@ -97,7 +235,8 @@
* Removed annoying maxFiles limit * Removed annoying maxFiles limit
* mbstring.func\_overload usage is safer * mbstring.func\_overload usage is safer
## Version 2.1.3 (2009-06-30) ## 2.1.3 - 2009-06-30
* CSS fixes * CSS fixes
* A few URI rewriting bugs fixed * A few URI rewriting bugs fixed
* comment/whitespace removal no longer breaks some values * comment/whitespace removal no longer breaks some values
@@ -112,7 +251,8 @@
* API: Can set contentType Minify\_Source objects (fixes an annoying [caveat](http://groups.google.com/group/minify/msg/8446d32ee99a4961)) * API: Can set contentType Minify\_Source objects (fixes an annoying [caveat](http://groups.google.com/group/minify/msg/8446d32ee99a4961))
* [Resolved Issue list](http://code.google.com/p/minify/issues/list?can=1&q=label%3ARelease-2.1.2%20status%3AVerified) * [Resolved Issue list](http://code.google.com/p/minify/issues/list?can=1&q=label%3ARelease-2.1.2%20status%3AVerified)
## Version 2.1.2 (2009-03-04) ## 2.1.2 - 2009-03-04
* Javascript fixes * Javascript fixes
* Debug mode no longer confused by `*/*` in strings/RegExps (jQuery) * Debug mode no longer confused by `*/*` in strings/RegExps (jQuery)
* quote characters inside RegExp literals no longer cause exception * quote characters inside RegExp literals no longer cause exception
@@ -124,14 +264,16 @@
* Builder app doesn't fail on systems without gzdeflate() * Builder app doesn't fail on systems without gzdeflate()
* APC caching class included * APC caching class included
## Version 2.1.1 (2008-10-19) ## 2.1.1 - 2008-10-19
* Bug fix release * Bug fix release
* Detection and workarounds for zlib.output\_compression and non-PHP encoding modules * Detection and workarounds for zlib.output\_compression and non-PHP encoding modules
* Zlib not required (mod\_rewrite, et.al., can still be used for encoding) * Zlib not required (mod\_rewrite, et.al., can still be used for encoding)
* HTML : More IE conditional comments preserved * HTML : More IE conditional comments preserved
* Minify\_groupUri() utility fixed * Minify\_groupUri() utility fixed
## Version 2.1.0 (2008-09-18) ## 2.1.0 - 2008-09-18
* "min" default application for quick deployment * "min" default application for quick deployment
* Minify URI Builder app & bookmarklet for quickly creating minify URIs * Minify URI Builder app & bookmarklet for quickly creating minify URIs
* Relative URIs in CSS file are fixed automatically by default * Relative URIs in CSS file are fixed automatically by default
@@ -147,8 +289,8 @@
* Minify\_Cache\_File has flock()s (by default) * Minify\_Cache\_File has flock()s (by default)
* Workaround for Windows mtime reporting bug * Workaround for Windows mtime reporting bug
## 2.0.0 - 2008-05-22
## Version 2.0.0 (2008-05-22)
* Complete code overhaul. Minify is now a PEAR-style class and toolkit for building customized minifying file servers. * Complete code overhaul. Minify is now a PEAR-style class and toolkit for building customized minifying file servers.
* Content-Encoding: deflate/gzip/compress, based on request headers * Content-Encoding: deflate/gzip/compress, based on request headers
* Expanded CSS and HTML minifiers with test cases * Expanded CSS and HTML minifiers with test cases
@@ -157,10 +299,12 @@
* Compression & encoding modules lazy-loaded as needed (304 responses use minimal code) * Compression & encoding modules lazy-loaded as needed (304 responses use minimal code)
* Separate utility classes for HTTP encoding and cache control * Separate utility classes for HTTP encoding and cache control
## Version 1.0.1 (2007-05-05) ## 1.0.1 - 2007-05-05
* Fixed various problems resolving pathnames when hosted on an NFS mount. * Fixed various problems resolving pathnames when hosted on an NFS mount.
* Fixed 'undefined constant' notice. * Fixed 'undefined constant' notice.
* Replaced old JSMin library with a much faster custom implementation. * Replaced old JSMin library with a much faster custom implementation.
## Version 1.0.0 (2007-05-02) ## 1.0.0 - 2007-05-02
* First release. * First release.

View File

@@ -1,4 +1,4 @@
<?php <?php
$app = (require __DIR__ . '/../bootstrap.php'); $app = (require __DIR__ . '/../bootstrap.php');
/* @var \Minify\App $app */ /* @var \Minify\App $app */
@@ -153,8 +153,8 @@ by Minify. E.g. <code>@import "<span class=minRoot>/min/?</span>g=css2";</code><
list</a>.</p> list</a>.</p>
<p><small>Powered by Minify <?php echo Minify::VERSION; ?></small></p> <p><small>Powered by Minify <?php echo Minify::VERSION; ?></small></p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="jquery-1.6.3.min.js"><\/script>')</script> <script>window.jQuery || document.write('<script src="jquery-1.12.4.min.js"><\/script>')</script>
<script> <script>
(function () { (function () {
// workaround required to test when /min isn't child of web root // workaround required to test when /min isn't child of web root

5
builder/jquery-1.12.4.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
<?php <?php
/** /**
* AJAX checks for zlib.output_compression * AJAX checks for zlib.output_compression
* *
* @package Minify * @package Minify
*/ */
@@ -29,7 +29,6 @@ if ($app->env->get('hello')) {
)); ));
$he->encode(); $he->encode();
$he->sendAll(); $he->sendAll();
} else { } else {
// echo status "0" or "1" // echo status "0" or "1"
header('Content-Type: text/plain'); header('Content-Type: text/plain');

View File

@@ -37,7 +37,7 @@ if (isset($_GET['oc'])) {
echo "<p class=topNote><strong>\$_SERVER['SUBDOMAIN_DOCUMENT_ROOT'] is set.</strong> " echo "<p class=topNote><strong>\$_SERVER['SUBDOMAIN_DOCUMENT_ROOT'] is set.</strong> "
. "You may need to set \$min_documentRoot to this in config.php</p>"; . "You may need to set \$min_documentRoot to this in config.php</p>";
} }
} }
//*/ //*/

View File

@@ -1,7 +1,7 @@
{ {
"name": "mrclay/minify", "name": "mrclay/minify",
"type": "library", "type": "library",
"description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers", "description": "Minify is a PHP app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers",
"homepage": "https://github.com/mrclay/minify", "homepage": "https://github.com/mrclay/minify",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"authors": [ "authors": [
@@ -17,31 +17,40 @@
"wiki": "https://github.com/mrclay/minify/blob/master/docs" "wiki": "https://github.com/mrclay/minify/blob/master/docs"
}, },
"autoload": { "autoload": {
"classmap": ["lib/"] "classmap": [
"lib/"
]
}, },
"autoload-dev": { "autoload-dev": {
"classmap": ["tests/TestCase.php"] "psr-4": {
"Minify\\Test\\": "tests/"
}
},
"config": {
"platform": {
"php": "8.1.0"
},
"sort-packages": true
}, },
"require": { "require": {
"php": "^8.1",
"ext-pcre": "*", "ext-pcre": "*",
"intervention/httpauth": "~2.0", "intervention/httpauth": "^2.0|^3.0",
"monolog/monolog": "~1.1", "marcusschwarz/lesserphp": "^0.5.5",
"monolog/monolog": "~1.1|~2.0|~3.0",
"mrclay/jsmin-php": "~2", "mrclay/jsmin-php": "~2",
"mrclay/props-dic": "^2.2", "mrclay/props-dic": "^4",
"php": "^5.3.0 || ^7.0",
"tubalmartin/cssmin": "~4" "tubalmartin/cssmin": "~4"
}, },
"require-dev": { "require-dev": {
"firephp/firephp-core": "~0.4.0", "firephp/firephp-core": "~0.4.0",
"leafo/lessphp": "~0.4.0",
"leafo/scssphp": "~0.6.6",
"meenie/javascript-packer": "~1.1", "meenie/javascript-packer": "~1.1",
"phpunit/phpunit": "4.8.*", "phpunit/phpunit": "^8",
"scssphp/scssphp": "^1.12",
"tedivm/jshrink": "~1.1.0" "tedivm/jshrink": "~1.1.0"
}, },
"suggest": { "suggest": {
"firephp/firephp-core": "Use FirePHP for Log messages", "firephp/firephp-core": "Use FirePHP for Log messages",
"leafo/lessphp": "LESS support",
"meenie/javascript-packer": "Keep track of the Packer PHP port using Composer" "meenie/javascript-packer": "Keep track of the Packer PHP port using Composer"
}, },
"scripts": { "scripts": {

View File

@@ -4,7 +4,6 @@
* *
* To test config options, place them in this file and add "&test" to your Minify URL. * To test config options, place them in this file and add "&test" to your Minify URL.
* Note that if this is on a public server, anyone can execute your test. * Note that if this is on a public server, anyone can execute your test.
* *
* @package Minify * @package Minify
*/ */

View File

@@ -2,7 +2,7 @@
/** /**
* Configuration for "min", the default application built with the Minify * Configuration for "min", the default application built with the Minify
* library * library
* *
* @package Minify * @package Minify
*/ */
@@ -47,7 +47,7 @@ $min_errorLogger = false;
* /min/f=file1.js send the cookie minDebug=file1.js * /min/f=file1.js send the cookie minDebug=file1.js
* You can manually enable debugging by appending "&debug" to a URI. * You can manually enable debugging by appending "&debug" to a URI.
* E.g. /min/?f=script1.js,script2.js&debug * E.g. /min/?f=script1.js,script2.js&debug
* *
* In 'debug' mode, Minify combines files with no minification and adds comments * In 'debug' mode, Minify combines files with no minification and adds comments
* to indicate line #s of the original files. * to indicate line #s of the original files.
*/ */
@@ -73,11 +73,11 @@ $min_allowDebugFlag = false;
/** /**
* Leave an empty string to use PHP's $_SERVER['DOCUMENT_ROOT']. * Leave an empty string to use PHP's $_SERVER['DOCUMENT_ROOT'].
* *
* On some servers, this value may be misconfigured or missing. If so, set this * On some servers, this value may be misconfigured or missing. If so, set this
* to your full document root path with no trailing slash. * to your full document root path with no trailing slash.
* E.g. '/home/accountname/public_html' or 'c:\\xampp\\htdocs' * E.g. '/home/accountname/public_html' or 'c:\\xampp\\htdocs'
* *
* If /min/ is directly inside your document root, just uncomment the * If /min/ is directly inside your document root, just uncomment the
* second line. The third line might work on some Apache servers. * second line. The third line might work on some Apache servers.
*/ */
$min_documentRoot = ''; $min_documentRoot = '';
@@ -87,7 +87,7 @@ $min_documentRoot = '';
/** /**
* Cache file locking. Set to false if filesystem is NFS. On at least one * Cache file locking. Set to false if filesystem is NFS. On at least one
* NFS system flock-ing attempts stalled PHP for 30 seconds! * NFS system flock-ing attempts stalled PHP for 30 seconds!
*/ */
$min_cacheFileLocking = true; $min_cacheFileLocking = true;
@@ -96,9 +96,9 @@ $min_cacheFileLocking = true;
/** /**
* Combining multiple CSS files can place @import declarations after rules, which * Combining multiple CSS files can place @import declarations after rules, which
* is invalid. Minify will attempt to detect when this happens and place a * is invalid. Minify will attempt to detect when this happens and place a
* warning comment at the top of the CSS output. To resolve this you can either * warning comment at the top of the CSS output. To resolve this you can either
* move the @imports within your CSS files, or enable this option, which will * move the @imports within your CSS files, or enable this option, which will
* move all @imports to the top of the output. Note that moving @imports could * move all @imports to the top of the output. Note that moving @imports could
* affect CSS values (which is why this option is disabled by default). * affect CSS values (which is why this option is disabled by default).
*/ */
$min_serveOptions['bubbleCssImports'] = false; $min_serveOptions['bubbleCssImports'] = false;
@@ -134,8 +134,8 @@ $min_serveOptions['maxAge'] = 1800;
* particular directories below DOCUMENT_ROOT, set this here. * particular directories below DOCUMENT_ROOT, set this here.
* You will still need to include the directory in the * You will still need to include the directory in the
* f or b GET parameters. * f or b GET parameters.
* *
* // = shortcut for DOCUMENT_ROOT * // = shortcut for DOCUMENT_ROOT
*/ */
//$min_serveOptions['minApp']['allowDirs'] = array('//js', '//css'); //$min_serveOptions['minApp']['allowDirs'] = array('//js', '//css');
@@ -149,7 +149,7 @@ $min_serveOptions['minApp']['groupsOnly'] = false;
/** /**
* By default, Minify will not minify files with names containing .min or -min * By default, Minify will not minify files with names containing .min or -min
* before the extension. E.g. myFile.min.js will not be processed by JSMin * before the extension. E.g. myFile.min.js will not be processed by JSMin
* *
* To minify all files, set this option to null. You could also specify your * To minify all files, set this option to null. You could also specify your
* own pattern that is matched against the filename. * own pattern that is matched against the filename.
*/ */
@@ -160,8 +160,8 @@ $min_serveOptions['minApp']['groupsOnly'] = false;
* If you minify CSS files stored in symlink-ed directories, the URI rewriting * If you minify CSS files stored in symlink-ed directories, the URI rewriting
* algorithm can fail. To prevent this, provide an array of link paths to * algorithm can fail. To prevent this, provide an array of link paths to
* target paths, where the link paths are within the document root. * target paths, where the link paths are within the document root.
* *
* Because paths need to be normalized for this to work, use "//" to substitute * Because paths need to be normalized for this to work, use "//" to substitute
* the doc root in the link paths (the array keys). E.g.: * the doc root in the link paths (the array keys). E.g.:
* <code> * <code>
* array('//symlink' => '/real/target/path') // unix * array('//symlink' => '/real/target/path') // unix
@@ -173,17 +173,17 @@ $min_symlinks = array();
/** /**
* If you upload files from Windows to a non-Windows server, Windows may report * If you upload files from Windows to a non-Windows server, Windows may report
* incorrect mtimes for the files. This may cause Minify to keep serving stale * incorrect mtimes for the files. This may cause Minify to keep serving stale
* cache files when source file changes are made too frequently (e.g. more than * cache files when source file changes are made too frequently (e.g. more than
* once an hour). * once an hour).
* *
* Immediately after modifying and uploading a file, use the touch command to * Immediately after modifying and uploading a file, use the touch command to
* update the mtime on the server. If the mtime jumps ahead by a number of hours, * update the mtime on the server. If the mtime jumps ahead by a number of hours,
* set this variable to that number. If the mtime moves back, this should not be * set this variable to that number. If the mtime moves back, this should not be
* needed. * needed.
* *
* In the Windows SFTP client WinSCP, there's an option that may fix this * In the Windows SFTP client WinSCP, there's an option that may fix this
* issue without changing the variable below. Under login > environment, * issue without changing the variable below. Under login > environment,
* select the option "Adjust remote timestamp with DST". * select the option "Adjust remote timestamp with DST".
* @link http://winscp.net/eng/docs/ui_login_environment#daylight_saving_time * @link http://winscp.net/eng/docs/ui_login_environment#daylight_saving_time
*/ */
@@ -198,4 +198,3 @@ $min_uploaderHoursBehind = 0;
*/ */
//$min_factories['minify'] = ... a callable accepting a Minify\App object //$min_factories['minify'] = ... a callable accepting a Minify\App object
//$min_factories['controller'] = ... a callable accepting a Minify\App object //$min_factories['controller'] = ... a callable accepting a Minify\App object

8
docker-compose.yml Normal file
View File

@@ -0,0 +1,8 @@
version: "3.7"
services:
apache:
image: php:8.3-apache
ports:
- 8080:80
volumes:
- .:/var/www/html/min

View File

@@ -1,9 +1,9 @@
<?php <?php
/** /**
* Sets up MinApp controller and serves files * Sets up MinApp controller and serves files
* *
* DO NOT EDIT! Configure this utility via config.php and groupsConfig.php * DO NOT EDIT! Configure this utility via config.php and groupsConfig.php
* *
* @package Minify * @package Minify
*/ */

View File

@@ -128,8 +128,8 @@ class HTTP_ConditionalGet
$etagAppend = ''; $etagAppend = '';
if (isset($spec['encoding'])) { if (isset($spec['encoding'])) {
$this->_stripEtag = true; $this->_stripEtag = true;
$this->_headers['Vary'] = 'Accept-Encoding';
if ('' !== $spec['encoding']) { if ('' !== $spec['encoding']) {
$this->_headers['Vary'] = 'Accept-Encoding';
if (0 === strpos($spec['encoding'], 'x-')) { if (0 === strpos($spec['encoding'], 'x-')) {
$spec['encoding'] = substr($spec['encoding'], 2); $spec['encoding'] = substr($spec['encoding'], 2);
} }
@@ -317,7 +317,7 @@ class HTTP_ConditionalGet
if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) { if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
return false; return false;
} }
$clientEtagList = get_magic_quotes_gpc() $clientEtagList = PHP_VERSION_ID < 50400 && get_magic_quotes_gpc()
? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])
: $_SERVER['HTTP_IF_NONE_MATCH']; : $_SERVER['HTTP_IF_NONE_MATCH'];
$clientEtags = explode(',', $clientEtagList); $clientEtags = explode(',', $clientEtagList);

View File

@@ -204,9 +204,10 @@ class HTTP_Encoder
} }
// gzip checks (slow) // gzip checks (slow)
if (preg_match( if (preg_match(
'@(?:^|,)\\s*((?:x-)?gzip)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' '@(?:^|,)\\s*((?:x-)?gzip)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@',
,$ae $ae,
,$m)) { $m
)) {
return array('gzip', $m[1]); return array('gzip', $m[1]);
} }
if ($allowDeflate) { if ($allowDeflate) {
@@ -217,14 +218,17 @@ class HTTP_Encoder
|| 0 === strpos($ae, 'deflate,') // opera || 0 === strpos($ae, 'deflate,') // opera
// slow parsing // slow parsing
|| preg_match( || preg_match(
'@(?:^|,)\\s*deflate\\s*(?:$|,|;\\s*q=(?:0\\.|1))@', $ae)) { '@(?:^|,)\\s*deflate\\s*(?:$|,|;\\s*q=(?:0\\.|1))@',
$ae
)) {
return array('deflate', 'deflate'); return array('deflate', 'deflate');
} }
} }
if ($allowCompress && preg_match( if ($allowCompress && preg_match(
'@(?:^|,)\\s*((?:x-)?compress)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' '@(?:^|,)\\s*((?:x-)?compress)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@',
,$ae $ae,
,$m)) { $m
)) {
return array('compress', $m[1]); return array('compress', $m[1]);
} }

View File

@@ -14,9 +14,6 @@ use Psr\Log\LoggerInterface;
* This library was inspired by {@link mailto:flashkot@mail.ru jscsscomp by Maxim Martynyuk} * This library was inspired by {@link mailto:flashkot@mail.ru jscsscomp by Maxim Martynyuk}
* and by the article {@link http://www.hunlock.com/blogs/Supercharged_Javascript "Supercharged JavaScript" by Patrick Hunlock}. * and by the article {@link http://www.hunlock.com/blogs/Supercharged_Javascript "Supercharged JavaScript" by Patrick Hunlock}.
* *
* Requires PHP 5.1.0.
* Tested on PHP 5.1.6.
*
* @package Minify * @package Minify
* @author Ryan Grove <ryan@wonko.com> * @author Ryan Grove <ryan@wonko.com>
* @author Stephen Clay <steve@mrclay.org> * @author Stephen Clay <steve@mrclay.org>
@@ -48,14 +45,14 @@ class Minify
* *
* @var Minify_CacheInterface * @var Minify_CacheInterface
*/ */
private $cache = null; private $cache;
/** /**
* Active controller for current request * Active controller for current request
* *
* @var Minify_Controller_Base * @var Minify_Controller_Base
*/ */
protected $controller = null; protected $controller;
/** /**
* @var Minify_Env * @var Minify_Env
@@ -77,12 +74,12 @@ class Minify
* *
* @var array * @var array
*/ */
protected $options = null; protected $options;
/** /**
* @var LoggerInterface|null * @var LoggerInterface|null
*/ */
protected $logger = null; protected $logger;
/** /**
* @param Minify_CacheInterface $cache * @param Minify_CacheInterface $cache
@@ -121,6 +118,7 @@ class Minify
'quiet' => false, // serve() will send headers and output 'quiet' => false, // serve() will send headers and output
'debug' => false, 'debug' => false,
'concatOnly' => false, 'concatOnly' => false,
'invalidate' => false,
// if you override these, the response codes MUST be directly after // if you override these, the response codes MUST be directly after
// the first space. // the first space.
@@ -245,7 +243,7 @@ class Minify
if (! $this->options['quiet']) { if (! $this->options['quiet']) {
$this->errorExit($this->options['badRequestHeader'], self::URL_DEBUG); $this->errorExit($this->options['badRequestHeader'], self::URL_DEBUG);
} else { } else {
list(,$statusCode) = explode(' ', $this->options['badRequestHeader']); list(, $statusCode) = explode(' ', $this->options['badRequestHeader']);
return array( return array(
'success' => false, 'success' => false,
@@ -287,6 +285,7 @@ class Minify
'lastModifiedTime' => $this->options['lastModifiedTime'], 'lastModifiedTime' => $this->options['lastModifiedTime'],
'isPublic' => $this->options['isPublic'], 'isPublic' => $this->options['isPublic'],
'encoding' => $this->options['encodeMethod'], 'encoding' => $this->options['encodeMethod'],
'invalidate' => $this->options['invalidate'],
); );
if ($this->options['maxAge'] > 0) { if ($this->options['maxAge'] > 0) {
@@ -302,20 +301,20 @@ class Minify
$cg->sendHeaders(); $cg->sendHeaders();
return; return;
} else {
return array(
'success' => true,
'statusCode' => 304,
'content' => '',
'headers' => $cg->getHeaders(),
);
} }
} else {
// client will need output return array(
$headers = $cg->getHeaders(); 'success' => true,
unset($cg); 'statusCode' => 304,
'content' => '',
'headers' => $cg->getHeaders(),
);
} }
// client will need output
$headers = $cg->getHeaders();
unset($cg);
if ($this->options['contentType'] === self::TYPE_CSS && $this->options['rewriteCssUris']) { if ($this->options['contentType'] === self::TYPE_CSS && $this->options['rewriteCssUris']) {
$this->setupUriRewrites(); $this->setupUriRewrites();
} }
@@ -473,7 +472,7 @@ class Minify
public function errorExit($header, $url = '', $msgHtml = '') public function errorExit($header, $url = '', $msgHtml = '')
{ {
$url = htmlspecialchars($url, ENT_QUOTES); $url = htmlspecialchars($url, ENT_QUOTES);
list(,$h1) = explode(' ', $header, 2); list(, $h1) = explode(' ', $header, 2);
$h1 = htmlspecialchars($h1); $h1 = htmlspecialchars($h1);
// FastCGI environments require 3rd arg to header() to be set // FastCGI environments require 3rd arg to header() to be set
list(, $code) = explode(' ', $header, 3); list(, $code) = explode(' ', $header, 3);
@@ -596,7 +595,8 @@ class Minify
! $source // yes, we ran out of sources ! $source // yes, we ran out of sources
|| $type === self::TYPE_CSS // yes, to process CSS individually (avoiding PCRE bugs/limits) || $type === self::TYPE_CSS // yes, to process CSS individually (avoiding PCRE bugs/limits)
|| $minifier !== $lastMinifier // yes, minifier changed || $minifier !== $lastMinifier // yes, minifier changed
|| $options !== $lastOptions)) { // yes, options changed || $options !== $lastOptions // yes, options changed
)) {
// minify previous sources with last settings // minify previous sources with last settings
$imploded = implode($implodeSeparator, $groupToProcessTogether); $imploded = implode($implodeSeparator, $groupToProcessTogether);
$groupToProcessTogether = array(); $groupToProcessTogether = array();

View File

@@ -2,23 +2,34 @@
namespace Minify; namespace Minify;
use Minify_Cache_File;
use Minify_CacheInterface;
use Minify_Controller_MinApp;
use Minify_ControllerInterface;
use Minify_DebugDetector;
use Minify_Env;
use Minify_Source_Factory;
use Props\Container; use Props\Container;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Monolog;
use Minify;
/** /**
* @property \Minify_CacheInterface $cache * @property Minify_CacheInterface $cache
* @property \Minify\Config $config * @property Config $config
* @property string $configPath * @property string $configPath
* @property \Minify_ControllerInterface $controller * @property Minify_ControllerInterface $controller
* @property string $dir * @property string $dir
* @property string $docRoot * @property string $docRoot
* @property \Minify_Env $env * @property Minify_Env $env
* @property \Monolog\Handler\ErrorLogHandler $errorLogHandler * @property Monolog\Handler\ErrorLogHandler $errorLogHandler
* @property array $groupsConfig * @property array $groupsConfig
* @property string $groupsConfigPath * @property string $groupsConfigPath
* @property \Psr\Log\LoggerInterface $logger * @property LoggerInterface $logger
* @property \Minify $minify * @property \Minify $minify
* @property array $serveOptions * @property array $serveOptions
* @property \Minify_Source_Factory $sourceFactory * @property Minify_Source_Factory $sourceFactory
* @property array $sourceFactoryOptions * @property array $sourceFactoryOptions
*/ */
class App extends Container class App extends Container
@@ -38,29 +49,29 @@ class App extends Container
$this->cache = function (App $app) use ($that) { $this->cache = function (App $app) use ($that) {
$config = $app->config; $config = $app->config;
if ($config->cachePath instanceof \Minify_CacheInterface) { if ($config->cachePath instanceof Minify_CacheInterface) {
return $config->cachePath; return $config->cachePath;
} }
if (!$config->cachePath || is_string($config->cachePath)) { if (!$config->cachePath || is_string($config->cachePath)) {
return new \Minify_Cache_File($config->cachePath, $config->cacheFileLocking, $app->logger); return new Minify_Cache_File($config->cachePath, $config->cacheFileLocking, $app->logger);
} }
$type = $that->typeOf($config->cachePath); $type = $that->typeOf($config->cachePath);
throw new \RuntimeException('$min_cachePath must be a path or implement Minify_CacheInterface.' throw new RuntimeException('$min_cachePath must be a path or implement Minify_CacheInterface.'
. " Given $type"); . " Given $type");
}; };
$this->config = function (App $app) { $this->config = function (App $app) {
$config = (require $app->configPath); $config = (require $app->configPath);
if ($config instanceof \Minify\Config) { if ($config instanceof Minify\Config) {
return $config; return $config;
} }
// copy from vars into properties // copy from vars into properties
$config = new \Minify\Config(); $config = new Minify\Config();
$propNames = array_keys(get_object_vars($config)); $propNames = array_keys(get_object_vars($config));
@@ -69,6 +80,12 @@ class App extends Container
}; };
$varNames = array_map($prefixer, $propNames); $varNames = array_map($prefixer, $propNames);
$varDefined = get_defined_vars();
$varNames = array_filter($varNames, function ($name) use ($varDefined) {
return array_key_exists($name, $varDefined);
});
$vars = compact($varNames); $vars = compact($varNames);
foreach ($varNames as $varName) { foreach ($varNames as $varName) {
@@ -94,18 +111,18 @@ class App extends Container
$config = $app->config; $config = $app->config;
if (empty($config->factories['controller'])) { if (empty($config->factories['controller'])) {
$ctrl = new \Minify_Controller_MinApp($app->env, $app->sourceFactory, $app->logger); $ctrl = new Minify_Controller_MinApp($app->env, $app->sourceFactory, $app->logger);
} else { } else {
$ctrl = call_user_func($config->factories['controller'], $app); $ctrl = call_user_func($config->factories['controller'], $app);
} }
if ($ctrl instanceof \Minify_ControllerInterface) { if ($ctrl instanceof Minify_ControllerInterface) {
return $ctrl; return $ctrl;
} }
$type = $that->typeOf($ctrl); $type = $that->typeOf($ctrl);
throw new \RuntimeException('$min_factories["controller"] callable must return an implementation' throw new RuntimeException('$min_factories["controller"] callable must return an implementation'
." of Minify_CacheInterface. Returned $type"); . " of Minify_CacheInterface. Returned $type");
}; };
$this->docRoot = function (App $app) { $this->docRoot = function (App $app) {
@@ -118,13 +135,13 @@ class App extends Container
}; };
$this->env = function (App $app) { $this->env = function (App $app) {
return new \Minify_Env($app->config->envArgs); return new Minify_Env($app->config->envArgs);
}; };
$this->errorLogHandler = function (App $app) { $this->errorLogHandler = function (App $app) {
$format = "%channel%.%level_name%: %message% %context% %extra%"; $format = "%channel%.%level_name%: %message% %context% %extra%";
$handler = new \Monolog\Handler\ErrorLogHandler(); $handler = new Monolog\Handler\ErrorLogHandler();
$handler->setFormatter(new \Monolog\Formatter\LineFormatter($format)); $handler->setFormatter(new Monolog\Formatter\LineFormatter($format));
return $handler; return $handler;
}; };
@@ -138,11 +155,11 @@ class App extends Container
$this->logger = function (App $app) use ($that) { $this->logger = function (App $app) use ($that) {
$value = $app->config->errorLogger; $value = $app->config->errorLogger;
if ($value instanceof \Psr\Log\LoggerInterface) { if ($value instanceof LoggerInterface) {
return $value; return $value;
} }
$logger = new \Monolog\Logger('minify'); $logger = new Monolog\Logger('minify');
if (!$value) { if (!$value) {
return $logger; return $logger;
@@ -150,12 +167,12 @@ class App extends Container
if ($value === true || $value instanceof \FirePHP) { if ($value === true || $value instanceof \FirePHP) {
$logger->pushHandler($app->errorLogHandler); $logger->pushHandler($app->errorLogHandler);
$logger->pushHandler(new \Monolog\Handler\FirePHPHandler()); $logger->pushHandler(new Monolog\Handler\FirePHPHandler());
return $logger; return $logger;
} }
if ($value instanceof \Monolog\Handler\HandlerInterface) { if ($value instanceof Monolog\Handler\HandlerInterface) {
$logger->pushHandler($value); $logger->pushHandler($value);
return $logger; return $logger;
@@ -163,15 +180,15 @@ class App extends Container
// BC // BC
if (is_object($value) && is_callable(array($value, 'log'))) { if (is_object($value) && is_callable(array($value, 'log'))) {
$handler = new \Minify\Logger\LegacyHandler($value); $handler = new Minify\Logger\LegacyHandler($value);
$logger->pushHandler($handler); $logger->pushHandler($handler);
return $logger; return $logger;
} }
$type = $that->typeOf($value); $type = $that->typeOf($value);
throw new \RuntimeException('If set, $min_errorLogger must be a PSR-3 logger or a Monolog handler.' throw new RuntimeException('If set, $min_errorLogger must be a PSR-3 logger or a Monolog handler.'
." Given $type"); . " Given $type");
}; };
$this->minify = function (App $app) use ($that) { $this->minify = function (App $app) use ($that) {
@@ -187,8 +204,8 @@ class App extends Container
} }
$type = $that->typeOf($minify); $type = $that->typeOf($minify);
throw new \RuntimeException('$min_factories["minify"] callable must return a Minify object.' throw new RuntimeException('$min_factories["minify"] callable must return a Minify object.'
." Returned $type"); . " Returned $type");
}; };
$this->serveOptions = function (App $app) { $this->serveOptions = function (App $app) {
@@ -207,7 +224,7 @@ class App extends Container
} }
if ($config->allowDebugFlag) { if ($config->allowDebugFlag) {
$ret['debug'] = \Minify_DebugDetector::shouldDebugRequest($env); $ret['debug'] = Minify_DebugDetector::shouldDebugRequest($env);
} }
if ($config->concatOnly) { if ($config->concatOnly) {
@@ -215,7 +232,7 @@ class App extends Container
} }
// check for URI versioning // check for URI versioning
if ($env->get('v') !== null || preg_match('/&\\d/', $app->env->server('QUERY_STRING'))) { if ($env->get('v') !== null || preg_match('/&\\d/', $app->env->server('QUERY_STRING') ?? '')) {
$ret['maxAge'] = 31536000; $ret['maxAge'] = 31536000;
} }
@@ -228,7 +245,7 @@ class App extends Container
}; };
$this->sourceFactory = function (App $app) { $this->sourceFactory = function (App $app) {
return new \Minify_Source_Factory($app->env, $app->sourceFactoryOptions, $app->cache); return new Minify_Source_Factory($app->env, $app->sourceFactoryOptions, $app->cache);
}; };
$this->sourceFactoryOptions = function (App $app) { $this->sourceFactoryOptions = function (App $app) {

View File

@@ -80,7 +80,6 @@ class Minify_Build
* *
* @param array $sources array of Minify_Source objects and/or file paths * @param array $sources array of Minify_Source objects and/or file paths
* *
* @return null
*/ */
public function __construct($sources) public function __construct($sources)
{ {

View File

@@ -91,8 +91,8 @@ class Minify_CSS
$symlinks = $options['symlinks']; $symlinks = $options['symlinks'];
return Minify_CSS_UriRewriter::rewrite($css, $currentDir, $docRoot, $symlinks); return Minify_CSS_UriRewriter::rewrite($css, $currentDir, $docRoot, $symlinks);
} else {
return Minify_CSS_UriRewriter::prepend($css, $options['prependRelativePath']);
} }
return Minify_CSS_UriRewriter::prepend($css, $options['prependRelativePath']);
} }
} }

View File

@@ -259,7 +259,7 @@ class Minify_CSS_Compressor
{ {
// Issue 210: must not eliminate WS between words in unquoted families // Issue 210: must not eliminate WS between words in unquoted families
$flags = PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY; $flags = PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY;
$pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, $flags); $pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], -1, $flags);
$out = 'font-family:'; $out = 'font-family:';
while (null !== ($piece = array_shift($pieces))) { while (null !== ($piece = array_shift($pieces))) {

View File

@@ -73,16 +73,16 @@ class Minify_CSSmin
} }
if ($options['currentDir']) { if ($options['currentDir']) {
return Minify_CSS_UriRewriter::rewrite( return Minify_CSS_UriRewriter::rewrite(
$css $css,
,$options['currentDir'] $options['currentDir'],
,$options['docRoot'] $options['docRoot'],
,$options['symlinks'] $options['symlinks']
);
} else {
return Minify_CSS_UriRewriter::prepend(
$css
,$options['prependRelativePath']
); );
} }
return Minify_CSS_UriRewriter::prepend(
$css,
$options['prependRelativePath']
);
} }
} }

View File

@@ -13,6 +13,8 @@
* *
* @package Minify * @package Minify
* @author Chris Edwards * @author Chris Edwards
*
* @deprecated Use Minify_Cache_APCu
**/ **/
class Minify_Cache_APC implements Minify_CacheInterface class Minify_Cache_APC implements Minify_CacheInterface
{ {

136
lib/Minify/Cache/APCu.php Normal file
View File

@@ -0,0 +1,136 @@
<?php
/**
* Class Minify_Cache_APCu
* @package Minify
*/
/**
* APCu-based cache class for Minify
*
* <code>
* Minify::setCache(new Minify_Cache_APCu());
* </code>
*
* @package Minify
* @author Chris Edwards
**/
class Minify_Cache_APCu implements Minify_CacheInterface
{
/**
* Create a Minify_Cache_APCu object, to be passed to
* Minify::setCache().
*
*
* @param int $expire seconds until expiration (default = 0
* meaning the item will not get an expiration date)
*
* @return null
*/
public function __construct($expire = 0)
{
$this->_exp = $expire;
}
/**
* Write data to cache.
*
* @param string $id cache id
*
* @param string $data
*
* @return bool success
*/
public function store($id, $data)
{
return apcu_store($id, "{$_SERVER['REQUEST_TIME']}|{$data}", $this->_exp);
}
/**
* Get the size of a cache entry
*
* @param string $id cache id
*
* @return int size in bytes
*/
public function getSize($id)
{
if (! $this->_fetch($id)) {
return false;
}
if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
return mb_strlen($this->_data, '8bit');
} else {
return strlen($this->_data);
}
}
/**
* Does a valid cache entry exist?
*
* @param string $id cache id
*
* @param int $srcMtime mtime of the original source file(s)
*
* @return bool exists
*/
public function isValid($id, $srcMtime)
{
return ($this->_fetch($id) && ($this->_lm >= $srcMtime));
}
/**
* Send the cached content to output
*
* @param string $id cache id
*/
public function display($id)
{
echo $this->_fetch($id) ? $this->_data : '';
}
/**
* Fetch the cached content
*
* @param string $id cache id
*
* @return string
*/
public function fetch($id)
{
return $this->_fetch($id) ? $this->_data : '';
}
private $_exp = null;
// cache of most recently fetched id
private $_lm = null;
private $_data = null;
private $_id = null;
/**
* Fetch data and timestamp from apcu, store in instance
*
* @param string $id
*
* @return bool success
*/
private function _fetch($id)
{
if ($this->_id === $id) {
return true;
}
$ret = apcu_fetch($id);
if (false === $ret) {
$this->_id = null;
return false;
}
list($this->_lm, $this->_data) = explode('|', $ret, 2);
$this->_id = $id;
return true;
}
}

View File

@@ -64,4 +64,4 @@ class Minify_Cache_Null implements Minify_CacheInterface
public function fetch($id) public function fetch($id)
{ {
} }
} }

View File

@@ -136,4 +136,4 @@ class Minify_Cache_WinCache implements Minify_CacheInterface
return true; return true;
} }
} }

View File

@@ -38,14 +38,14 @@ class Minify_ClosureCompiler
* *
* @var string * @var string
*/ */
public static $jarFile = null; public static $jarFile;
/** /**
* Writable temp directory. This must be set before calling minifyJs(). * Writable temp directory. This must be set before calling minifyJs().
* *
* @var string * @var string
*/ */
public static $tempDir = null; public static $tempDir;
/** /**
* Filepath of "java" executable (may be needed if not in shell's PATH) * Filepath of "java" executable (may be needed if not in shell's PATH)
@@ -129,7 +129,7 @@ class Minify_ClosureCompiler
$this->getOptionsCommandLine($userOptions) $this->getOptionsCommandLine($userOptions)
); );
return join(' ', $args) . ' ' . escapeshellarg($tmpFile); return implode(' ', $args) . ' ' . escapeshellarg($tmpFile);
} }
/** /**
@@ -188,7 +188,7 @@ class Minify_ClosureCompiler
*/ */
protected function checkTempdir($tempDir) protected function checkTempdir($tempDir)
{ {
if (!is_dir($tempDir)) { if ($tempDir === null || !is_dir($tempDir)) {
throw new Minify_ClosureCompiler_Exception('$tempDir(' . $tempDir . ') is not a valid direcotry.'); throw new Minify_ClosureCompiler_Exception('$tempDir(' . $tempDir . ') is not a valid direcotry.');
} }
if (!is_writable($tempDir)) { if (!is_writable($tempDir)) {

View File

@@ -68,4 +68,3 @@ class Minify_Controller_Files extends Minify_Controller_Base
return new Minify_ServeConfiguration($options, $sources); return new Minify_ServeConfiguration($options, $sources);
} }
} }

View File

@@ -48,7 +48,7 @@ class Minify_Controller_Groups extends Minify_Controller_Files
if (isset($server['ORIG_PATH_INFO'])) { if (isset($server['ORIG_PATH_INFO'])) {
$pathInfo = substr($server['ORIG_PATH_INFO'], 1); $pathInfo = substr($server['ORIG_PATH_INFO'], 1);
} elseif (isset($server['PATH_INFO'])) { } elseif (isset($server['PATH_INFO'])) {
$pathInfo = substr($server['PATH_INFO'], 1) $pathInfo = substr($server['PATH_INFO'], 1);
} else { } else {
$pathInfo = false; $pathInfo = false;
} }
@@ -73,4 +73,3 @@ class Minify_Controller_Groups extends Minify_Controller_Files
return parent::createConfiguration($options); return parent::createConfiguration($options);
} }
} }

View File

@@ -66,4 +66,3 @@ class Minify_Controller_Page extends Minify_Controller_Base
return new Minify_ServeConfiguration($options, $sources, $selectionId); return new Minify_ServeConfiguration($options, $sources, $selectionId);
} }
} }

View File

@@ -19,4 +19,4 @@ interface Minify_ControllerInterface
* @return Minify_Env * @return Minify_Env
*/ */
public function getEnv(); public function getEnv();
} }

View File

@@ -102,10 +102,10 @@ class Minify_Env
return $path; return $path;
} }
protected $server = null; protected $server;
protected $get = null; protected $get;
protected $post = null; protected $post;
protected $cookie = null; protected $cookie;
/** /**
* Compute $_SERVER['DOCUMENT_ROOT'] for IIS using SCRIPT_FILENAME and SCRIPT_NAME. * Compute $_SERVER['DOCUMENT_ROOT'] for IIS using SCRIPT_FILENAME and SCRIPT_NAME.

View File

@@ -22,6 +22,11 @@ class Minify_HTML
* @var boolean * @var boolean
*/ */
protected $_jsCleanComments = true; protected $_jsCleanComments = true;
/**
* @var string
*/
protected $_html;
/** /**
* "Minify" an HTML page * "Minify" an HTML page
@@ -99,64 +104,67 @@ class Minify_HTML
// replace SCRIPTs (and minify) with placeholders // replace SCRIPTs (and minify) with placeholders
$this->_html = preg_replace_callback( $this->_html = preg_replace_callback(
'/(\\s*)<script(\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i' '/(\\s*)<script(\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/iu',
,array($this, '_removeScriptCB') array($this, '_removeScriptCB'),
,$this->_html); $this->_html
);
// replace STYLEs (and minify) with placeholders // replace STYLEs (and minify) with placeholders
$this->_html = preg_replace_callback( $this->_html = preg_replace_callback(
'/\\s*<style(\\b[^>]*>)([\\s\\S]*?)<\\/style>\\s*/i' '/\\s*<style(\\b[^>]*>)([\\s\\S]*?)<\\/style>\\s*/iu',
,array($this, '_removeStyleCB') array($this, '_removeStyleCB'),
,$this->_html); $this->_html
);
// remove HTML comments (not containing IE conditional comments). // remove HTML comments (not containing IE conditional comments).
$this->_html = preg_replace_callback( $this->_html = preg_replace_callback(
'/<!--([\\s\\S]*?)-->/' '/<!--([\\s\\S]*?)-->/u',
,array($this, '_commentCB') array($this, '_commentCB'),
,$this->_html); $this->_html
);
// replace PREs with placeholders // replace PREs with placeholders
$this->_html = preg_replace_callback('/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i' $this->_html = preg_replace_callback('/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/iu', array($this, '_removePreCB'), $this->_html);
,array($this, '_removePreCB')
,$this->_html);
// replace TEXTAREAs with placeholders // replace TEXTAREAs with placeholders
$this->_html = preg_replace_callback( $this->_html = preg_replace_callback(
'/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i' '/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/iu',
,array($this, '_removeTextareaCB') array($this, '_removeTextareaCB'),
,$this->_html); $this->_html
);
// trim each line. // trim each line.
// @todo take into account attribute values that span multiple lines. // @todo take into account attribute values that span multiple lines.
$this->_html = preg_replace('/^\\s+|\\s+$/m', '', $this->_html); $this->_html = preg_replace('/^\\s+|\\s+$/mu', '', $this->_html);
// remove ws around block/undisplayed elements // remove ws around block/undisplayed elements
$this->_html = preg_replace('/\\s+(<\\/?(?:area|article|aside|base(?:font)?|blockquote|body' $this->_html = preg_replace('/\\s+(<\\/?(?:area|article|aside|base(?:font)?|blockquote|body'
.'|canvas|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|figcaption|figure|footer|form' .'|canvas|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|figcaption|figure|footer|form'
.'|frame(?:set)?|h[1-6]|head|header|hgroup|hr|html|legend|li|link|main|map|menu|meta|nav' .'|frame(?:set)?|h[1-6]|head|header|hgroup|hr|html|legend|li|link|main|map|menu|meta|nav'
.'|ol|opt(?:group|ion)|output|p|param|section|t(?:able|body|head|d|h||r|foot|itle)' .'|ol|opt(?:group|ion)|output|p|param|section|t(?:able|body|head|d|h||r|foot|itle)'
.'|ul|video)\\b[^>]*>)/i', '$1', $this->_html); .'|ul|video)\\b[^>]*>)/iu', '$1', $this->_html);
// remove ws outside of all elements // remove ws outside of all elements
$this->_html = preg_replace( $this->_html = preg_replace(
'/>(\\s(?:\\s*))?([^<]+)(\\s(?:\s*))?</' '/>(\\s(?:\\s*))?([^<]+)(\\s(?:\s*))?</u',
,'>$1$2$3<' '>$1$2$3<',
,$this->_html); $this->_html
);
// use newlines before 1st attribute in open tags (to limit line lengths) // use newlines before 1st attribute in open tags (to limit line lengths)
$this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html); $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/iu', "$1\n$2", $this->_html);
// fill placeholders // fill placeholders
$this->_html = str_replace( $this->_html = str_replace(
array_keys($this->_placeholders) array_keys($this->_placeholders),
,array_values($this->_placeholders) array_values($this->_placeholders),
,$this->_html $this->_html
); );
// issue 229: multi-pass to catch scripts that didn't get replaced in textareas // issue 229: multi-pass to catch scripts that didn't get replaced in textareas
$this->_html = str_replace( $this->_html = str_replace(
array_keys($this->_placeholders) array_keys($this->_placeholders),
,array_values($this->_placeholders) array_values($this->_placeholders),
,$this->_html $this->_html
); );
return $this->_html; return $this->_html;
@@ -164,7 +172,7 @@ class Minify_HTML
protected function _commentCB($m) protected function _commentCB($m)
{ {
return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<![')) return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<![') || 0 === strpos($m[1], '#'))
? $m[0] ? $m[0]
: ''; : '';
} }
@@ -177,11 +185,11 @@ class Minify_HTML
return $placeholder; return $placeholder;
} }
protected $_isXhtml = null; protected $_isXhtml;
protected $_replacementHash = null; protected $_replacementHash;
protected $_placeholders = array(); protected $_placeholders = array();
protected $_cssMinifier = null; protected $_cssMinifier;
protected $_jsMinifier = null; protected $_jsMinifier;
protected function _removePreCB($m) protected function _removePreCB($m)
{ {
@@ -198,7 +206,7 @@ class Minify_HTML
$openStyle = "<style{$m[1]}"; $openStyle = "<style{$m[1]}";
$css = $m[2]; $css = $m[2];
// remove HTML comments // remove HTML comments
$css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css); $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/u', '', $css);
// remove CDATA section markers // remove CDATA section markers
$css = $this->_removeCdata($css); $css = $this->_removeCdata($css);
@@ -209,7 +217,8 @@ class Minify_HTML
: 'trim'; : 'trim';
$css = call_user_func($minifier, $css); $css = call_user_func($minifier, $css);
return $this->_reservePlace($this->_needsCdata($css) return $this->_reservePlace(
$this->_needsCdata($css)
? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>" ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
: "{$openStyle}{$css}</style>" : "{$openStyle}{$css}</style>"
); );
@@ -226,7 +235,7 @@ class Minify_HTML
// remove HTML comments (and ending "//" if present) // remove HTML comments (and ending "//" if present)
if ($this->_jsCleanComments) { if ($this->_jsCleanComments) {
$js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js); $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/u', '', $js);
} }
// remove CDATA section markers // remove CDATA section markers
@@ -238,7 +247,8 @@ class Minify_HTML
: 'trim'; : 'trim';
$js = call_user_func($minifier, $js); $js = call_user_func($minifier, $js);
return $this->_reservePlace($this->_needsCdata($js) return $this->_reservePlace(
$this->_needsCdata($js)
? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}" ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
: "{$ws1}{$openScript}{$js}</script>{$ws2}" : "{$ws1}{$openScript}{$js}</script>{$ws2}"
); );
@@ -253,6 +263,6 @@ class Minify_HTML
protected function _needsCdata($str) protected function _needsCdata($str)
{ {
return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str)); return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/u', $str));
} }
} }

View File

@@ -32,15 +32,15 @@ class Minify_ImportProcessor
} }
// allows callback funcs to know the current directory // allows callback funcs to know the current directory
private $_currentDir = null; private $_currentDir;
// allows callback funcs to know the directory of the file that inherits this one // allows callback funcs to know the directory of the file that inherits this one
private $_previewsDir = null; private $_previewsDir;
// allows _importCB to write the fetched content back to the obj // allows _importCB to write the fetched content back to the obj
private $_importedContent = ''; private $_importedContent = '';
private static $_isCss = null; private static $_isCss;
/** /**
* @param String $currentDir * @param String $currentDir
@@ -66,7 +66,7 @@ class Minify_ImportProcessor
$this->_currentDir = dirname($file); $this->_currentDir = dirname($file);
// remove UTF-8 BOM if present // remove UTF-8 BOM if present
if (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) { if (pack("CCC", 0xef, 0xbb, 0xbf) === substr($content, 0, 3)) {
$content = substr($content, 3); $content = substr($content, 3);
} }
// ensure uniform EOLs // ensure uniform EOLs
@@ -182,7 +182,7 @@ class Minify_ImportProcessor
private function truepath($path) private function truepath($path)
{ {
// whether $path is unix or not // whether $path is unix or not
$unipath = (strlen($path) == 0) || ($path{0} != '/'); $unipath = ('' === $path) || ($path[0] !== '/');
// attempts to detect if path is relative in which case, add cwd // attempts to detect if path is relative in which case, add cwd
if (strpos($path, ':') === false && $unipath) { if (strpos($path, ':') === false && $unipath) {
@@ -194,10 +194,10 @@ class Minify_ImportProcessor
$parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
$absolutes = array(); $absolutes = array();
foreach ($parts as $part) { foreach ($parts as $part) {
if ('.' == $part) { if ('.' === $part) {
continue; continue;
} }
if ('..' == $part) { if ('..' === $part) {
array_pop($absolutes); array_pop($absolutes);
} else { } else {
$absolutes[] = $part; $absolutes[] = $part;

View File

@@ -54,7 +54,7 @@ class Minify_JS_ClosureCompiler
/** /**
* @var string $url URL of compiler server. defaults to Google's * @var string $url URL of compiler server. defaults to Google's
*/ */
protected $serviceUrl = 'http://closure-compiler.appspot.com/compile'; protected $serviceUrl = 'https://closure-compiler.appspot.com/compile';
/** /**
* @var int $maxBytes The maximum JS size that can be sent to the compiler server in bytes * @var int $maxBytes The maximum JS size that can be sent to the compiler server in bytes
@@ -174,6 +174,9 @@ class Minify_JS_ClosureCompiler
$contents = file_get_contents($this->serviceUrl, false, stream_context_create(array( $contents = file_get_contents($this->serviceUrl, false, stream_context_create(array(
'http' => array( 'http' => array(
'method' => 'POST', 'method' => 'POST',
'compilation_level' => 'SIMPLE',
'output_format' => 'text',
'output_info' => 'compiled_code',
'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close\r\n", 'header' => "Content-type: application/x-www-form-urlencoded\r\nConnection: close\r\n",
'content' => $postBody, 'content' => $postBody,
'max_redirects' => 0, 'max_redirects' => 0,
@@ -192,13 +195,13 @@ class Minify_JS_ClosureCompiler
curl_close($ch); curl_close($ch);
} else { } else {
throw new Minify_JS_ClosureCompiler_Exception( throw new Minify_JS_ClosureCompiler_Exception(
"Could not make HTTP request: allow_url_open is false and cURL not available" "Could not make HTTP request: allow_url_open is false and cURL not available"
); );
} }
if (false === $contents) { if (false === $contents) {
throw new Minify_JS_ClosureCompiler_Exception( throw new Minify_JS_ClosureCompiler_Exception(
"No HTTP response from server" "No HTTP response from server"
); );
} }

View File

@@ -49,7 +49,7 @@ class Minify_Lines
$newLines = array(); $newLines = array();
while (null !== ($line = array_shift($lines))) { while (null !== ($line = array_shift($lines))) {
if (('' !== $id) && (0 == $i % 50)) { if (('' !== $id) && (0 === $i % 50)) {
if ($inComment) { if ($inComment) {
array_push($newLines, '', "/* {$id} *|", ''); array_push($newLines, '', "/* {$id} *|", '');
} else { } else {

View File

@@ -63,7 +63,7 @@ class Minify_NailgunClosureCompiler extends Minify_ClosureCompiler
$server = array( $server = array(
self::$javaExecutable, self::$javaExecutable,
'-server', '-server',
'-cp', join(':', $classPath), '-cp', implode(':', $classPath),
self::NG_SERVER, self::NG_SERVER,
); );
@@ -101,13 +101,13 @@ class Minify_NailgunClosureCompiler extends Minify_ClosureCompiler
private function startServer() private function startServer()
{ {
$serverCommand = join(' ', $this->getServerCommandLine()); $serverCommand = implode(' ', $this->getServerCommandLine());
$psCommand = $this->shell("ps -o cmd= -C " . self::$javaExecutable); $psCommand = $this->shell("ps -o cmd= -C " . self::$javaExecutable);
if (array_search($serverCommand, $psCommand) !== false) { if (in_array($serverCommand, $psCommand, true)) {
// already started! // already started!
return; return;
} }
$this->shell("$serverCommand </dev/null >/dev/null 2>/dev/null & sleep 10"); $this->shell("$serverCommand </dev/null >/dev/null 2>/dev/null & sleep 10");
} }
} }

View File

@@ -1,7 +1,6 @@
<?php <?php
use Leafo\ScssPhp\Compiler; use ScssPhp\ScssPhp\Compiler;
use Leafo\ScssPhp\Server; use ScssPhp\ScssPhp\Version;
use Leafo\ScssPhp\Version;
/** /**
* Class for using SCSS files * Class for using SCSS files
@@ -152,12 +151,12 @@ class Minify_ScssCssSource extends Minify_Source
// and will treat the @import line as css import // and will treat the @import line as css import
$scss->setImportPaths(dirname($filename)); $scss->setImportPaths(dirname($filename));
$css = $scss->compile(file_get_contents($filename), $filename); $css = $scss->compileString(file_get_contents($filename), $filename)->getCss();
$elapsed = round((microtime(true) - $start), 4); $elapsed = round((microtime(true) - $start), 4);
$v = Version::VERSION; $v = Version::VERSION;
$ts = date('r', $start); $ts = date('r', (int) $start);
$css = "/* compiled by scssphp $v on $ts (${elapsed}s) */\n\n" . $css; $css = "/* compiled by scssphp $v on $ts ({$elapsed}s) */\n\n" . $css;
$imports = $scss->getParsedFiles(); $imports = $scss->getParsedFiles();

View File

@@ -19,12 +19,12 @@ class Minify_Source implements Minify_SourceInterface
/** /**
* @var int time of last modification * @var int time of last modification
*/ */
protected $lastModified = null; protected $lastModified;
/** /**
* @var callback minifier function specifically for this source. * @var callback minifier function specifically for this source.
*/ */
protected $minifier = null; protected $minifier;
/** /**
* @var array minification options specific to this source. * @var array minification options specific to this source.
@@ -34,27 +34,27 @@ class Minify_Source implements Minify_SourceInterface
/** /**
* @var string full path of file * @var string full path of file
*/ */
protected $filepath = null; protected $filepath;
/** /**
* @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*) * @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*)
*/ */
protected $contentType = null; protected $contentType;
/** /**
* @var string * @var string
*/ */
protected $content = null; protected $content;
/** /**
* @var callable * @var callable
*/ */
protected $getContentFunc = null; protected $getContentFunc;
/** /**
* @var string * @var string
*/ */
protected $id = null; protected $id;
/** /**
* Create a Minify_Source * Create a Minify_Source
@@ -137,7 +137,7 @@ class Minify_Source implements Minify_SourceInterface
$minifier = 'Minify::nullMinifier'; $minifier = 'Minify::nullMinifier';
} }
if ($minifier !== null && !is_callable($minifier, true)) { if ($minifier !== null && !is_callable($minifier, true)) {
throw new \InvalidArgumentException('minifier must be null or a valid callable'); throw new InvalidArgumentException('minifier must be null or a valid callable');
} }
$this->minifier = $minifier; $this->minifier = $minifier;
} }
@@ -180,8 +180,13 @@ class Minify_Source implements Minify_SourceInterface
} else { } else {
$content = file_get_contents($this->filepath); $content = file_get_contents($this->filepath);
} }
// remove UTF-8 BOM if present // remove UTF-8 BOM if present
return ("\xEF\xBB\xBF" === substr($content, 0, 3)) ? substr($content, 3) : $content; if (strpos($content, "\xEF\xBB\xBF") === 0) {
return substr($content, 3);
}
return $content;
} }
/** /**

View File

@@ -170,7 +170,7 @@ class Minify_Source_Factory
if ($this->options['noMinPattern'] && preg_match($this->options['noMinPattern'], $basename)) { if ($this->options['noMinPattern'] && preg_match($this->options['noMinPattern'], $basename)) {
if (preg_match('~\.(css|less)$~i', $basename)) { if (preg_match('~\.(css|less)$~i', $basename)) {
$spec['minifyOptions']['compress'] = false; $spec['minifyOptions']['compress'] = false;
// we still want URI rewriting to work for CSS // we still want URI rewriting to work for CSS
} else { } else {
$spec['minifier'] = 'Minify::nullMinifier'; $spec['minifier'] = 'Minify::nullMinifier';
} }

View File

@@ -38,7 +38,7 @@ class Minify_YUICompressor
* *
* @var string * @var string
*/ */
public static $jarFile = null; public static $jarFile;
/** /**
* Writable temp directory. This must be set before calling minifyJs() * Writable temp directory. This must be set before calling minifyJs()
@@ -46,7 +46,7 @@ class Minify_YUICompressor
* *
* @var string * @var string
*/ */
public static $tempDir = null; public static $tempDir;
/** /**
* Filepath of "java" executable (may be needed if not in shell's PATH) * Filepath of "java" executable (may be needed if not in shell's PATH)
@@ -154,4 +154,3 @@ class Minify_YUICompressor
} }
} }
} }

View File

@@ -390,4 +390,3 @@ class Cli
$this->errors[$letter][] = sprintf($msg, $value); $this->errors[$letter][] = sprintf($msg, $value);
} }
} }

View File

@@ -27,7 +27,7 @@ $outfile = $cli->values['o'];
$testRun = $cli->values['t']; $testRun = $cli->values['t'];
$docRoot = $cli->values['d']; $docRoot = $cli->values['d'];
$pathRewriter = function($css, $options) { $pathRewriter = function ($css, $options) {
return Minify_CSS_UriRewriter::rewrite($css, $options['currentDir'], $options['docRoot']); return Minify_CSS_UriRewriter::rewrite($css, $options['currentDir'], $options['docRoot']);
}; };
@@ -54,9 +54,8 @@ $combined = Minify::combine($sources) . "\n";
if ($testRun) { if ($testRun) {
echo $combined; echo $combined;
echo Minify_CSS_UriRewriter::$debugText . "\n"; echo Minify_CSS_UriRewriter::$debugText . "\n";
} else { } else {
$fp = $cli->openOutput(); $fp = $cli->openOutput();
fwrite($fp, $combined); fwrite($fp, $combined);
$cli->closeOutput(); $cli->closeOutput();
} }

View File

@@ -4,6 +4,6 @@
require __DIR__ . '/../config.php'; require __DIR__ . '/../config.php';
$minifyCachePath = isset($min_cachePath) $minifyCachePath = isset($min_cachePath)
? $min_cachePath ? $min_cachePath
: ''; : '';

View File

@@ -13,7 +13,8 @@ $app->cache = new Minify_Cache_Null();
$env = $app->env; $env = $app->env;
function h($txt) { function h($txt)
{
return htmlspecialchars($txt, ENT_QUOTES, 'UTF-8'); return htmlspecialchars($txt, ENT_QUOTES, 'UTF-8');
} }
@@ -22,13 +23,12 @@ if ($env->post('textIn')) {
} }
if ($env->post('method') === 'Minify and serve') { if ($env->post('method') === 'Minify and serve') {
$base = trim($env->post('base')); $base = trim($env->post('base'));
if ($base) { if ($base) {
$textIn = preg_replace( $textIn = preg_replace(
'@(<head\\b[^>]*>)@i' '@(<head\\b[^>]*>)@i',
,'$1<base href="' . h($base) . '" />' '$1<base href="' . h($base) . '" />',
,$textIn $textIn
); );
} }
@@ -58,7 +58,6 @@ $tpl = array();
$tpl['classes'] = array('Minify_HTML', 'JSMin\\JSMin', 'Minify_CSS', 'Minify_Lines'); $tpl['classes'] = array('Minify_HTML', 'JSMin\\JSMin', 'Minify_CSS', 'Minify_Lines');
if (in_array($env->post('method'), $tpl['classes'])) { if (in_array($env->post('method'), $tpl['classes'])) {
$args = array($textIn); $args = array($textIn);
if ($env->post('method') === 'Minify_HTML') { if ($env->post('method') === 'Minify_HTML') {
$args[] = array( $args[] = array(
@@ -88,7 +87,8 @@ sendPage($tpl);
* @param string $input * @param string $input
* @return string HTML * @return string HTML
*/ */
function getExceptionMsg(Exception $e, $input) { function getExceptionMsg(Exception $e, $input)
{
$msg = "<p>" . h($e->getMessage()) . "</p>"; $msg = "<p>" . h($e->getMessage()) . "</p>";
if (0 === strpos(get_class($e), 'JSMin_Unterminated') if (0 === strpos(get_class($e), 'JSMin_Unterminated')
&& preg_match('~byte (\d+)~', $e->getMessage(), $m)) { && preg_match('~byte (\d+)~', $e->getMessage(), $m)) {
@@ -113,37 +113,35 @@ function getExceptionMsg(Exception $e, $input) {
* *
* @param array $vars * @param array $vars
*/ */
function sendPage($vars) { function sendPage($vars)
header('Content-Type: text/html; charset=utf-8'); {
?> header('Content-Type: text/html; charset=utf-8'); ?>
<!DOCTYPE html><head><title>minifyTextarea</title></head> <!DOCTYPE html><head><title>minifyTextarea</title></head>
<p><strong>Warning! Please do not place this application on a public site.</strong> This should be used only for testing.</p> <p><strong>Warning! Please do not place this application on a public site.</strong> This should be used only for testing.</p>
<?php <?php
if (isset($vars['exceptionMsg'])) { if (isset($vars['exceptionMsg'])) {
echo $vars['exceptionMsg']; echo $vars['exceptionMsg'];
} }
if (isset($vars['time'])) { if (isset($vars['time'])) {
echo " echo "
<table> <table>
<tr><th>Bytes in</th><td>{$vars['inBytes']} (after line endings normalized to <code>\\n</code>)</td></tr> <tr><th>Bytes in</th><td>{$vars['inBytes']} (after line endings normalized to <code>\\n</code>)</td></tr>
<tr><th>Bytes out</th><td>{$vars['outBytes']} (reduced " . round(100 - (100 * $vars['outBytes'] / $vars['inBytes'])) . "%)</td></tr> <tr><th>Bytes out</th><td>{$vars['outBytes']} (reduced " . round(100 - (100 * $vars['outBytes'] / $vars['inBytes'])) . "%)</td></tr>
<tr><th>Time (s)</th><td>" . round($vars['time'], 5) . "</td></tr> <tr><th>Time (s)</th><td>" . round($vars['time'], 5) . "</td></tr>
</table> </table>
"; ";
} } ?>
?>
<form action="?2" method="post"> <form action="?2" method="post">
<p><label>Content<br><textarea name="textIn" cols="80" rows="35" style="width:99%"><?php <p><label>Content<br><textarea name="textIn" cols="80" rows="35" style="width:99%"><?php
if (isset($vars['output'])) { if (isset($vars['output'])) {
echo h($vars['output']); echo h($vars['output']);
} } ?></textarea></label></p>
?></textarea></label></p>
<p>Minify with: <p>Minify with:
<?php foreach ($vars['classes'] as $minClass): ?> <?php foreach ($vars['classes'] as $minClass): ?>
<input type="submit" name="method" value="<?php echo $minClass; ?>"> <input type="submit" name="method" value="<?php echo $minClass; ?>">
<?php endForEach; ?> <?php endforeach; ?>
</p> </p>
<p>...or <input type="submit" name="method" value="Minify and serve"> this HTML to the browser. Also minify: <p>...or <input type="submit" name="method" value="Minify and serve"> this HTML to the browser. Also minify:
<label>CSS <input type="checkbox" name="minCss" checked></label> : <label>CSS <input type="checkbox" name="minCss" checked></label> :

View File

@@ -12,23 +12,26 @@ $app->cache = new Minify_Cache_Null();
$env = $app->env; $env = $app->env;
function getPost($key) { function getPost($key)
{
if (! isset($_POST[$key])) { if (! isset($_POST[$key])) {
return null; return null;
} }
return get_magic_quotes_gpc() return (PHP_VERSION_ID < 50400 && get_magic_quotes_gpc())
? stripslashes($_POST[$key]) ? stripslashes($_POST[$key])
: $_POST[$key]; : $_POST[$key];
} }
function sniffType($headers) { function sniffType($headers)
{
$charset = 'utf-8'; $charset = 'utf-8';
$type = null; $type = null;
$headers = "\n\n" . implode("\n\n", $headers) . "\n\n"; $headers = "\n\n" . implode("\n\n", $headers) . "\n\n";
if (preg_match( if (preg_match(
'@\\n\\nContent-Type: *([\\w/\\+-]+)( *; *charset *= *([\\w-]+))? *\\n\\n@i' '@\\n\\nContent-Type: *([\\w/\\+-]+)( *; *charset *= *([\\w-]+))? *\\n\\n@i',
,$headers $headers,
,$m)) { $m
)) {
$sentType = $m[1]; $sentType = $m[1];
if (isset($m[3])) { if (isset($m[3])) {
$charset = $m[3]; $charset = $m[3];
@@ -49,7 +52,6 @@ function sniffType($headers) {
} }
if (isset($_POST['url'])) { if (isset($_POST['url'])) {
require '../config.php'; require '../config.php';
$url = trim($env->post('url')); $url = trim($env->post('url'));
@@ -88,13 +90,13 @@ if (isset($_POST['url'])) {
die('Unrecognized Content-Type: ' . $type['sent']); die('Unrecognized Content-Type: ' . $type['sent']);
} }
if ($type['minify'] === 'text/html' if ($type['minify'] === 'text/html'
&& isset($_POST['addBase']) && isset($_POST['addBase'])
&& ! preg_match('@<base\\b@i', $content)) { && ! preg_match('@<base\\b@i', $content)) {
$content = preg_replace( $content = preg_replace(
'@(<head\\b[^>]*>)@i' '@(<head\\b[^>]*>)@i',
,'$1<base href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" />' '$1<base href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" />',
,$content $content
); );
} }

View File

@@ -8,9 +8,13 @@ $env = $app->env;
header('Content-Type: text/html;charset=utf-8'); header('Content-Type: text/html;charset=utf-8');
function h($str) { return htmlspecialchars($str, ENT_QUOTES); } function h($str)
{
return htmlspecialchars($str, ENT_QUOTES);
}
function getInput($name, $default = '', $size = 50) { function getInput($name, $default = '', $size = 50)
{
global $env; global $env;
$val = $env->post($name, $default); $val = $env->post($name, $default);
return "<input type='text' name='{$name}' value='" . h($val) . "' size='{$size}' />"; return "<input type='text' name='{$name}' value='" . h($val) . "' size='{$size}' />";

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- http://phpunit.de/manual/current/en/appendixes.configuration.html --> <!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit <phpunit
backupGlobals="false" backupGlobals="false"
backupStaticAttributes="false" backupStaticAttributes="false"
@@ -10,7 +10,6 @@
convertWarningsToExceptions="true" convertWarningsToExceptions="true"
processIsolation="false" processIsolation="false"
stopOnFailure="false" stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"> bootstrap="vendor/autoload.php">
<testsuites> <testsuites>
@@ -32,6 +31,7 @@
<directory>.</directory> <directory>.</directory>
<exclude> <exclude>
<directory>tests</directory> <directory>tests</directory>
<directory>vendor</directory>
</exclude> </exclude>
</whitelist> </whitelist>
</filter> </filter>

View File

@@ -13,7 +13,8 @@ if (!$enabled) {
die('Set $enabled to true to see server info.'); die('Set $enabled to true to see server info.');
} }
function assertTrue($test, $message) { function assertTrue($test, $message)
{
if (!$test) { if (!$test) {
echo "Warning: $message\n"; echo "Warning: $message\n";
} }

View File

@@ -7,12 +7,12 @@ if (is_file(__DIR__ . '/bootstrap.php')) {
$bootstrap_file = __DIR__ . '/../bootstrap.php'; $bootstrap_file = __DIR__ . '/../bootstrap.php';
} }
$send_400 = function($content = 'Bad URL') { $send_400 = function ($content = 'Bad URL') {
http_response_code(400); http_response_code(400);
die($content); die($content);
}; };
$send_301 = function($url) { $send_301 = function ($url) {
http_response_code(301); http_response_code(301);
header("Cache-Control: max-age=31536000"); header("Cache-Control: max-age=31536000");
header("Location: $url"); header("Location: $url");

View File

@@ -10,7 +10,8 @@ namespace Minify\StaticService;
* @param string $type "css" or "js" * @param string $type "css" or "js"
* @return string * @return string
*/ */
function build_uri($static_uri, $query, $type) { function build_uri($static_uri, $query, $type)
{
$static_uri = rtrim($static_uri, '/'); $static_uri = rtrim($static_uri, '/');
$query = ltrim($query, '?'); $query = ltrim($query, '?');
@@ -30,7 +31,8 @@ function build_uri($static_uri, $query, $type) {
* @param bool $auto_create Automatically create the directory if missing? * @param bool $auto_create Automatically create the directory if missing?
* @return null|string null if missing or can't create * @return null|string null if missing or can't create
*/ */
function get_cache_time($auto_create = true) { function get_cache_time($auto_create = true)
{
foreach (scandir(__DIR__) as $entry) { foreach (scandir(__DIR__) as $entry) {
if (ctype_digit($entry)) { if (ctype_digit($entry)) {
return $entry; return $entry;
@@ -50,14 +52,16 @@ function get_cache_time($auto_create = true) {
return $time; return $time;
} }
function flush_cache() { function flush_cache()
{
$time = get_cache_time(false); $time = get_cache_time(false);
if ($time) { if ($time) {
remove_tree(__DIR__ . "/$time"); remove_tree(__DIR__ . "/$time");
} }
} }
function remove_tree($dir) { function remove_tree($dir)
{
$files = array_diff(scandir($dir), array('.', '..')); $files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) { foreach ($files as $file) {

View File

@@ -1,5 +1,9 @@
<?php <?php
namespace Minify\Test;
use HTTP_ConditionalGet;
class HTTPConditionalGetTest extends TestCase class HTTPConditionalGetTest extends TestCase
{ {
public function TestData() public function TestData()
@@ -123,7 +127,7 @@ class HTTPConditionalGetTest extends TestCase
if (null === $inm) { if (null === $inm) {
unset($_SERVER['HTTP_IF_NONE_MATCH']); unset($_SERVER['HTTP_IF_NONE_MATCH']);
} else { } else {
$_SERVER['HTTP_IF_NONE_MATCH'] = get_magic_quotes_gpc() $_SERVER['HTTP_IF_NONE_MATCH'] = PHP_VERSION_ID < 50400 && get_magic_quotes_gpc()
? addslashes($inm) : ? addslashes($inm) :
$inm; $inm;
} }

View File

@@ -1,9 +1,13 @@
<?php <?php
namespace Minify\Test;
use HTTP_Encoder;
class HTTPEncoderTest extends TestCase class HTTPEncoderTest extends TestCase
{ {
/** /**
* @dataProvider testToIe6Data * @dataProvider ToIe6DataProvider
* @preserveGlobals * @preserveGlobals
*/ */
public function testToIe6($ua, $ae, $exp, $desc) public function testToIe6($ua, $ae, $exp, $desc)
@@ -16,7 +20,7 @@ class HTTPEncoderTest extends TestCase
$this->assertSame($exp, $ret, $desc); $this->assertSame($exp, $ret, $desc);
} }
public function testToIe6Data() public function ToIe6DataProvider()
{ {
return array( return array(
array( array(
@@ -65,7 +69,7 @@ class HTTPEncoderTest extends TestCase
} }
/** /**
* @dataProvider testEncodeNonIeData * @dataProvider EncodeNonIeDataProvider
*/ */
public function testEncodeNonIe($ua, $ae, $exp, $desc) public function testEncodeNonIe($ua, $ae, $exp, $desc)
{ {
@@ -77,7 +81,7 @@ class HTTPEncoderTest extends TestCase
$this->assertSame($exp, $ret, $desc); $this->assertSame($exp, $ret, $desc);
} }
public function testEncodeNonIeData() public function EncodeNonIeDataProvider()
{ {
return array( return array(
array( array(
@@ -104,20 +108,22 @@ class HTTPEncoderTest extends TestCase
$encodingTests = array( $encodingTests = array(
array('method' => 'deflate', 'inv' => 'gzinflate', 'exp' => 32268), array('method' => 'deflate', 'inv' => 'gzinflate', 'exp' => 32268),
array('method' => 'gzip', 'inv' => '_gzdecode', 'exp' => 32286), array('method' => 'gzip', 'inv' => __NAMESPACE__ . '\\_gzdecode', 'exp' => 32286),
array('method' => 'compress', 'inv' => 'gzuncompress', 'exp' => 32325), array('method' => 'compress', 'inv' => 'gzuncompress', 'exp' => 32325),
); );
foreach ($encodingTests as $test) { foreach ($encodingTests as $test) {
$e = new HTTP_Encoder(array( $e = new HTTP_Encoder(
'content' => $variedContent, array(
'method' => $test['method'], 'content' => $variedContent,
)); 'method' => $test['method'],
)
);
$e->encode(9); $e->encode(9);
$ret = $this->countBytes($e->getContent()); $ret = $this->countBytes($e->getContent());
// test uncompression // test uncompression
$roundTrip = @call_user_func($test['inv'], $e->getContent()); $roundTrip = call_user_func($test['inv'], $e->getContent());
$desc = "{$test['method']} : uncompress possible"; $desc = "{$test['method']} : uncompress possible";
$this->assertSame($variedContent, $roundTrip, $desc); $this->assertSame($variedContent, $roundTrip, $desc);
@@ -149,12 +155,12 @@ function _gzdecode($data)
} }
// http://www.php.net/manual/en/function.gzdecode.php#82930 // http://www.php.net/manual/en/function.gzdecode.php#82930
function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null) function _phpman_gzdecode($data, &$filename = '', &$error = '', $maxlength = 0)
{ {
$mbIntEnc = null; $mbIntEnc = null;
$hasMbOverload = (function_exists('mb_strlen') $hasMbOverload = (function_exists('mb_strlen')
&& (ini_get('mbstring.func_overload') !== '') && (ini_get('mbstring.func_overload') !== '')
&& ((int)ini_get('mbstring.func_overload') & 2)); && ((int) ini_get('mbstring.func_overload') & 2));
if ($hasMbOverload) { if ($hasMbOverload) {
$mbIntEnc = mb_internal_encoding(); $mbIntEnc = mb_internal_encoding();
mb_internal_encoding('8bit'); mb_internal_encoding('8bit');
@@ -162,15 +168,15 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
$len = strlen($data); $len = strlen($data);
if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) { if ($len < 18 || strcmp(substr($data, 0, 2), "\x1f\x8b")) {
$error = "Not in GZIP format."; $error = "Not in GZIP format.";
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
mb_internal_encoding($mbIntEnc); mb_internal_encoding($mbIntEnc);
} }
return null; // Not GZIP format (See RFC 1952) return null; // Not GZIP format (See RFC 1952)
} }
$method = ord(substr($data,2,1)); // Compression method $method = ord(substr($data, 2, 1)); // Compression method
$flags = ord(substr($data,3,1)); // Flags $flags = ord(substr($data, 3, 1)); // Flags
if ($flags & 31 != $flags) { if ($flags & 31 != $flags) {
$error = "Reserved bits not allowed."; $error = "Reserved bits not allowed.";
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
@@ -179,13 +185,13 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
return null; return null;
} }
// NOTE: $mtime may be negative (PHP integer limitations) // NOTE: $mtime may be negative (PHP integer limitations)
$mtime = unpack("V", substr($data,4,4)); $mtime = unpack("V", substr($data, 4, 4));
$mtime = $mtime[1]; $mtime = $mtime[1];
$xfl = substr($data,8,1); $xfl = substr($data, 8, 1);
$os = substr($data,8,1); $os = substr($data, 8, 1);
$headerlen = 10; $headerlen = 10;
$extralen = 0; $extralen = 0;
$extra = ""; $extra = "";
if ($flags & 4) { if ($flags & 4) {
// 2-byte length prefixed EXTRA data in header // 2-byte length prefixed EXTRA data in header
if ($len - $headerlen - 2 < 8) { if ($len - $headerlen - 2 < 8) {
@@ -194,7 +200,7 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
} }
return false; // invalid return false; // invalid
} }
$extralen = unpack("v",substr($data,8,2)); $extralen = unpack("v", substr($data, 8, 2));
$extralen = $extralen[1]; $extralen = $extralen[1];
if ($len - $headerlen - 2 - $extralen < 8) { if ($len - $headerlen - 2 - $extralen < 8) {
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
@@ -202,7 +208,7 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
} }
return false; // invalid return false; // invalid
} }
$extra = substr($data,10,$extralen); $extra = substr($data, 10, $extralen);
$headerlen += 2 + $extralen; $headerlen += 2 + $extralen;
} }
$filenamelen = 0; $filenamelen = 0;
@@ -215,14 +221,14 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
} }
return false; // invalid return false; // invalid
} }
$filenamelen = strpos(substr($data,$headerlen),chr(0)); $filenamelen = strpos(substr($data, $headerlen), chr(0));
if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) { if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) {
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
mb_internal_encoding($mbIntEnc); mb_internal_encoding($mbIntEnc);
} }
return false; // invalid return false; // invalid
} }
$filename = substr($data,$headerlen,$filenamelen); $filename = substr($data, $headerlen, $filenamelen);
$headerlen += $filenamelen + 1; $headerlen += $filenamelen + 1;
} }
$commentlen = 0; $commentlen = 0;
@@ -235,14 +241,14 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
} }
return false; // invalid return false; // invalid
} }
$commentlen = strpos(substr($data,$headerlen),chr(0)); $commentlen = strpos(substr($data, $headerlen), chr(0));
if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) { if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) {
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
mb_internal_encoding($mbIntEnc); mb_internal_encoding($mbIntEnc);
} }
return false; // Invalid header format return false; // Invalid header format
} }
$comment = substr($data,$headerlen,$commentlen); $comment = substr($data, $headerlen, $commentlen);
$headerlen += $commentlen + 1; $headerlen += $commentlen + 1;
} }
$headercrc = ""; $headercrc = "";
@@ -254,8 +260,8 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
} }
return false; // invalid return false; // invalid
} }
$calccrc = crc32(substr($data,0,$headerlen)) & 0xffff; $calccrc = crc32(substr($data, 0, $headerlen)) & 0xffff;
$headercrc = unpack("v", substr($data,$headerlen,2)); $headercrc = unpack("v", substr($data, $headerlen, 2));
$headercrc = $headercrc[1]; $headercrc = $headercrc[1];
if ($headercrc != $calccrc) { if ($headercrc != $calccrc) {
$error = "Header checksum failed."; $error = "Header checksum failed.";
@@ -267,12 +273,12 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
$headerlen += 2; $headerlen += 2;
} }
// GZIP FOOTER // GZIP FOOTER
$datacrc = unpack("V",substr($data,-8,4)); $datacrc = unpack("V", substr($data, -8, 4));
$datacrc = sprintf('%u',$datacrc[1] & 0xFFFFFFFF); $datacrc = sprintf('%u', $datacrc[1] & 0xFFFFFFFF);
$isize = unpack("V",substr($data,-4)); $isize = unpack("V", substr($data, -4));
$isize = $isize[1]; $isize = $isize[1];
// decompression: // decompression:
$bodylen = $len-$headerlen-8; $bodylen = $len - $headerlen - 8;
if ($bodylen < 1) { if ($bodylen < 1) {
// IMPLEMENTATION BUG! // IMPLEMENTATION BUG!
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
@@ -280,28 +286,28 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
} }
return null; return null;
} }
$body = substr($data,$headerlen,$bodylen); $body = substr($data, $headerlen, $bodylen);
$data = ""; $data = "";
if ($bodylen > 0) { if ($bodylen > 0) {
switch ($method) { switch ($method) {
case 8: case 8:
// Currently the only supported compression method: // Currently the only supported compression method:
$data = gzinflate($body,$maxlength); $data = gzinflate($body, $maxlength);
break; break;
default: default:
$error = "Unknown compression method."; $error = "Unknown compression method.";
if ($mbIntEnc !== null) { if ($mbIntEnc !== null) {
mb_internal_encoding($mbIntEnc); mb_internal_encoding($mbIntEnc);
} }
return false; return false;
} }
} // zero-byte body content is allowed } // zero-byte body content is allowed
// Verifiy CRC32 // Verifiy CRC32
$crc = sprintf("%u",crc32($data)); $crc = sprintf("%u", crc32($data));
$crcOK = $crc == $datacrc; $crcOK = $crc == $datacrc;
$lenOK = $isize == strlen($data); $lenOK = $isize == strlen($data);
if (!$lenOK || !$crcOK) { if (!$lenOK || !$crcOK) {
$error = ( $lenOK ? '' : 'Length check FAILED. ') . ( $crcOK ? '' : 'Checksum FAILED.'); $error = ($lenOK ? '' : 'Length check FAILED. ') . ($crcOK ? '' : 'Checksum FAILED.');
$ret = false; $ret = false;
} }
$ret = $data; $ret = $data;
@@ -309,4 +315,4 @@ function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null)
mb_internal_encoding($mbIntEnc); mb_internal_encoding($mbIntEnc);
} }
return $ret; return $ret;
} }

View File

@@ -1,8 +1,11 @@
<?php <?php
namespace Minify\Test;
use Exception;
use JSMin\JSMin; use JSMin\JSMin;
class JsMinTest extends TestCase class JSMinTest extends TestCase
{ {
public function test1() public function test1()
{ {
@@ -54,7 +57,8 @@ class JsMinTest extends TestCase
* @param string $label * @param string $label
* @param string $expClass * @param string $expClass
* @param string $expMessage * @param string $expMessage
* @dataProvider testJSMinExceptionData *
* @dataProvider JSMinExceptionDataProvider
*/ */
public function testJSMinException($js, $label, $expClass, $expMessage) public function testJSMinException($js, $label, $expClass, $expMessage)
{ {
@@ -68,7 +72,7 @@ class JsMinTest extends TestCase
$this->assertTrue($eClass === $expClass && $eMsg === $expMessage, 'Throw on ' . $label); $this->assertTrue($eClass === $expClass && $eMsg === $expMessage, 'Throw on ' . $label);
} }
public function testJSMinExceptionData() public function JSMinExceptionDataProvider()
{ {
// $js, $label, $expClass, $expMessage // $js, $label, $expClass, $expMessage
return array( return array(
@@ -122,4 +126,4 @@ class JsMinTest extends TestCase
), ),
); );
} }
} }

View File

@@ -1,6 +1,11 @@
<?php <?php
class JsClosureCompilerTest extends PHPUnit_Framework_TestCase namespace Minify\Test;
use Minify_JS_ClosureCompiler;
use Minify_JS_ClosureCompiler_Exception;
class JsClosureCompilerTest extends TestCase
{ {
public function test1() public function test1()
{ {
@@ -27,7 +32,11 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase
$this->compile($src); $this->compile($src);
} catch (Minify_JS_ClosureCompiler_Exception $e) { } catch (Minify_JS_ClosureCompiler_Exception $e) {
} }
$this->assertInstanceOf('Minify_JS_ClosureCompiler_Exception', $e, 'Throws Minify_JS_ClosureCompiler_Exception'); $this->assertInstanceOf(
'Minify_JS_ClosureCompiler_Exception',
$e,
'Throws Minify_JS_ClosureCompiler_Exception'
);
} }
// Test maximum byte size check (default) // Test maximum byte size check (default)
@@ -40,7 +49,11 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase
$this->compile($src); $this->compile($src);
} catch (Minify_JS_ClosureCompiler_Exception $e) { } catch (Minify_JS_ClosureCompiler_Exception $e) {
} }
$this->assertInstanceOf('Minify_JS_ClosureCompiler_Exception', $e, 'Throws Minify_JS_ClosureCompiler_Exception'); $this->assertInstanceOf(
'Minify_JS_ClosureCompiler_Exception',
$e,
'Throws Minify_JS_ClosureCompiler_Exception'
);
$expected = 'POST content larger than ' . Minify_JS_ClosureCompiler::DEFAULT_MAX_BYTES . ' bytes'; $expected = 'POST content larger than ' . Minify_JS_ClosureCompiler::DEFAULT_MAX_BYTES . ' bytes';
$this->assertEquals($expected, $e->getMessage(), 'Message must tell how big maximum byte size is'); $this->assertEquals($expected, $e->getMessage(), 'Message must tell how big maximum byte size is');
@@ -69,7 +82,11 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase
)); ));
} catch (Minify_JS_ClosureCompiler_Exception $e) { } catch (Minify_JS_ClosureCompiler_Exception $e) {
} }
$this->assertInstanceOf('Minify_JS_ClosureCompiler_Exception', $e, 'Throws Minify_JS_ClosureCompiler_Exception'); $this->assertInstanceOf(
'Minify_JS_ClosureCompiler_Exception',
$e,
'Throws Minify_JS_ClosureCompiler_Exception'
);
$expected = 'POST content larger than ' . $allowedBytes . ' bytes'; $expected = 'POST content larger than ' . $allowedBytes . ' bytes';
$this->assertEquals($expected, $e->getMessage(), 'Message must tell how big maximum byte size is'); $this->assertEquals($expected, $e->getMessage(), 'Message must tell how big maximum byte size is');
@@ -88,7 +105,11 @@ class JsClosureCompilerTest extends PHPUnit_Framework_TestCase
)); ));
} catch (Minify_JS_ClosureCompiler_Exception $e) { } catch (Minify_JS_ClosureCompiler_Exception $e) {
} }
$this->assertInstanceOf('Minify_JS_ClosureCompiler_Exception', $e, 'Throws Minify_JS_ClosureCompiler_Exception'); $this->assertInstanceOf(
'Minify_JS_ClosureCompiler_Exception',
$e,
'Throws Minify_JS_ClosureCompiler_Exception'
);
} }
public function test7() public function test7()

View File

@@ -1,8 +1,14 @@
<?php <?php
namespace Minify\Test;
use Minify_HTML_Helper;
class LessSourceTest extends TestCase class LessSourceTest extends TestCase
{ {
public function setUp() public string $realDocRoot;
public function setUp(): void
{ {
$this->realDocRoot = $_SERVER['DOCUMENT_ROOT']; $this->realDocRoot = $_SERVER['DOCUMENT_ROOT'];
$_SERVER['DOCUMENT_ROOT'] = self::$document_root; $_SERVER['DOCUMENT_ROOT'] = self::$document_root;
@@ -35,4 +41,4 @@ class LessSourceTest extends TestCase
$this->assertEquals("/min/g=less&amp;{$max}", $res); $this->assertEquals("/min/g=less&amp;{$max}", $res);
} }
} }

View File

@@ -1,5 +1,10 @@
<?php <?php
namespace Minify\Test;
use Minify_Build;
use Minify_Source;
class MinifyBuildTest extends TestCase class MinifyBuildTest extends TestCase
{ {
public function test() public function test()
@@ -20,4 +25,4 @@ class MinifyBuildTest extends TestCase
$this->assertEquals($b->uri('/path'), "/path?{$maxTime}", 'uri() with no querystring'); $this->assertEquals($b->uri('/path'), "/path?{$maxTime}", 'uri() with no querystring');
$this->assertEquals($b->uri('/path?hello'), "/path?hello&amp;{$maxTime}", 'uri() with existing querystring'); $this->assertEquals($b->uri('/path?hello'), "/path?hello&amp;{$maxTime}", 'uri() with existing querystring');
} }
} }

View File

@@ -1,8 +1,12 @@
<?php <?php
namespace Minify\Test;
use Minify_CSS_UriRewriter;
class MinifyCSSUriRewriterTest extends TestCase class MinifyCSSUriRewriterTest extends TestCase
{ {
public function setUp() public function setUp(): void
{ {
Minify_CSS_UriRewriter::$debugText = ''; Minify_CSS_UriRewriter::$debugText = '';
} }
@@ -12,9 +16,10 @@ class MinifyCSSUriRewriterTest extends TestCase
$in = file_get_contents(self::$test_files . '/css_uriRewriter/in.css'); $in = file_get_contents(self::$test_files . '/css_uriRewriter/in.css');
$expected = file_get_contents(self::$test_files . '/css_uriRewriter/exp.css'); $expected = file_get_contents(self::$test_files . '/css_uriRewriter/exp.css');
$actual = Minify_CSS_UriRewriter::rewrite( $actual = Minify_CSS_UriRewriter::rewrite(
$in $in,
, self::$test_files . '/css_uriRewriter' // currentDir self::$test_files . '/css_uriRewriter' // currentDir
, self::$document_root // use DOCUMENT_ROOT = '/full/path/to/min_unit_tests' ,
self::$document_root // use DOCUMENT_ROOT = '/full/path/to/min_unit_tests'
); );
$this->assertEquals($expected, $actual, 'rewrite, debug: ' . Minify_CSS_UriRewriter::$debugText); $this->assertEquals($expected, $actual, 'rewrite, debug: ' . Minify_CSS_UriRewriter::$debugText);
@@ -43,9 +48,9 @@ class MinifyCSSUriRewriterTest extends TestCase
$in = '../../../../assets/skins/sam/sprite.png'; $in = '../../../../assets/skins/sam/sprite.png';
$exp = '/yui/assets/skins/sam/sprite.png'; $exp = '/yui/assets/skins/sam/sprite.png';
$actual = Minify_CSS_UriRewriter::rewriteRelative( $actual = Minify_CSS_UriRewriter::rewriteRelative(
$in $in,
, 'sf_root_dir\web\yui\menu\assets\skins\sam' 'sf_root_dir\web\yui\menu\assets\skins\sam',
, 'sf_root_dir\web' 'sf_root_dir\web'
); );
$this->assertEquals($exp, $actual, 'Issue 99, debug: ' . Minify_CSS_UriRewriter::$debugText); $this->assertEquals($exp, $actual, 'Issue 99, debug: ' . Minify_CSS_UriRewriter::$debugText);

View File

@@ -1,11 +1,14 @@
<?php <?php
namespace Minify\Test;
use Minify_Cache_APC;
class MinifyCacheAPCTest extends TestCase class MinifyCacheAPCTest extends TestCase
{ {
public function setUp() public function setUp(): void
{ {
if (!function_exists('apc_store')) { if (!function_exists('apc_store')) {
// FIXME: is APCu extension ok too?
$this->markTestSkipped("To test this component, install APC extension"); $this->markTestSkipped("To test this component, install APC extension");
} }
} }
@@ -18,4 +21,4 @@ class MinifyCacheAPCTest extends TestCase
$cache = new Minify_Cache_APC(); $cache = new Minify_Cache_APC();
$this->assertTestCache($cache, $id, $data); $this->assertTestCache($cache, $id, $data);
} }
} }

View File

@@ -0,0 +1,25 @@
<?php
namespace Minify\Test;
use Minify_Cache_APCu;
class MinifyCacheAPCuTest extends TestCase
{
public function setUp(): void
{
if (!function_exists('apcu_store')) {
$this->markTestSkipped("To test this component, install APCu extension");
}
ini_set('apc.enable_cli', 1);
}
public function test1()
{
$data = str_repeat(md5(time()) . 'í', 100); // 3400 bytes in UTF-8
$id = 'Minify_test_cache';
$cache = new Minify_Cache_APCu();
$this->assertTestCache($cache, $id, $data);
}
}

View File

@@ -1,5 +1,9 @@
<?php <?php
namespace Minify\Test;
use Minify_Cache_File;
class MinifyCacheFileTest extends TestCase class MinifyCacheFileTest extends TestCase
{ {
public function test1() public function test1()

View File

@@ -1,11 +1,16 @@
<?php <?php
namespace Minify\Test;
use Memcache;
use Minify_Cache_Memcache;
class MinifyCacheMemcacheTest extends TestCase class MinifyCacheMemcacheTest extends TestCase
{ {
/** @var Memcache */ /** @var Memcache */
private $mc; private $mc;
public function setUp() public function setUp(): void
{ {
if (!function_exists('memcache_set')) { if (!function_exists('memcache_set')) {
$this->markTestSkipped("To test this component, install memcache in PHP"); $this->markTestSkipped("To test this component, install memcache in PHP");
@@ -40,4 +45,3 @@ class MinifyCacheMemcacheTest extends TestCase
$this->assertTestCache($cache, $id, $data); $this->assertTestCache($cache, $id, $data);
} }
} }

View File

@@ -1,8 +1,12 @@
<?php <?php
namespace Minify\Test;
use Minify_Cache_WinCache;
class MinifyCacheWinCacheTest extends TestCase class MinifyCacheWinCacheTest extends TestCase
{ {
public function setUp() public function setUp(): void
{ {
if (!function_exists('wincache_ucache_info')) { if (!function_exists('wincache_ucache_info')) {
$this->markTestSkipped("To test this component, install WinCache extension"); $this->markTestSkipped("To test this component, install WinCache extension");
@@ -17,4 +21,4 @@ class MinifyCacheWinCacheTest extends TestCase
$cache = new Minify_Cache_WinCache(); $cache = new Minify_Cache_WinCache();
$this->assertTestCache($cache, $id, $data); $this->assertTestCache($cache, $id, $data);
} }
} }

View File

@@ -1,8 +1,12 @@
<?php <?php
namespace Minify\Test;
use Minify_Cache_ZendPlatform;
class MinifyCacheZendPlatformTest extends TestCase class MinifyCacheZendPlatformTest extends TestCase
{ {
public function setUp() public function setUp(): void
{ {
if (!function_exists('output_cache_put')) { if (!function_exists('output_cache_put')) {
// FIXME: be specific what to actually install // FIXME: be specific what to actually install
@@ -18,4 +22,4 @@ class MinifyCacheZendPlatformTest extends TestCase
$cache = new Minify_Cache_ZendPlatform(); $cache = new Minify_Cache_ZendPlatform();
$this->assertTestCache($cache, $id, $data); $this->assertTestCache($cache, $id, $data);
} }
} }

View File

@@ -1,8 +1,13 @@
<?php <?php
namespace Minify\Test;
use Exception;
use Minify_ClosureCompiler;
class MinifyClosureCompilerTest extends TestCase class MinifyClosureCompilerTest extends TestCase
{ {
public static function setupBeforeClass() public static function setupBeforeClass(): void
{ {
parent::setupBeforeClass(); parent::setupBeforeClass();
Minify_ClosureCompiler::$isDebug = true; Minify_ClosureCompiler::$isDebug = true;

View File

@@ -1,5 +1,9 @@
<?php <?php
namespace Minify\Test;
use Minify_CommentPreserver;
class MinifyCommentPreserverTest extends TestCase class MinifyCommentPreserverTest extends TestCase
{ {
public function test() public function test()
@@ -27,4 +31,4 @@ class MinifyCommentPreserverTest extends TestCase
++$callCount; ++$callCount;
return $callCount . strtoupper($content); return $callCount . strtoupper($content);
} }
} }

View File

@@ -1,17 +1,22 @@
<?php <?php
namespace Minify\Test;
use Minify_HTML_Helper;
use Minify_Source;
class MinifyHTMLHelperTest extends TestCase class MinifyHTMLHelperTest extends TestCase
{ {
private $realDocRoot; private $realDocRoot;
public function setUp() public function setUp(): void
{ {
$this->realDocRoot = $_SERVER['DOCUMENT_ROOT']; $this->realDocRoot = $_SERVER['DOCUMENT_ROOT'];
$_SERVER['DOCUMENT_ROOT'] = self::$document_root; $_SERVER['DOCUMENT_ROOT'] = self::$document_root;
} }
// TODO: this is probably not needed if backupGlobals is enabled? // TODO: this is probably not needed if backupGlobals is enabled?
public function tearDown() public function tearDown(): void
{ {
$_SERVER['DOCUMENT_ROOT'] = $this->realDocRoot; $_SERVER['DOCUMENT_ROOT'] = $this->realDocRoot;
} }
@@ -38,11 +43,16 @@ class MinifyHTMLHelperTest extends TestCase
$this->assertEquals($expected, $actual, 'non-existent group & debug'); $this->assertEquals($expected, $actual, 'non-existent group & debug');
$expected = "/myApp/min/?g=css&amp;{$maxTime}"; $expected = "/myApp/min/?g=css&amp;{$maxTime}";
$actual = Minify_HTML_Helper::getUri('css', array( $actual = Minify_HTML_Helper::getUri(
'rewriteWorks' => false 'css',
, 'minAppUri' => '/myApp/min/' array(
, 'groupsConfigFile' => self::$test_files . '/htmlHelper_groupsConfig.php' 'rewriteWorks' => false
)); ,
'minAppUri' => '/myApp/min/'
,
'groupsConfigFile' => self::$test_files . '/htmlHelper_groupsConfig.php'
)
);
$this->assertEquals($expected, $actual, 'existing group'); $this->assertEquals($expected, $actual, 'existing group');
@@ -51,25 +61,33 @@ class MinifyHTMLHelperTest extends TestCase
require_once $utilsFile; require_once $utilsFile;
$fiveSecondsAgo = $_SERVER['REQUEST_TIME'] - 5; $fiveSecondsAgo = $_SERVER['REQUEST_TIME'] - 5;
$obj = new Minify_Source(array( $obj = new Minify_Source(
'id' => '1', array(
'content' => '1', 'id' => '1',
'lastModified' => $fiveSecondsAgo, 'content' => '1',
)); 'lastModified' => $fiveSecondsAgo,
)
);
$output = Minify_mtime(array($uri1, $uri2, $obj)); $output = Minify_mtime(array($uri1, $uri2, $obj));
$this->assertEquals($fiveSecondsAgo, $output, 'utils.php : Minify_mtime w/ files & obj'); $this->assertEquals($fiveSecondsAgo, $output, 'utils.php : Minify_mtime w/ files & obj');
$obj = new Minify_Source(array( $obj = new Minify_Source(
'id' => '2', array(
'content' => '2', 'id' => '2',
'lastModified' => strtotime('2000-01-01'), 'content' => '2',
)); 'lastModified' => strtotime('2000-01-01'),
$output = Minify_mtime(array( )
$obj );
, 'css' $output = Minify_mtime(
), self::$test_files . '/htmlHelper_groupsConfig.php'); array(
$obj
,
'css'
),
self::$test_files . '/htmlHelper_groupsConfig.php'
);
$this->assertEquals($maxTime, $output, 'utils.php : Minify_mtime w/ obj & group'); $this->assertEquals($maxTime, $output, 'utils.php : Minify_mtime w/ obj & group');
} }
} }
} }

View File

@@ -1,5 +1,9 @@
<?php <?php
namespace Minify\Test;
use Minify_HTML;
class MinifyHTMLTest extends TestCase class MinifyHTMLTest extends TestCase
{ {
public function test1() public function test1()

View File

@@ -1,5 +1,9 @@
<?php <?php
namespace Minify\Test;
use Minify_ImportProcessor;
class MinifyImportProcessorTest extends TestCase class MinifyImportProcessorTest extends TestCase
{ {
public function test() public function test()
@@ -19,6 +23,10 @@ class MinifyImportProcessorTest extends TestCase
realpath($linDir . '/lib/css/example.css'), realpath($linDir . '/lib/css/example.css'),
); );
$this->assertEquals($expectedIncludes, Minify_ImportProcessor::$filesIncluded, 'included right files in right order'); $this->assertEquals(
$expectedIncludes,
Minify_ImportProcessor::$filesIncluded,
'included right files in right order'
);
} }
} }

View File

@@ -1,5 +1,13 @@
<?php <?php
namespace Minify\Test;
use Minify;
use Minify_Cache_Null;
use Minify_Controller_Files;
use Minify_Env;
use Minify_Source_Factory;
class MinifyLinesTest extends TestCase class MinifyLinesTest extends TestCase
{ {
public function test_lines() public function test_lines()

View File

@@ -1,8 +1,14 @@
<?php <?php
namespace Minify\Test;
use Exception;
use Minify_ClosureCompiler;
use Minify_NailgunClosureCompiler;
class MinifyNailgunClosureCompilerTest extends TestCase class MinifyNailgunClosureCompilerTest extends TestCase
{ {
public static function setupBeforeClass() public static function setupBeforeClass(): void
{ {
parent::setupBeforeClass(); parent::setupBeforeClass();
Minify_ClosureCompiler::$isDebug = true; Minify_ClosureCompiler::$isDebug = true;
@@ -48,4 +54,4 @@ class MinifyNailgunClosureCompilerTest extends TestCase
$this->markTestSkipped($e->getMessage()); $this->markTestSkipped($e->getMessage());
} }
} }
} }

View File

@@ -1,5 +1,13 @@
<?php <?php
namespace Minify\Test;
use Minify;
use Minify_Cache_Null;
use Minify_Controller_Files;
use Minify_Env;
use Minify_Source_Factory;
class MinifyTest extends TestCase class MinifyTest extends TestCase
{ {
public function test_Minify() public function test_Minify()
@@ -37,7 +45,6 @@ class MinifyTest extends TestCase
'content' => '', 'content' => '',
'headers' => array( 'headers' => array(
'Expires' => gmdate('D, d M Y H:i:s \G\M\T', $_SERVER['REQUEST_TIME'] + 1800), 'Expires' => gmdate('D, d M Y H:i:s \G\M\T', $_SERVER['REQUEST_TIME'] + 1800),
'Vary' => 'Accept-Encoding',
'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified), 'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified),
'ETag' => "\"pub{$lastModified}\"", 'ETag' => "\"pub{$lastModified}\"",
'Cache-Control' => 'max-age=1800', 'Cache-Control' => 'max-age=1800',
@@ -55,8 +62,8 @@ class MinifyTest extends TestCase
$content = preg_replace('/\\r\\n?/', "\n", file_get_contents($minifyTestPath . '/minified.js')); $content = preg_replace('/\\r\\n?/', "\n", file_get_contents($minifyTestPath . '/minified.js'));
$lastModified = max( $lastModified = max(
filemtime($minifyTestPath . '/email.js') filemtime($minifyTestPath . '/email.js'),
, filemtime($minifyTestPath . '/QueryString.js') filemtime($minifyTestPath . '/QueryString.js')
); );
$expected = array( $expected = array(
'success' => true, 'success' => true,
@@ -146,7 +153,10 @@ class MinifyTest extends TestCase
)); ));
$output = $output['content']; $output = $output['content'];
$this->assertFalse(strpos($output, $defaultOptions['importWarning']), 'Issue 89 : don\'t warn about valid imports'); $this->assertFalse(
strpos($output, $defaultOptions['importWarning']),
'Issue 89 : don\'t warn about valid imports'
);
// Test Issue 132 // Test Issue 132
if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) { if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
@@ -156,7 +166,11 @@ class MinifyTest extends TestCase
'encodeOutput' => false, 'encodeOutput' => false,
)); ));
$this->assertEquals(77, $output['headers']['Content-Length'], 'Issue 132 : mbstring.func_overload shouldn\'t cause incorrect Content-Length'); $this->assertEquals(
77,
$output['headers']['Content-Length'],
'Issue 132 : mbstring.func_overload shouldn\'t cause incorrect Content-Length'
);
} }
// Test minifying CSS and responding with Etag/Last-Modified // Test minifying CSS and responding with Etag/Last-Modified

View File

@@ -1,8 +1,13 @@
<?php <?php
namespace Minify\Test;
use Exception;
use Minify_YUICompressor;
class MinifyYuiCSSTest extends TestCase class MinifyYuiCSSTest extends TestCase
{ {
public static function setupBeforeClass() public static function setupBeforeClass(): void
{ {
parent::setupBeforeClass(); parent::setupBeforeClass();
@@ -13,7 +18,8 @@ class MinifyYuiCSSTest extends TestCase
Minify_YUICompressor::$tempDir = sys_get_temp_dir(); Minify_YUICompressor::$tempDir = sys_get_temp_dir();
} }
public function setUp() { public function setUp(): void
{
$this->assertHasJar(); $this->assertHasJar();
} }
@@ -49,9 +55,9 @@ class MinifyYuiCSSTest extends TestCase
{ {
$this->assertNotEmpty(Minify_YUICompressor::$jarFile); $this->assertNotEmpty(Minify_YUICompressor::$jarFile);
try { try {
$this->assertFileExists(Minify_YUICompressor::$jarFile , "Have YUI yuicompressor.jar"); $this->assertFileExists(Minify_YUICompressor::$jarFile, "Have YUI yuicompressor.jar");
} catch (Exception $e) { } catch (Exception $e) {
$this->markTestSkipped($e->getMessage()); $this->markTestSkipped($e->getMessage());
} }
} }
} }

View File

@@ -1,13 +1,15 @@
<?php <?php
namespace Minify\Test;
use Minify_HTML_Helper;
class ScssSourceTest extends TestCase class ScssSourceTest extends TestCase
{ {
public function setUp() public string $realDocRoot;
{
if (version_compare(PHP_VERSION, '5.4.0', '<')) {
$this->markTestSkipped('scssphp is not compatible with this PHP version.');
}
public function setUp(): void
{
$this->realDocRoot = $_SERVER['DOCUMENT_ROOT']; $this->realDocRoot = $_SERVER['DOCUMENT_ROOT'];
$_SERVER['DOCUMENT_ROOT'] = self::$document_root; $_SERVER['DOCUMENT_ROOT'] = self::$document_root;
} }
@@ -39,4 +41,4 @@ class ScssSourceTest extends TestCase
$this->assertEquals("/min/g=scss&amp;{$max}", $res); $this->assertEquals("/min/g=scss&amp;{$max}", $res);
} }
} }

View File

@@ -1,13 +1,17 @@
<?php <?php
class TestCase extends PHPUnit_Framework_TestCase namespace Minify\Test;
use Minify_CacheInterface;
abstract class TestCase extends \PHPUnit\Framework\TestCase
{ {
/** @var string */ /** @var string */
protected static $document_root; protected static $document_root;
/** @var string */ /** @var string */
protected static $test_files; protected static $test_files;
public static function setupBeforeClass() public static function setupBeforeClass(): void
{ {
self::$document_root = __DIR__; self::$document_root = __DIR__;
self::$test_files = __DIR__ . '/_test_files'; self::$test_files = __DIR__ . '/_test_files';
@@ -21,7 +25,7 @@ class TestCase extends PHPUnit_Framework_TestCase
*/ */
protected function countBytes($str) protected function countBytes($str)
{ {
return (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) return (function_exists('mb_strlen') && ((int) ini_get('mbstring.func_overload') & 2))
? mb_strlen($str, '8bit') ? mb_strlen($str, '8bit')
: strlen($str); : strlen($str);
} }
@@ -66,4 +70,4 @@ class TestCase extends PHPUnit_Framework_TestCase
return $contents; return $contents;
} }
} }

View File

@@ -9,6 +9,11 @@
<meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design." /> <meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design." />
<meta name="robots" content="all" /> <meta name="robots" content="all" />
<title>css Zen Garden: The Beauty in CSS Design</title> <title>css Zen Garden: The Beauty in CSS Design</title>
<!--# if expr="$HTTP_COOKIE=/minify\=1/" -->
<meta name="generator" content="minify-cookie" />
<!--# else -->
<meta name="generator" content="minify-no-cookie" />
<!--# endif -->
<!-- to correct the unsightly Flash of Unstyled Content. http://www.bluerobot.com/web/css/fouc.asp --> <!-- to correct the unsightly Flash of Unstyled Content. http://www.bluerobot.com/web/css/fouc.asp -->
<script type="text/javascript"><!-- <script type="text/javascript"><!--
@@ -63,11 +68,11 @@ css hack {
display:none; display:none;
} }
</style> </style>
<link <link
rel="Shortcut Icon" rel="Shortcut Icon"
type="image/x-icon" type="image/x-icon"
href="http://www.csszengarden.com/favicon.ico" /> href="http://www.csszengarden.com/favicon.ico" />
<link <link
rel="alternate" rel="alternate"
type="application/rss+xml" type="application/rss+xml"
title="RSS" title="RSS"
@@ -78,7 +83,7 @@ css hack {
<div id="container"> <div id="container">
<div id="pageHeader"> <div id="pageHeader">
<h1><span>css Zen Garden</span></h1> <h1><span>css Zen Garden</span></h1>
<h2><span>The Beauty of <acronym title="Cascading Style Sheets">CSS</acronym> <h2><span>The Beauty of <acronym title="Cascading Style Sheets">CSS</acronym>
Design</span></h2> Design</span></h2>
</div> </div>
<pre> <pre>

View File

@@ -4,7 +4,12 @@ http-equiv="content-type" content="text/html; charset=iso-8859-1" /><meta
name="author" content="Dave Shea" /><meta name="author" content="Dave Shea" /><meta
name="keywords" content="design, css, cascading, style, sheets, xhtml, graphic design, w3c, web standards, visual, display" /><meta name="keywords" content="design, css, cascading, style, sheets, xhtml, graphic design, w3c, web standards, visual, display" /><meta
name="description" content="A demonstration of what can be accomplished visually through CSS-based design." /><meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design." /><meta
name="robots" content="all" /><title>css Zen Garden: The Beauty in CSS Design</title> <script type="text/javascript">var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} name="robots" content="all" /><title>css Zen Garden: The Beauty in CSS Design</title>
<!--# if expr="$HTTP_COOKIE=/minify\=1/" --><meta
name="generator" content="minify-cookie" />
<!--# else --><meta
name="generator" content="minify-no-cookie" />
<!--# endif --> <script type="text/javascript">var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'}
is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;}
if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}</script> <script type="text/javascript">/*<![CDATA[*/var i=0;while(++i<10) if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}</script> <script type="text/javascript">/*<![CDATA[*/var i=0;while(++i<10)
{}/*]]>*/</script> <script type="text/javascript">i=1;</script> <script type="text/javascript">/*<![CDATA[*/(i<1);/*]]>*/</script> <!--[if IE 6]><style type="text/css">/*<![CDATA[*//*! copyright: you'll need CDATA for this < & */ {}/*]]>*/</script> <script type="text/javascript">i=1;</script> <script type="text/javascript">/*<![CDATA[*/(i<1);/*]]>*/</script> <!--[if IE 6]><style type="text/css">/*<![CDATA[*//*! copyright: you'll need CDATA for this < & */

View File

@@ -9,6 +9,11 @@
<meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design."> <meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design.">
<meta name="robots" content="all"> <meta name="robots" content="all">
<title>css Zen Garden: The Beauty in CSS Design</title> <title>css Zen Garden: The Beauty in CSS Design</title>
<!--# if expr="$HTTP_COOKIE=/minify\=1/" -->
<meta name="generator" content="minify-cookie" />
<!--# else -->
<meta name="generator" content="minify-no-cookie" />
<!--# endif -->
<!-- to correct the unsightly Flash of Unstyled Content. http://www.bluerobot.com/web/css/fouc.asp --> <!-- to correct the unsightly Flash of Unstyled Content. http://www.bluerobot.com/web/css/fouc.asp -->
<script type="text/javascript"><!-- <script type="text/javascript"><!--
@@ -61,11 +66,11 @@ css hack {
display:none; display:none;
} }
</style> </style>
<link <link
rel="Shortcut Icon" rel="Shortcut Icon"
type="image/x-icon" type="image/x-icon"
href="http://www.csszengarden.com/favicon.ico"> href="http://www.csszengarden.com/favicon.ico">
<link <link
rel="alternate" rel="alternate"
type="application/rss+xml" type="application/rss+xml"
title="RSS" title="RSS"
@@ -76,7 +81,7 @@ css hack {
<div id="container"> <div id="container">
<div id="pageHeader"> <div id="pageHeader">
<h1><span>css Zen Garden</span></h1> <h1><span>css Zen Garden</span></h1>
<h2><span>The Beauty of <acronym title="Cascading Style Sheets">CSS</acronym> <h2><span>The Beauty of <acronym title="Cascading Style Sheets">CSS</acronym>
Design</span></h2> Design</span></h2>
</div> </div>
<pre> <pre>

View File

@@ -4,7 +4,12 @@ http-equiv="content-type" content="text/html; charset=iso-8859-1"><meta
name="author" content="Dave Shea"><meta name="author" content="Dave Shea"><meta
name="keywords" content="design, css, cascading, style, sheets, xhtml, graphic design, w3c, web standards, visual, display"><meta name="keywords" content="design, css, cascading, style, sheets, xhtml, graphic design, w3c, web standards, visual, display"><meta
name="description" content="A demonstration of what can be accomplished visually through CSS-based design."><meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design."><meta
name="robots" content="all"><title>css Zen Garden: The Beauty in CSS Design</title> <script type="text/javascript">var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'} name="robots" content="all"><title>css Zen Garden: The Beauty in CSS Design</title>
<!--# if expr="$HTTP_COOKIE=/minify\=1/" --><meta
name="generator" content="minify-cookie" />
<!--# else --><meta
name="generator" content="minify-no-cookie" />
<!--# endif --> <script type="text/javascript">var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'}
is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;} is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;}
if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}</script> <script type="text/javascript">var i=0;while(++i<10) if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}</script> <script type="text/javascript">var i=0;while(++i<10)
{}</script> <script type="text/javascript">i=1;</script> <script type="text/javascript">(i<1);</script> <!--[if IE 6]><style type="text/css">/*! copyright: you'll need CDATA for this < & */ {}</script> <script type="text/javascript">i=1;</script> <script type="text/javascript">(i<1);</script> <!--[if IE 6]><style type="text/css">/*! copyright: you'll need CDATA for this < & */

View File

@@ -48,7 +48,7 @@ function Minify_getUri($keyOrFiles, $opts = array())
* *
* Since this makes a bunch of stat() calls, you might not want to check this * Since this makes a bunch of stat() calls, you might not want to check this
* on every request. * on every request.
* *
* @param array $keysAndFiles group keys and/or file paths/URIs. * @param array $keysAndFiles group keys and/or file paths/URIs.
* @return int latest modification time of all given keys/files * @return int latest modification time of all given keys/files
*/ */