PluginProbe
Autoptimize / 1.5
Autoptimize v1.5
2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 All 107 releases
autoptimize / classes / autoptimizeScripts.php

autoptimizeScripts.php in Autoptimize 1.5, at classes/autoptimizeScripts.php

270 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class autoptimizeScripts extends autoptimizeBase
4 {
5 private $scripts = array();
6 // fgo: add html5.js to avoid aggregating html5 support for older IE browsers
7 private $dontmove = array('document.write','html5.js','show_ads.js','google_ad','blogcatalog.com/w','tweetmeme.com/i','mybloglog.com/','var s_sid = ','histats.com/js','smowtion_size','ads.smowtion.com/ad.js','sc_project','statcounter.com/counter/counter.js','widgets.amung.us','WAU_','wau_add','ws.amazon.com/widgets','media.fastclick.net','/ads/','comment-form-quicktags/quicktags.php','edToolbar','intensedebate.com','ch_client','scripts.chitika.net/','_gaq.push','jotform.com/');
8 private $domove = array('gaJsHost','load_cmc','jd.gallery.transitions.js','swfobject.embedSWF(','tiny_mce.js','tinyMCEPreInit.go');
9 private $domovelast = array('addthis.com','/afsonline/show_afs_search.js','disqus.js','networkedblogs.com/getnetworkwidget','infolinks.com/js/','jd.gallery.js.php','jd.gallery.transitions.js','swfobject.embedSWF(','linkwithin.com/widget.js','tiny_mce.js','tinyMCEPreInit.go');
10 private $trycatch = false;
11 private $yui = false;
12 private $jscode = '';
13 private $url = '';
14 private $move = array('first' => array(), 'last' => array());
15 private $restofcontent = '';
16 private $md5hash = '';
17
18 //Reads the page and collects script tags
19 public function read($options)
20 {
21 //Remove everything that's not the header
22 if($options['justhead'] == true)
23 {
24 $content = explode('</head>',$this->content,2);
25 $this->content = $content[0].'</head>';
26 $this->restofcontent = $content[1];
27 }
28
29 //Should we add try-catch?
30 if($options['trycatch'] == true)
31 $this->trycatch = true;
32
33 //Do we use yui?
34 $this->yui = $options['yui'];
35
36 //Get script files
37 if(preg_match_all('#<script.*</script>#Usmi',$this->content,$matches))
38 {
39 foreach($matches[0] as $tag)
40 {
41 if(preg_match('#src=("|\')(.*)("|\')#Usmi',$tag,$source))
42 {
43 //External script
44 $url = current(explode('?',$source[2],2));
45 $path = $this->getpath($url);
46 if($path !==false && preg_match('#\.js$#',$path))
47 {
48 //Inline
49 if($this->ismergeable($tag))
50 {
51 //We can merge it
52 $this->scripts[] = $path;
53 }else{
54 //No merge, but maybe we can move it
55 if($this->ismovable($tag))
56 {
57 //Yeah, move it
58 if($this->movetolast($tag))
59 {
60 $this->move['last'][] = $tag;
61 }else{
62 $this->move['first'][] = $tag;
63 }
64 }else{
65 //We shouldn't touch this
66 $tag = '';
67 }
68 }
69 }else{
70 //External script (example: google analytics)
71 //OR Script is dynamic (.php etc)
72 if($this->ismovable($tag))
73 {
74 if($this->movetolast($tag))
75 {
76 $this->move['last'][] = $tag;
77 }else{
78 $this->move['first'][] = $tag;
79 }
80 }else{
81 //We shouldn't touch this
82 $tag = '';
83 }
84 }
85 }else{
86 //Inline script
87 if($this->ismergeable($tag))
88 {
89 preg_match('#<script.*>(.*)</script>#Usmi',$tag,$code);
90 $code = preg_replace('#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm','$1',$code[1]);
91 $code = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/','',$code);
92 $this->scripts[] = 'INLINE;'.$code;
93 }else{
94 //Can we move this?
95 if($this->ismovable($tag))
96 {
97 if($this->movetolast($tag))
98 {
99 $this->move['last'][] = $tag;
100 }else{
101 $this->move['first'][] = $tag;
102 }
103 }else{
104 //We shouldn't touch this
105 $tag = '';
106 }
107 }
108 }
109
110 //Remove the original script tag
111 $this->content = str_replace($tag,'',$this->content);
112 }
113
114 return true;
115 }
116
117 //No script files :(
118 return false;
119 }
120
121 //Joins and optimizes JS
122 public function minify()
123 {
124 foreach($this->scripts as $script)
125 {
126 if(preg_match('#^INLINE;#',$script))
127 {
128 //Inline script
129 $script = preg_replace('#^INLINE;#','',$script);
130 //Add try-catch?
131 if($this->trycatch)
132 $script = 'try{'.$script.'}catch(e){}';
133 $this->jscode .= "\n".$script;
134 }else{
135 //External script
136 if($script !== false && file_exists($script) && is_readable($script))
137 {
138 $script = file_get_contents($script);
139 //Add try-catch?
140 if($this->trycatch)
141 $script = 'try{'.$script.'}catch(e){}';
142 $this->jscode .= "\n".$script;
143 }/*else{
144 //Couldn't read JS. Maybe getpath isn't working?
145 }*/
146 }
147 }
148
149 //Check for already-minified code
150 $this->md5hash = md5($this->jscode);
151 $ccheck = new autoptimizeCache($this->md5hash,'js');
152 if($ccheck->check())
153 {
154 $this->jscode = $ccheck->retrieve();
155 return true;
156 }
157 unset($ccheck);
158
159 //$this->jscode has all the uncompressed code now.
160 if($this->yui == false && class_exists('JSMin'))
161 {
162 $this->jscode = trim(JSMin::minify($this->jscode));
163 return true;
164 }elseif($this->yui == true && autoptimizeYUI::available()){
165 $this->jscode = autoptimizeYUI::compress('js',$this->jscode);
166 return true;
167 }else{
168 return false;
169 }
170 }
171
172 //Caches the JS in uncompressed, deflated and gzipped form.
173 public function cache()
174 {
175 $cache = new autoptimizeCache($this->md5hash,'js');
176 if(!$cache->check())
177 {
178 //Cache our code
179 $cache->cache($this->jscode,'text/javascript');
180 }
181 $this->url = AUTOPTIMIZE_CACHE_URL.$cache->getname();
182 }
183
184 //Returns the content
185 public function getcontent()
186 {
187 //Restore the full content
188 if(!empty($this->restofcontent))
189 {
190 $this->content .= $this->restofcontent;
191 $this->restofcontent = '';
192 }
193
194 //Add the scripts
195 $bodyreplacement = implode('',$this->move['first']);
196 $bodyreplacement .= '<script type="text/javascript" src="'.$this->url.'"></script>';
197 $bodyreplacement .= implode('',$this->move['last']).'</body>';
198 $this->content = str_replace('</body>',$bodyreplacement,$this->content);
199
200 //Return the modified HTML
201 return $this->content;
202 }
203
204 //Checks agains the whitelist
205 private function ismergeable($tag)
206 {
207 foreach($this->domove as $match)
208 {
209 if(strpos($tag,$match)!==false)
210 {
211 //Matched something
212 return false;
213 }
214 }
215
216 foreach($this->dontmove as $match)
217 {
218 if(strpos($tag,$match)!==false)
219 {
220 //Matched something
221 return false;
222 }
223 }
224
225 //If we're here it's safe to merge
226 return true;
227 }
228
229 //Checks agains the blacklist
230 private function ismovable($tag)
231 {
232
233 foreach($this->domove as $match)
234 {
235 if(strpos($tag,$match)!==false)
236 {
237 //Matched something
238 return true;
239 }
240 }
241
242 foreach($this->dontmove as $match)
243 {
244 if(strpos($tag,$match)!==false)
245 {
246 //Matched something
247 return false;
248 }
249 }
250
251 //If we're here it's safe to move
252 return true;
253 }
254
255 private function movetolast($tag)
256 {
257 foreach($this->domovelast as $match)
258 {
259 if(strpos($tag,$match)!==false)
260 {
261 //Matched, return true
262 return true;
263 }
264 }
265
266 //Should be in 'first'
267 return false;
268 }
269 }
270