51 const ACTION_KEEP_A = 1;
52 const ACTION_DELETE_A = 2;
53 const ACTION_DELETE_A_B= 3;
57 protected $input =
'';
58 protected $inputIndex = 0;
59 protected $inputLength = 0;
60 protected $lookAhead = null;
61 protected $output =
'';
74 $jsmin =
new JSMin($js);
86 $this->input = str_replace(
"\r\n",
"\n", $input);
87 $this->inputLength = strlen($this->input);
111 case self::ACTION_KEEP_A:
112 $this->output .= $this->a;
114 case self::ACTION_DELETE_A:
117 if ($this->a ===
"'" || $this->a ===
'"') {
119 $this->output .= $this->a;
120 $this->a = $this->
get();
122 if ($this->a === $this->b) {
126 if (ord($this->a) <= self::ORD_LF) {
130 if ($this->a ===
'\\') {
131 $this->output .= $this->a;
132 $this->a = $this->
get();
137 case self::ACTION_DELETE_A_B:
138 $this->b = $this->
next();
140 if ($this->b ===
'/' && (
141 $this->a ===
'(' || $this->a ===
',' || $this->a ===
'=' ||
142 $this->a ===
':' || $this->a ===
'[' || $this->a ===
'!' ||
143 $this->a ===
'&' || $this->a ===
'|' || $this->a ===
'?' ||
144 $this->a ===
'{' || $this->a ===
'}' || $this->a ===
';' ||
145 $this->a ===
"\n" )) {
147 $this->output .= $this->a . $this->b;
150 $this->a = $this->
get();
152 if ($this->a ===
'[') {
158 $this->output .= $this->a;
159 $this->a = $this->
get();
161 if ($this->a ===
']') {
163 } elseif ($this->a ===
'\\') {
164 $this->output .= $this->a;
165 $this->a = $this->
get();
166 } elseif (ord($this->a) <= self::ORD_LF) {
167 throw new JSMinException(
'Unterminated regular expression set in regex literal.');
170 } elseif ($this->a ===
'/') {
172 } elseif ($this->a ===
'\\') {
173 $this->output .= $this->a;
174 $this->a = $this->
get();
175 } elseif (ord($this->a) <= self::ORD_LF) {
176 throw new JSMinException(
'Unterminated regular expression literal.');
179 $this->output .= $this->a;
182 $this->b = $this->
next();
192 protected function get() {
193 $c = $this->lookAhead;
194 $this->lookAhead = null;
197 if ($this->inputIndex < $this->inputLength) {
198 $c = substr($this->input, $this->inputIndex, 1);
199 $this->inputIndex += 1;
209 if ($c === null || $c ===
"\n" || ord($c) >= self::ORD_SPACE) {
222 return ord($c) > 126 || $c ===
'\\' || preg_match(
'/^[\w\$]$/', $c) === 1;
232 protected function min() {
234 $this->
action(self::ACTION_DELETE_A_B);
236 while ($this->a !== null) {
240 $this->
action(self::ACTION_KEEP_A);
242 $this->
action(self::ACTION_DELETE_A);
253 $this->
action(self::ACTION_KEEP_A);
257 $this->
action(self::ACTION_DELETE_A_B);
262 $this->
action(self::ACTION_KEEP_A);
265 $this->
action(self::ACTION_DELETE_A);
274 $this->
action(self::ACTION_KEEP_A);
278 $this->
action(self::ACTION_DELETE_A_B);
290 $this->
action(self::ACTION_KEEP_A);
295 $this->
action(self::ACTION_KEEP_A);
298 $this->
action(self::ACTION_DELETE_A_B);
304 $this->
action(self::ACTION_KEEP_A);
310 return $this->output;
326 switch($this->
peek()) {
331 if (ord($c) <= self::ORD_LF) {
340 switch($this->
get()) {
342 if ($this->
peek() ===
'/') {
368 $this->lookAhead = $this->
get();
369 return $this->lookAhead;