Script Compressor
Item 7 of 9
1 <?php 2 3 //====================================================================================================== 4 // title: PHP based Javascript Compressor 5 // author: Daniel Pupius (pupius.co.uk) 6 // created: 13/06/2003 7 // description: PHP function that takes in a string of javascript and compresses all the whitespace 8 // and strips the comments. It is directly based on the JavaScript Crunchinator by Mike 9 // Hall that can be found at BrainJar.com (http://www.brainjar.com/js/crunch/) 10 // 11 // The main difference is that this script doesn't crunch everything onto one line, the 12 // aim was to reduce the filesize of imported JavaScript behaviours for size critical 13 // e-learning material. But in order to ensure the script still runs we only remove as 14 // many lines as we can without compromising the code (e.g. incase of missing ';') 15 // 16 // This method also has the added advantage that it is still possible to debug compressed 17 // code. 18 // 19 // We also leave /* */ style comments, to allow some form of copyright or information to 20 // be left in the final output. 21 // 22 // I believe it also works quite successfully with cascading style sheets... 23 // 24 // To use simply call the function on a string of javascript, or pass it a filename, e.g: 25 // $newstring = compress_javascript($rawstring); 26 // $newstring = compress_javascript($filename,true); 27 //====================================================================================================== 28 29 function compress_javascript($str,$isfile=false) { 30 31 //if the $str actually holds a filename then open the file: 32 if($isfile) { 33 $fp = fopen ($str, "rb"); 34 $str = fread ($fp, filesize ($str)); 35 fclose ($fp); 36 } 37 38 39 //remove windows cariage returns 40 $str = str_replace("\r","",$str); 41 42 //array to store replaced literal strings 43 $literal_strings = array(); 44 45 //explode the string into lines 46 $lines = explode("\n",$str); 47 48 49 //loop through all the lines, building a new string at the same time as removing literal strings 50 $clean = ""; 51 $inComment = false; 52 $literal = ""; 53 $inQuote = false; 54 $escaped = false; 55 $quoteChar = ""; 56 57 for($i=0;$i<count($lines);$i++) { 58 $line = $lines[$i]; 59 60 $inNormalComment = false; 61 62 //loop through line's characters and take out any literal strings, replace them with ___i___ where i is the index of this string 63 for($j=0;$j<strlen($line);$j++) { 64 $c = substr($line,$j,1); 65 $d = substr($line,$j,2); 66 67 //look for start of quote 68 if(!$inQuote && !$inComment) { 69 //is this character a quote or a comment 70 if(($c=="\"" || $c=="'") && !$inComment && !$inNormalComment) { 71 $inQuote = true; 72 $inComment = false; 73 $escaped = false; 74 $quoteChar = $c; 75 $literal = $c; 76 77 } else if($d=="/*" && !$inNormalComment) { 78 $inQuote = false; 79 $inComment = true; 80 $escaped = false; 81 $quoteChar = $d; 82 $literal = $d; 83 84 $j++; 85 86 //ignore string markers that are found inside comments 87 } else if($d=="//") { 88 $inNormalComment = true; 89 $clean .= $c; 90 } else { 91 $clean .= $c; 92 } 93 94 95 //allready in a string so find end quote 96 } else { 97 if($c == $quoteChar && !$escaped && !$inComment) { 98 $inQuote = false; 99 $literal .= $c; 100 101 //subsitute in a marker for the string 102 $clean .= "___" . count($literal_strings) . "___"; 103 104 //push the string onto our array 105 array_push($literal_strings,$literal); 106 107 } else if($inComment && $d=="*/") { 108 $inComment = false; 109 $literal .= $d; 110 111 //subsitute in a marker for the string 112 $clean .= "___" . count($literal_strings) . "___"; 113 114 //push the string onto our array 115 array_push($literal_strings,$literal); 116 117 $j++; 118 119 } else if($c == "\\" && !$escaped) $escaped = true; 120 else $escaped = false; 121 122 $literal .= $c; 123 } 124 } 125 126 if($inComment) $literal .= "\n"; 127 $clean .= "\n"; 128 } 129 130 //explode the clean string into lines again 131 $lines = explode("\n",$clean); 132 133 134 //now process each line at a time 135 for($i=0;$i<count($lines);$i++) { 136 $line = $lines[$i]; 137 138 //remove comments 139 $line = preg_replace("/\/\/(.*)/","",$line); 140 141 //strip leading and trailing whitespace 142 $line = trim($line); 143 144 //remove all whitespace with a single space 145 $line = preg_replace("/\s+/"," ",$line); 146 147 //remove any whitespace that occurs after/before an operator 148 $line = preg_replace("/\s*([!\}\{;,&=\|\-\+\*\/\)\(:])\s*/","\\1",$line); 149 150 $lines[$i] = $line; 151 } 152 153 //implode the lines 154 $str = implode("\n",$lines); 155 156 //make sure there is a max of 1 \n after each line 157 $str = preg_replace("/[\n]+/","\n",$str); 158 159 //strip out line breaks that immediately follow a semi-colon 160 $str = preg_replace("/;\n/",";",$str); 161 162 //curly brackets aren't on their own 163 $str = preg_replace("/[\n]*\{[\n]*/","{",$str); 164 165 //finally loop through and replace all the literal strings: 166 for($i=0;$i<count($literal_strings);$i++) $str = str_replace("___".$i."___",$literal_strings[$i],$str); 167 168 //print_r($literal_strings); 169 170 return $str; 171 } 172 173 //header("Content-Type: text/plain"); 174 //$str = compress_javascript("../styles/_interface.css",true); 175 //$str = compress_javascript("../behaviours/act_api.js",true); 176 //echo $str; 177 178 ?> 179