http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/i18n/bidiformatter.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/i18n/bidiformatter.js b/externs/GCL/externs/goog/i18n/bidiformatter.js new file mode 100644 index 0000000..0583f5b --- /dev/null +++ b/externs/GCL/externs/goog/i18n/bidiformatter.js @@ -0,0 +1,596 @@ +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utility for formatting text for display in a potentially + * opposite-directionality context without garbling. + * Mostly a port of http://go/formatter.cc. + */ + + +goog.provide('goog.i18n.BidiFormatter'); + +goog.require('goog.html.SafeHtml'); +goog.require('goog.html.legacyconversions'); +goog.require('goog.i18n.bidi'); +goog.require('goog.i18n.bidi.Dir'); +goog.require('goog.i18n.bidi.Format'); + + + +/** + * Utility class for formatting text for display in a potentially + * opposite-directionality context without garbling. Provides the following + * functionality: + * + * 1. BiDi Wrapping + * When text in one language is mixed into a document in another, opposite- + * directionality language, e.g. when an English business name is embedded in a + * Hebrew web page, both the inserted string and the text following it may be + * displayed incorrectly unless the inserted string is explicitly separated + * from the surrounding text in a "wrapper" that declares its directionality at + * the start and then resets it back at the end. This wrapping can be done in + * HTML mark-up (e.g. a 'span dir="rtl"' tag) or - only in contexts where + * mark-up can not be used - in Unicode BiDi formatting codes (LRE|RLE and PDF). + * Providing such wrapping services is the basic purpose of the BiDi formatter. + * + * 2. Directionality estimation + * How does one know whether a string about to be inserted into surrounding + * text has the same directionality? Well, in many cases, one knows that this + * must be the case when writing the code doing the insertion, e.g. when a + * localized message is inserted into a localized page. In such cases there is + * no need to involve the BiDi formatter at all. In the remaining cases, e.g. + * when the string is user-entered or comes from a database, the language of + * the string (and thus its directionality) is not known a priori, and must be + * estimated at run-time. The BiDi formatter does this automatically. + * + * 3. Escaping + * When wrapping plain text - i.e. text that is not already HTML or HTML- + * escaped - in HTML mark-up, the text must first be HTML-escaped to prevent XSS + * attacks and other nasty business. This of course is always true, but the + * escaping can not be done after the string has already been wrapped in + * mark-up, so the BiDi formatter also serves as a last chance and includes + * escaping services. + * + * Thus, in a single call, the formatter will escape the input string as + * specified, determine its directionality, and wrap it as necessary. It is + * then up to the caller to insert the return value in the output. + * + * See http://wiki/Main/TemplatesAndBiDi for more information. + * + * @param {goog.i18n.bidi.Dir|number|boolean|null} contextDir The context + * directionality, in one of the following formats: + * 1. A goog.i18n.bidi.Dir constant. NEUTRAL is treated the same as null, + * i.e. unknown, for backward compatibility with legacy calls. + * 2. A number (positive = LTR, negative = RTL, 0 = unknown). + * 3. A boolean (true = RTL, false = LTR). + * 4. A null for unknown directionality. + * @param {boolean=} opt_alwaysSpan Whether {@link #spanWrap} should always + * use a 'span' tag, even when the input directionality is neutral or + * matches the context, so that the DOM structure of the output does not + * depend on the combination of directionalities. Default: false. + * @constructor + * @final + */ +goog.i18n.BidiFormatter = function(contextDir, opt_alwaysSpan) { + /** + * The overall directionality of the context in which the formatter is being + * used. + * @type {?goog.i18n.bidi.Dir} + * @private + */ + this.contextDir_ = goog.i18n.bidi.toDir(contextDir, true /* opt_noNeutral */); + + /** + * Whether {@link #spanWrap} and similar methods should always use the same + * span structure, regardless of the combination of directionalities, for a + * stable DOM structure. + * @type {boolean} + * @private + */ + this.alwaysSpan_ = !!opt_alwaysSpan; +}; + + +/** + * @return {?goog.i18n.bidi.Dir} The context directionality. + */ +goog.i18n.BidiFormatter.prototype.getContextDir = function() { + return this.contextDir_; +}; + + +/** + * @return {boolean} Whether alwaysSpan is set. + */ +goog.i18n.BidiFormatter.prototype.getAlwaysSpan = function() { + return this.alwaysSpan_; +}; + + +/** + * @param {goog.i18n.bidi.Dir|number|boolean|null} contextDir The context + * directionality, in one of the following formats: + * 1. A goog.i18n.bidi.Dir constant. NEUTRAL is treated the same as null, + * i.e. unknown. + * 2. A number (positive = LTR, negative = RTL, 0 = unknown). + * 3. A boolean (true = RTL, false = LTR). + * 4. A null for unknown directionality. + */ +goog.i18n.BidiFormatter.prototype.setContextDir = function(contextDir) { + this.contextDir_ = goog.i18n.bidi.toDir(contextDir, true /* opt_noNeutral */); +}; + + +/** + * @param {boolean} alwaysSpan Whether {@link #spanWrap} should always use a + * 'span' tag, even when the input directionality is neutral or matches the + * context, so that the DOM structure of the output does not depend on the + * combination of directionalities. + */ +goog.i18n.BidiFormatter.prototype.setAlwaysSpan = function(alwaysSpan) { + this.alwaysSpan_ = alwaysSpan; +}; + + +/** + * Returns the directionality of input argument {@code str}. + * Identical to {@link goog.i18n.bidi.estimateDirection}. + * + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @return {goog.i18n.bidi.Dir} Estimated overall directionality of {@code str}. + */ +goog.i18n.BidiFormatter.prototype.estimateDirection = + goog.i18n.bidi.estimateDirection; + + +/** + * Returns true if two given directionalities are opposite. + * Note: the implementation is based on the numeric values of the Dir enum. + * + * @param {?goog.i18n.bidi.Dir} dir1 1st directionality. + * @param {?goog.i18n.bidi.Dir} dir2 2nd directionality. + * @return {boolean} Whether the directionalities are opposite. + * @private + */ +goog.i18n.BidiFormatter.prototype.areDirectionalitiesOpposite_ = function(dir1, + dir2) { + return dir1 * dir2 < 0; +}; + + +/** + * Returns a unicode BiDi mark matching the context directionality (LRM or + * RLM) if {@code opt_dirReset}, and if either the directionality or the exit + * directionality of {@code str} is opposite to the context directionality. + * Otherwise returns the empty string. + * + * @param {string} str The input text. + * @param {goog.i18n.bidi.Dir} dir {@code str}'s overall directionality. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @param {boolean=} opt_dirReset Whether to perform the reset. Default: false. + * @return {string} A unicode BiDi mark or the empty string. + * @private + */ +goog.i18n.BidiFormatter.prototype.dirResetIfNeeded_ = function(str, dir, + opt_isHtml, opt_dirReset) { + // endsWithRtl and endsWithLtr are called only if needed (short-circuit). + if (opt_dirReset && + (this.areDirectionalitiesOpposite_(dir, this.contextDir_) || + (this.contextDir_ == goog.i18n.bidi.Dir.LTR && + goog.i18n.bidi.endsWithRtl(str, opt_isHtml)) || + (this.contextDir_ == goog.i18n.bidi.Dir.RTL && + goog.i18n.bidi.endsWithLtr(str, opt_isHtml)))) { + return this.contextDir_ == goog.i18n.bidi.Dir.LTR ? + goog.i18n.bidi.Format.LRM : goog.i18n.bidi.Format.RLM; + } else { + return ''; + } +}; + + +/** + * Returns "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" if + * it is LTR. In case it's NEUTRAL, returns "rtl" if the context directionality + * is RTL, and "ltr" otherwise. + * Needed for GXP, which can't handle dirAttr. + * Example use case: + * <td expr:dir='bidiFormatter.dirAttrValue(foo)'> + * <gxp:eval expr='foo'> + * </td> + * + * @param {string} str Text whose directionality is to be estimated. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @return {string} "rtl" or "ltr", according to the logic described above. + */ +goog.i18n.BidiFormatter.prototype.dirAttrValue = function(str, opt_isHtml) { + return this.knownDirAttrValue(this.estimateDirection(str, opt_isHtml)); +}; + + +/** + * Returns "rtl" if the given directionality is RTL, and "ltr" if it is LTR. In + * case it's NEUTRAL, returns "rtl" if the context directionality is RTL, and + * "ltr" otherwise. + * + * @param {goog.i18n.bidi.Dir} dir A directionality. + * @return {string} "rtl" or "ltr", according to the logic described above. + */ +goog.i18n.BidiFormatter.prototype.knownDirAttrValue = function(dir) { + var resolvedDir = dir == goog.i18n.bidi.Dir.NEUTRAL ? this.contextDir_ : dir; + return resolvedDir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr'; +}; + + +/** + * Returns 'dir="ltr"' or 'dir="rtl"', depending on {@code str}'s estimated + * directionality, if it is not the same as the context directionality. + * Otherwise, returns the empty string. + * + * @param {string} str Text whose directionality is to be estimated. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @return {string} 'dir="rtl"' for RTL text in non-RTL context; 'dir="ltr"' for + * LTR text in non-LTR context; else, the empty string. + */ +goog.i18n.BidiFormatter.prototype.dirAttr = function(str, opt_isHtml) { + return this.knownDirAttr(this.estimateDirection(str, opt_isHtml)); +}; + + +/** + * Returns 'dir="ltr"' or 'dir="rtl"', depending on the given directionality, if + * it is not the same as the context directionality. Otherwise, returns the + * empty string. + * + * @param {goog.i18n.bidi.Dir} dir A directionality. + * @return {string} 'dir="rtl"' for RTL text in non-RTL context; 'dir="ltr"' for + * LTR text in non-LTR context; else, the empty string. + */ +goog.i18n.BidiFormatter.prototype.knownDirAttr = function(dir) { + if (dir != this.contextDir_) { + return dir == goog.i18n.bidi.Dir.RTL ? 'dir="rtl"' : + dir == goog.i18n.bidi.Dir.LTR ? 'dir="ltr"' : ''; + } + return ''; +}; + + +/** + * Formats a string of unknown directionality for use in HTML output of the + * context directionality, so an opposite-directionality string is neither + * garbled nor garbles what follows it. + * The algorithm: estimates the directionality of input argument {@code html}. + * In case its directionality doesn't match the context directionality, wraps it + * with a 'span' tag and adds a "dir" attribute (either 'dir="rtl"' or + * 'dir="ltr"'). If setAlwaysSpan(true) was used, the input is always wrapped + * with 'span', skipping just the dir attribute when it's not needed. + * + * If {@code opt_dirReset}, and if the overall directionality or the exit + * directionality of {@code str} are opposite to the context directionality, a + * trailing unicode BiDi mark matching the context directionality is appened + * (LRM or RLM). + * + * @param {!goog.html.SafeHtml} html The input HTML. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code html}. Default: true. + * @return {!goog.html.SafeHtml} Input text after applying the processing. + */ +goog.i18n.BidiFormatter.prototype.spanWrapSafeHtml = function(html, + opt_dirReset) { + return this.spanWrapSafeHtmlWithKnownDir(null, html, opt_dirReset); +}; + + +/** + * String version of {@link #spanWrapSafeHtml}. + * + * If !{@code opt_isHtml}, HTML-escapes {@code str} regardless of wrapping. + * + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code str}. Default: true. + * @return {string} Input text after applying the above processing. + */ +goog.i18n.BidiFormatter.prototype.spanWrap = function(str, opt_isHtml, + opt_dirReset) { + return this.spanWrapWithKnownDir(null, str, opt_isHtml, opt_dirReset); +}; + + +/** + * Formats a string of given directionality for use in HTML output of the + * context directionality, so an opposite-directionality string is neither + * garbled nor garbles what follows it. + * The algorithm: If {@code dir} doesn't match the context directionality, wraps + * {@code html} with a 'span' tag and adds a "dir" attribute (either 'dir="rtl"' + * or 'dir="ltr"'). If setAlwaysSpan(true) was used, the input is always wrapped + * with 'span', skipping just the dir attribute when it's not needed. + * + * If {@code opt_dirReset}, and if {@code dir} or the exit directionality of + * {@code html} are opposite to the context directionality, a trailing unicode + * BiDi mark matching the context directionality is appened (LRM or RLM). + * + * @param {?goog.i18n.bidi.Dir} dir {@code html}'s overall directionality, or + * null if unknown and needs to be estimated. + * @param {!goog.html.SafeHtml} html The input HTML. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code html}. Default: true. + * @return {!goog.html.SafeHtml} Input text after applying the processing. + */ +goog.i18n.BidiFormatter.prototype.spanWrapSafeHtmlWithKnownDir = function(dir, + html, opt_dirReset) { + if (dir == null) { + dir = this.estimateDirection(goog.html.SafeHtml.unwrap(html), true); + } + return this.spanWrapWithKnownDir_(dir, html, opt_dirReset); +}; + + +/** + * String version of {@link #spanWrapSafeHtmlWithKnownDir}. + * + * If !{@code opt_isHtml}, HTML-escapes {@code str} regardless of wrapping. + * + * @param {?goog.i18n.bidi.Dir} dir {@code str}'s overall directionality, or + * null if unknown and needs to be estimated. + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code str}. Default: true. + * @return {string} Input text after applying the above processing. + */ +goog.i18n.BidiFormatter.prototype.spanWrapWithKnownDir = function(dir, str, + opt_isHtml, opt_dirReset) { + // We're calling legacy conversions, but quickly unwrapping it. + var html = opt_isHtml ? goog.html.legacyconversions.safeHtmlFromString(str) : + goog.html.SafeHtml.htmlEscape(str); + return goog.html.SafeHtml.unwrap( + this.spanWrapSafeHtmlWithKnownDir(dir, html, opt_dirReset)); +}; + + +/** + * The internal implementation of spanWrapSafeHtmlWithKnownDir for non-null dir, + * to help the compiler optimize. + * + * @param {goog.i18n.bidi.Dir} dir {@code str}'s overall directionality. + * @param {!goog.html.SafeHtml} html The input HTML. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code str}. Default: true. + * @return {!goog.html.SafeHtml} Input text after applying the above processing. + * @private + */ +goog.i18n.BidiFormatter.prototype.spanWrapWithKnownDir_ = function(dir, html, + opt_dirReset) { + opt_dirReset = opt_dirReset || (opt_dirReset == undefined); + + var result; + // Whether to add the "dir" attribute. + var dirCondition = + dir != goog.i18n.bidi.Dir.NEUTRAL && dir != this.contextDir_; + if (this.alwaysSpan_ || dirCondition) { // Wrap is needed + var dirAttribute; + if (dirCondition) { + dirAttribute = dir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr'; + } + result = goog.html.SafeHtml.create('span', {'dir': dirAttribute}, html); + } else { + result = html; + } + var str = goog.html.SafeHtml.unwrap(html); + result = goog.html.SafeHtml.concatWithDir(goog.i18n.bidi.Dir.NEUTRAL, result, + this.dirResetIfNeeded_(str, dir, true, opt_dirReset)); + return result; +}; + + +/** + * Formats a string of unknown directionality for use in plain-text output of + * the context directionality, so an opposite-directionality string is neither + * garbled nor garbles what follows it. + * As opposed to {@link #spanWrap}, this makes use of unicode BiDi formatting + * characters. In HTML, its *only* valid use is inside of elements that do not + * allow mark-up, e.g. an 'option' tag. + * The algorithm: estimates the directionality of input argument {@code str}. + * In case it doesn't match the context directionality, wraps it with Unicode + * BiDi formatting characters: RLE{@code str}PDF for RTL text, and + * LRE{@code str}PDF for LTR text. + * + * If {@code opt_dirReset}, and if the overall directionality or the exit + * directionality of {@code str} are opposite to the context directionality, a + * trailing unicode BiDi mark matching the context directionality is appended + * (LRM or RLM). + * + * Does *not* do HTML-escaping regardless of the value of {@code opt_isHtml}. + * The return value can be HTML-escaped as necessary. + * + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code str}. Default: true. + * @return {string} Input text after applying the above processing. + */ +goog.i18n.BidiFormatter.prototype.unicodeWrap = function(str, opt_isHtml, + opt_dirReset) { + return this.unicodeWrapWithKnownDir(null, str, opt_isHtml, opt_dirReset); +}; + + +/** + * Formats a string of given directionality for use in plain-text output of the + * context directionality, so an opposite-directionality string is neither + * garbled nor garbles what follows it. + * As opposed to {@link #spanWrapWithKnownDir}, makes use of unicode BiDi + * formatting characters. In HTML, its *only* valid use is inside of elements + * that do not allow mark-up, e.g. an 'option' tag. + * The algorithm: If {@code dir} doesn't match the context directionality, wraps + * {@code str} with Unicode BiDi formatting characters: RLE{@code str}PDF for + * RTL text, and LRE{@code str}PDF for LTR text. + * + * If {@code opt_dirReset}, and if the overall directionality or the exit + * directionality of {@code str} are opposite to the context directionality, a + * trailing unicode BiDi mark matching the context directionality is appended + * (LRM or RLM). + * + * Does *not* do HTML-escaping regardless of the value of {@code opt_isHtml}. + * The return value can be HTML-escaped as necessary. + * + * @param {?goog.i18n.bidi.Dir} dir {@code str}'s overall directionality, or + * null if unknown and needs to be estimated. + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code str}. Default: true. + * @return {string} Input text after applying the above processing. + */ +goog.i18n.BidiFormatter.prototype.unicodeWrapWithKnownDir = function(dir, str, + opt_isHtml, opt_dirReset) { + if (dir == null) { + dir = this.estimateDirection(str, opt_isHtml); + } + return this.unicodeWrapWithKnownDir_(dir, str, opt_isHtml, opt_dirReset); +}; + + +/** + * The internal implementation of unicodeWrapWithKnownDir for non-null dir, to + * help the compiler optimize. + * + * @param {goog.i18n.bidi.Dir} dir {@code str}'s overall directionality. + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @param {boolean=} opt_dirReset Whether to append a trailing unicode bidi mark + * matching the context directionality, when needed, to prevent the possible + * garbling of whatever may follow {@code str}. Default: true. + * @return {string} Input text after applying the above processing. + * @private + */ +goog.i18n.BidiFormatter.prototype.unicodeWrapWithKnownDir_ = function(dir, str, + opt_isHtml, opt_dirReset) { + opt_dirReset = opt_dirReset || (opt_dirReset == undefined); + var result = []; + if (dir != goog.i18n.bidi.Dir.NEUTRAL && dir != this.contextDir_) { + result.push(dir == goog.i18n.bidi.Dir.RTL ? goog.i18n.bidi.Format.RLE : + goog.i18n.bidi.Format.LRE); + result.push(str); + result.push(goog.i18n.bidi.Format.PDF); + } else { + result.push(str); + } + + result.push(this.dirResetIfNeeded_(str, dir, opt_isHtml, opt_dirReset)); + return result.join(''); +}; + + +/** + * Returns a Unicode BiDi mark matching the context directionality (LRM or RLM) + * if the directionality or the exit directionality of {@code str} are opposite + * to the context directionality. Otherwise returns the empty string. + * + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @return {string} A Unicode bidi mark matching the global directionality or + * the empty string. + */ +goog.i18n.BidiFormatter.prototype.markAfter = function(str, opt_isHtml) { + return this.markAfterKnownDir(null, str, opt_isHtml); +}; + + +/** + * Returns a Unicode BiDi mark matching the context directionality (LRM or RLM) + * if the given directionality or the exit directionality of {@code str} are + * opposite to the context directionality. Otherwise returns the empty string. + * + * @param {?goog.i18n.bidi.Dir} dir {@code str}'s overall directionality, or + * null if unknown and needs to be estimated. + * @param {string} str The input text. + * @param {boolean=} opt_isHtml Whether {@code str} is HTML / HTML-escaped. + * Default: false. + * @return {string} A Unicode bidi mark matching the global directionality or + * the empty string. + */ +goog.i18n.BidiFormatter.prototype.markAfterKnownDir = function( + dir, str, opt_isHtml) { + if (dir == null) { + dir = this.estimateDirection(str, opt_isHtml); + } + return this.dirResetIfNeeded_(str, dir, opt_isHtml, true); +}; + + +/** + * Returns the Unicode BiDi mark matching the context directionality (LRM for + * LTR context directionality, RLM for RTL context directionality), or the + * empty string for neutral / unknown context directionality. + * + * @return {string} LRM for LTR context directionality and RLM for RTL context + * directionality. + */ +goog.i18n.BidiFormatter.prototype.mark = function() { + switch (this.contextDir_) { + case (goog.i18n.bidi.Dir.LTR): + return goog.i18n.bidi.Format.LRM; + case (goog.i18n.bidi.Dir.RTL): + return goog.i18n.bidi.Format.RLM; + default: + return ''; + } +}; + + +/** + * Returns 'right' for RTL context directionality. Otherwise (LTR or neutral / + * unknown context directionality) returns 'left'. + * + * @return {string} 'right' for RTL context directionality and 'left' for other + * context directionality. + */ +goog.i18n.BidiFormatter.prototype.startEdge = function() { + return this.contextDir_ == goog.i18n.bidi.Dir.RTL ? + goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT; +}; + + +/** + * Returns 'left' for RTL context directionality. Otherwise (LTR or neutral / + * unknown context directionality) returns 'right'. + * + * @return {string} 'left' for RTL context directionality and 'right' for other + * context directionality. + */ +goog.i18n.BidiFormatter.prototype.endEdge = function() { + return this.contextDir_ == goog.i18n.bidi.Dir.RTL ? + goog.i18n.bidi.LEFT : goog.i18n.bidi.RIGHT; +};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/i18n/charlistdecompressor.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/i18n/charlistdecompressor.js b/externs/GCL/externs/goog/i18n/charlistdecompressor.js new file mode 100644 index 0000000..48fae13 --- /dev/null +++ b/externs/GCL/externs/goog/i18n/charlistdecompressor.js @@ -0,0 +1,158 @@ +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview The decompressor for Base88 compressed character lists. + * + * The compression is by base 88 encoding the delta between two adjacent + * characters in ths list. The deltas can be positive or negative. Also, there + * would be character ranges. These three types of values + * are given enum values 0, 1 and 2 respectively. Initial 3 bits are used for + * encoding the type and total length of the encoded value. Length enums 0, 1 + * and 2 represents lengths 1, 2 and 4. So (value * 8 + type * 3 + length enum) + * is encoded in base 88 by following characters for numbers from 0 to 87: + * 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ (continued in next line) + * abcdefghijklmnopqrstuvwxyz!#$%()*+,-.:;<=>?@[]^_`{|}~ + * + * Value uses 0 based counting. That is value for the range [a, b] is 0 and + * that of [a, c] is 1. Simillarly, the delta of "ab" is 0. + * + * Following python script can be used to compress character lists taken + * standard input: http://go/charlistcompressor.py + * + */ + +goog.provide('goog.i18n.CharListDecompressor'); + +goog.require('goog.array'); +goog.require('goog.i18n.uChar'); + + + +/** + * Class to decompress base88 compressed character list. + * @constructor + * @final + */ +goog.i18n.CharListDecompressor = function() { + this.buildCharMap_('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr' + + 'stuvwxyz!#$%()*+,-.:;<=>?@[]^_`{|}~'); +}; + + +/** + * 1-1 mapping from ascii characters used in encoding to an integer in the + * range 0 to 87. + * @type {Object} + * @private + */ +goog.i18n.CharListDecompressor.prototype.charMap_ = null; + + +/** + * Builds the map from ascii characters used for the base88 scheme to number + * each character represents. + * @param {string} str The string of characters used in base88 scheme. + * @private + */ +goog.i18n.CharListDecompressor.prototype.buildCharMap_ = function(str) { + if (!this.charMap_) { + this.charMap_ = {}; + for (var i = 0; i < str.length; i++) { + this.charMap_[str.charAt(i)] = i; + } + } +}; + + +/** + * Gets the number encoded in base88 scheme by a substring of given length + * and placed at the a given position of the string. + * @param {string} str String containing sequence of characters encoding a + * number in base 88 scheme. + * @param {number} start Starting position of substring encoding the number. + * @param {number} leng Length of the substring encoding the number. + * @return {number} The encoded number. + * @private + */ +goog.i18n.CharListDecompressor.prototype.getCodeAt_ = function(str, start, + leng) { + var result = 0; + for (var i = 0; i < leng; i++) { + var c = this.charMap_[str.charAt(start + i)]; + result += c * Math.pow(88, i); + } + return result; +}; + + +/** + * Add character(s) specified by the value and type to given list and return + * the next character in the sequence. + * @param {Array<string>} list The list of characters to which the specified + * characters are appended. + * @param {number} lastcode The last codepoint that was added to the list. + * @param {number} value The value component that representing the delta or + * range. + * @param {number} type The type component that representing whether the value + * is a positive or negative delta or range. + * @return {number} Last codepoint that is added to the list. + * @private + */ +goog.i18n.CharListDecompressor.prototype.addChars_ = function(list, lastcode, + value, type) { + if (type == 0) { + lastcode += value + 1; + goog.array.extend(list, goog.i18n.uChar.fromCharCode(lastcode)); + } else if (type == 1) { + lastcode -= value + 1; + goog.array.extend(list, goog.i18n.uChar.fromCharCode(lastcode)); + } else if (type == 2) { + for (var i = 0; i <= value; i++) { + lastcode++; + goog.array.extend(list, goog.i18n.uChar.fromCharCode(lastcode)); + } + } + return lastcode; +}; + + +/** + * Gets the list of characters specified in the given string by base 88 scheme. + * @param {string} str The string encoding character list. + * @return {!Array<string>} The list of characters specified by the given + * string in base 88 scheme. + */ +goog.i18n.CharListDecompressor.prototype.toCharList = function(str) { + var metasize = 8; + var result = []; + var lastcode = 0; + var i = 0; + while (i < str.length) { + var c = this.charMap_[str.charAt(i)]; + var meta = c % metasize; + var type = Math.floor(meta / 3); + var leng = (meta % 3) + 1; + if (leng == 3) { + leng++; + } + var code = this.getCodeAt_(str, i, leng); + var value = Math.floor(code / metasize); + lastcode = this.addChars_(result, lastcode, value, type); + + i += leng; + } + return result; +}; +
