00001 <?php
00002
00007 abstract class JavaScriptFFS extends SimpleFFS {
00008 public function getFileExtensions() {
00009 return array( '.js' );
00010 }
00011
00019 abstract protected function transformKey( $key );
00020
00027 abstract protected function header( $code, $authors );
00028
00032 abstract protected function footer();
00033
00038 public function readFromVariable( $data ) {
00039
00040 $authors = preg_replace( "#/\* Translators\:\n(.*?)\n \*/(.*)#s", '$1', $data );
00041 if ( $authors === $data ) {
00042 $authors = array();
00043 } else {
00044 $authors = explode( "\n", $authors );
00045 $count = count( $authors );
00046 for ( $i = 0; $i < $count; $i++ ) {
00047
00048 $authors[$i] = substr( $authors[$i], 6 );
00049 }
00050 }
00051
00052
00053
00057 $dataStart = strpos( $data, '{' );
00058 $dataEnd = strrpos( $data, '}' );
00059
00063 $data = substr( $data, $dataStart + 1, $dataEnd - $dataStart - 1 );
00064
00068 $data = preg_replace( '#^(\s*?)//(.*?)$#m', '', $data );
00069
00073 $data = preg_replace( "#\'\,\n#", "\",\n", $data );
00074
00078 $data = trim( $data );
00079
00087 $data = explode( "\",\n", $data );
00088
00089 $messages = array();
00090 foreach ( $data as $segment ) {
00094 $segment .= '"';
00095
00099 $segment = str_replace( '"+', '" +', $segment );
00100 $segment = explode( '" +', $segment );
00101 $count = count( $segment );
00102 for ( $i = 0; $i < $count; $i++ ) {
00103 $segment[$i] = ltrim( ltrim( $segment[$i] ), '"' );
00104 }
00105 $segment = implode( $segment );
00106
00110 $segment = preg_replace( "#\:(\s+)[\\\"\']#", ': "', $segment );
00111
00115 $segments = explode( ': "', $segment );
00116
00120 $key = trim( trim( $segments[0] ), "'\"" );
00121 $value = trim( trim( $segments[1] ), "'\"" );
00122
00126 $messages[$key] = self::unescapeJsString( $value );
00127 }
00128
00129 $messages = $this->group->getMangler()->mangle( $messages );
00130
00131 return array(
00132 'AUTHORS' => $authors,
00133 'MESSAGES' => $messages
00134 );
00135 }
00136
00141 public function writeReal( MessageCollection $collection ) {
00142 $header = $this->header( $collection->code, $collection->getAuthors() );
00143
00144 $mangler = $this->group->getMangler();
00145
00149 $body = '';
00153 foreach ( $collection as $message ) {
00154 if ( strlen( $message->translation() ) === 0 ) {
00155 continue;
00156 }
00157
00158 $key = $mangler->unmangle( $message->key() );
00159 $key = $this->transformKey( Xml::escapeJsString( $key ) );
00160
00161 $translation = Xml::escapeJsString( $message->translation() );
00162
00163 $body .= "\t{$key}: \"{$translation}\",\n";
00164 }
00165
00166 if ( strlen( $body ) === 0 ) {
00167 return false;
00168 }
00169
00173 $body = substr( $body, 0, -2 );
00174 $body .= "\n";
00175
00176 return $header . $body . $this->footer();
00177 }
00178
00183 protected function authorsList( $authors ) {
00184 if ( count( $authors ) === 0 ) {
00185 return '';
00186 }
00187
00188 $authorsList = '';
00189 foreach ( $authors as $author ) {
00190 $authorsList .= " * - $author\n";
00191 }
00192
00193
00194 return substr( " * Translators:\n$authorsList", 0, -1 );
00195 }
00196
00201 protected static function unescapeJsString( $string ) {
00202
00203 $pairs = array(
00204 "\\" => "\\\\",
00205 "\"" => "\\\"",
00206 "'" => "\\'",
00207 "\n" => "\\n",
00208 "\r" => "\\r",
00209
00210
00211 "<" => "\\x3c",
00212 ">" => "\\x3e",
00213
00214
00215 "&" => "\\x26",
00216
00217
00218
00219
00220
00221
00222
00223 "\xe2\x80\x8c" => "\\u200c",
00224 "\xe2\x80\x8d" => "\\u200d",
00225 );
00226 $pairs = array_flip( $pairs );
00227
00228 return strtr( $string, $pairs );
00229 }
00230 }
00231
00236 class ShapadoJsFFS extends JavaScriptFFS {
00237
00243 protected function transformKey( $key ) {
00244 return $key;
00245 }
00246
00252 protected function header( $code, $authors ) {
00253 global $wgSitename;
00254
00255 $name = TranslateUtils::getLanguageName( $code );
00256 $native = TranslateUtils::getLanguageName( $code, $code );
00257 $authorsList = $this->authorsList( $authors );
00258
00260 return <<<EOT
00267 var I18n = {
00268
00269 EOT;
00271 }
00272
00276 protected function footer() {
00277 return "};\n\n";
00278 }
00279 }