├── .gitignore
├── system
└── expressionengine
│ └── third_party
│ └── minimee
│ ├── config.php
│ ├── views
│ ├── eedebug_panel.php
│ └── settings_form.php
│ ├── libraries
│ ├── Minify
│ │ ├── Loader.php
│ │ ├── DebugDetector.php
│ │ ├── Packer.php
│ │ ├── Logger.php
│ │ ├── Controller
│ │ │ ├── Files.php
│ │ │ ├── Page.php
│ │ │ ├── Groups.php
│ │ │ ├── Version1.php
│ │ │ ├── Base.php
│ │ │ └── MinApp.php
│ │ ├── CommentPreserver.php
│ │ ├── Build.php
│ │ ├── Cache
│ │ │ ├── APC.php
│ │ │ ├── XCache.php
│ │ │ ├── ZendPlatform.php
│ │ │ ├── Memcache.php
│ │ │ └── File.php
│ │ ├── CSS.php
│ │ ├── ClosureCompiler.php
│ │ ├── JS
│ │ │ └── ClosureCompiler.php
│ │ ├── Lines.php
│ │ ├── YUICompressor.php
│ │ ├── Source.php
│ │ ├── YUI
│ │ │ └── CssCompressor.php
│ │ ├── HTML
│ │ │ └── Helper.php
│ │ ├── ImportProcessor.php
│ │ ├── CSS
│ │ │ ├── Compressor.php
│ │ │ └── UriRewriter.php
│ │ └── HTML.php
│ ├── EpiCurl.php
│ └── HTTP
│ │ ├── Encoder.php
│ │ └── ConditionalGet.php
│ ├── language
│ └── english
│ │ └── lang.minimee.php
│ ├── classes
│ └── Minimee_helper.php
│ └── ext.minimee.php
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
--------------------------------------------------------------------------------
/system/expressionengine/third_party/minimee/config.php:
--------------------------------------------------------------------------------
1 |
2 | INFO: Basic messages logged at each signficant point in process
3 | DEBUG: Possible problem or event that may explain unexpected behaviour
4 | ERROR: Minimee has failed, and this is why.
5 |
6 |
58 | * echo $b->uri('/site.js');
59 | * // outputs "/site.js?1678242"
60 | *
61 | * echo $b->uri('/scriptaculous.js?load=effects');
62 | * // outputs "/scriptaculous.js?load=effects&1678242"
63 | *
64 | *
65 | * @param string $uri
66 | * @param boolean $forceAmpersand (default = false) Force the use of ampersand to
67 | * append the timestamp to the URI.
68 | * @return string
69 | */
70 | public function uri($uri, $forceAmpersand = false) {
71 | $sep = ($forceAmpersand || strpos($uri, '?') !== false)
72 | ? self::$ampersand
73 | : '?';
74 | return "{$uri}{$sep}{$this->lastModified}";
75 | }
76 |
77 | /**
78 | * Create a build object
79 | *
80 | * @param array $sources array of Minify_Source objects and/or file paths
81 | *
82 | * @return null
83 | */
84 | public function __construct($sources)
85 | {
86 | $max = 0;
87 | foreach ((array)$sources as $source) {
88 | if ($source instanceof Minify_Source) {
89 | $max = max($max, $source->lastModified);
90 | } elseif (is_string($source)) {
91 | if (0 === strpos($source, '//')) {
92 | $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1);
93 | }
94 | if (is_file($source)) {
95 | $max = max($max, filemtime($source));
96 | }
97 | }
98 | }
99 | $this->lastModified = $max;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/system/expressionengine/third_party/minimee/libraries/Minify/Cache/APC.php:
--------------------------------------------------------------------------------
1 |
11 | * Minify::setCache(new Minify_Cache_APC());
12 | *
13 | *
14 | * @package Minify
15 | * @author Chris Edwards
16 | **/
17 | class Minify_Cache_APC {
18 |
19 | /**
20 | * Create a Minify_Cache_APC object, to be passed to
21 | * Minify::setCache().
22 | *
23 | *
24 | * @param int $expire seconds until expiration (default = 0
25 | * meaning the item will not get an expiration date)
26 | *
27 | * @return null
28 | */
29 | public function __construct($expire = 0)
30 | {
31 | $this->_exp = $expire;
32 | }
33 |
34 | /**
35 | * Write data to cache.
36 | *
37 | * @param string $id cache id
38 | *
39 | * @param string $data
40 | *
41 | * @return bool success
42 | */
43 | public function store($id, $data)
44 | {
45 | return apc_store($id, "{$_SERVER['REQUEST_TIME']}|{$data}", $this->_exp);
46 | }
47 |
48 | /**
49 | * Get the size of a cache entry
50 | *
51 | * @param string $id cache id
52 | *
53 | * @return int size in bytes
54 | */
55 | public function getSize($id)
56 | {
57 | if (! $this->_fetch($id)) {
58 | return false;
59 | }
60 | return (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2))
61 | ? mb_strlen($this->_data, '8bit')
62 | : strlen($this->_data);
63 | }
64 |
65 | /**
66 | * Does a valid cache entry exist?
67 | *
68 | * @param string $id cache id
69 | *
70 | * @param int $srcMtime mtime of the original source file(s)
71 | *
72 | * @return bool exists
73 | */
74 | public function isValid($id, $srcMtime)
75 | {
76 | return ($this->_fetch($id) && ($this->_lm >= $srcMtime));
77 | }
78 |
79 | /**
80 | * Send the cached content to output
81 | *
82 | * @param string $id cache id
83 | */
84 | public function display($id)
85 | {
86 | echo $this->_fetch($id)
87 | ? $this->_data
88 | : '';
89 | }
90 |
91 | /**
92 | * Fetch the cached content
93 | *
94 | * @param string $id cache id
95 | *
96 | * @return string
97 | */
98 | public function fetch($id)
99 | {
100 | return $this->_fetch($id)
101 | ? $this->_data
102 | : '';
103 | }
104 |
105 | private $_exp = null;
106 |
107 | // cache of most recently fetched id
108 | private $_lm = null;
109 | private $_data = null;
110 | private $_id = null;
111 |
112 | /**
113 | * Fetch data and timestamp from apc, store in instance
114 | *
115 | * @param string $id
116 | *
117 | * @return bool success
118 | */
119 | private function _fetch($id)
120 | {
121 | if ($this->_id === $id) {
122 | return true;
123 | }
124 | $ret = apc_fetch($id);
125 | if (false === $ret) {
126 | $this->_id = null;
127 | return false;
128 | }
129 | list($this->_lm, $this->_data) = explode('|', $ret, 2);
130 | $this->_id = $id;
131 | return true;
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/system/expressionengine/third_party/minimee/libraries/Minify/Cache/XCache.php:
--------------------------------------------------------------------------------
1 |
14 | * Minify::setCache(new Minify_Cache_XCache());
15 | *
16 | *
17 | * @package Minify
18 | * @author Elan Ruusamäe
47 | * array('//symlink' => '/real/target/path') // unix
48 | * array('//static' => 'D:\\staticStorage') // Windows
49 | *
50 | *
51 | * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT'])
52 | * see Minify_CSS_UriRewriter::rewrite
53 | *
54 | * @return string
55 | */
56 | public static function minify($css, $options = array())
57 | {
58 | $options = array_merge(array(
59 | 'compress' => true,
60 | 'removeCharsets' => true,
61 | 'preserveComments' => true,
62 | 'currentDir' => null,
63 | 'docRoot' => $_SERVER['DOCUMENT_ROOT'],
64 | 'prependRelativePath' => null,
65 | 'symlinks' => array(),
66 | ), $options);
67 |
68 | if ($options['removeCharsets']) {
69 | $css = preg_replace('/@charset[^;]+;\\s*/', '', $css);
70 | }
71 | if ($options['compress']) {
72 | if (! $options['preserveComments']) {
73 | $css = Minify_CSS_Compressor::process($css, $options);
74 | } else {
75 | $css = Minify_CommentPreserver::process(
76 | $css
77 | ,array('Minify_CSS_Compressor', 'process')
78 | ,array($options)
79 | );
80 | }
81 | }
82 | if (! $options['currentDir'] && ! $options['prependRelativePath']) {
83 | return $css;
84 | }
85 | if ($options['currentDir']) {
86 | return Minify_CSS_UriRewriter::rewrite(
87 | $css
88 | ,$options['currentDir']
89 | ,$options['docRoot']
90 | ,$options['symlinks']
91 | );
92 | } else {
93 | return Minify_CSS_UriRewriter::prepend(
94 | $css
95 | ,$options['prependRelativePath']
96 | );
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/system/expressionengine/third_party/minimee/libraries/Minify/ClosureCompiler.php:
--------------------------------------------------------------------------------
1 |
16 | * Minify_ClosureCompiler::$jarFile = '/path/to/closure-compiler-20120123.jar';
17 | * Minify_ClosureCompiler::$tempDir = '/tmp';
18 | * $code = Minify_ClosureCompiler::minify(
19 | * $code,
20 | * array('compilation_level' => 'SIMPLE_OPTIMIZATIONS')
21 | * );
22 | *
23 | * --compilation_level WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, ADVANCED_OPTIMIZATIONS
24 | *
25 | *
26 | *
27 | * @todo unit tests, $options docs
28 | * @todo more options support (or should just passthru them all?)
29 | *
30 | * @package Minify
31 | * @author Stephen Clay ' . $label . ' ' . $setting . '
'; 22 | 23 | 24 | /** 25 | * begin our DOM wrapper 26 | */ 27 | echo '' . form_submit('submit', lang('save'), 'class="submit"') . '
'; 197 | $this->table->clear(); 198 | echo form_close(); 199 | ?> 200 | 201 | 252 | 253 | 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 40 | */ 41 | protected $_options = null; 42 | 43 | /** 44 | * Are we "in" a hack? I.e. are some browsers targetted until the next comment? 45 | * 46 | * @var bool 47 | */ 48 | protected $_inHack = false; 49 | 50 | 51 | /** 52 | * Constructor 53 | * 54 | * @param array $options (currently ignored) 55 | */ 56 | private function __construct($options) { 57 | $this->_options = $options; 58 | } 59 | 60 | /** 61 | * Minify a CSS string 62 | * 63 | * @param string $css 64 | * 65 | * @return string 66 | */ 67 | protected function _process($css) 68 | { 69 | $css = str_replace("\r\n", "\n", $css); 70 | 71 | // preserve empty comment after '>' 72 | // http://www.webdevout.net/css-hacks#in_css-selectors 73 | $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css); 74 | 75 | // preserve empty comment between property and value 76 | // http://css-discuss.incutio.com/?page=BoxModelHack 77 | $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css); 78 | $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css); 79 | 80 | // apply callback to all valid comments (and strip out surrounding ws 81 | $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@' 82 | ,array($this, '_commentCB'), $css); 83 | 84 | // remove ws around { } and last semicolon in declaration block 85 | $css = preg_replace('/\\s*{\\s*/', '{', $css); 86 | $css = preg_replace('/;?\\s*}\\s*/', '}', $css); 87 | 88 | // remove ws surrounding semicolons 89 | $css = preg_replace('/\\s*;\\s*/', ';', $css); 90 | 91 | // remove ws around urls 92 | $css = preg_replace('/ 93 | url\\( # url( 94 | \\s* 95 | ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis) 96 | \\s* 97 | \\) # ) 98 | /x', 'url($1)', $css); 99 | 100 | // remove ws between rules and colons 101 | $css = preg_replace('/ 102 | \\s* 103 | ([{;]) # 1 = beginning of block or rule separator 104 | \\s* 105 | ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter) 106 | \\s* 107 | : 108 | \\s* 109 | (\\b|[#\'"-]) # 3 = first character of a value 110 | /x', '$1$2:$3', $css); 111 | 112 | // remove ws in selectors 113 | $css = preg_replace_callback('/ 114 | (?: # non-capture 115 | \\s* 116 | [^~>+,\\s]+ # selector part 117 | \\s* 118 | [,>+~] # combinators 119 | )+ 120 | \\s* 121 | [^~>+,\\s]+ # selector part 122 | { # open declaration block 123 | /x' 124 | ,array($this, '_selectorsCB'), $css); 125 | 126 | // minimize hex colors 127 | $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i' 128 | , '$1#$2$3$4$5', $css); 129 | 130 | // remove spaces between font families 131 | $css = preg_replace_callback('/font-family:([^;}]+)([;}])/' 132 | ,array($this, '_fontFamilyCB'), $css); 133 | 134 | $css = preg_replace('/@import\\s+url/', '@import url', $css); 135 | 136 | // replace any ws involving newlines with a single newline 137 | $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css); 138 | 139 | // separate common descendent selectors w/ newlines (to limit line lengths) 140 | $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css); 141 | 142 | // Use newline after 1st numeric value (to limit line lengths). 143 | $css = preg_replace('/ 144 | ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value 145 | \\s+ 146 | /x' 147 | ,"$1\n", $css); 148 | 149 | // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/ 150 | $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css); 151 | 152 | return trim($css); 153 | } 154 | 155 | /** 156 | * Replace what looks like a set of selectors 157 | * 158 | * @param array $m regex matches 159 | * 160 | * @return string 161 | */ 162 | protected function _selectorsCB($m) 163 | { 164 | // remove ws around the combinators 165 | return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]); 166 | } 167 | 168 | /** 169 | * Process a comment and return a replacement 170 | * 171 | * @param array $m regex matches 172 | * 173 | * @return string 174 | */ 175 | protected function _commentCB($m) 176 | { 177 | $hasSurroundingWs = (trim($m[0]) !== $m[1]); 178 | $m = $m[1]; 179 | // $m is the comment content w/o the surrounding tokens, 180 | // but the return value will replace the entire comment. 181 | if ($m === 'keep') { 182 | return '/**/'; 183 | } 184 | if ($m === '" "') { 185 | // component of http://tantek.com/CSS/Examples/midpass.html 186 | return '/*" "*/'; 187 | } 188 | if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) { 189 | // component of http://tantek.com/CSS/Examples/midpass.html 190 | return '/*";}}/* */'; 191 | } 192 | if ($this->_inHack) { 193 | // inversion: feeding only to one browser 194 | if (preg_match('@ 195 | ^/ # comment started like /*/ 196 | \\s* 197 | (\\S[\\s\\S]+?) # has at least some non-ws content 198 | \\s* 199 | /\\* # ends like /*/ or /**/ 200 | @x', $m, $n)) { 201 | // end hack mode after this comment, but preserve the hack and comment content 202 | $this->_inHack = false; 203 | return "/*/{$n[1]}/**/"; 204 | } 205 | } 206 | if (substr($m, -1) === '\\') { // comment ends like \*/ 207 | // begin hack mode and preserve hack 208 | $this->_inHack = true; 209 | return '/*\\*/'; 210 | } 211 | if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */ 212 | // begin hack mode and preserve hack 213 | $this->_inHack = true; 214 | return '/*/*/'; 215 | } 216 | if ($this->_inHack) { 217 | // a regular comment ends hack mode but should be preserved 218 | $this->_inHack = false; 219 | return '/**/'; 220 | } 221 | // Issue 107: if there's any surrounding whitespace, it may be important, so 222 | // replace the comment with a single space 223 | return $hasSurroundingWs // remove all other comments 224 | ? ' ' 225 | : ''; 226 | } 227 | 228 | /** 229 | * Process a font-family listing and return a replacement 230 | * 231 | * @param array $m regex matches 232 | * 233 | * @return string 234 | */ 235 | protected function _fontFamilyCB($m) 236 | { 237 | // Issue 210: must not eliminate WS between words in unquoted families 238 | $pieces = preg_split('/(\'[^\']+\'|"[^"]+")/', $m[1], null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 239 | $out = 'font-family:'; 240 | while (null !== ($piece = array_shift($pieces))) { 241 | if ($piece[0] !== '"' && $piece[0] !== "'") { 242 | $piece = preg_replace('/\\s+/', ' ', $piece); 243 | $piece = preg_replace('/\\s?,\\s?/', ',', $piece); 244 | } 245 | $out .= $piece; 246 | } 247 | return $out . $m[2]; 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /system/expressionengine/third_party/minimee/libraries/Minify/HTML.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Minify_HTML { 20 | /** 21 | * @var boolean 22 | */ 23 | protected $_jsCleanComments = true; 24 | 25 | /** 26 | * "Minify" an HTML page 27 | * 28 | * @param string $html 29 | * 30 | * @param array $options 31 | * 32 | * 'cssMinifier' : (optional) callback function to process content of STYLE 33 | * elements. 34 | * 35 | * 'jsMinifier' : (optional) callback function to process content of SCRIPT 36 | * elements. Note: the type attribute is ignored. 37 | * 38 | * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If 39 | * unset, minify will sniff for an XHTML doctype. 40 | * 41 | * @return string 42 | */ 43 | public static function minify($html, $options = array()) { 44 | $min = new self($html, $options); 45 | return $min->process(); 46 | } 47 | 48 | 49 | /** 50 | * Create a minifier object 51 | * 52 | * @param string $html 53 | * 54 | * @param array $options 55 | * 56 | * 'cssMinifier' : (optional) callback function to process content of STYLE 57 | * elements. 58 | * 59 | * 'jsMinifier' : (optional) callback function to process content of SCRIPT 60 | * elements. Note: the type attribute is ignored. 61 | * 62 | * 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block 63 | * 64 | * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If 65 | * unset, minify will sniff for an XHTML doctype. 66 | * 67 | * @return null 68 | */ 69 | public function __construct($html, $options = array()) 70 | { 71 | $this->_html = str_replace("\r\n", "\n", trim($html)); 72 | if (isset($options['xhtml'])) { 73 | $this->_isXhtml = (bool)$options['xhtml']; 74 | } 75 | if (isset($options['cssMinifier'])) { 76 | $this->_cssMinifier = $options['cssMinifier']; 77 | } 78 | if (isset($options['jsMinifier'])) { 79 | $this->_jsMinifier = $options['jsMinifier']; 80 | } 81 | if (isset($options['jsCleanComments'])) { 82 | $this->_jsCleanComments = (bool)$options['jsCleanComments']; 83 | } 84 | } 85 | 86 | 87 | /** 88 | * Minify the markeup given in the constructor 89 | * 90 | * @return string 91 | */ 92 | public function process() 93 | { 94 | if ($this->_isXhtml === null) { 95 | $this->_isXhtml = (false !== strpos($this->_html, '_html); 149 | 150 | // fill placeholders 151 | $this->_html = str_replace( 152 | array_keys($this->_placeholders) 153 | ,array_values($this->_placeholders) 154 | ,$this->_html 155 | ); 156 | // issue 229: multi-pass to catch scripts that didn't get replaced in textareas 157 | $this->_html = str_replace( 158 | array_keys($this->_placeholders) 159 | ,array_values($this->_placeholders) 160 | ,$this->_html 161 | ); 162 | return $this->_html; 163 | } 164 | 165 | protected function _commentCB($m) 166 | { 167 | return (0 === strpos($m[1], '[') || false !== strpos($m[1], '_replacementHash . count($this->_placeholders) . '%'; 175 | $this->_placeholders[$placeholder] = $content; 176 | return $placeholder; 177 | } 178 | 179 | protected $_isXhtml = null; 180 | protected $_replacementHash = null; 181 | protected $_placeholders = array(); 182 | protected $_cssMinifier = null; 183 | protected $_jsMinifier = null; 184 | 185 | protected function _removePreCB($m) 186 | { 187 | return $this->_reservePlace("_reservePlace("