[ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * BookmarkletGen : converts readable Javascript code into a bookmarklet link 5 * 6 * Features : 7 * - removes comments 8 * - compresses code, not literal strings 9 * Example: 10 * function someName( param ) { alert( "this is a string" ) } 11 * will return: 12 * function%20someName(param){alert("this is a string")} 13 * - wraps code into a self invoking function 14 * 15 * This is basically a slightly enhanced PHP port of the excellent Bookmarklet Crunchinator 16 * http://ted.mielczarek.org/code/mozilla/bookmarklet.html 17 * 18 */ 19 namespace Ozh\Bookmarkletgen; 20 21 class Bookmarkletgen { 22 23 private $literal_strings = array(); 24 25 /** 26 * Main function, calls all others 27 * 28 * @param string $code Javascript code to bookmarkletify 29 * @return string Bookmarklet link 30 */ 31 public function crunch( $code ) { 32 $out = "(function() {\n" . $code . "\n})();"; 33 34 $out = $this->replace_strings( $out ); 35 $out = $this->kill_comments( $out ); 36 $out = $this->compress_white_space( $out ); 37 $out = $this->combine_strings( $out ); 38 $out = $this->restore_strings( $out ); 39 $out = $this->encodeURIComponent( $out ); 40 $out = 'javascript:' . $out; 41 42 return $out; 43 } 44 45 /** 46 * PHP port of Javascript function encodeURIComponent 47 * 48 * From http://stackoverflow.com/a/1734255/36850 49 * 50 * @since 51 * @param string $str String to encode 52 * @return string Encoded string 53 */ 54 // 55 private function encodeURIComponent( $str ) { 56 $revert = array( 57 '%21'=>'!', '%2A'=>'*', '%28'=>'(', '%29'=>')', 58 ); 59 60 return strtr( rawurlencode( $str ), $revert ); 61 } 62 63 /** 64 * Kill comment lines and blocks 65 * 66 * @param string $code Commented Javascript code 67 * @return string Commentless code 68 */ 69 private function kill_comments( $code ) { 70 $code = preg_replace( '!\s*//.+$!m', '', $code ); 71 $code = preg_replace( '!/\*.+?\*/!sm', '', $code ); // s modifier: dot matches new lines 72 73 return $code; 74 } 75 76 /** 77 * Compress white space 78 * 79 * Remove some extraneous spaces and make the whole script a one liner 80 * 81 * @param string $code Javascript code 82 * @return string Compressed code 83 */ 84 private function compress_white_space( $code ) { 85 // Tabs to space, no more than 1 consecutive space 86 $code = preg_replace( '!\t!m', ' ', $code ); 87 $code = preg_replace( '![ ]{2,}!m', ' ', $code ); 88 89 // Remove uneccessary white space around operators, braces and brackets. 90 // \xHH sequence is: !%&()*+,-/:;<=>?[]\{|}~ 91 $code = preg_replace( '/\s([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])/m', "$1", $code ); 92 $code = preg_replace( '/([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])\s/m', "$1", $code ); 93 94 // Split on each line, trim leading/trailing white space, kill empty lines, combine everything in one line 95 $code = preg_split( '/\r\n|\r|\n/', $code ); 96 foreach( $code as $i => $line ) { 97 $code[ $i ] = trim( $line ); 98 } 99 $code = implode( '', $code ); 100 101 return $code; 102 } 103 104 /** 105 * Combine any consecutive strings 106 * 107 * In the case we have two consecutive quoted strings (eg: "hello" + "world"), save a couple more 108 * length and combine them 109 * 110 * @param string $code Javascript code 111 * @return string Javascript code 112 */ 113 private function combine_strings( $code ) { 114 $code = preg_replace('/"\+"/m', "", $code); 115 $code = preg_replace("/'\+'/m", "", $code); 116 117 return $code; 118 } 119 120 121 /** 122 * Replace all literal strings (eg: "hello world") with a placeholder and collect them in an array 123 * 124 * The idea is that strings cannot be trimmed or white-space optimized: take them out first before uglifying 125 * the code, then we'll reinject them back in later 126 * 127 * @param string $code Javascript code 128 * @return string Javascript code with placeholders (eg "__1__") instead of literal strings 129 */ 130 private function replace_strings( $code ) { 131 $return = ""; 132 $literal = ""; 133 $quoteChar = ""; 134 $escaped = false; 135 136 // Split script into individual lines. 137 $lines = explode("\n", $code); 138 $count = count( $lines ); 139 for( $i = 0; $i < $count; $i++ ) { 140 141 $j = 0; 142 $inQuote = false; 143 while ($j < strlen( $lines[$i] ) ) { 144 $c = $lines[ $i ][ $j ]; 145 146 // If not already in a string, look for the start of one. 147 if (!$inQuote) { 148 if ($c == '"' || $c == "'") { 149 $inQuote = true; 150 $escaped = false; 151 $quoteChar = $c; 152 $literal = $c; 153 } 154 else { 155 $return .= $c; 156 } 157 } 158 159 // Already in a string, look for end and copy characters. 160 else { 161 if ($c == $quoteChar && !$escaped) { 162 $inQuote = false; 163 $literal .= $quoteChar; 164 $return .= "__" . count( $this->literal_strings ) . "__"; 165 $this->literal_strings[ count( $this->literal_strings ) ] = $literal; 166 } 167 else if ($c == "\\" && !$escaped) { 168 $escaped = true; 169 } 170 else { 171 $escaped = false; 172 } 173 $literal .= $c; 174 } 175 $j++; 176 } 177 $return .= "\n"; 178 } 179 180 return $return; 181 } 182 183 /** 184 * Restore literal strings by replacing their placeholders with actual strings 185 * 186 * @param string $code Javascript code with placeholders 187 * @return string Javascript code with actual strings 188 */ 189 private function restore_strings( $code ) { 190 foreach( $this->literal_strings as $i => $string ) { 191 $code = preg_replace( '/__' . $i . '__/', $string, $code, 1 ); 192 } 193 194 return $code; 195 } 196 197 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Feb 22 05:10:06 2025 | Cross-referenced by PHPXref 0.7.1 |