Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
JavaScriptFFS.php
1<?php
2
7abstract class JavaScriptFFS extends SimpleFFS {
8 public function getFileExtensions() {
9 return [ '.js' ];
10 }
11
19 abstract protected function transformKey( $key );
20
27 abstract protected function header( $code, array $authors );
28
32 abstract protected function footer();
33
38 public function readFromVariable( $data ) {
39 /* Parse authors list */
40 $authors = preg_replace( "#/\* Translators\:\n(.*?)\n \*/(.*)#s", '$1', $data );
41 if ( $authors === $data ) {
42 $authors = [];
43 } else {
44 $authors = array_map(
45 static function ( $author ) {
46 // Each line should look like " * - Translatorname"
47 return substr( $author, 6 );
48 },
49 explode( "\n", $authors )
50 );
51 }
52
53 /* Pre-processing of messages */
54
58 $dataStart = strpos( $data, '{' );
59 $dataEnd = strrpos( $data, '}' );
60
64 $data = substr( $data, $dataStart + 1, $dataEnd - $dataStart - 1 );
65
69 $data = preg_replace( '#^(\s*?)//(.*?)$#m', '', $data );
70
74 $data = preg_replace( "#\'\,\n#", "\",\n", $data );
75
79 $data = trim( $data );
80
88 $data = explode( "\",\n", $data );
89
90 $messages = [];
91 foreach ( $data as $segment ) {
95 $segment .= '"';
96
100 $segment = preg_replace( '/"\s*\+\s*"/', '', $segment );
101
102 list( $key, $value ) = preg_split( '/:\s*[\'"]/', $segment, 2 );
103
107 $key = trim( trim( $key ), "'\"" );
108 $value = trim( trim( $value ), "'\"" );
109
113 $messages[$key] = self::unescapeJsString( $value );
114 }
115
116 $messages = $this->group->getMangler()->mangleArray( $messages );
117
118 return [
119 'AUTHORS' => $authors,
120 'MESSAGES' => $messages
121 ];
122 }
123
128 public function writeReal( MessageCollection $collection ) {
129 $header = $this->header( $collection->code, $collection->getAuthors() );
130
131 $mangler = $this->group->getMangler();
132
136 $body = '';
138 foreach ( $collection as $message ) {
139 if ( strlen( $message->translation() ) === 0 ) {
140 continue;
141 }
142
143 $key = $mangler->unmangle( $message->key() );
144 $key = $this->transformKey( self::escapeJsString( $key ) );
145
146 $translation = self::escapeJsString( $message->translation() );
147
148 $body .= "\t{$key}: \"{$translation}\",\n";
149 }
150
151 if ( strlen( $body ) === 0 ) {
152 return false;
153 }
154
158 $body = substr( $body, 0, -2 );
159 $body .= "\n";
160
161 return $header . $body . $this->footer();
162 }
163
168 protected function authorsList( array $authors ) {
169 if ( $authors === [] ) {
170 return '';
171 }
172
173 $authorsList = '';
174 foreach ( $authors as $author ) {
175 $authorsList .= " * - $author\n";
176 }
177
178 // Remove trailing newline, and return.
179 return substr( " * Translators:\n$authorsList", 0, -1 );
180 }
181
182 // See ECMA 262 section 7.8.4 for string literal format
183 private static $pairs = [
184 "\\" => "\\\\",
185 "\"" => "\\\"",
186 "'" => "\\'",
187 "\n" => "\\n",
188 "\r" => "\\r",
189
190 // To avoid closing the element or CDATA section.
191 '<' => "\\x3c",
192 '>' => "\\x3e",
193
194 // To avoid any complaints about bad entity refs.
195 '&' => "\\x26",
196
197 /*
198 * Work around https://bugzilla.mozilla.org/show_bug.cgi?id=274152
199 * Encode certain Unicode formatting chars so affected
200 * versions of Gecko do not misinterpret our strings;
201 * this is a common problem with Farsi text.
202 */
203 "\xe2\x80\x8c" => "\\u200c", // ZERO WIDTH NON-JOINER
204 "\xe2\x80\x8d" => "\\u200d", // ZERO WIDTH JOINER
205 ];
206
211 protected static function escapeJsString( $string ) {
212 return strtr( $string, self::$pairs );
213 }
214
219 protected static function unescapeJsString( $string ) {
220 return strtr( $string, array_flip( self::$pairs ) );
221 }
222}
Generic file format support for JavaScript formatted files.
transformKey( $key)
Message keys format.
getFileExtensions()
Return the commonly used file extensions for these formats.
static escapeJsString( $string)
header( $code, array $authors)
Header of message file.
authorsList(array $authors)
static unescapeJsString( $string)
writeReal(MessageCollection $collection)
footer()
Footer of message file.
readFromVariable( $data)
Core message collection class.
getAuthors()
Lists all translators that have contributed to the latest revisions of each translation.