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.
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
+ }