Changeset 1766 for trunk/modules/media/libraries/JavaScriptPacker.php
- Timestamp:
- 01/21/2008 06:56:39 AM (10 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/media/libraries/JavaScriptPacker.php
r1641 r1766 73 73 private $_fastDecode = true; 74 74 private $_specialChars = false; 75 75 76 76 private $LITERAL_ENCODING = array( 77 77 'None' => 0, … … 80 80 'High ASCII' => 95 81 81 ); 82 82 83 83 public function __construct($_script, $_encoding = 62, $_fastDecode = true, $_specialChars = false) 84 84 { … … 90 90 $this->_specialChars = $_specialChars; 91 91 } 92 92 93 93 public function pack() { 94 94 $this->_addParser('_basicCompression'); … … 97 97 if ($this->_encoding) 98 98 $this->_addParser('_encodeKeywords'); 99 99 100 100 // go! 101 101 return $this->_pack($this->_script); 102 102 } 103 103 104 104 // apply all parsing routines 105 105 private function _pack($script) { … … 109 109 return $script; 110 110 } 111 111 112 112 // keep a list of parsing functions, they'll be executed all at once 113 113 private $_parsers = array(); … … 115 115 $this->_parsers[] = $parser; 116 116 } 117 117 118 118 // zero encoding - just removal of white space and comments 119 119 private function _basicCompression($script) { … … 145 145 return $parser->exec($script); 146 146 } 147 147 148 148 private function _encodeSpecialChars($script) { 149 149 $parser = new ParseMaster(); … … 158 158 // quick ref 159 159 $encoded = $keywords['encoded']; 160 160 161 161 $parser->add($regexp, 162 162 array( … … 167 167 return $parser->exec($script); 168 168 } 169 169 170 170 private function _encodeKeywords($script) { 171 171 // escape high-ascii values already in the script (i.e. in strings) … … 180 180 $keywords = $this->_analyze($script, $regexp, $encode); 181 181 $encoded = $keywords['encoded']; 182 182 183 183 // encode 184 184 $parser->add($regexp, … … 196 196 } 197 197 } 198 198 199 199 private function _analyze($script, $regexp, $encode) { 200 200 // analyse … … 243 243 } 244 244 } while ($i); 245 245 246 246 // sort the words by frequency 247 247 // Note: the javascript and php version of sort can be different : … … 269 269 'protected' => $_protected); 270 270 } 271 271 272 272 private $_count = array(); 273 273 private function _sortWords($match1, $match2) { 274 274 return $this->_count[$match2] - $this->_count[$match1]; 275 275 } 276 276 277 277 // build the boot function used for loading and decoding 278 278 private function _bootStrap($packed, $keywords) { … … 341 341 $unpackPacker = new JavaScriptPacker($unpack, 0, false, true); 342 342 $unpack = $unpackPacker->pack(); 343 343 344 344 // arguments 345 345 $params = array($packed, $ascii, $count, $keywords); … … 349 349 } 350 350 $params = implode(',', $params); 351 351 352 352 // the whole thing 353 353 return 'eval(' . $unpack . '(' . $params . "))\n"; 354 354 } 355 355 356 356 private $buffer; 357 357 private function _insertFastDecode($match) { … … 361 361 return '{$encode=' . $this->buffer . ';'; 362 362 } 363 363 364 364 // mmm.. ..which one do i need ?? 365 365 private function _getEncoder($ascii) { … … 367 367 '_encode95' : '_encode62' : '_encode36' : '_encode10'; 368 368 } 369 369 370 370 // zero encoding 371 371 // characters: 0123456789 … … 373 373 return $charCode; 374 374 } 375 375 376 376 // inherent base36 support 377 377 // characters: 0123456789abcdefghijklmnopqrstuvwxyz … … 379 379 return base_convert($charCode, 10, 36); 380 380 } 381 381 382 382 // hitch a ride on base36 and add the upper case alpha characters 383 383 // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ … … 388 388 } 389 389 $charCode = $charCode % $this->_encoding; 390 390 391 391 if ($charCode > 35) 392 392 return $res . chr($charCode + 29); … … 394 394 return $res . base_convert($charCode, 10, 36); 395 395 } 396 396 397 397 // use high-ascii values 398 398 // characters: ¡¢£¤¥¦§¨©ª«¬Â®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßà áâãäåæçèéêëìÃîïðñòóôõö÷øùúûüýþ … … 401 401 if ($charCode >= $this->_encoding) 402 402 $res = $this->_encode95($charCode / $this->_encoding); 403 403 404 404 return $res . chr(($charCode % $this->_encoding) + 161); 405 405 } 406 406 407 407 private function _safeRegExp($string) { 408 408 return '/'.preg_replace('/\$/', '\\\$', $string).'/'; 409 409 } 410 410 411 411 private function _encodePrivate($charCode) { 412 412 return "_" . $charCode; 413 413 } 414 414 415 415 // protect characters used by the parser 416 416 private function _escape($script) { 417 417 return preg_replace('/([\\\\\'])/', '\\\$1', $script); 418 418 } 419 419 420 420 // protect high-ascii characters already in the script 421 421 private function _escape95($script) { … … 429 429 return '\x'.((string)dechex(ord($match))); 430 430 } 431 432 431 432 433 433 private function _getJSFunction($aName) { 434 434 if (defined('self::JSFUNCTION'.$aName)) … … 437 437 return ''; 438 438 } 439 439 440 440 // JavaScript Functions used. 441 441 // Note : In Dean's version, these functions are converted … … 445 445 // 'while (aBool) { anAction(); }'. 446 446 // The JavaScript functions below are corrected. 447 447 448 448 // unpacking function - this is the boot strap function 449 449 // data extracted from this packing routine is passed to … … 468 468 }'; 469 469 */ 470 470 471 471 // code-snippet inserted into the unpacker to speed up decoding 472 472 const JSFUNCTION_decodeBody = … … 501 501 }'; 502 502 */ 503 503 504 504 // zero encoding 505 505 // characters: 0123456789 … … 508 508 return $charCode; 509 509 }';//;'; 510 510 511 511 // inherent base36 support 512 512 // characters: 0123456789abcdefghijklmnopqrstuvwxyz … … 515 515 return $charCode.toString(36); 516 516 }';//;'; 517 517 518 518 // hitch a ride on base36 and add the upper case alpha characters 519 519 // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ … … 523 523 (($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); 524 524 }'; 525 525 526 526 // use high-ascii values 527 527 // characters: ¡¢£¤¥¦§¨©ª«¬Â®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßà áâãäåæçèéêëìÃîïðñòóôõö÷øùúûüýþ … … 531 531 String.fromCharCode($charCode % _encoding + 161); 532 532 }'; 533 533 534 534 } 535 535 … … 538 538 public $ignoreCase = false; 539 539 public $escapeChar = ''; 540 540 541 541 // constants 542 542 const EXPRESSION = 0; 543 543 const REPLACEMENT = 1; 544 544 const LENGTH = 2; 545 545 546 546 // used to determine nesting levels 547 547 private $GROUPS = '/\\(/';//g … … 552 552 private $QUOTE = '/\'/'; 553 553 private $DELETED = '/\\x01[^\\x01]*\\x01/';//g 554 554 555 555 public function add($expression, $replacement = '') { 556 556 // count the number of sub-expressions 557 557 // - add one because each pattern is itself a sub-expression 558 558 $length = 1 + preg_match_all($this->GROUPS, $this->_internalEscape((string)$expression), $out); 559 559 560 560 // treat only strings $replacement 561 561 if (is_string($replacement)) { … … 585 585 else $this->_add('/^$/', $replacement, $length); 586 586 } 587 587 588 588 public function exec($string) { 589 589 // execute the global replacement 590 590 $this->_escaped = array(); 591 591 592 592 // simulate the _patterns.toSTring of Dean 593 593 $regexp = '/'; … … 597 597 $regexp = substr($regexp, 0, -1) . '/'; 598 598 $regexp .= ($this->ignoreCase) ? 'i' : ''; 599 599 600 600 $string = $this->_escape($string, $this->escapeChar); 601 601 $string = preg_replace_callback( … … 608 608 ); 609 609 $string = $this->_unescape($string, $this->escapeChar); 610 610 611 611 return preg_replace($this->DELETED, '', $string); 612 612 } 613 613 614 614 public function reset() { 615 615 // clear the patterns collection so that this object may be re-used … … 620 620 private $_escaped = array(); // escaped characters 621 621 private $_patterns = array(); // patterns stored by index 622 622 623 623 // create and add a new pattern to the patterns collection 624 624 private function _add() { … … 626 626 $this->_patterns[] = $arguments; 627 627 } 628 628 629 629 // this is the global replace function (it's quite complicated) 630 630 private function _replacement($arguments) { 631 631 if (empty($arguments)) return ''; 632 632 633 633 $i = 1; $j = 0; 634 634 // loop through the patterns … … 638 638 if (isset($arguments[$i]) && ($arguments[$i] != '')) { 639 639 $replacement = $pattern[self::REPLACEMENT]; 640 640 641 641 if (is_array($replacement) && isset($replacement['fn'])) { 642 642 643 643 if (isset($replacement['data'])) $this->buffer = $replacement['data']; 644 644 return call_user_func(array(&$this, $replacement['fn']), $arguments, $i); 645 645 646 646 } elseif (is_int($replacement)) { 647 647 return $arguments[$replacement + $i]; 648 648 649 649 } 650 650 $delete = ($this->escapeChar == '' || … … 652 652 ? '' : "\x01" . $arguments[$i] . "\x01"; 653 653 return $delete . $replacement; 654 654 655 655 // skip over references to sub-expressions 656 656 } else { … … 659 659 } 660 660 } 661 661 662 662 private function _backReferences($match, $offset) { 663 663 $replacement = $this->buffer['replacement']; … … 669 669 return $replacement; 670 670 } 671 671 672 672 private function _replace_name($match, $offset){ 673 673 $length = strlen($match[$offset + 2]); … … 675 675 return substr($match[$offset + 1], $start, $length) . $match[$offset + 4]; 676 676 } 677 677 678 678 private function _replace_encoded($match, $offset) { 679 679 return $this->buffer[$match[$offset]]; 680 680 } 681 682 681 682 683 683 // php : we cannot pass additional data to preg_replace_callback, 684 684 // and we cannot use &$this in create_function, so let's go to lower level 685 685 private $buffer; 686 686 687 687 // encode escaped characters 688 688 private function _escape($string, $escapeChar) { … … 694 694 $string 695 695 ); 696 696 697 697 } else { 698 698 return $string; … … 703 703 return $this->buffer; 704 704 } 705 705 706 706 // decode escaped characters 707 707 private function _unescape($string, $escapeChar) { … … 715 715 $string 716 716 ); 717 717 718 718 } else { 719 719 return $string; … … 729 729 return $this->buffer['escapeChar'] . $temp; 730 730 } 731 731 732 732 private function _internalEscape($string) { 733 733 return preg_replace($this->ESCAPE, '', $string);
