bixbite 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +49 -0
  3. data/VERSION +1 -0
  4. data/bin/bixbite +73 -0
  5. data/lib/bixbite.rb +13 -0
  6. data/lib/bixbite/command.rb +14 -0
  7. data/lib/bixbite/create.rb +76 -0
  8. data/template/Rakefile +25 -0
  9. data/template/assets/bixbite/Rakefile.rb +297 -0
  10. data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
  11. data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
  12. data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
  13. data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
  14. data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
  15. data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
  16. data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
  17. data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
  18. data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
  19. data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
  20. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
  21. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
  22. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
  23. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
  24. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
  25. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
  26. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
  27. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
  28. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
  29. data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
  30. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
  31. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
  32. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
  33. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
  34. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
  35. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
  36. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
  37. data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
  38. data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
  39. data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
  40. data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
  41. data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
  42. data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
  43. data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
  44. data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
  45. data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
  46. data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
  47. data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
  48. data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
  49. data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
  50. data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
  51. data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
  52. data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
  53. data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
  54. data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
  55. data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
  56. data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
  57. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
  58. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
  59. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
  60. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
  61. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
  62. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
  63. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
  64. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
  65. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
  66. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
  67. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
  68. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
  69. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
  70. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
  71. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
  72. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
  73. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
  74. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
  75. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
  76. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
  77. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
  78. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
  79. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
  80. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
  81. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
  82. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
  83. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
  84. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
  85. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
  86. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
  87. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
  88. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
  89. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
  90. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
  91. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
  92. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
  93. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
  94. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
  95. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
  96. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
  97. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
  98. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
  99. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
  100. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
  101. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
  102. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
  103. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
  104. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
  105. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
  106. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
  107. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
  108. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
  109. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
  110. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
  111. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
  112. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
  113. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
  114. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
  115. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
  116. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
  117. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
  118. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
  119. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
  120. data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
  121. data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
  122. data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
  123. data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
  124. data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
  125. data/template/assets/utilities/pngout +0 -0
  126. data/template/deploy/public_html/.htaccess +0 -0
  127. data/template/documentation/js/.htaccess +0 -0
  128. data/template/src/html/.htaccess +76 -0
  129. data/template/src/html/css/cmn/global.css +96 -0
  130. data/template/src/html/css/cmn/ie.css +15 -0
  131. data/template/src/html/css/cmn/ie6.css +15 -0
  132. data/template/src/html/images/cmn/.htaccess +0 -0
  133. data/template/src/html/images/tmp/.htaccess +0 -0
  134. data/template/src/html/includes/debug.inc +5 -0
  135. data/template/src/html/includes/footer.inc +52 -0
  136. data/template/src/html/includes/header.inc +61 -0
  137. data/template/src/html/includes/html.inc +3 -0
  138. data/template/src/html/includes/namespace.inc +19 -0
  139. data/template/src/html/includes/page.inc +151 -0
  140. data/template/src/html/index.html +35 -0
  141. data/template/src/html/js/cmn/bootstrap.js +74 -0
  142. data/template/src/html/js/cmn/global.js +142 -0
  143. data/template/src/html/js/cmn/lib/LAB.js +348 -0
  144. data/template/src/html/min/.htaccess +4 -0
  145. data/template/src/html/min/MinifyCLI.php +19 -0
  146. data/template/src/html/min/README.txt +132 -0
  147. data/template/src/html/min/builder/_index.js +242 -0
  148. data/template/src/html/min/builder/bm.js +36 -0
  149. data/template/src/html/min/builder/index.php +182 -0
  150. data/template/src/html/min/builder/ocCheck.php +36 -0
  151. data/template/src/html/min/builder/rewriteTest.js +1 -0
  152. data/template/src/html/min/config.php +187 -0
  153. data/template/src/html/min/groupsConfig.php +34 -0
  154. data/template/src/html/min/index.php +66 -0
  155. data/template/src/html/min/lib/FirePHP.php +1370 -0
  156. data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
  157. data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
  158. data/template/src/html/min/lib/JSMin.php +314 -0
  159. data/template/src/html/min/lib/JSMinPlus.php +1872 -0
  160. data/template/src/html/min/lib/Minify.php +532 -0
  161. data/template/src/html/min/lib/Minify/Build.php +103 -0
  162. data/template/src/html/min/lib/Minify/CSS.php +83 -0
  163. data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
  164. data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
  165. data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
  166. data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
  167. data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
  168. data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
  169. data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
  170. data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
  171. data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
  172. data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
  173. data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
  174. data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
  175. data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
  176. data/template/src/html/min/lib/Minify/HTML.php +245 -0
  177. data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
  178. data/template/src/html/min/lib/Minify/Lines.php +131 -0
  179. data/template/src/html/min/lib/Minify/Logger.php +45 -0
  180. data/template/src/html/min/lib/Minify/Packer.php +37 -0
  181. data/template/src/html/min/lib/Minify/Source.php +187 -0
  182. data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
  183. data/template/src/html/min/lib/Solar/Dir.php +199 -0
  184. data/template/src/html/min/lib/closure-compiler.jar +0 -0
  185. data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
  186. data/template/src/html/min/utils.php +90 -0
  187. data/template/src/templates/css/template.css +7 -0
  188. data/template/src/templates/js/template.js +72 -0
  189. data/template/src/templates/template.html +18 -0
  190. data/template/src/yaml/config.yml +46 -0
  191. data/template/src/yaml/deploy.yml +35 -0
  192. data/test/bixbite_test.rb +7 -0
  193. data/test/test_helper.rb +10 -0
  194. metadata +278 -0
@@ -0,0 +1,532 @@
1
+ <?php
2
+ /**
3
+ * Class Minify
4
+ * @package Minify
5
+ */
6
+
7
+ /**
8
+ * Minify_Source
9
+ */
10
+ require_once 'Minify/Source.php';
11
+
12
+ /**
13
+ * Minify - Combines, minifies, and caches JavaScript and CSS files on demand.
14
+ *
15
+ * See README for usage instructions (for now).
16
+ *
17
+ * This library was inspired by {@link mailto:flashkot@mail.ru jscsscomp by Maxim Martynyuk}
18
+ * and by the article {@link http://www.hunlock.com/blogs/Supercharged_Javascript "Supercharged JavaScript" by Patrick Hunlock}.
19
+ *
20
+ * Requires PHP 5.1.0.
21
+ * Tested on PHP 5.1.6.
22
+ *
23
+ * @package Minify
24
+ * @author Ryan Grove <ryan@wonko.com>
25
+ * @author Stephen Clay <steve@mrclay.org>
26
+ * @copyright 2008 Ryan Grove, Stephen Clay. All rights reserved.
27
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
28
+ * @link http://code.google.com/p/minify/
29
+ */
30
+ class Minify {
31
+
32
+ const VERSION = '2.1.3';
33
+ const TYPE_CSS = 'text/css';
34
+ const TYPE_HTML = 'text/html';
35
+ // there is some debate over the ideal JS Content-Type, but this is the
36
+ // Apache default and what Yahoo! uses..
37
+ const TYPE_JS = 'application/x-javascript';
38
+
39
+ /**
40
+ * How many hours behind are the file modification times of uploaded files?
41
+ *
42
+ * If you upload files from Windows to a non-Windows server, Windows may report
43
+ * incorrect mtimes for the files. Immediately after modifying and uploading a
44
+ * file, use the touch command to update the mtime on the server. If the mtime
45
+ * jumps ahead by a number of hours, set this variable to that number. If the mtime
46
+ * moves back, this should not be needed.
47
+ *
48
+ * @var int $uploaderHoursBehind
49
+ */
50
+ public static $uploaderHoursBehind = 0;
51
+
52
+ /**
53
+ * If this string is not empty AND the serve() option 'bubbleCssImports' is
54
+ * NOT set, then serve() will check CSS files for @import declarations that
55
+ * appear too late in the combined stylesheet. If found, serve() will prepend
56
+ * the output with this warning.
57
+ *
58
+ * @var string $importWarning
59
+ */
60
+ public static $importWarning = "/* See http://code.google.com/p/minify/wiki/CommonProblems#@imports_can_appear_in_invalid_locations_in_combined_CSS_files */\n";
61
+
62
+ /**
63
+ * Specify a cache object (with identical interface as Minify_Cache_File) or
64
+ * a path to use with Minify_Cache_File.
65
+ *
66
+ * If not called, Minify will not use a cache and, for each 200 response, will
67
+ * need to recombine files, minify and encode the output.
68
+ *
69
+ * @param mixed $cache object with identical interface as Minify_Cache_File or
70
+ * a directory path, or null to disable caching. (default = '')
71
+ *
72
+ * @param bool $fileLocking (default = true) This only applies if the first
73
+ * parameter is a string.
74
+ *
75
+ * @return null
76
+ */
77
+ public static function setCache($cache = '', $fileLocking = true)
78
+ {
79
+ if (is_string($cache)) {
80
+ require_once 'Minify/Cache/File.php';
81
+ self::$_cache = new Minify_Cache_File($cache, $fileLocking);
82
+ } else {
83
+ self::$_cache = $cache;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Serve a request for a minified file.
89
+ *
90
+ * Here are the available options and defaults in the base controller:
91
+ *
92
+ * 'isPublic' : send "public" instead of "private" in Cache-Control
93
+ * headers, allowing shared caches to cache the output. (default true)
94
+ *
95
+ * 'quiet' : set to true to have serve() return an array rather than sending
96
+ * any headers/output (default false)
97
+ *
98
+ * 'encodeOutput' : set to false to disable content encoding, and not send
99
+ * the Vary header (default true)
100
+ *
101
+ * 'encodeMethod' : generally you should let this be determined by
102
+ * HTTP_Encoder (leave null), but you can force a particular encoding
103
+ * to be returned, by setting this to 'gzip' or '' (no encoding)
104
+ *
105
+ * 'encodeLevel' : level of encoding compression (0 to 9, default 9)
106
+ *
107
+ * 'contentTypeCharset' : appended to the Content-Type header sent. Set to a falsey
108
+ * value to remove. (default 'utf-8')
109
+ *
110
+ * 'maxAge' : set this to the number of seconds the client should use its cache
111
+ * before revalidating with the server. This sets Cache-Control: max-age and the
112
+ * Expires header. Unlike the old 'setExpires' setting, this setting will NOT
113
+ * prevent conditional GETs. Note this has nothing to do with server-side caching.
114
+ *
115
+ * 'rewriteCssUris' : If true, serve() will automatically set the 'currentDir'
116
+ * minifier option to enable URI rewriting in CSS files (default true)
117
+ *
118
+ * 'bubbleCssImports' : If true, all @import declarations in combined CSS
119
+ * files will be move to the top. Note this may alter effective CSS values
120
+ * due to a change in order. (default false)
121
+ *
122
+ * 'debug' : set to true to minify all sources with the 'Lines' controller, which
123
+ * eases the debugging of combined files. This also prevents 304 responses.
124
+ * @see Minify_Lines::minify()
125
+ *
126
+ * 'minifiers' : to override Minify's default choice of minifier function for
127
+ * a particular content-type, specify your callback under the key of the
128
+ * content-type:
129
+ * <code>
130
+ * // call customCssMinifier($css) for all CSS minification
131
+ * $options['minifiers'][Minify::TYPE_CSS] = 'customCssMinifier';
132
+ *
133
+ * // don't minify Javascript at all
134
+ * $options['minifiers'][Minify::TYPE_JS] = '';
135
+ * </code>
136
+ *
137
+ * 'minifierOptions' : to send options to the minifier function, specify your options
138
+ * under the key of the content-type. E.g. To send the CSS minifier an option:
139
+ * <code>
140
+ * // give CSS minifier array('optionName' => 'optionValue') as 2nd argument
141
+ * $options['minifierOptions'][Minify::TYPE_CSS]['optionName'] = 'optionValue';
142
+ * </code>
143
+ *
144
+ * 'contentType' : (optional) this is only needed if your file extension is not
145
+ * js/css/html. The given content-type will be sent regardless of source file
146
+ * extension, so this should not be used in a Groups config with other
147
+ * Javascript/CSS files.
148
+ *
149
+ * Any controller options are documented in that controller's setupSources() method.
150
+ *
151
+ * @param mixed instance of subclass of Minify_Controller_Base or string name of
152
+ * controller. E.g. 'Files'
153
+ *
154
+ * @param array $options controller/serve options
155
+ *
156
+ * @return mixed null, or, if the 'quiet' option is set to true, an array
157
+ * with keys "success" (bool), "statusCode" (int), "content" (string), and
158
+ * "headers" (array).
159
+ */
160
+ public static function serve($controller, $options = array())
161
+ {
162
+ if (is_string($controller)) {
163
+ // make $controller into object
164
+ $class = 'Minify_Controller_' . $controller;
165
+ if (! class_exists($class, false)) {
166
+ require_once "Minify/Controller/"
167
+ . str_replace('_', '/', $controller) . ".php";
168
+ }
169
+ $controller = new $class();
170
+ }
171
+
172
+ // set up controller sources and mix remaining options with
173
+ // controller defaults
174
+ $options = $controller->setupSources($options);
175
+ $options = $controller->analyzeSources($options);
176
+ self::$_options = $controller->mixInDefaultOptions($options);
177
+
178
+ // check request validity
179
+ if (! $controller->sources) {
180
+ // invalid request!
181
+ if (! self::$_options['quiet']) {
182
+ header(self::$_options['badRequestHeader']);
183
+ echo self::$_options['badRequestHeader'];
184
+ return;
185
+ } else {
186
+ list(,$statusCode) = explode(' ', self::$_options['badRequestHeader']);
187
+ return array(
188
+ 'success' => false
189
+ ,'statusCode' => (int)$statusCode
190
+ ,'content' => ''
191
+ ,'headers' => array()
192
+ );
193
+ }
194
+ }
195
+
196
+ self::$_controller = $controller;
197
+
198
+ if (self::$_options['debug']) {
199
+ self::_setupDebug($controller->sources);
200
+ self::$_options['maxAge'] = 0;
201
+ }
202
+
203
+ // determine encoding
204
+ if (self::$_options['encodeOutput']) {
205
+ if (self::$_options['encodeMethod'] !== null) {
206
+ // controller specifically requested this
207
+ $contentEncoding = self::$_options['encodeMethod'];
208
+ } else {
209
+ // sniff request header
210
+ require_once 'HTTP/Encoder.php';
211
+ // depending on what the client accepts, $contentEncoding may be
212
+ // 'x-gzip' while our internal encodeMethod is 'gzip'. Calling
213
+ // getAcceptedEncoding(false, false) leaves out compress and deflate as options.
214
+ list(self::$_options['encodeMethod'], $contentEncoding) = HTTP_Encoder::getAcceptedEncoding(false, false);
215
+ }
216
+ } else {
217
+ self::$_options['encodeMethod'] = ''; // identity (no encoding)
218
+ }
219
+
220
+ // check client cache
221
+ require_once 'HTTP/ConditionalGet.php';
222
+ $cgOptions = array(
223
+ 'lastModifiedTime' => self::$_options['lastModifiedTime']
224
+ ,'isPublic' => self::$_options['isPublic']
225
+ ,'encoding' => self::$_options['encodeMethod']
226
+ );
227
+ if (self::$_options['maxAge'] > 0) {
228
+ $cgOptions['maxAge'] = self::$_options['maxAge'];
229
+ }
230
+ $cg = new HTTP_ConditionalGet($cgOptions);
231
+ if ($cg->cacheIsValid) {
232
+ // client's cache is valid
233
+ if (! self::$_options['quiet']) {
234
+ $cg->sendHeaders();
235
+ return;
236
+ } else {
237
+ return array(
238
+ 'success' => true
239
+ ,'statusCode' => 304
240
+ ,'content' => ''
241
+ ,'headers' => $cg->getHeaders()
242
+ );
243
+ }
244
+ } else {
245
+ // client will need output
246
+ $headers = $cg->getHeaders();
247
+ unset($cg);
248
+ }
249
+
250
+ if (self::$_options['contentType'] === self::TYPE_CSS
251
+ && self::$_options['rewriteCssUris']) {
252
+ reset($controller->sources);
253
+ while (list($key, $source) = each($controller->sources)) {
254
+ if ($source->filepath
255
+ && !isset($source->minifyOptions['currentDir'])
256
+ && !isset($source->minifyOptions['prependRelativePath'])
257
+ ) {
258
+ $source->minifyOptions['currentDir'] = dirname($source->filepath);
259
+ }
260
+ }
261
+ }
262
+
263
+ // check server cache
264
+ if (null !== self::$_cache) {
265
+ // using cache
266
+ // the goal is to use only the cache methods to sniff the length and
267
+ // output the content, as they do not require ever loading the file into
268
+ // memory.
269
+ $cacheId = 'minify_' . self::_getCacheId();
270
+ $fullCacheId = (self::$_options['encodeMethod'])
271
+ ? $cacheId . '.gz'
272
+ : $cacheId;
273
+ // check cache for valid entry
274
+ $cacheIsReady = self::$_cache->isValid($fullCacheId, self::$_options['lastModifiedTime']);
275
+ if ($cacheIsReady) {
276
+ $cacheContentLength = self::$_cache->getSize($fullCacheId);
277
+ } else {
278
+ // generate & cache content
279
+ $content = self::_combineMinify();
280
+ self::$_cache->store($cacheId, $content);
281
+ if (function_exists('gzencode')) {
282
+ self::$_cache->store($cacheId . '.gz', gzencode($content, self::$_options['encodeLevel']));
283
+ }
284
+ }
285
+ } else {
286
+ // no cache
287
+ $cacheIsReady = false;
288
+ $content = self::_combineMinify();
289
+ }
290
+ if (! $cacheIsReady && self::$_options['encodeMethod']) {
291
+ // still need to encode
292
+ $content = gzencode($content, self::$_options['encodeLevel']);
293
+ }
294
+
295
+ // add headers
296
+ $headers['Content-Length'] = $cacheIsReady
297
+ ? $cacheContentLength
298
+ : strlen($content);
299
+ $headers['Content-Type'] = self::$_options['contentTypeCharset']
300
+ ? self::$_options['contentType'] . '; charset=' . self::$_options['contentTypeCharset']
301
+ : self::$_options['contentType'];
302
+ if (self::$_options['encodeMethod'] !== '') {
303
+ $headers['Content-Encoding'] = $contentEncoding;
304
+ }
305
+ if (self::$_options['encodeOutput']) {
306
+ $headers['Vary'] = 'Accept-Encoding';
307
+ }
308
+
309
+ if (! self::$_options['quiet']) {
310
+ // output headers & content
311
+ foreach ($headers as $name => $val) {
312
+ header($name . ': ' . $val);
313
+ }
314
+ if ($cacheIsReady) {
315
+ self::$_cache->display($fullCacheId);
316
+ } else {
317
+ echo $content;
318
+ }
319
+ } else {
320
+ return array(
321
+ 'success' => true
322
+ ,'statusCode' => 200
323
+ ,'content' => $cacheIsReady
324
+ ? self::$_cache->fetch($fullCacheId)
325
+ : $content
326
+ ,'headers' => $headers
327
+ );
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Return combined minified content for a set of sources
333
+ *
334
+ * No internal caching will be used and the content will not be HTTP encoded.
335
+ *
336
+ * @param array $sources array of filepaths and/or Minify_Source objects
337
+ *
338
+ * @param array $options (optional) array of options for serve. By default
339
+ * these are already set: quiet = true, encodeMethod = '', lastModifiedTime = 0.
340
+ *
341
+ * @return string
342
+ */
343
+ public static function combine($sources, $options = array())
344
+ {
345
+ $cache = self::$_cache;
346
+ self::$_cache = null;
347
+ $options = array_merge(array(
348
+ 'files' => (array)$sources
349
+ ,'quiet' => true
350
+ ,'encodeMethod' => ''
351
+ ,'lastModifiedTime' => 0
352
+ ), $options);
353
+ $out = self::serve('Files', $options);
354
+ self::$_cache = $cache;
355
+ return $out['content'];
356
+ }
357
+
358
+ /**
359
+ * On IIS, create $_SERVER['DOCUMENT_ROOT']
360
+ *
361
+ * @param bool $unsetPathInfo (default false) if true, $_SERVER['PATH_INFO']
362
+ * will be unset (it is inconsistent with Apache's setting)
363
+ *
364
+ * @return null
365
+ */
366
+ public static function setDocRoot($unsetPathInfo = false)
367
+ {
368
+ if (isset($_SERVER['SERVER_SOFTWARE'])
369
+ && 0 === strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/')
370
+ ) {
371
+ $_SERVER['DOCUMENT_ROOT'] = rtrim(substr(
372
+ $_SERVER['PATH_TRANSLATED']
373
+ ,0
374
+ ,strlen($_SERVER['PATH_TRANSLATED']) - strlen($_SERVER['SCRIPT_NAME'])
375
+ ), '\\');
376
+ if ($unsetPathInfo) {
377
+ unset($_SERVER['PATH_INFO']);
378
+ }
379
+ require_once 'Minify/Logger.php';
380
+ Minify_Logger::log("setDocRoot() set DOCUMENT_ROOT to \"{$_SERVER['DOCUMENT_ROOT']}\"");
381
+ }
382
+ }
383
+
384
+ /**
385
+ * @var mixed Minify_Cache_* object or null (i.e. no server cache is used)
386
+ */
387
+ private static $_cache = null;
388
+
389
+ /**
390
+ * @var Minify_Controller active controller for current request
391
+ */
392
+ protected static $_controller = null;
393
+
394
+ /**
395
+ * @var array options for current request
396
+ */
397
+ protected static $_options = null;
398
+
399
+ /**
400
+ * Set up sources to use Minify_Lines
401
+ *
402
+ * @param array $sources Minify_Source instances
403
+ *
404
+ * @return null
405
+ */
406
+ protected static function _setupDebug($sources)
407
+ {
408
+ foreach ($sources as $source) {
409
+ $source->minifier = array('Minify_Lines', 'minify');
410
+ $id = $source->getId();
411
+ $source->minifyOptions = array(
412
+ 'id' => (is_file($id) ? basename($id) : $id)
413
+ );
414
+ }
415
+ }
416
+
417
+ /**
418
+ * Combines sources and minifies the result.
419
+ *
420
+ * @return string
421
+ */
422
+ protected static function _combineMinify()
423
+ {
424
+ $type = self::$_options['contentType']; // ease readability
425
+
426
+ // when combining scripts, make sure all statements separated and
427
+ // trailing single line comment is terminated
428
+ $implodeSeparator = ($type === self::TYPE_JS)
429
+ ? "\n;"
430
+ : '';
431
+ // allow the user to pass a particular array of options to each
432
+ // minifier (designated by type). source objects may still override
433
+ // these
434
+ $defaultOptions = isset(self::$_options['minifierOptions'][$type])
435
+ ? self::$_options['minifierOptions'][$type]
436
+ : array();
437
+ // if minifier not set, default is no minification. source objects
438
+ // may still override this
439
+ $defaultMinifier = isset(self::$_options['minifiers'][$type])
440
+ ? self::$_options['minifiers'][$type]
441
+ : false;
442
+
443
+ if (Minify_Source::haveNoMinifyPrefs(self::$_controller->sources)) {
444
+ // all source have same options/minifier, better performance
445
+ // to combine, then minify once
446
+ foreach (self::$_controller->sources as $source) {
447
+ $pieces[] = $source->getContent();
448
+ }
449
+ $content = implode($implodeSeparator, $pieces);
450
+ if ($defaultMinifier) {
451
+ self::$_controller->loadMinifier($defaultMinifier);
452
+ $content = call_user_func($defaultMinifier, $content, $defaultOptions);
453
+ }
454
+ } else {
455
+ // minify each source with its own options and minifier, then combine
456
+ foreach (self::$_controller->sources as $source) {
457
+ // allow the source to override our minifier and options
458
+ $minifier = (null !== $source->minifier)
459
+ ? $source->minifier
460
+ : $defaultMinifier;
461
+ $options = (null !== $source->minifyOptions)
462
+ ? array_merge($defaultOptions, $source->minifyOptions)
463
+ : $defaultOptions;
464
+ if ($minifier) {
465
+ self::$_controller->loadMinifier($minifier);
466
+ // get source content and minify it
467
+ $pieces[] = call_user_func($minifier, $source->getContent(), $options);
468
+ } else {
469
+ $pieces[] = $source->getContent();
470
+ }
471
+ }
472
+ $content = implode($implodeSeparator, $pieces);
473
+ }
474
+
475
+ if ($type === self::TYPE_CSS && false !== strpos($content, '@import')) {
476
+ $content = self::_handleCssImports($content);
477
+ }
478
+
479
+ // do any post-processing (esp. for editing build URIs)
480
+ if (self::$_options['postprocessorRequire']) {
481
+ require_once self::$_options['postprocessorRequire'];
482
+ }
483
+ if (self::$_options['postprocessor']) {
484
+ $content = call_user_func(self::$_options['postprocessor'], $content, $type);
485
+ }
486
+ return $content;
487
+ }
488
+
489
+ /**
490
+ * Make a unique cache id for for this request.
491
+ *
492
+ * Any settings that could affect output are taken into consideration
493
+ *
494
+ * @return string
495
+ */
496
+ protected static function _getCacheId()
497
+ {
498
+ return md5(serialize(array(
499
+ Minify_Source::getDigest(self::$_controller->sources)
500
+ ,self::$_options['minifiers']
501
+ ,self::$_options['minifierOptions']
502
+ ,self::$_options['postprocessor']
503
+ ,self::$_options['bubbleCssImports']
504
+ )));
505
+ }
506
+
507
+ /**
508
+ * Bubble CSS @imports to the top or prepend a warning if an
509
+ * @import is detected not at the top.
510
+ */
511
+ protected static function _handleCssImports($css)
512
+ {
513
+ if (self::$_options['bubbleCssImports']) {
514
+ // bubble CSS imports
515
+ preg_match_all('/@import.*?;/', $css, $imports);
516
+ $css = implode('', $imports[0]) . preg_replace('/@import.*?;/', '', $css);
517
+ } else if ('' !== self::$importWarning) {
518
+ // remove comments so we don't mistake { in a comment as a block
519
+ $noCommentCss = preg_replace('@/\\*[\\s\\S]*?\\*/@', '', $css);
520
+ $lastImportPos = strrpos($noCommentCss, '@import');
521
+ $firstBlockPos = strpos($noCommentCss, '{');
522
+ if (false !== $lastImportPos
523
+ && false !== $firstBlockPos
524
+ && $firstBlockPos < $lastImportPos
525
+ ) {
526
+ // { appears before @import : prepend warning
527
+ $css = self::$importWarning . $css;
528
+ }
529
+ }
530
+ return $css;
531
+ }
532
+ }