PageSourceSearch

https://auction.dargate.com/public/js/jquery.i18n/src/jquery.i18n.parser.js?t=1761753285

js dargate.com collected 2026-09-26 19:30:33 UTC 8,174 bytes, 310 lines download raw bytes

vendor: 8,174 bytes, lines 1-310
1/*!
2 * jQuery Internationalization library
3 *
4 * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
5 *
6 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
7 * anything special to choose one license or the other and you don't have to
8 * notify anyone which license you are using. You are free to use
9 * UniversalLanguageSelector in commercial projects as long as the copyright
10 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
11 *
12 * @licence GNU General Public Licence 2.0 or later
13 * @licence MIT License
14 */
15
16( function ( $ ) {
17	'use strict';
18
19	var MessageParser = function ( options ) {
20		this.options = $.extend( {}, $.i18n.parser.defaults, options );
21		this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
22		this.emitter = $.i18n.parser.emitter;
23	};
24
25	MessageParser.prototype = {
26
27		constructor: MessageParser,
28
29		simpleParse: function ( message, parameters ) {
30			return message.replace( /\$(\d+)/g, function ( str, match ) {
31				var index = parseInt( match, 10 ) - 1;
32
33				return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
34			} );
35		},
36
37		parse: function ( message, replacements ) {
38			if ( message.indexOf( '{{' ) < 0 ) {
39				return this.simpleParse( message, replacements );
40			}
41
42			this.emitter.language = $.i18n.languages[ $.i18n().locale ] ||
43				$.i18n.languages[ 'default' ];
44
45			return this.emitter.emit( this.ast( message ), replacements );
46		},
47
48		ast: function ( message ) {
49			var pipe, colon, backslash, anyCharacter, dollar, digits, regularLiteral,
50				regularLiteralWithoutBar, regularLiteralWithoutSpace, escapedOrLiteralWithoutBar,
51				escapedOrRegularLiteral, templateContents, templateName, openTemplate,
52				closeTemplate, expression, paramExpression, result,
53				pos = 0;
54
55			// Try parsers until one works, if none work return null
56			function choice( parserSyntax ) {
57				return function () {
58					var i, result;
59
60					for ( i = 0; i < parserSyntax.length; i++ ) {
61						result = parserSyntax[ i ]();
62
63						if ( result !== null ) {
64							return result;
65						}
66					}
67
68					return null;
69				};
70			}
71
72			// Try several parserSyntax-es in a row.
73			// All must succeed; otherwise, return null.
74			// This is the only eager one.
75			function sequence( parserSyntax ) {
76				var i, res,
77					originalPos = pos,
78					result = [];
79
80				for ( i = 0; i < parserSyntax.length; i++ ) {
81					res = parserSyntax[ i ]();
82
83					if ( res === null ) {
84						pos = originalPos;
85
86						return null;
87					}
88
89					result.push( res );
90				}
91
92				return result;
93			}
94
95			// Run the same parser over and over until it fails.
96			// Must succeed a minimum of n times; otherwise, return null.
97			function nOrMore( n, p ) {
98				return function () {
99					var originalPos = pos,
100						result = [],
101						parsed = p();
102
103					while ( parsed !== null ) {
104						result.push( parsed );
105						parsed = p();
106					}
107
108					if ( result.length < n ) {
109						pos = originalPos;
110
111						return null;
112					}
113
114					return result;
115				};
116			}
117
118			// Helpers -- just make parserSyntax out of simpler JS builtin types
119
120			function makeStringParser( s ) {
121				var len = s.length;
122
123				return function () {
124					var result = null;
125
126					if ( message.slice( pos, pos + len ) === s ) {
127						result = s;
128						pos += len;
129					}
130
131					return result;
132				};
133			}
134
135			function makeRegexParser( regex ) {
136				return function () {
137					var matches = message.slice( pos ).match( regex );
138
139					if ( matches === null ) {
140						return null;
141					}
142
143					pos += matches[ 0 ].length;
144
145					return matches[ 0 ];
146				};
147			}
148
149			pipe = makeStringParser( '|' );
150			colon = makeStringParser( ':' );
151			backslash = makeStringParser( '\\' );
152			anyCharacter = makeRegexParser( /^./ );
153			dollar = makeStringParser( '$' );
154			digits = makeRegexParser( /^\d+/ );
155			regularLiteral = makeRegexParser( /^[^{}[\]$\\]/ );
156			regularLiteralWithoutBar = makeRegexParser( /^[^{}[\]$\\|]/ );
157			regularLiteralWithoutSpace = makeRegexParser( /^[^{}[\]$\s]/ );
158
159			// There is a general pattern:
160			// parse a thing;
161			// if it worked, apply transform,
162			// otherwise return null.
163			// But using this as a combinator seems to cause problems
164			// when combined with nOrMore().
165			// May be some scoping issue.
166			function transform( p, fn ) {
167				return function () {
168					var result = p();
169
170					return result === null ? null : fn( result );
171				};
172			}
173
174			// Used to define "literals" within template parameters. The pipe
175			// character is the parameter delimeter, so by default
176			// it is not a literal in the parameter
177			function literalWithoutBar() {
178				var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
179
180				return result === null ? null : result.join( '' );
181			}
182
183			function literal() {
184				var result = nOrMore( 1, escapedOrRegularLiteral )();
185
186				return result === null ? null : result.join( '' );
187			}
188
189			function escapedLiteral() {
190				var result = sequence( [ backslash, anyCharacter ] );
191
192				return result === null ? null : result[ 1 ];
193			}
194
195			choice( [ escapedLiteral, regularLiteralWithoutSpace ] );
196			escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] );
197			escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] );
198
199			function replacement() {
200				var result = sequence( [ dollar, digits ] );
201
202				if ( result === null ) {
203					return null;
204				}
205
206				return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ];
207			}
208
209			templateName = transform(
210				// see $wgLegalTitleChars
211				// not allowing : due to the need to catch "PLURAL:$1"
212				makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
213
214				function ( result ) {
215					return result.toString();
216				}
217			);
218
219			function templateParam() {
220				var expr,
221					result = sequence( [ pipe, nOrMore( 0, paramExpression ) ] );
222
223				if ( result === null ) {
224					return null;
225				}
226
227				expr = result[ 1 ];
228
229				// use a "CONCAT" operator if there are multiple nodes,
230				// otherwise return the first node, raw.
231				return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ];
232			}
233
234			function templateWithReplacement() {
235				var result = sequence( [ templateName, colon, replacement ] );
236
237				return result === null ? null : [ result[ 0 ], result[ 2 ] ];
238			}
239
240			function templateWithOutReplacement() {
241				var result = sequence( [ templateName, colon, paramExpression ] );
242
243				return result === null ? null : [ result[ 0 ], result[ 2 ] ];
244			}
245
246			templateContents = choice( [
247				function () {
248					var res = sequence( [
249						// templates can have placeholders for dynamic
250						// replacement eg: {{PLURAL:$1|one car|$1 cars}}
251						// or no placeholders eg:
252						// {{GRAMMAR:genitive|{{SITENAME}}}
253						choice( [ templateWithReplacement, templateWithOutReplacement ] ),
254						nOrMore( 0, templateParam )
255					] );
256
257					return res === null ? null : res[ 0 ].concat( res[ 1 ] );
258				},
259				function () {
260					var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] );
261
262					if ( res === null ) {
263						return null;
264					}
265
266					return [ res[ 0 ] ].concat( res[ 1 ] );
267				}
268			] );
269
270			openTemplate = makeStringParser( '{{' );
271			closeTemplate = makeStringParser( '}}' );
272
273			function template() {
274				var result = sequence( [ openTemplate, templateContents, closeTemplate ] );
275
276				return result === null ? null : result[ 1 ];
277			}
278
279			expression = choice( [ template, replacement, literal ] );
280			paramExpression = choice( [ template, replacement, literalWithoutBar ] );
281
282			function start() {
283				var result = nOrMore( 0, expression )();
284
285				if ( result === null ) {
286					return null;
287				}
288
289				return [ 'CONCAT' ].concat( result );
290			}
291
292			result = start();
293
294			/*
295			 * For success, the pos must have gotten to the end of the input
296			 * and returned a non-null.
297			 * n.b. This is part of language infrastructure, so we do not throw an
298			 * internationalizable message.
299			 */
300			if ( result === null || pos !== message.length ) {
301				throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message );
302			}
303
304			return result;
305		}
306
307	};
308
309	$.extend( $.i18n.parser, new MessageParser() );
310}( jQuery ) );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.