PluginProbe
Autoptimize / 3.1.16
Autoptimize v3.1.16
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.0 → 3.1.16 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 {}