PluginProbe
Autoptimize / trunk
Autoptimize vtrunk
3.1.16 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 All 108 releases
← All changes | classes/external/php/jsmin.php +32 -24 2.4.1 → trunk View file →
@@ -1,5 +1,8 @@
1 1 <?php
2 +
3 +//namespace JSMin;
4 +
2 5 /**
3 6 * JSMin.php - modified PHP implementation of Douglas Crockford's JSMin.
4 7 *
5 8 * <code>
@@ -52,14 +55,9 @@
52 55 * @copyright 2008 Ryan Grove <[email protected]> (PHP port)
53 56 * @license http://opensource.org/licenses/mit-license.php MIT License
54 57 * @link http://code.google.com/p/jsmin-php/
55 58 */
56 -
57 -// This is from https://github.com/mrclay/jsmin-php 2.3.2
58 -
59 59 class JSMin {
60 - const ORD_LF = 10;
61 - const ORD_SPACE = 32;
62 60 const ACTION_KEEP_A = 1;
63 61 const ACTION_DELETE_A = 2;
64 62 const ACTION_DELETE_A_B = 3;
65 63
@@ -122,9 +120,9 @@
122 120
123 121 while ($this->a !== null) {
124 122 // determine next command
125 123 $command = self::ACTION_KEEP_A; // default
126 - if ($this->a === ' ') {
124 + if ($this->isWhiteSpace($this->a)) {
127 125 if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
128 126 && ($this->b === $this->lastByteOut)) {
129 127 // Don't delete this space. If we do, the addition/subtraction
130 128 // could be parsed as a post-increment
@@ -130,23 +128,23 @@
130 128 // could be parsed as a post-increment
131 129 } elseif (! $this->isAlphaNum($this->b)) {
132 130 $command = self::ACTION_DELETE_A;
133 131 }
134 - } elseif ($this->a === "\n") {
135 - if ($this->b === ' ') {
132 + } elseif ($this->isLineTerminator($this->a)) {
133 + if ($this->isWhiteSpace($this->b)) {
136 134 $command = self::ACTION_DELETE_A_B;
137 135
138 136 // in case of mbstring.func_overload & 2, must check for null b,
139 137 // otherwise mb_strpos will give WARNING
140 138 } elseif ($this->b === null
141 - || (false === strpos('{[(+-!~', $this->b)
139 + || (false === strpos('{[(+-!~#', $this->b)
142 140 && ! $this->isAlphaNum($this->b))) {
143 141 $command = self::ACTION_DELETE_A;
144 142 }
145 143 } elseif (! $this->isAlphaNum($this->a)) {
146 - if ($this->b === ' '
147 - || ($this->b === "\n"
148 - && (false === strpos('}])+-"\'', $this->a)))) {
144 + if ($this->isWhiteSpace($this->b)
145 + || ($this->isLineTerminator($this->b)
146 + && (false === strpos('}])+-"\'`', $this->a)))) {
149 147 $command = self::ACTION_DELETE_A_B;
150 148 }
151 149 }
152 150 $this->action($command);
@@ -164,9 +162,9 @@
164 162 * ACTION_DELETE_A = Copy B to A. Get the next B.
165 163 * ACTION_DELETE_A_B = Get the next B.
166 164 *
167 165 * @param int $command
168 - * @throws JSMin_UnterminatedRegExpException|JSMin_UnterminatedStringException
166 + * @throws JSMin_UnterminatedRegExpException|UnterminatedStringException
169 167 */
170 168 protected function action($command)
171 169 {
172 170 // make sure we don't compress "a + ++b" to "a+++b", etc.
@@ -195,9 +193,10 @@
195 193
196 194 // fallthrough intentional
197 195 case self::ACTION_DELETE_A: // 2
198 196 $this->a = $this->b;
199 - if ($this->a === "'" || $this->a === '"') { // string literal
197 + if ($this->a === "'" || $this->a === '"' || $this->a === '`') { // string/template literal
198 + $delimiter = $this->a;
200 199 $str = $this->a; // in case needed for exception
201 200 for(;;) {
202 201 $this->output .= $this->a;
203 202 $this->lastByteOut = $this->a;
@@ -205,9 +204,11 @@
205 204 $this->a = $this->get();
206 205 if ($this->a === $this->b) { // end quote
207 206 break;
208 207 }
209 - if ($this->isEOF($this->a)) {
208 + if ($delimiter === '`' && $this->isLineTerminator($this->a)) {
209 + // leave the newline
210 + } elseif ($this->isEOF($this->a)) {
210 211 $byte = $this->inputIndex - 1;
211 212 throw new JSMin_UnterminatedStringException(
212 213 "JSMin: Unterminated String at byte {$byte}: {$str}");
213 214 }
@@ -215,9 +216,9 @@
215 216 if ($this->a === '\\') {
216 217 $this->output .= $this->a;
217 218 $this->lastByteOut = $this->a;
218 219
219 - $this->a = $this->get();
220 + $this->a = $this->get();
220 221 $str .= $this->a;
221 222 }
222 223 }
223 224 }
@@ -283,9 +284,9 @@
283 284 }
284 285
285 286 // check if first non-ws token is "/" (see starts-regex.js)
286 287 $length = strlen($this->output);
287 - if ($this->a === ' ' || $this->a === "\n") {
288 + if ($this->isWhiteSpace($this->a) || $this->isLineTerminator($this->a)) {
288 289 if ($length < 2) { // weird edge case
289 290 return true;
290 291 }
291 292 }
@@ -305,9 +306,9 @@
305 306 return false;
306 307 }
307 308
308 309 // it's a regexp. Remove unneeded whitespace after keyword
309 - if ($this->a === ' ' || $this->a === "\n") {
310 + if ($this->isWhiteSpace($this->a) || $this->isLineTerminator($this->a)) {
310 311 $this->a = '';
311 312 }
312 313
313 314 return true;
@@ -331,15 +332,12 @@
331 332 } else {
332 333 $c = null;
333 334 }
334 335 }
335 - if (ord($c) >= self::ORD_SPACE || $c === "\n" || $c === null) {
336 - return $c;
337 - }
338 336 if ($c === "\r") {
339 337 return "\n";
340 338 }
341 - return ' ';
339 + return $c;
342 340 }
343 341
344 342 /**
345 343 * Does $a indicate end of input?
@@ -348,9 +346,9 @@
348 346 * @return bool
349 347 */
350 348 protected function isEOF($a)
351 349 {
352 - return ord($a) <= self::ORD_LF;
350 + return $a === null || $this->isLineTerminator($a);
353 351 }
354 352
355 353 /**
356 354 * Get next char (without getting it). If is ctrl character, translate to a space or newline.
@@ -383,9 +381,9 @@
383 381 $comment = '';
384 382 while (true) {
385 383 $get = $this->get();
386 384 $comment .= $get;
387 - if (ord($get) <= self::ORD_LF) { // end of line reached
385 + if ($this->isEOF($get)) {
388 386 // if IE conditional comment
389 387 if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
390 388 $this->keptComment .= "/{$comment}";
391 389 }
@@ -449,8 +447,18 @@
449 447 break;
450 448 }
451 449 }
452 450 return $get;
451 + }
452 +
453 + protected function isWhiteSpace($s) {
454 + // https://www.ecma-international.org/ecma-262/#sec-white-space
455 + return $s !== null && strpos(" \t\v\f", $s) !== false;
456 + }
457 +
458 + protected function isLineTerminator($s) {
459 + // https://www.ecma-international.org/ecma-262/#sec-line-terminators
460 + return $s !== null && strpos("\n\r", $s) !== false;
453 461 }
454 462 }
455 463
456 464 class JSMin_UnterminatedStringException extends Exception {}