1: <?php
2:
3: /*
4: Function: xajaxCompressFile
5:
6: <xajax> will call this function internally to compress the javascript code for
7: more efficient delivery.
8:
9: Parameters:
10:
11: $sFile - (stirng): The file to be compressed.
12: */
13: function xajaxCompressFile($sFile)
14: {
15: //remove windows cariage returns
16: $sFile = str_replace("\r",'',$sFile);
17:
18: //array to store replaced literal strings
19: $literal_strings = array();
20:
21: //explode the string into lines
22: $lines = explode("\n",$sFile);
23: //loop through all the lines, building a new string at the same time as removing literal strings
24: $clean = '';
25: $inComment = false;
26: $literal = '';
27: $inQuote = false;
28: $escaped = false;
29: $quoteChar = '';
30:
31: $iLen = count($lines);
32: for($i=0; $i<$iLen; ++$i)
33: {
34: $line = $lines[$i];
35: $inNormalComment = false;
36:
37: //loop through line's characters and take out any literal strings, replace them with ___i___ where i is the index of this string
38: $jLen = strlen($line);
39: for($j=0; $j<$jLen; ++$j)
40: {
41: $c = substr($line,$j,1);
42: $d = substr($line,$j,2);
43:
44: //look for start of quote
45: if(!$inQuote && !$inComment)
46: {
47: //is this character a quote or a comment
48: if(($c=='"' || $c=="'") && !$inComment && !$inNormalComment)
49: {
50: $inQuote = true;
51: $inComment = false;
52: $escaped = false;
53: $quoteChar = $c;
54: $literal = $c;
55: }
56: else if($d=="/*" && !$inNormalComment)
57: {
58: $inQuote = false;
59: $inComment = true;
60: $escaped = false;
61: $quoteChar = $d;
62: $literal = $d;
63: $j++;
64: }
65: else if($d=="//") //ignore string markers that are found inside comments
66: {
67: $inNormalComment = true;
68: }
69: else
70: {
71: if (!$inNormalComment)
72: $clean .= $c;
73: }
74: }
75: else //allready in a string so find end quote
76: {
77: if($c == $quoteChar && !$escaped && !$inComment)
78: {
79: $inQuote = false;
80: $literal .= $c;
81:
82: //subsitute in a marker for the string
83: $clean .= "___" . count($literal_strings) . "___";
84:
85: //push the string onto our array
86: array_push($literal_strings,$literal);
87:
88: }
89: else if($inComment && $d=="*/")
90: {
91: $inComment = false;
92: $literal .= $d;
93: ++$j;
94: }
95: else if($c == "\\" && !$escaped)
96: $escaped = true;
97: else
98: $escaped = false;
99:
100: $literal .= $c;
101: }
102: }
103: if($inComment) $literal .= "\n";
104: $clean .= "\n";
105: }
106: //explode the clean string into lines again
107: $lines = explode("\n",$clean);
108:
109: //now process each line at a time
110: $iLen = count($lines);
111: for($i=0; $i<$iLen; ++$i)
112: {
113: $line = $lines[$i];
114:
115: //remove comments
116: $line = preg_replace("/\/\/(.*)/","",$line);
117:
118: //strip leading and trailing whitespace
119: $line = trim($line);
120:
121: //remove all whitespace with a single space
122: $line = preg_replace("/\s+/"," ",$line);
123:
124: //remove any whitespace that occurs after/before an operator
125: $line = preg_replace("/\s*([!\}\{;,&=\|\-\+\*\/\)\(:])\s*/","\\1",$line);
126:
127: $lines[$i] = $line;
128: }
129:
130: //implode the lines
131: $sFile = implode("\n",$lines);
132:
133: //make sure there is a max of 1 \n after each line
134: $sFile = preg_replace("/[\n]+/","\n",$sFile);
135:
136: //strip out line breaks that immediately follow a semi-colon
137: $sFile = preg_replace("/;\n/",";",$sFile);
138:
139: //curly brackets aren't on their own
140: $sFile = preg_replace("/[\n]*\{[\n]*/","{",$sFile);
141:
142: //finally loop through and replace all the literal strings:
143: $iLen = count($literal_strings);
144: for($i=0; $i<$iLen; ++$i)
145: $sFile = str_replace('___'.$i.'___',$literal_strings[$i],$sFile);
146:
147: return $sFile;
148: }
149: