Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/i18n/bidiformatter.js
2868 views
1
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Utility for formatting text for display in a potentially
17
* opposite-directionality context without garbling.
18
* Mostly a port of http://go/formatter.cc.
19
*/
20
21
22
goog.provide('goog.i18n.BidiFormatter');
23
24
goog.require('goog.html.SafeHtml');
25
goog.require('goog.i18n.bidi');
26
goog.require('goog.i18n.bidi.Dir');
27
goog.require('goog.i18n.bidi.Format');
28
29
30
31
/**
32
* Utility class for formatting text for display in a potentially
33
* opposite-directionality context without garbling. Provides the following
34
* functionality:
35
*
36
* 1. BiDi Wrapping
37
* When text in one language is mixed into a document in another, opposite-
38
* directionality language, e.g. when an English business name is embedded in a
39
* Hebrew web page, both the inserted string and the text following it may be
40
* displayed incorrectly unless the inserted string is explicitly separated
41
* from the surrounding text in a "wrapper" that declares its directionality at
42
* the start and then resets it back at the end. This wrapping can be done in
43
* HTML mark-up (e.g. a 'span dir="rtl"' tag) or - only in contexts where
44
* mark-up can not be used - in Unicode BiDi formatting codes (LRE|RLE and PDF).
45
* Providing such wrapping services is the basic purpose of the BiDi formatter.
46
*
47
* 2. Directionality estimation
48
* How does one know whether a string about to be inserted into surrounding
49
* text has the same directionality? Well, in many cases, one knows that this
50
* must be the case when writing the code doing the insertion, e.g. when a
51
* localized message is inserted into a localized page. In such cases there is
52
* no need to involve the BiDi formatter at all. In the remaining cases, e.g.
53
* when the string is user-entered or comes from a database, the language of
54
* the string (and thus its directionality) is not known a priori, and must be
55
* estimated at run-time. The BiDi formatter does this automatically.
56
*
57
* 3. Escaping
58
* When wrapping plain text - i.e. text that is not already HTML or HTML-
59
* escaped - in HTML mark-up, the text must first be HTML-escaped to prevent XSS
60
* attacks and other nasty business. This of course is always true, but the
61
* escaping can not be done after the string has already been wrapped in
62
* mark-up, so the BiDi formatter also serves as a last chance and includes
63
* escaping services.
64
*
65
* Thus, in a single call, the formatter will escape the input string as
66
* specified, determine its directionality, and wrap it as necessary. It is
67
* then up to the caller to insert the return value in the output.
68
*
69
* See http://wiki/Main/TemplatesAndBiDi for more information.
70
*
71
* @param {goog.i18n.bidi.Dir|number|boolean|null} contextDir The context
72
* directionality, in one of the following formats:
73
* 1. A goog.i18n.bidi.Dir constant. NEUTRAL is treated the same as null,
74
* i.e. unknown, for backward compatibility with legacy calls.
75
* 2. A number (positive = LTR, negative = RTL, 0 = unknown).
76
* 3. A boolean (true = RTL, false = LTR).
77
* 4. A null for unknown directionality.
78
* @param {boolean=} opt_alwaysSpan Whether {@link #spanWrap} should always
79
* use a 'span' tag, even when the input directionality is neutral or
80
* matches the context, so that the DOM structure of the output does not
81
* depend on the combination of directionalities. Default: false.
82
* @constructor
83
* @final
84
*/
85
goog.i18n.BidiFormatter = function(contextDir, opt_alwaysSpan) {
86
/**
87
* The overall directionality of the context in which the formatter is being
88
* used.
89
* @type {?goog.i18n.bidi.Dir}
90
* @private
91
*/
92
this.contextDir_ = goog.i18n.bidi.toDir(contextDir, true /* opt_noNeutral */);
93
94
/**
95
* Whether {@link #spanWrap} and similar methods should always use the same
96
* span structure, regardless of the combination of directionalities, for a
97
* stable DOM structure.
98
* @type {boolean}
99
* @private
100
*/
101
this.alwaysSpan_ = !!opt_alwaysSpan;
102
};
103
104
105
/**
106
* @return {?goog.i18n.bidi.Dir} The context directionality.
107
*/
108
goog.i18n.BidiFormatter.prototype.getContextDir = function() {
109
return this.contextDir_;
110
};
111
112
113
/**
114
* @return {boolean} Whether alwaysSpan is set.
115
*/
116
goog.i18n.BidiFormatter.prototype.getAlwaysSpan = function() {
117
return this.alwaysSpan_;
118
};
119
120
121
/**
122
* @param {goog.i18n.bidi.Dir|number|boolean|null} contextDir The context
123
* directionality, in one of the following formats:
124
* 1. A goog.i18n.bidi.Dir constant. NEUTRAL is treated the same as null,
125
* i.e. unknown.
126
* 2. A number (positive = LTR, negative = RTL, 0 = unknown).
127
* 3. A boolean (true = RTL, false = LTR).
128
* 4. A null for unknown directionality.
129
*/
130
goog.i18n.BidiFormatter.prototype.setContextDir = function(contextDir) {
131
this.contextDir_ = goog.i18n.bidi.toDir(contextDir, true /* opt_noNeutral */);
132
};
133
134
135
/**
136
* @param {boolean} alwaysSpan Whether {@link #spanWrap} should always use a
137
* 'span' tag, even when the input directionality is neutral or matches the
138
* context, so that the DOM structure of the output does not depend on the
139
* combination of directionalities.
140
*/
141
goog.i18n.BidiFormatter.prototype.setAlwaysSpan = function(alwaysSpan) {
142
this.alwaysSpan_ = alwaysSpan;
143
};
144
145
146
/**
147
* Returns the directionality of input argument {@code str}.
148
* Identical to {@link goog.i18n.bidi.estimateDirection}.
149
*
150
* @param {string} str The input text.
151
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
152
* Default: false.
153
* @return {goog.i18n.bidi.Dir} Estimated overall directionality of {@code str}.
154
*/
155
goog.i18n.BidiFormatter.prototype.estimateDirection =
156
goog.i18n.bidi.estimateDirection;
157
158
159
/**
160
* Returns true if two given directionalities are opposite.
161
* Note: the implementation is based on the numeric values of the Dir enum.
162
*
163
* @param {?goog.i18n.bidi.Dir} dir1 1st directionality.
164
* @param {?goog.i18n.bidi.Dir} dir2 2nd directionality.
165
* @return {boolean} Whether the directionalities are opposite.
166
* @private
167
*/
168
goog.i18n.BidiFormatter.prototype.areDirectionalitiesOpposite_ = function(
169
dir1, dir2) {
170
return Number(dir1) * Number(dir2) < 0;
171
};
172
173
174
/**
175
* Returns a unicode BiDi mark matching the context directionality (LRM or
176
* RLM) if {@code opt_dirReset}, and if either the directionality or the exit
177
* directionality of {@code str} is opposite to the context directionality.
178
* Otherwise returns the empty string.
179
*
180
* @param {string} str The input text.
181
* @param {goog.i18n.bidi.Dir} dir {@code str}'s overall directionality.
182
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
183
* Default: false.
184
* @param {boolean=} opt_dirReset Whether to perform the reset. Default: false.
185
* @return {string} A unicode BiDi mark or the empty string.
186
* @private
187
*/
188
goog.i18n.BidiFormatter.prototype.dirResetIfNeeded_ = function(
189
str, dir, opt_isHtml, opt_dirReset) {
190
// endsWithRtl and endsWithLtr are called only if needed (short-circuit).
191
if (opt_dirReset &&
192
(this.areDirectionalitiesOpposite_(dir, this.contextDir_) ||
193
(this.contextDir_ == goog.i18n.bidi.Dir.LTR &&
194
goog.i18n.bidi.endsWithRtl(str, opt_isHtml)) ||
195
(this.contextDir_ == goog.i18n.bidi.Dir.RTL &&
196
goog.i18n.bidi.endsWithLtr(str, opt_isHtml)))) {
197
return this.contextDir_ == goog.i18n.bidi.Dir.LTR ?
198
goog.i18n.bidi.Format.LRM :
199
goog.i18n.bidi.Format.RLM;
200
} else {
201
return '';
202
}
203
};
204
205
206
/**
207
* Returns "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" if
208
* it is LTR. In case it's NEUTRAL, returns "rtl" if the context directionality
209
* is RTL, and "ltr" otherwise.
210
* Needed for GXP, which can't handle dirAttr.
211
* Example use case:
212
* &lt;td expr:dir='bidiFormatter.dirAttrValue(foo)'&gt;
213
* &lt;gxp:eval expr='foo'&gt;
214
* &lt;/td&gt;
215
*
216
* @param {string} str Text whose directionality is to be estimated.
217
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
218
* Default: false.
219
* @return {string} "rtl" or "ltr", according to the logic described above.
220
*/
221
goog.i18n.BidiFormatter.prototype.dirAttrValue = function(str, opt_isHtml) {
222
return this.knownDirAttrValue(this.estimateDirection(str, opt_isHtml));
223
};
224
225
226
/**
227
* Returns "rtl" if the given directionality is RTL, and "ltr" if it is LTR. In
228
* case it's NEUTRAL, returns "rtl" if the context directionality is RTL, and
229
* "ltr" otherwise.
230
*
231
* @param {goog.i18n.bidi.Dir} dir A directionality.
232
* @return {string} "rtl" or "ltr", according to the logic described above.
233
*/
234
goog.i18n.BidiFormatter.prototype.knownDirAttrValue = function(dir) {
235
var resolvedDir = dir == goog.i18n.bidi.Dir.NEUTRAL ? this.contextDir_ : dir;
236
return resolvedDir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr';
237
};
238
239
240
/**
241
* Returns 'dir="ltr"' or 'dir="rtl"', depending on {@code str}'s estimated
242
* directionality, if it is not the same as the context directionality.
243
* Otherwise, returns the empty string.
244
*
245
* @param {string} str Text whose directionality is to be estimated.
246
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
247
* Default: false.
248
* @return {string} 'dir="rtl"' for RTL text in non-RTL context; 'dir="ltr"' for
249
* LTR text in non-LTR context; else, the empty string.
250
*/
251
goog.i18n.BidiFormatter.prototype.dirAttr = function(str, opt_isHtml) {
252
return this.knownDirAttr(this.estimateDirection(str, opt_isHtml));
253
};
254
255
256
/**
257
* Returns 'dir="ltr"' or 'dir="rtl"', depending on the given directionality, if
258
* it is not the same as the context directionality. Otherwise, returns the
259
* empty string.
260
*
261
* @param {goog.i18n.bidi.Dir} dir A directionality.
262
* @return {string} 'dir="rtl"' for RTL text in non-RTL context; 'dir="ltr"' for
263
* LTR text in non-LTR context; else, the empty string.
264
*/
265
goog.i18n.BidiFormatter.prototype.knownDirAttr = function(dir) {
266
if (dir != this.contextDir_) {
267
return dir == goog.i18n.bidi.Dir.RTL ?
268
'dir="rtl"' :
269
dir == goog.i18n.bidi.Dir.LTR ? 'dir="ltr"' : '';
270
}
271
return '';
272
};
273
274
275
/**
276
* Formats a string of unknown directionality for use in HTML output of the
277
* context directionality, so an opposite-directionality string is neither
278
* garbled nor garbles what follows it.
279
* The algorithm: estimates the directionality of input argument {@code html}.
280
* In case its directionality doesn't match the context directionality, wraps it
281
* with a 'span' tag and adds a "dir" attribute (either 'dir="rtl"' or
282
* 'dir="ltr"'). If setAlwaysSpan(true) was used, the input is always wrapped
283
* with 'span', skipping just the dir attribute when it's not needed.
284
*
285
* If {@code opt_dirReset}, and if the overall directionality or the exit
286
* directionality of {@code str} are opposite to the context directionality, a
287
* trailing unicode BiDi mark matching the context directionality is appened
288
* (LRM or RLM).
289
*
290
* @param {!goog.html.SafeHtml} html The input HTML.
291
* @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark
292
* matching the context directionality, when needed, to prevent the possible
293
* garbling of whatever may follow {@code html}. Default: true.
294
* @return {!goog.html.SafeHtml} Input text after applying the processing.
295
*/
296
goog.i18n.BidiFormatter.prototype.spanWrapSafeHtml = function(
297
html, opt_dirReset) {
298
return this.spanWrapSafeHtmlWithKnownDir(null, html, opt_dirReset);
299
};
300
301
302
/**
303
* Formats a string of given directionality for use in HTML output of the
304
* context directionality, so an opposite-directionality string is neither
305
* garbled nor garbles what follows it.
306
* The algorithm: If {@code dir} doesn't match the context directionality, wraps
307
* {@code html} with a 'span' tag and adds a "dir" attribute (either 'dir="rtl"'
308
* or 'dir="ltr"'). If setAlwaysSpan(true) was used, the input is always wrapped
309
* with 'span', skipping just the dir attribute when it's not needed.
310
*
311
* If {@code opt_dirReset}, and if {@code dir} or the exit directionality of
312
* {@code html} are opposite to the context directionality, a trailing unicode
313
* BiDi mark matching the context directionality is appened (LRM or RLM).
314
*
315
* @param {?goog.i18n.bidi.Dir} dir {@code html}'s overall directionality, or
316
* null if unknown and needs to be estimated.
317
* @param {!goog.html.SafeHtml} html The input HTML.
318
* @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark
319
* matching the context directionality, when needed, to prevent the possible
320
* garbling of whatever may follow {@code html}. Default: true.
321
* @return {!goog.html.SafeHtml} Input text after applying the processing.
322
*/
323
goog.i18n.BidiFormatter.prototype.spanWrapSafeHtmlWithKnownDir = function(
324
dir, html, opt_dirReset) {
325
if (dir == null) {
326
dir = this.estimateDirection(goog.html.SafeHtml.unwrap(html), true);
327
}
328
return this.spanWrapWithKnownDir_(dir, html, opt_dirReset);
329
};
330
331
332
/**
333
* The internal implementation of spanWrapSafeHtmlWithKnownDir for non-null dir,
334
* to help the compiler optimize.
335
*
336
* @param {goog.i18n.bidi.Dir} dir {@code str}'s overall directionality.
337
* @param {!goog.html.SafeHtml} html The input HTML.
338
* @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark
339
* matching the context directionality, when needed, to prevent the possible
340
* garbling of whatever may follow {@code str}. Default: true.
341
* @return {!goog.html.SafeHtml} Input text after applying the above processing.
342
* @private
343
*/
344
goog.i18n.BidiFormatter.prototype.spanWrapWithKnownDir_ = function(
345
dir, html, opt_dirReset) {
346
opt_dirReset = opt_dirReset || (opt_dirReset == undefined);
347
348
var result;
349
// Whether to add the "dir" attribute.
350
var dirCondition =
351
dir != goog.i18n.bidi.Dir.NEUTRAL && dir != this.contextDir_;
352
if (this.alwaysSpan_ || dirCondition) { // Wrap is needed
353
var dirAttribute;
354
if (dirCondition) {
355
dirAttribute = dir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr';
356
}
357
result = goog.html.SafeHtml.create('span', {'dir': dirAttribute}, html);
358
} else {
359
result = html;
360
}
361
var str = goog.html.SafeHtml.unwrap(html);
362
result = goog.html.SafeHtml.concatWithDir(
363
goog.i18n.bidi.Dir.NEUTRAL, result,
364
this.dirResetIfNeeded_(str, dir, true, opt_dirReset));
365
return result;
366
};
367
368
369
/**
370
* Formats a string of unknown directionality for use in plain-text output of
371
* the context directionality, so an opposite-directionality string is neither
372
* garbled nor garbles what follows it.
373
* As opposed to {@link #spanWrap}, this makes use of unicode BiDi formatting
374
* characters. In HTML, its *only* valid use is inside of elements that do not
375
* allow mark-up, e.g. an 'option' tag.
376
* The algorithm: estimates the directionality of input argument {@code str}.
377
* In case it doesn't match the context directionality, wraps it with Unicode
378
* BiDi formatting characters: RLE{@code str}PDF for RTL text, and
379
* LRE{@code str}PDF for LTR text.
380
*
381
* If {@code opt_dirReset}, and if the overall directionality or the exit
382
* directionality of {@code str} are opposite to the context directionality, a
383
* trailing unicode BiDi mark matching the context directionality is appended
384
* (LRM or RLM).
385
*
386
* Does *not* do HTML-escaping regardless of the value of {@code opt_isHtml}.
387
* The return value can be HTML-escaped as necessary.
388
*
389
* @param {string} str The input text.
390
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
391
* Default: false.
392
* @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark
393
* matching the context directionality, when needed, to prevent the possible
394
* garbling of whatever may follow {@code str}. Default: true.
395
* @return {string} Input text after applying the above processing.
396
*/
397
goog.i18n.BidiFormatter.prototype.unicodeWrap = function(
398
str, opt_isHtml, opt_dirReset) {
399
return this.unicodeWrapWithKnownDir(null, str, opt_isHtml, opt_dirReset);
400
};
401
402
403
/**
404
* Formats a string of given directionality for use in plain-text output of the
405
* context directionality, so an opposite-directionality string is neither
406
* garbled nor garbles what follows it.
407
* As opposed to {@link #spanWrapWithKnownDir}, makes use of unicode BiDi
408
* formatting characters. In HTML, its *only* valid use is inside of elements
409
* that do not allow mark-up, e.g. an 'option' tag.
410
* The algorithm: If {@code dir} doesn't match the context directionality, wraps
411
* {@code str} with Unicode BiDi formatting characters: RLE{@code str}PDF for
412
* RTL text, and LRE{@code str}PDF for LTR text.
413
*
414
* If {@code opt_dirReset}, and if the overall directionality or the exit
415
* directionality of {@code str} are opposite to the context directionality, a
416
* trailing unicode BiDi mark matching the context directionality is appended
417
* (LRM or RLM).
418
*
419
* Does *not* do HTML-escaping regardless of the value of {@code opt_isHtml}.
420
* The return value can be HTML-escaped as necessary.
421
*
422
* @param {?goog.i18n.bidi.Dir} dir {@code str}'s overall directionality, or
423
* null if unknown and needs to be estimated.
424
* @param {string} str The input text.
425
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
426
* Default: false.
427
* @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark
428
* matching the context directionality, when needed, to prevent the possible
429
* garbling of whatever may follow {@code str}. Default: true.
430
* @return {string} Input text after applying the above processing.
431
*/
432
goog.i18n.BidiFormatter.prototype.unicodeWrapWithKnownDir = function(
433
dir, str, opt_isHtml, opt_dirReset) {
434
if (dir == null) {
435
dir = this.estimateDirection(str, opt_isHtml);
436
}
437
return this.unicodeWrapWithKnownDir_(dir, str, opt_isHtml, opt_dirReset);
438
};
439
440
441
/**
442
* The internal implementation of unicodeWrapWithKnownDir for non-null dir, to
443
* help the compiler optimize.
444
*
445
* @param {goog.i18n.bidi.Dir} dir {@code str}'s overall directionality.
446
* @param {string} str The input text.
447
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
448
* Default: false.
449
* @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark
450
* matching the context directionality, when needed, to prevent the possible
451
* garbling of whatever may follow {@code str}. Default: true.
452
* @return {string} Input text after applying the above processing.
453
* @private
454
*/
455
goog.i18n.BidiFormatter.prototype.unicodeWrapWithKnownDir_ = function(
456
dir, str, opt_isHtml, opt_dirReset) {
457
opt_dirReset = opt_dirReset || (opt_dirReset == undefined);
458
var result = [];
459
if (dir != goog.i18n.bidi.Dir.NEUTRAL && dir != this.contextDir_) {
460
result.push(
461
dir == goog.i18n.bidi.Dir.RTL ? goog.i18n.bidi.Format.RLE :
462
goog.i18n.bidi.Format.LRE);
463
result.push(str);
464
result.push(goog.i18n.bidi.Format.PDF);
465
} else {
466
result.push(str);
467
}
468
469
result.push(this.dirResetIfNeeded_(str, dir, opt_isHtml, opt_dirReset));
470
return result.join('');
471
};
472
473
474
/**
475
* Returns a Unicode BiDi mark matching the context directionality (LRM or RLM)
476
* if the directionality or the exit directionality of {@code str} are opposite
477
* to the context directionality. Otherwise returns the empty string.
478
*
479
* @param {string} str The input text.
480
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
481
* Default: false.
482
* @return {string} A Unicode bidi mark matching the global directionality or
483
* the empty string.
484
*/
485
goog.i18n.BidiFormatter.prototype.markAfter = function(str, opt_isHtml) {
486
return this.markAfterKnownDir(null, str, opt_isHtml);
487
};
488
489
490
/**
491
* Returns a Unicode BiDi mark matching the context directionality (LRM or RLM)
492
* if the given directionality or the exit directionality of {@code str} are
493
* opposite to the context directionality. Otherwise returns the empty string.
494
*
495
* @param {?goog.i18n.bidi.Dir} dir {@code str}'s overall directionality, or
496
* null if unknown and needs to be estimated.
497
* @param {string} str The input text.
498
* @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped.
499
* Default: false.
500
* @return {string} A Unicode bidi mark matching the global directionality or
501
* the empty string.
502
*/
503
goog.i18n.BidiFormatter.prototype.markAfterKnownDir = function(
504
dir, str, opt_isHtml) {
505
if (dir == null) {
506
dir = this.estimateDirection(str, opt_isHtml);
507
}
508
return this.dirResetIfNeeded_(str, dir, opt_isHtml, true);
509
};
510
511
512
/**
513
* Returns the Unicode BiDi mark matching the context directionality (LRM for
514
* LTR context directionality, RLM for RTL context directionality), or the
515
* empty string for neutral / unknown context directionality.
516
*
517
* @return {string} LRM for LTR context directionality and RLM for RTL context
518
* directionality.
519
*/
520
goog.i18n.BidiFormatter.prototype.mark = function() {
521
switch (this.contextDir_) {
522
case (goog.i18n.bidi.Dir.LTR):
523
return goog.i18n.bidi.Format.LRM;
524
case (goog.i18n.bidi.Dir.RTL):
525
return goog.i18n.bidi.Format.RLM;
526
default:
527
return '';
528
}
529
};
530
531
532
/**
533
* Returns 'right' for RTL context directionality. Otherwise (LTR or neutral /
534
* unknown context directionality) returns 'left'.
535
*
536
* @return {string} 'right' for RTL context directionality and 'left' for other
537
* context directionality.
538
*/
539
goog.i18n.BidiFormatter.prototype.startEdge = function() {
540
return this.contextDir_ == goog.i18n.bidi.Dir.RTL ? goog.i18n.bidi.RIGHT :
541
goog.i18n.bidi.LEFT;
542
};
543
544
545
/**
546
* Returns 'left' for RTL context directionality. Otherwise (LTR or neutral /
547
* unknown context directionality) returns 'right'.
548
*
549
* @return {string} 'left' for RTL context directionality and 'right' for other
550
* context directionality.
551
*/
552
goog.i18n.BidiFormatter.prototype.endEdge = function() {
553
return this.contextDir_ == goog.i18n.bidi.Dir.RTL ? goog.i18n.bidi.LEFT :
554
goog.i18n.bidi.RIGHT;
555
};
556
557