bixbite 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.markdown +49 -0
- data/VERSION +1 -0
- data/bin/bixbite +73 -0
- data/lib/bixbite.rb +13 -0
- data/lib/bixbite/command.rb +14 -0
- data/lib/bixbite/create.rb +76 -0
- data/template/Rakefile +25 -0
- data/template/assets/bixbite/Rakefile.rb +297 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
- data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
- data/template/assets/utilities/pngout +0 -0
- data/template/deploy/public_html/.htaccess +0 -0
- data/template/documentation/js/.htaccess +0 -0
- data/template/src/html/.htaccess +76 -0
- data/template/src/html/css/cmn/global.css +96 -0
- data/template/src/html/css/cmn/ie.css +15 -0
- data/template/src/html/css/cmn/ie6.css +15 -0
- data/template/src/html/images/cmn/.htaccess +0 -0
- data/template/src/html/images/tmp/.htaccess +0 -0
- data/template/src/html/includes/debug.inc +5 -0
- data/template/src/html/includes/footer.inc +52 -0
- data/template/src/html/includes/header.inc +61 -0
- data/template/src/html/includes/html.inc +3 -0
- data/template/src/html/includes/namespace.inc +19 -0
- data/template/src/html/includes/page.inc +151 -0
- data/template/src/html/index.html +35 -0
- data/template/src/html/js/cmn/bootstrap.js +74 -0
- data/template/src/html/js/cmn/global.js +142 -0
- data/template/src/html/js/cmn/lib/LAB.js +348 -0
- data/template/src/html/min/.htaccess +4 -0
- data/template/src/html/min/MinifyCLI.php +19 -0
- data/template/src/html/min/README.txt +132 -0
- data/template/src/html/min/builder/_index.js +242 -0
- data/template/src/html/min/builder/bm.js +36 -0
- data/template/src/html/min/builder/index.php +182 -0
- data/template/src/html/min/builder/ocCheck.php +36 -0
- data/template/src/html/min/builder/rewriteTest.js +1 -0
- data/template/src/html/min/config.php +187 -0
- data/template/src/html/min/groupsConfig.php +34 -0
- data/template/src/html/min/index.php +66 -0
- data/template/src/html/min/lib/FirePHP.php +1370 -0
- data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
- data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
- data/template/src/html/min/lib/JSMin.php +314 -0
- data/template/src/html/min/lib/JSMinPlus.php +1872 -0
- data/template/src/html/min/lib/Minify.php +532 -0
- data/template/src/html/min/lib/Minify/Build.php +103 -0
- data/template/src/html/min/lib/Minify/CSS.php +83 -0
- data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
- data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
- data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
- data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
- data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
- data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
- data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
- data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
- data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
- data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
- data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
- data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
- data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
- data/template/src/html/min/lib/Minify/HTML.php +245 -0
- data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
- data/template/src/html/min/lib/Minify/Lines.php +131 -0
- data/template/src/html/min/lib/Minify/Logger.php +45 -0
- data/template/src/html/min/lib/Minify/Packer.php +37 -0
- data/template/src/html/min/lib/Minify/Source.php +187 -0
- data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
- data/template/src/html/min/lib/Solar/Dir.php +199 -0
- data/template/src/html/min/lib/closure-compiler.jar +0 -0
- data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
- data/template/src/html/min/utils.php +90 -0
- data/template/src/templates/css/template.css +7 -0
- data/template/src/templates/js/template.js +72 -0
- data/template/src/templates/template.html +18 -0
- data/template/src/yaml/config.yml +46 -0
- data/template/src/yaml/deploy.yml +35 -0
- data/test/bixbite_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +278 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_Build
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
require_once 'Minify/Source.php';
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Maintain a single last modification time for a group of Minify sources to
|
11
|
+
* allow use of far off Expires headers in Minify.
|
12
|
+
*
|
13
|
+
* <code>
|
14
|
+
* // in config file
|
15
|
+
* $groupSources = array(
|
16
|
+
* 'js' => array('file1.js', 'file2.js')
|
17
|
+
* ,'css' => array('file1.css', 'file2.css', 'file3.css')
|
18
|
+
* )
|
19
|
+
*
|
20
|
+
* // during HTML generation
|
21
|
+
* $jsBuild = new Minify_Build($groupSources['js']);
|
22
|
+
* $cssBuild = new Minify_Build($groupSources['css']);
|
23
|
+
*
|
24
|
+
* $script = "<script type='text/javascript' src='"
|
25
|
+
* . $jsBuild->uri('/min.php/js') . "'></script>";
|
26
|
+
* $link = "<link rel='stylesheet' type='text/css' href='"
|
27
|
+
* . $cssBuild->uri('/min.php/css') . "'>";
|
28
|
+
*
|
29
|
+
* // in min.php
|
30
|
+
* Minify::serve('Groups', array(
|
31
|
+
* 'groups' => $groupSources
|
32
|
+
* ,'setExpires' => (time() + 86400 * 365)
|
33
|
+
* ));
|
34
|
+
* </code>
|
35
|
+
*
|
36
|
+
* @package Minify
|
37
|
+
* @author Stephen Clay <steve@mrclay.org>
|
38
|
+
*/
|
39
|
+
class Minify_Build {
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Last modification time of all files in the build
|
43
|
+
*
|
44
|
+
* @var int
|
45
|
+
*/
|
46
|
+
public $lastModified = 0;
|
47
|
+
|
48
|
+
/**
|
49
|
+
* String to use as ampersand in uri(). Set this to '&' if
|
50
|
+
* you are not HTML-escaping URIs.
|
51
|
+
*
|
52
|
+
* @var string
|
53
|
+
*/
|
54
|
+
public static $ampersand = '&';
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Get a time-stamped URI
|
58
|
+
*
|
59
|
+
* <code>
|
60
|
+
* echo $b->uri('/site.js');
|
61
|
+
* // outputs "/site.js?1678242"
|
62
|
+
*
|
63
|
+
* echo $b->uri('/scriptaculous.js?load=effects');
|
64
|
+
* // outputs "/scriptaculous.js?load=effects&1678242"
|
65
|
+
* </code>
|
66
|
+
*
|
67
|
+
* @param string $uri
|
68
|
+
* @param boolean $forceAmpersand (default = false) Force the use of ampersand to
|
69
|
+
* append the timestamp to the URI.
|
70
|
+
* @return string
|
71
|
+
*/
|
72
|
+
public function uri($uri, $forceAmpersand = false) {
|
73
|
+
$sep = ($forceAmpersand || strpos($uri, '?') !== false)
|
74
|
+
? self::$ampersand
|
75
|
+
: '?';
|
76
|
+
return "{$uri}{$sep}{$this->lastModified}";
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Create a build object
|
81
|
+
*
|
82
|
+
* @param array $sources array of Minify_Source objects and/or file paths
|
83
|
+
*
|
84
|
+
* @return null
|
85
|
+
*/
|
86
|
+
public function __construct($sources)
|
87
|
+
{
|
88
|
+
$max = 0;
|
89
|
+
foreach ((array)$sources as $source) {
|
90
|
+
if ($source instanceof Minify_Source) {
|
91
|
+
$max = max($max, $source->lastModified);
|
92
|
+
} elseif (is_string($source)) {
|
93
|
+
if (0 === strpos($source, '//')) {
|
94
|
+
$source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1);
|
95
|
+
}
|
96
|
+
if (is_file($source)) {
|
97
|
+
$max = max($max, filemtime($source));
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
$this->lastModified = $max;
|
102
|
+
}
|
103
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_CSS
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Minify CSS
|
9
|
+
*
|
10
|
+
* This class uses Minify_CSS_Compressor and Minify_CSS_UriRewriter to
|
11
|
+
* minify CSS and rewrite relative URIs.
|
12
|
+
*
|
13
|
+
* @package Minify
|
14
|
+
* @author Stephen Clay <steve@mrclay.org>
|
15
|
+
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
16
|
+
*/
|
17
|
+
class Minify_CSS {
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Minify a CSS string
|
21
|
+
*
|
22
|
+
* @param string $css
|
23
|
+
*
|
24
|
+
* @param array $options available options:
|
25
|
+
*
|
26
|
+
* 'preserveComments': (default true) multi-line comments that begin
|
27
|
+
* with "/*!" will be preserved with newlines before and after to
|
28
|
+
* enhance readability.
|
29
|
+
*
|
30
|
+
* 'prependRelativePath': (default null) if given, this string will be
|
31
|
+
* prepended to all relative URIs in import/url declarations
|
32
|
+
*
|
33
|
+
* 'currentDir': (default null) if given, this is assumed to be the
|
34
|
+
* directory of the current CSS file. Using this, minify will rewrite
|
35
|
+
* all relative URIs in import/url declarations to correctly point to
|
36
|
+
* the desired files. For this to work, the files *must* exist and be
|
37
|
+
* visible by the PHP process.
|
38
|
+
*
|
39
|
+
* 'symlinks': (default = array()) If the CSS file is stored in
|
40
|
+
* a symlink-ed directory, provide an array of link paths to
|
41
|
+
* target paths, where the link paths are within the document root. Because
|
42
|
+
* paths need to be normalized for this to work, use "//" to substitute
|
43
|
+
* the doc root in the link paths (the array keys). E.g.:
|
44
|
+
* <code>
|
45
|
+
* array('//symlink' => '/real/target/path') // unix
|
46
|
+
* array('//static' => 'D:\\staticStorage') // Windows
|
47
|
+
* </code>
|
48
|
+
*
|
49
|
+
* @return string
|
50
|
+
*/
|
51
|
+
public static function minify($css, $options = array())
|
52
|
+
{
|
53
|
+
require_once 'Minify/CSS/Compressor.php';
|
54
|
+
if (isset($options['preserveComments'])
|
55
|
+
&& !$options['preserveComments']) {
|
56
|
+
$css = Minify_CSS_Compressor::process($css, $options);
|
57
|
+
} else {
|
58
|
+
require_once 'Minify/CommentPreserver.php';
|
59
|
+
$css = Minify_CommentPreserver::process(
|
60
|
+
$css
|
61
|
+
,array('Minify_CSS_Compressor', 'process')
|
62
|
+
,array($options)
|
63
|
+
);
|
64
|
+
}
|
65
|
+
if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
|
66
|
+
return $css;
|
67
|
+
}
|
68
|
+
require_once 'Minify/CSS/UriRewriter.php';
|
69
|
+
if (isset($options['currentDir'])) {
|
70
|
+
return Minify_CSS_UriRewriter::rewrite(
|
71
|
+
$css
|
72
|
+
,$options['currentDir']
|
73
|
+
,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
|
74
|
+
,isset($options['symlinks']) ? $options['symlinks'] : array()
|
75
|
+
);
|
76
|
+
} else {
|
77
|
+
return Minify_CSS_UriRewriter::prepend(
|
78
|
+
$css
|
79
|
+
,$options['prependRelativePath']
|
80
|
+
);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
@@ -0,0 +1,250 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_CSS_Compressor
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Compress CSS
|
9
|
+
*
|
10
|
+
* This is a heavy regex-based removal of whitespace, unnecessary
|
11
|
+
* comments and tokens, and some CSS value minimization, where practical.
|
12
|
+
* Many steps have been taken to avoid breaking comment-based hacks,
|
13
|
+
* including the ie5/mac filter (and its inversion), but expect tricky
|
14
|
+
* hacks involving comment tokens in 'content' value strings to break
|
15
|
+
* minimization badly. A test suite is available.
|
16
|
+
*
|
17
|
+
* @package Minify
|
18
|
+
* @author Stephen Clay <steve@mrclay.org>
|
19
|
+
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
20
|
+
*/
|
21
|
+
class Minify_CSS_Compressor {
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Minify a CSS string
|
25
|
+
*
|
26
|
+
* @param string $css
|
27
|
+
*
|
28
|
+
* @param array $options (currently ignored)
|
29
|
+
*
|
30
|
+
* @return string
|
31
|
+
*/
|
32
|
+
public static function process($css, $options = array())
|
33
|
+
{
|
34
|
+
$obj = new Minify_CSS_Compressor($options);
|
35
|
+
return $obj->_process($css);
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @var array options
|
40
|
+
*/
|
41
|
+
protected $_options = null;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* @var bool Are we "in" a hack?
|
45
|
+
*
|
46
|
+
* I.e. are some browsers targetted until the next comment?
|
47
|
+
*/
|
48
|
+
protected $_inHack = false;
|
49
|
+
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Constructor
|
53
|
+
*
|
54
|
+
* @param array $options (currently ignored)
|
55
|
+
*
|
56
|
+
* @return null
|
57
|
+
*/
|
58
|
+
private function __construct($options) {
|
59
|
+
$this->_options = $options;
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Minify a CSS string
|
64
|
+
*
|
65
|
+
* @param string $css
|
66
|
+
*
|
67
|
+
* @return string
|
68
|
+
*/
|
69
|
+
protected function _process($css)
|
70
|
+
{
|
71
|
+
$css = str_replace("\r\n", "\n", $css);
|
72
|
+
|
73
|
+
// preserve empty comment after '>'
|
74
|
+
// http://www.webdevout.net/css-hacks#in_css-selectors
|
75
|
+
$css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
|
76
|
+
|
77
|
+
// preserve empty comment between property and value
|
78
|
+
// http://css-discuss.incutio.com/?page=BoxModelHack
|
79
|
+
$css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
|
80
|
+
$css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
|
81
|
+
|
82
|
+
// apply callback to all valid comments (and strip out surrounding ws
|
83
|
+
$css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
|
84
|
+
,array($this, '_commentCB'), $css);
|
85
|
+
|
86
|
+
// remove ws around { } and last semicolon in declaration block
|
87
|
+
$css = preg_replace('/\\s*{\\s*/', '{', $css);
|
88
|
+
$css = preg_replace('/;?\\s*}\\s*/', '}', $css);
|
89
|
+
|
90
|
+
// remove ws surrounding semicolons
|
91
|
+
$css = preg_replace('/\\s*;\\s*/', ';', $css);
|
92
|
+
|
93
|
+
// remove ws around urls
|
94
|
+
$css = preg_replace('/
|
95
|
+
url\\( # url(
|
96
|
+
\\s*
|
97
|
+
([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis)
|
98
|
+
\\s*
|
99
|
+
\\) # )
|
100
|
+
/x', 'url($1)', $css);
|
101
|
+
|
102
|
+
// remove ws between rules and colons
|
103
|
+
$css = preg_replace('/
|
104
|
+
\\s*
|
105
|
+
([{;]) # 1 = beginning of block or rule separator
|
106
|
+
\\s*
|
107
|
+
([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter)
|
108
|
+
\\s*
|
109
|
+
:
|
110
|
+
\\s*
|
111
|
+
(\\b|[#\'"]) # 3 = first character of a value
|
112
|
+
/x', '$1$2:$3', $css);
|
113
|
+
|
114
|
+
// remove ws in selectors
|
115
|
+
$css = preg_replace_callback('/
|
116
|
+
(?: # non-capture
|
117
|
+
\\s*
|
118
|
+
[^~>+,\\s]+ # selector part
|
119
|
+
\\s*
|
120
|
+
[,>+~] # combinators
|
121
|
+
)+
|
122
|
+
\\s*
|
123
|
+
[^~>+,\\s]+ # selector part
|
124
|
+
{ # open declaration block
|
125
|
+
/x'
|
126
|
+
,array($this, '_selectorsCB'), $css);
|
127
|
+
|
128
|
+
// minimize hex colors
|
129
|
+
$css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
|
130
|
+
, '$1#$2$3$4$5', $css);
|
131
|
+
|
132
|
+
// remove spaces between font families
|
133
|
+
$css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
|
134
|
+
,array($this, '_fontFamilyCB'), $css);
|
135
|
+
|
136
|
+
$css = preg_replace('/@import\\s+url/', '@import url', $css);
|
137
|
+
|
138
|
+
// replace any ws involving newlines with a single newline
|
139
|
+
$css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
|
140
|
+
|
141
|
+
// separate common descendent selectors w/ newlines (to limit line lengths)
|
142
|
+
$css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
|
143
|
+
|
144
|
+
// Use newline after 1st numeric value (to limit line lengths).
|
145
|
+
$css = preg_replace('/
|
146
|
+
((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
|
147
|
+
\\s+
|
148
|
+
/x'
|
149
|
+
,"$1\n", $css);
|
150
|
+
|
151
|
+
// prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
|
152
|
+
$css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
|
153
|
+
|
154
|
+
return trim($css);
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Replace what looks like a set of selectors
|
159
|
+
*
|
160
|
+
* @param array $m regex matches
|
161
|
+
*
|
162
|
+
* @return string
|
163
|
+
*/
|
164
|
+
protected function _selectorsCB($m)
|
165
|
+
{
|
166
|
+
// remove ws around the combinators
|
167
|
+
return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Process a comment and return a replacement
|
172
|
+
*
|
173
|
+
* @param array $m regex matches
|
174
|
+
*
|
175
|
+
* @return string
|
176
|
+
*/
|
177
|
+
protected function _commentCB($m)
|
178
|
+
{
|
179
|
+
$hasSurroundingWs = (trim($m[0]) !== $m[1]);
|
180
|
+
$m = $m[1];
|
181
|
+
// $m is the comment content w/o the surrounding tokens,
|
182
|
+
// but the return value will replace the entire comment.
|
183
|
+
if ($m === 'keep') {
|
184
|
+
return '/**/';
|
185
|
+
}
|
186
|
+
if ($m === '" "') {
|
187
|
+
// component of http://tantek.com/CSS/Examples/midpass.html
|
188
|
+
return '/*" "*/';
|
189
|
+
}
|
190
|
+
if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
|
191
|
+
// component of http://tantek.com/CSS/Examples/midpass.html
|
192
|
+
return '/*";}}/* */';
|
193
|
+
}
|
194
|
+
if ($this->_inHack) {
|
195
|
+
// inversion: feeding only to one browser
|
196
|
+
if (preg_match('@
|
197
|
+
^/ # comment started like /*/
|
198
|
+
\\s*
|
199
|
+
(\\S[\\s\\S]+?) # has at least some non-ws content
|
200
|
+
\\s*
|
201
|
+
/\\* # ends like /*/ or /**/
|
202
|
+
@x', $m, $n)) {
|
203
|
+
// end hack mode after this comment, but preserve the hack and comment content
|
204
|
+
$this->_inHack = false;
|
205
|
+
return "/*/{$n[1]}/**/";
|
206
|
+
}
|
207
|
+
}
|
208
|
+
if (substr($m, -1) === '\\') { // comment ends like \*/
|
209
|
+
// begin hack mode and preserve hack
|
210
|
+
$this->_inHack = true;
|
211
|
+
return '/*\\*/';
|
212
|
+
}
|
213
|
+
if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
|
214
|
+
// begin hack mode and preserve hack
|
215
|
+
$this->_inHack = true;
|
216
|
+
return '/*/*/';
|
217
|
+
}
|
218
|
+
if ($this->_inHack) {
|
219
|
+
// a regular comment ends hack mode but should be preserved
|
220
|
+
$this->_inHack = false;
|
221
|
+
return '/**/';
|
222
|
+
}
|
223
|
+
// Issue 107: if there's any surrounding whitespace, it may be important, so
|
224
|
+
// replace the comment with a single space
|
225
|
+
return $hasSurroundingWs // remove all other comments
|
226
|
+
? ' '
|
227
|
+
: '';
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* Process a font-family listing and return a replacement
|
232
|
+
*
|
233
|
+
* @param array $m regex matches
|
234
|
+
*
|
235
|
+
* @return string
|
236
|
+
*/
|
237
|
+
protected function _fontFamilyCB($m)
|
238
|
+
{
|
239
|
+
$m[1] = preg_replace('/
|
240
|
+
\\s*
|
241
|
+
(
|
242
|
+
"[^"]+" # 1 = family in double qutoes
|
243
|
+
|\'[^\']+\' # or 1 = family in single quotes
|
244
|
+
|[\\w\\-]+ # or 1 = unquoted family
|
245
|
+
)
|
246
|
+
\\s*
|
247
|
+
/x', '$1', $m[1]);
|
248
|
+
return 'font-family:' . $m[1] . $m[2];
|
249
|
+
}
|
250
|
+
}
|
@@ -0,0 +1,270 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_CSS_UriRewriter
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Rewrite file-relative URIs as root-relative in CSS files
|
9
|
+
*
|
10
|
+
* @package Minify
|
11
|
+
* @author Stephen Clay <steve@mrclay.org>
|
12
|
+
*/
|
13
|
+
class Minify_CSS_UriRewriter {
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Defines which class to call as part of callbacks, change this
|
17
|
+
* if you extend Minify_CSS_UriRewriter
|
18
|
+
* @var string
|
19
|
+
*/
|
20
|
+
protected static $className = 'Minify_CSS_UriRewriter';
|
21
|
+
|
22
|
+
/**
|
23
|
+
* rewrite() and rewriteRelative() append debugging information here
|
24
|
+
* @var string
|
25
|
+
*/
|
26
|
+
public static $debugText = '';
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Rewrite file relative URIs as root relative in CSS files
|
30
|
+
*
|
31
|
+
* @param string $css
|
32
|
+
*
|
33
|
+
* @param string $currentDir The directory of the current CSS file.
|
34
|
+
*
|
35
|
+
* @param string $docRoot The document root of the web site in which
|
36
|
+
* the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']).
|
37
|
+
*
|
38
|
+
* @param array $symlinks (default = array()) If the CSS file is stored in
|
39
|
+
* a symlink-ed directory, provide an array of link paths to
|
40
|
+
* target paths, where the link paths are within the document root. Because
|
41
|
+
* paths need to be normalized for this to work, use "//" to substitute
|
42
|
+
* the doc root in the link paths (the array keys). E.g.:
|
43
|
+
* <code>
|
44
|
+
* array('//symlink' => '/real/target/path') // unix
|
45
|
+
* array('//static' => 'D:\\staticStorage') // Windows
|
46
|
+
* </code>
|
47
|
+
*
|
48
|
+
* @return string
|
49
|
+
*/
|
50
|
+
public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array())
|
51
|
+
{
|
52
|
+
self::$_docRoot = self::_realpath(
|
53
|
+
$docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']
|
54
|
+
);
|
55
|
+
self::$_currentDir = self::_realpath($currentDir);
|
56
|
+
self::$_symlinks = array();
|
57
|
+
|
58
|
+
// normalize symlinks
|
59
|
+
foreach ($symlinks as $link => $target) {
|
60
|
+
$link = ($link === '//')
|
61
|
+
? self::$_docRoot
|
62
|
+
: str_replace('//', self::$_docRoot . '/', $link);
|
63
|
+
$link = strtr($link, '/', DIRECTORY_SEPARATOR);
|
64
|
+
self::$_symlinks[$link] = self::_realpath($target);
|
65
|
+
}
|
66
|
+
|
67
|
+
self::$debugText .= "docRoot : " . self::$_docRoot . "\n"
|
68
|
+
. "currentDir : " . self::$_currentDir . "\n";
|
69
|
+
if (self::$_symlinks) {
|
70
|
+
self::$debugText .= "symlinks : " . var_export(self::$_symlinks, 1) . "\n";
|
71
|
+
}
|
72
|
+
self::$debugText .= "\n";
|
73
|
+
|
74
|
+
$css = self::_trimUrls($css);
|
75
|
+
|
76
|
+
// rewrite
|
77
|
+
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
|
78
|
+
,array(self::$className, '_processUriCB'), $css);
|
79
|
+
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
80
|
+
,array(self::$className, '_processUriCB'), $css);
|
81
|
+
|
82
|
+
return $css;
|
83
|
+
}
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Prepend a path to relative URIs in CSS files
|
87
|
+
*
|
88
|
+
* @param string $css
|
89
|
+
*
|
90
|
+
* @param string $path The path to prepend.
|
91
|
+
*
|
92
|
+
* @return string
|
93
|
+
*/
|
94
|
+
public static function prepend($css, $path)
|
95
|
+
{
|
96
|
+
self::$_prependPath = $path;
|
97
|
+
|
98
|
+
$css = self::_trimUrls($css);
|
99
|
+
|
100
|
+
// append
|
101
|
+
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
|
102
|
+
,array(self::$className, '_processUriCB'), $css);
|
103
|
+
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
104
|
+
,array(self::$className, '_processUriCB'), $css);
|
105
|
+
|
106
|
+
self::$_prependPath = null;
|
107
|
+
return $css;
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
/**
|
112
|
+
* @var string directory of this stylesheet
|
113
|
+
*/
|
114
|
+
private static $_currentDir = '';
|
115
|
+
|
116
|
+
/**
|
117
|
+
* @var string DOC_ROOT
|
118
|
+
*/
|
119
|
+
private static $_docRoot = '';
|
120
|
+
|
121
|
+
/**
|
122
|
+
* @var array directory replacements to map symlink targets back to their
|
123
|
+
* source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
|
124
|
+
*/
|
125
|
+
private static $_symlinks = array();
|
126
|
+
|
127
|
+
/**
|
128
|
+
* @var string path to prepend
|
129
|
+
*/
|
130
|
+
private static $_prependPath = null;
|
131
|
+
|
132
|
+
private static function _trimUrls($css)
|
133
|
+
{
|
134
|
+
return preg_replace('/
|
135
|
+
url\\( # url(
|
136
|
+
\\s*
|
137
|
+
([^\\)]+?) # 1 = URI (assuming does not contain ")")
|
138
|
+
\\s*
|
139
|
+
\\) # )
|
140
|
+
/x', 'url($1)', $css);
|
141
|
+
}
|
142
|
+
|
143
|
+
private static function _processUriCB($m)
|
144
|
+
{
|
145
|
+
// $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
146
|
+
$isImport = ($m[0][0] === '@');
|
147
|
+
// determine URI and the quote character (if any)
|
148
|
+
if ($isImport) {
|
149
|
+
$quoteChar = $m[1];
|
150
|
+
$uri = $m[2];
|
151
|
+
} else {
|
152
|
+
// $m[1] is either quoted or not
|
153
|
+
$quoteChar = ($m[1][0] === "'" || $m[1][0] === '"')
|
154
|
+
? $m[1][0]
|
155
|
+
: '';
|
156
|
+
$uri = ($quoteChar === '')
|
157
|
+
? $m[1]
|
158
|
+
: substr($m[1], 1, strlen($m[1]) - 2);
|
159
|
+
}
|
160
|
+
// analyze URI
|
161
|
+
if ('/' !== $uri[0] // root-relative
|
162
|
+
&& false === strpos($uri, '//') // protocol (non-data)
|
163
|
+
&& 0 !== strpos($uri, 'data:') // data protocol
|
164
|
+
) {
|
165
|
+
// URI is file-relative: rewrite depending on options
|
166
|
+
$uri = (self::$_prependPath !== null)
|
167
|
+
? (self::$_prependPath . $uri)
|
168
|
+
: self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
|
169
|
+
}
|
170
|
+
return $isImport
|
171
|
+
? "@import {$quoteChar}{$uri}{$quoteChar}"
|
172
|
+
: "url({$quoteChar}{$uri}{$quoteChar})";
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Rewrite a file relative URI as root relative
|
177
|
+
*
|
178
|
+
* <code>
|
179
|
+
* Minify_CSS_UriRewriter::rewriteRelative(
|
180
|
+
* '../img/hello.gif'
|
181
|
+
* , '/home/user/www/css' // path of CSS file
|
182
|
+
* , '/home/user/www' // doc root
|
183
|
+
* );
|
184
|
+
* // returns '/img/hello.gif'
|
185
|
+
*
|
186
|
+
* // example where static files are stored in a symlinked directory
|
187
|
+
* Minify_CSS_UriRewriter::rewriteRelative(
|
188
|
+
* 'hello.gif'
|
189
|
+
* , '/var/staticFiles/theme'
|
190
|
+
* , '/home/user/www'
|
191
|
+
* , array('/home/user/www/static' => '/var/staticFiles')
|
192
|
+
* );
|
193
|
+
* // returns '/static/theme/hello.gif'
|
194
|
+
* </code>
|
195
|
+
*
|
196
|
+
* @param string $uri file relative URI
|
197
|
+
*
|
198
|
+
* @param string $realCurrentDir realpath of the current file's directory.
|
199
|
+
*
|
200
|
+
* @param string $realDocRoot realpath of the site document root.
|
201
|
+
*
|
202
|
+
* @param array $symlinks (default = array()) If the file is stored in
|
203
|
+
* a symlink-ed directory, provide an array of link paths to
|
204
|
+
* real target paths, where the link paths "appear" to be within the document
|
205
|
+
* root. E.g.:
|
206
|
+
* <code>
|
207
|
+
* array('/home/foo/www/not/real/path' => '/real/target/path') // unix
|
208
|
+
* array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows
|
209
|
+
* </code>
|
210
|
+
*
|
211
|
+
* @return string
|
212
|
+
*/
|
213
|
+
public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
|
214
|
+
{
|
215
|
+
// prepend path with current dir separator (OS-independent)
|
216
|
+
$path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
|
217
|
+
. DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
|
218
|
+
|
219
|
+
self::$debugText .= "file-relative URI : {$uri}\n"
|
220
|
+
. "path prepended : {$path}\n";
|
221
|
+
|
222
|
+
// "unresolve" a symlink back to doc root
|
223
|
+
foreach ($symlinks as $link => $target) {
|
224
|
+
if (0 === strpos($path, $target)) {
|
225
|
+
// replace $target with $link
|
226
|
+
$path = $link . substr($path, strlen($target));
|
227
|
+
|
228
|
+
self::$debugText .= "symlink unresolved : {$path}\n";
|
229
|
+
|
230
|
+
break;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
// strip doc root
|
234
|
+
$path = substr($path, strlen($realDocRoot));
|
235
|
+
|
236
|
+
self::$debugText .= "docroot stripped : {$path}\n";
|
237
|
+
|
238
|
+
// fix to root-relative URI
|
239
|
+
|
240
|
+
$uri = strtr($path, '/\\', '//');
|
241
|
+
|
242
|
+
// remove /./ and /../ where possible
|
243
|
+
$uri = str_replace('/./', '/', $uri);
|
244
|
+
// inspired by patch from Oleg Cherniy
|
245
|
+
do {
|
246
|
+
$uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, 1, $changed);
|
247
|
+
} while ($changed);
|
248
|
+
|
249
|
+
self::$debugText .= "traversals removed : {$uri}\n\n";
|
250
|
+
|
251
|
+
return $uri;
|
252
|
+
}
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Get realpath with any trailing slash removed. If realpath() fails,
|
256
|
+
* just remove the trailing slash.
|
257
|
+
*
|
258
|
+
* @param string $path
|
259
|
+
*
|
260
|
+
* @return mixed path with no trailing slash
|
261
|
+
*/
|
262
|
+
protected static function _realpath($path)
|
263
|
+
{
|
264
|
+
$realPath = realpath($path);
|
265
|
+
if ($realPath !== false) {
|
266
|
+
$path = $realPath;
|
267
|
+
}
|
268
|
+
return rtrim($path, '/\\');
|
269
|
+
}
|
270
|
+
}
|