http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/format/format.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/format/format.js b/externs/GCL/externs/goog/format/format.js new file mode 100644 index 0000000..f78067d --- /dev/null +++ b/externs/GCL/externs/goog/format/format.js @@ -0,0 +1,502 @@ +// Copyright 2006 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 Provides utility functions for formatting strings, numbers etc. + * + */ + +goog.provide('goog.format'); + +goog.require('goog.i18n.GraphemeBreak'); +goog.require('goog.string'); +goog.require('goog.userAgent'); + + +/** + * Formats a number of bytes in human readable form. + * 54, 450K, 1.3M, 5G etc. + * @param {number} bytes The number of bytes to show. + * @param {number=} opt_decimals The number of decimals to use. Defaults to 2. + * @return {string} The human readable form of the byte size. + */ +goog.format.fileSize = function(bytes, opt_decimals) { + return goog.format.numBytesToString(bytes, opt_decimals, false); +}; + + +/** + * Checks whether string value containing scaling units (K, M, G, T, P, m, + * u, n) can be converted to a number. + * + * Where there is a decimal, there must be a digit to the left of the + * decimal point. + * + * Negative numbers are valid. + * + * Examples: + * 0, 1, 1.0, 10.4K, 2.3M, -0.3P, 1.2m + * + * @param {string} val String value to check. + * @return {boolean} True if string could be converted to a numeric value. + */ +goog.format.isConvertableScaledNumber = function(val) { + return goog.format.SCALED_NUMERIC_RE_.test(val); +}; + + +/** + * Converts a string to numeric value, taking into account the units. + * If string ends in 'B', use binary conversion. + * @param {string} stringValue String to be converted to numeric value. + * @return {number} Numeric value for string. + */ +goog.format.stringToNumericValue = function(stringValue) { + if (goog.string.endsWith(stringValue, 'B')) { + return goog.format.stringToNumericValue_( + stringValue, goog.format.NUMERIC_SCALES_BINARY_); + } + return goog.format.stringToNumericValue_( + stringValue, goog.format.NUMERIC_SCALES_SI_); +}; + + +/** + * Converts a string to number of bytes, taking into account the units. + * Binary conversion. + * @param {string} stringValue String to be converted to numeric value. + * @return {number} Numeric value for string. + */ +goog.format.stringToNumBytes = function(stringValue) { + return goog.format.stringToNumericValue_( + stringValue, goog.format.NUMERIC_SCALES_BINARY_); +}; + + +/** + * Converts a numeric value to string representation. SI conversion. + * @param {number} val Value to be converted. + * @param {number=} opt_decimals The number of decimals to use. Defaults to 2. + * @return {string} String representation of number. + */ +goog.format.numericValueToString = function(val, opt_decimals) { + return goog.format.numericValueToString_( + val, goog.format.NUMERIC_SCALES_SI_, opt_decimals); +}; + + +/** + * Converts number of bytes to string representation. Binary conversion. + * Default is to return the additional 'B' suffix, e.g. '10.5KB' to minimize + * confusion with counts that are scaled by powers of 1000. + * @param {number} val Value to be converted. + * @param {number=} opt_decimals The number of decimals to use. Defaults to 2. + * @param {boolean=} opt_suffix If true, include trailing 'B' in returned + * string. Default is true. + * @param {boolean=} opt_useSeparator If true, number and scale will be + * separated by a no break space. Default is false. + * @return {string} String representation of number of bytes. + */ +goog.format.numBytesToString = function(val, opt_decimals, opt_suffix, + opt_useSeparator) { + var suffix = ''; + if (!goog.isDef(opt_suffix) || opt_suffix) { + suffix = 'B'; + } + return goog.format.numericValueToString_( + val, goog.format.NUMERIC_SCALES_BINARY_, opt_decimals, suffix, + opt_useSeparator); +}; + + +/** + * Converts a string to numeric value, taking into account the units. + * @param {string} stringValue String to be converted to numeric value. + * @param {Object} conversion Dictionary of conversion scales. + * @return {number} Numeric value for string. If it cannot be converted, + * returns NaN. + * @private + */ +goog.format.stringToNumericValue_ = function(stringValue, conversion) { + var match = stringValue.match(goog.format.SCALED_NUMERIC_RE_); + if (!match) { + return NaN; + } + var val = match[1] * conversion[match[2]]; + return val; +}; + + +/** + * Converts a numeric value to string, using specified conversion + * scales. + * @param {number} val Value to be converted. + * @param {Object} conversion Dictionary of scaling factors. + * @param {number=} opt_decimals The number of decimals to use. Default is 2. + * @param {string=} opt_suffix Optional suffix to append. + * @param {boolean=} opt_useSeparator If true, number and scale will be + * separated by a space. Default is false. + * @return {string} The human readable form of the byte size. + * @private + */ +goog.format.numericValueToString_ = function(val, conversion, + opt_decimals, opt_suffix, opt_useSeparator) { + var prefixes = goog.format.NUMERIC_SCALE_PREFIXES_; + var orig_val = val; + var symbol = ''; + var separator = ''; + var scale = 1; + if (val < 0) { + val = -val; + } + for (var i = 0; i < prefixes.length; i++) { + var unit = prefixes[i]; + scale = conversion[unit]; + if (val >= scale || (scale <= 1 && val > 0.1 * scale)) { + // Treat values less than 1 differently, allowing 0.5 to be "0.5" rather + // than "500m" + symbol = unit; + break; + } + } + if (!symbol) { + scale = 1; + } else { + if (opt_suffix) { + symbol += opt_suffix; + } + if (opt_useSeparator) { + separator = ' '; + } + } + var ex = Math.pow(10, goog.isDef(opt_decimals) ? opt_decimals : 2); + return Math.round(orig_val / scale * ex) / ex + separator + symbol; +}; + + +/** + * Regular expression for detecting scaling units, such as K, M, G, etc. for + * converting a string representation to a numeric value. + * + * Also allow 'k' to be aliased to 'K'. These could be used for SI (powers + * of 1000) or Binary (powers of 1024) conversions. + * + * Also allow final 'B' to be interpreted as byte-count, implicitly triggering + * binary conversion (e.g., '10.2MB'). + * + * @type {RegExp} + * @private + */ +goog.format.SCALED_NUMERIC_RE_ = /^([-]?\d+\.?\d*)([K,M,G,T,P,k,m,u,n]?)[B]?$/; + + +/** + * Ordered list of scaling prefixes in decreasing order. + * @private {Array<string>} + */ +goog.format.NUMERIC_SCALE_PREFIXES_ = [ + 'P', 'T', 'G', 'M', 'K', '', 'm', 'u', 'n' +]; + + +/** + * Scaling factors for conversion of numeric value to string. SI conversion. + * @type {Object} + * @private + */ +goog.format.NUMERIC_SCALES_SI_ = { + '': 1, + 'n': 1e-9, + 'u': 1e-6, + 'm': 1e-3, + 'k': 1e3, + 'K': 1e3, + 'M': 1e6, + 'G': 1e9, + 'T': 1e12, + 'P': 1e15 +}; + + +/** + * Scaling factors for conversion of numeric value to string. Binary + * conversion. + * @type {Object} + * @private + */ +goog.format.NUMERIC_SCALES_BINARY_ = { + '': 1, + 'n': Math.pow(1024, -3), + 'u': Math.pow(1024, -2), + 'm': 1.0 / 1024, + 'k': 1024, + 'K': 1024, + 'M': Math.pow(1024, 2), + 'G': Math.pow(1024, 3), + 'T': Math.pow(1024, 4), + 'P': Math.pow(1024, 5) +}; + + +/** + * First Unicode code point that has the Mark property. + * @type {number} + * @private + */ +goog.format.FIRST_GRAPHEME_EXTEND_ = 0x300; + + +/** + * Returns true if and only if given character should be treated as a breaking + * space. All ASCII control characters, the main Unicode range of spacing + * characters (U+2000 to U+200B inclusive except for U+2007), and several other + * Unicode space characters are treated as breaking spaces. + * @param {number} charCode The character code under consideration. + * @return {boolean} True if the character is a breaking space. + * @private + */ +goog.format.isTreatedAsBreakingSpace_ = function(charCode) { + return (charCode <= goog.format.WbrToken_.SPACE) || + (charCode >= 0x1000 && + ((charCode >= 0x2000 && charCode <= 0x2006) || + (charCode >= 0x2008 && charCode <= 0x200B) || + charCode == 0x1680 || + charCode == 0x180E || + charCode == 0x2028 || + charCode == 0x2029 || + charCode == 0x205f || + charCode == 0x3000)); +}; + + +/** + * Returns true if and only if given character is an invisible formatting + * character. + * @param {number} charCode The character code under consideration. + * @return {boolean} True if the character is an invisible formatting character. + * @private + */ +goog.format.isInvisibleFormattingCharacter_ = function(charCode) { + // See: http://unicode.org/charts/PDF/U2000.pdf + return (charCode >= 0x200C && charCode <= 0x200F) || + (charCode >= 0x202A && charCode <= 0x202E); +}; + + +/** + * Inserts word breaks into an HTML string at a given interval. The counter is + * reset if a space or a character which behaves like a space is encountered, + * but it isn't incremented if an invisible formatting character is encountered. + * WBRs aren't inserted into HTML tags or entities. Entities count towards the + * character count, HTML tags do not. + * + * With common strings aliased, objects allocations are constant based on the + * length of the string: N + 3. This guarantee does not hold if the string + * contains an element >= U+0300 and hasGraphemeBreak is non-trivial. + * + * @param {string} str HTML to insert word breaks into. + * @param {function(number, number, boolean): boolean} hasGraphemeBreak A + * function determining if there is a grapheme break between two characters, + * in the same signature as goog.i18n.GraphemeBreak.hasGraphemeBreak. + * @param {number=} opt_maxlen Maximum length after which to ensure + * there is a break. Default is 10 characters. + * @return {string} The string including word breaks. + * @private + */ +goog.format.insertWordBreaksGeneric_ = function(str, hasGraphemeBreak, + opt_maxlen) { + var maxlen = opt_maxlen || 10; + if (maxlen > str.length) return str; + + var rv = []; + var n = 0; // The length of the current token + + // This will contain the ampersand or less-than character if one of the + // two has been seen; otherwise, the value is zero. + var nestingCharCode = 0; + + // First character position from input string that has not been outputted. + var lastDumpPosition = 0; + + var charCode = 0; + for (var i = 0; i < str.length; i++) { + // Using charCodeAt versus charAt avoids allocating new string objects. + var lastCharCode = charCode; + charCode = str.charCodeAt(i); + + // Don't add a WBR before characters that might be grapheme extending. + var isPotentiallyGraphemeExtending = + charCode >= goog.format.FIRST_GRAPHEME_EXTEND_ && + !hasGraphemeBreak(lastCharCode, charCode, true); + + // Don't add a WBR at the end of a word. For the purposes of determining + // work breaks, all ASCII control characters and some commonly encountered + // Unicode spacing characters are treated as breaking spaces. + if (n >= maxlen && + !goog.format.isTreatedAsBreakingSpace_(charCode) && + !isPotentiallyGraphemeExtending) { + // Flush everything seen so far, and append a word break. + rv.push(str.substring(lastDumpPosition, i), goog.format.WORD_BREAK_HTML); + lastDumpPosition = i; + n = 0; + } + + if (!nestingCharCode) { + // Not currently within an HTML tag or entity + + if (charCode == goog.format.WbrToken_.LT || + charCode == goog.format.WbrToken_.AMP) { + + // Entering an HTML Entity '&' or open tag '<' + nestingCharCode = charCode; + } else if (goog.format.isTreatedAsBreakingSpace_(charCode)) { + + // A space or control character -- reset the token length + n = 0; + } else if (!goog.format.isInvisibleFormattingCharacter_(charCode)) { + + // A normal flow character - increment. For grapheme extending + // characters, this is not *technically* a new character. However, + // since the grapheme break detector might be overly conservative, + // we have to continue incrementing, or else we won't even be able + // to add breaks when we get to things like punctuation. For the + // case where we have a full grapheme break detector, it is okay if + // we occasionally break slightly early. + n++; + } + } else if (charCode == goog.format.WbrToken_.GT && + nestingCharCode == goog.format.WbrToken_.LT) { + + // Leaving an HTML tag, treat the tag as zero-length + nestingCharCode = 0; + } else if (charCode == goog.format.WbrToken_.SEMI_COLON && + nestingCharCode == goog.format.WbrToken_.AMP) { + + // Leaving an HTML entity, treat it as length one + nestingCharCode = 0; + n++; + } + } + + // Take care of anything we haven't flushed so far. + rv.push(str.substr(lastDumpPosition)); + + return rv.join(''); +}; + + +/** + * Inserts word breaks into an HTML string at a given interval. + * + * This method is as aggressive as possible, using a full table of Unicode + * characters where it is legal to insert word breaks; however, this table + * comes at a 2.5k pre-gzip (~1k post-gzip) size cost. Consider using + * insertWordBreaksBasic to minimize the size impact. + * + * @param {string} str HTML to insert word breaks into. + * @param {number=} opt_maxlen Maximum length after which to ensure there is a + * break. Default is 10 characters. + * @return {string} The string including word breaks. + */ +goog.format.insertWordBreaks = function(str, opt_maxlen) { + return goog.format.insertWordBreaksGeneric_(str, + goog.i18n.GraphemeBreak.hasGraphemeBreak, opt_maxlen); +}; + + +/** + * Determines conservatively if a character has a Grapheme break. + * + * Conforms to a similar signature as goog.i18n.GraphemeBreak, but is overly + * conservative, returning true only for characters in common scripts that + * are simple to account for. + * + * @param {number} lastCharCode The previous character code. Ignored. + * @param {number} charCode The character code under consideration. It must be + * at least \u0300 as a precondition -- this case is covered by + * insertWordBreaksGeneric_. + * @param {boolean=} opt_extended Ignored, to conform with the interface. + * @return {boolean} Whether it is one of the recognized subsets of characters + * with a grapheme break. + * @private + */ +goog.format.conservativelyHasGraphemeBreak_ = function( + lastCharCode, charCode, opt_extended) { + // Return false for everything except the most common Cyrillic characters. + // Don't worry about Latin characters, because insertWordBreaksGeneric_ + // itself already handles those. + // TODO(gboyer): Also account for Greek, Armenian, and Georgian if it is + // simple to do so. + return charCode >= 0x400 && charCode < 0x523; +}; + + +// TODO(gboyer): Consider using a compile-time flag to switch implementations +// rather than relying on the developers to toggle implementations. +/** + * Inserts word breaks into an HTML string at a given interval. + * + * This method is less aggressive than insertWordBreaks, only inserting + * breaks next to punctuation and between Latin or Cyrillic characters. + * However, this is good enough for the common case of URLs. It also + * works for all Latin and Cyrillic languages, plus CJK has no need for word + * breaks. When this method is used, goog.i18n.GraphemeBreak may be dead + * code eliminated. + * + * @param {string} str HTML to insert word breaks into. + * @param {number=} opt_maxlen Maximum length after which to ensure there is a + * break. Default is 10 characters. + * @return {string} The string including word breaks. + */ +goog.format.insertWordBreaksBasic = function(str, opt_maxlen) { + return goog.format.insertWordBreaksGeneric_(str, + goog.format.conservativelyHasGraphemeBreak_, opt_maxlen); +}; + + +/** + * True iff the current userAgent is IE8 or above. + * @type {boolean} + * @private + */ +goog.format.IS_IE8_OR_ABOVE_ = goog.userAgent.IE && + goog.userAgent.isVersionOrHigher(8); + + +/** + * Constant for the WBR replacement used by insertWordBreaks. Safari requires + * <wbr></wbr>, Opera needs the ­ entity, though this will give a visible + * hyphen at breaks. IE8 uses a zero width space. + * Other browsers just use <wbr>. + * @type {string} + */ +goog.format.WORD_BREAK_HTML = + goog.userAgent.WEBKIT ? + '<wbr></wbr>' : goog.userAgent.OPERA ? + '­' : goog.format.IS_IE8_OR_ABOVE_ ? + '​' : '<wbr>'; + + +/** + * Tokens used within insertWordBreaks. + * @private + * @enum {number} + */ +goog.format.WbrToken_ = { + LT: 60, // '<'.charCodeAt(0) + GT: 62, // '>'.charCodeAt(0) + AMP: 38, // '&'.charCodeAt(0) + SEMI_COLON: 59, // ';'.charCodeAt(0) + SPACE: 32 // ' '.charCodeAt(0) +};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/format/htmlprettyprinter.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/format/htmlprettyprinter.js b/externs/GCL/externs/goog/format/htmlprettyprinter.js new file mode 100644 index 0000000..86366fa --- /dev/null +++ b/externs/GCL/externs/goog/format/htmlprettyprinter.js @@ -0,0 +1,408 @@ +// Copyright 2008 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 Provides functions to parse and pretty-print HTML strings. + * + */ + +goog.provide('goog.format.HtmlPrettyPrinter'); +goog.provide('goog.format.HtmlPrettyPrinter.Buffer'); + +goog.require('goog.dom.TagName'); +goog.require('goog.object'); +goog.require('goog.string.StringBuffer'); + + + +/** + * This class formats HTML to be more human-readable. + * TODO(user): Add hierarchical indentation. + * @param {number=} opt_timeOutMillis Max # milliseconds to spend on #format. If + * this time is exceeded, return partially formatted. 0 or negative number + * indicates no timeout. + * @constructor + * @final + */ +goog.format.HtmlPrettyPrinter = function(opt_timeOutMillis) { + /** + * Max # milliseconds to spend on #format. + * @type {number} + * @private + */ + this.timeOutMillis_ = opt_timeOutMillis && opt_timeOutMillis > 0 ? + opt_timeOutMillis : 0; +}; + + +/** + * Singleton. + * @private {goog.format.HtmlPrettyPrinter?} + */ +goog.format.HtmlPrettyPrinter.instance_ = null; + + +/** + * Singleton lazy initializer. + * @return {!goog.format.HtmlPrettyPrinter} Singleton. + * @private + */ +goog.format.HtmlPrettyPrinter.getInstance_ = function() { + if (!goog.format.HtmlPrettyPrinter.instance_) { + goog.format.HtmlPrettyPrinter.instance_ = + new goog.format.HtmlPrettyPrinter(); + } + return goog.format.HtmlPrettyPrinter.instance_; +}; + + +/** + * Static utility function. See prototype #format. + * @param {string} html The HTML text to pretty print. + * @return {string} Formatted result. + */ +goog.format.HtmlPrettyPrinter.format = function(html) { + return goog.format.HtmlPrettyPrinter.getInstance_().format(html); +}; + + +/** + * List of patterns used to tokenize HTML for pretty printing. Cache + * subexpression for tag name. + * comment|meta-tag|tag|text|other-less-than-characters + * @private {!RegExp} + * @const + */ +goog.format.HtmlPrettyPrinter.TOKEN_REGEX_ = + /(?:<!--.*?-->|<!.*?>|<(\/?)(\w+)[^>]*>|[^<]+|<)/g; + + +/** + * Tags whose contents we don't want pretty printed. + * @private {!Object} + * @const + */ +goog.format.HtmlPrettyPrinter.NON_PRETTY_PRINTED_TAGS_ = goog.object.createSet( + goog.dom.TagName.SCRIPT, + goog.dom.TagName.STYLE, + goog.dom.TagName.PRE, + 'XMP'); + + +/** + * 'Block' tags. We should add newlines before and after these tags during + * pretty printing. Tags drawn mostly from HTML4 definitions for block and other + * non-online tags, excepting the ones in + * #goog.format.HtmlPrettyPrinter.NON_PRETTY_PRINTED_TAGS_. + * @private {!Object} + * @const + */ +goog.format.HtmlPrettyPrinter.BLOCK_TAGS_ = goog.object.createSet( + goog.dom.TagName.ADDRESS, + goog.dom.TagName.APPLET, + goog.dom.TagName.AREA, + goog.dom.TagName.BASE, + goog.dom.TagName.BASEFONT, + goog.dom.TagName.BLOCKQUOTE, + goog.dom.TagName.BODY, + goog.dom.TagName.CAPTION, + goog.dom.TagName.CENTER, + goog.dom.TagName.COL, + goog.dom.TagName.COLGROUP, + goog.dom.TagName.DIR, + goog.dom.TagName.DIV, + goog.dom.TagName.DL, + goog.dom.TagName.FIELDSET, + goog.dom.TagName.FORM, + goog.dom.TagName.FRAME, + goog.dom.TagName.FRAMESET, + goog.dom.TagName.H1, + goog.dom.TagName.H2, + goog.dom.TagName.H3, + goog.dom.TagName.H4, + goog.dom.TagName.H5, + goog.dom.TagName.H6, + goog.dom.TagName.HEAD, + goog.dom.TagName.HR, + goog.dom.TagName.HTML, + goog.dom.TagName.IFRAME, + goog.dom.TagName.ISINDEX, + goog.dom.TagName.LEGEND, + goog.dom.TagName.LINK, + goog.dom.TagName.MENU, + goog.dom.TagName.META, + goog.dom.TagName.NOFRAMES, + goog.dom.TagName.NOSCRIPT, + goog.dom.TagName.OL, + goog.dom.TagName.OPTGROUP, + goog.dom.TagName.OPTION, + goog.dom.TagName.P, + goog.dom.TagName.PARAM, + goog.dom.TagName.TABLE, + goog.dom.TagName.TBODY, + goog.dom.TagName.TD, + goog.dom.TagName.TFOOT, + goog.dom.TagName.TH, + goog.dom.TagName.THEAD, + goog.dom.TagName.TITLE, + goog.dom.TagName.TR, + goog.dom.TagName.UL); + + +/** + * Non-block tags that break flow. We insert a line break after, but not before + * these. Tags drawn from HTML4 definitions. + * @private {!Object} + * @const + */ +goog.format.HtmlPrettyPrinter.BREAKS_FLOW_TAGS_ = goog.object.createSet( + goog.dom.TagName.BR, + goog.dom.TagName.DD, + goog.dom.TagName.DT, + goog.dom.TagName.BR, + goog.dom.TagName.LI, + goog.dom.TagName.NOFRAMES); + + +/** + * Empty tags. These are treated as both start and end tags. + * @private {!Object} + * @const + */ +goog.format.HtmlPrettyPrinter.EMPTY_TAGS_ = goog.object.createSet( + goog.dom.TagName.BR, + goog.dom.TagName.HR, + goog.dom.TagName.ISINDEX); + + +/** + * Breaks up HTML so it's easily readable by the user. + * @param {string} html The HTML text to pretty print. + * @return {string} Formatted result. + * @throws {Error} Regex error, data loss, or endless loop detected. + */ +goog.format.HtmlPrettyPrinter.prototype.format = function(html) { + // Trim leading whitespace, but preserve first indent; in other words, keep + // any spaces immediately before the first non-whitespace character (that's + // what $1 is), but remove all other leading whitespace. This adjustment + // historically had been made in Docs. The motivation is that some + // browsers prepend several line breaks in designMode. + html = html.replace(/^\s*?( *\S)/, '$1'); + + // Trim trailing whitespace. + html = html.replace(/\s+$/, ''); + + // Keep track of how much time we've used. + var timeOutMillis = this.timeOutMillis_; + var startMillis = timeOutMillis ? goog.now() : 0; + + // Handles concatenation of the result and required line breaks. + var buffer = new goog.format.HtmlPrettyPrinter.Buffer(); + + // Declare these for efficiency since we access them in a loop. + var tokenRegex = goog.format.HtmlPrettyPrinter.TOKEN_REGEX_; + var nonPpTags = goog.format.HtmlPrettyPrinter.NON_PRETTY_PRINTED_TAGS_; + var blockTags = goog.format.HtmlPrettyPrinter.BLOCK_TAGS_; + var breaksFlowTags = goog.format.HtmlPrettyPrinter.BREAKS_FLOW_TAGS_; + var emptyTags = goog.format.HtmlPrettyPrinter.EMPTY_TAGS_; + + // Used to verify we're making progress through our regex tokenization. + var lastIndex = 0; + + // Use this to track non-pretty-printed tags and childen. + var nonPpTagStack = []; + + // Loop through each matched token. + var match; + while (match = tokenRegex.exec(html)) { + // Get token. + var token = match[0]; + + // Is this token a tag? match.length == 3 for tags, 1 for all others. + if (match.length == 3) { + var tagName = match[2]; + if (tagName) { + tagName = tagName.toUpperCase(); + } + + // Non-pretty-printed tags? + if (nonPpTags.hasOwnProperty(tagName)) { + // End tag? + if (match[1] == '/') { + // Do we have a matching start tag? + var stackSize = nonPpTagStack.length; + var startTagName = stackSize ? nonPpTagStack[stackSize - 1] : null; + if (startTagName == tagName) { + // End of non-pretty-printed block. Line break after. + nonPpTagStack.pop(); + buffer.pushToken(false, token, !nonPpTagStack.length); + } else { + // Malformed HTML. No line breaks. + buffer.pushToken(false, token, false); + } + } else { + // Start of non-pretty-printed block. Line break before. + buffer.pushToken(!nonPpTagStack.length, token, false); + nonPpTagStack.push(tagName); + } + } else if (nonPpTagStack.length) { + // Inside non-pretty-printed block, no new line breaks. + buffer.pushToken(false, token, false); + } else if (blockTags.hasOwnProperty(tagName)) { + // Put line break before start block and after end block tags. + var isEmpty = emptyTags.hasOwnProperty(tagName); + var isEndTag = match[1] == '/'; + buffer.pushToken(isEmpty || !isEndTag, token, isEmpty || isEndTag); + } else if (breaksFlowTags.hasOwnProperty(tagName)) { + var isEmpty = emptyTags.hasOwnProperty(tagName); + var isEndTag = match[1] == '/'; + // Put line break after end flow-breaking tags. + buffer.pushToken(false, token, isEndTag || isEmpty); + } else { + // All other tags, no line break. + buffer.pushToken(false, token, false); + } + } else { + // Non-tags, no line break. + buffer.pushToken(false, token, false); + } + + // Double check that we're making progress. + var newLastIndex = tokenRegex.lastIndex; + if (!token || newLastIndex <= lastIndex) { + throw Error('Regex failed to make progress through source html.'); + } + lastIndex = newLastIndex; + + // Out of time? + if (timeOutMillis) { + if (goog.now() - startMillis > timeOutMillis) { + // Push unprocessed data as one big token and reset regex object. + buffer.pushToken(false, html.substring(tokenRegex.lastIndex), false); + tokenRegex.lastIndex = 0; + break; + } + } + } + + // Ensure we end in a line break. + buffer.lineBreak(); + + // Construct result string. + var result = String(buffer); + + // Length should be original length plus # line breaks added. + var expectedLength = html.length + buffer.breakCount; + if (result.length != expectedLength) { + throw Error('Lost data pretty printing html.'); + } + + return result; +}; + + + +/** + * This class is a buffer to which we push our output. It tracks line breaks to + * make sure we don't add unnecessary ones. + * @constructor + * @final + */ +goog.format.HtmlPrettyPrinter.Buffer = function() { + /** + * Tokens to be output in #toString. + * @type {goog.string.StringBuffer} + * @private + */ + this.out_ = new goog.string.StringBuffer(); +}; + + +/** + * Tracks number of line breaks added. + * @type {number} + */ +goog.format.HtmlPrettyPrinter.Buffer.prototype.breakCount = 0; + + +/** + * Tracks if we are at the start of a new line. + * @type {boolean} + * @private + */ +goog.format.HtmlPrettyPrinter.Buffer.prototype.isBeginningOfNewLine_ = true; + + +/** + * Tracks if we need a new line before the next token. + * @type {boolean} + * @private + */ +goog.format.HtmlPrettyPrinter.Buffer.prototype.needsNewLine_ = false; + + +/** + * Adds token and necessary line breaks to output buffer. + * @param {boolean} breakBefore If true, add line break before token if + * necessary. + * @param {string} token Token to push. + * @param {boolean} breakAfter If true, add line break after token if + * necessary. + */ +goog.format.HtmlPrettyPrinter.Buffer.prototype.pushToken = function( + breakBefore, token, breakAfter) { + // If this token needs a preceeding line break, and + // we haven't already added a line break, and + // this token does not start with a line break, + // then add line break. + // Due to FF3.0 bug with lists, we don't insert a /n + // right before </ul>. See bug 1520665. + if ((this.needsNewLine_ || breakBefore) && + !/^\r?\n/.test(token) && + !/\/ul/i.test(token)) { + this.lineBreak(); + } + + // Token. + this.out_.append(token); + + // Remember if this string ended with a line break so we know we don't have to + // insert another one before the next token. + this.isBeginningOfNewLine_ = /\r?\n$/.test(token); + + // Remember if this token requires a line break after it. We don't insert it + // here because we might not have to if the next token starts with a line + // break. + this.needsNewLine_ = breakAfter && !this.isBeginningOfNewLine_; +}; + + +/** + * Append line break if we need one. + */ +goog.format.HtmlPrettyPrinter.Buffer.prototype.lineBreak = function() { + if (!this.isBeginningOfNewLine_) { + this.out_.append('\n'); + ++this.breakCount; + } +}; + + +/** + * @return {string} String representation of tokens. + * @override + */ +goog.format.HtmlPrettyPrinter.Buffer.prototype.toString = function() { + return this.out_.toString(); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/format/internationalizedemailaddress.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/format/internationalizedemailaddress.js b/externs/GCL/externs/goog/format/internationalizedemailaddress.js new file mode 100644 index 0000000..fd1dfe6 --- /dev/null +++ b/externs/GCL/externs/goog/format/internationalizedemailaddress.js @@ -0,0 +1,256 @@ +// Copyright 2014 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 Provides functions to parse and manipulate internationalized + * email addresses. This is useful in the context of Email Address + * Internationalization (EAI) as defined by RFC6530. + * + */ + +goog.provide('goog.format.InternationalizedEmailAddress'); + +goog.require('goog.format.EmailAddress'); + +goog.require('goog.string'); + + + +/** + * Formats an email address string for display, and allows for extraction of + * the individual components of the address. + * @param {string=} opt_address The email address. + * @param {string=} opt_name The name associated with the email address. + * @constructor + * @extends {goog.format.EmailAddress} + */ +goog.format.InternationalizedEmailAddress = function(opt_address, opt_name) { + goog.format.InternationalizedEmailAddress.base( + this, 'constructor', opt_address, opt_name); +}; +goog.inherits( + goog.format.InternationalizedEmailAddress, goog.format.EmailAddress); + + +/** + * A string representing the RegExp for the local part of an EAI email address. + * @private + */ +goog.format.InternationalizedEmailAddress.EAI_LOCAL_PART_REGEXP_STR_ = + '((?!\\s)[+a-zA-Z0-9_.!#$%&\'*\\/=?^`{|}~\u0080-\uFFFFFF-])+'; + + +/** + * A string representing the RegExp for a label in the domain part of an EAI + * email address. + * @private + */ +goog.format.InternationalizedEmailAddress.EAI_LABEL_CHAR_REGEXP_STR_ = + '(?!\\s)[a-zA-Z0-9\u0080-\u3001\u3003-\uFF0D\uFF0F-\uFF60\uFF62-\uFFFFFF-]'; + + +/** + * A string representing the RegExp for the domain part of an EAI email address. + * @private + */ +goog.format.InternationalizedEmailAddress.EAI_DOMAIN_PART_REGEXP_STR_ = + // A unicode character (ASCII or Unicode excluding periods) + '(' + goog.format.InternationalizedEmailAddress.EAI_LABEL_CHAR_REGEXP_STR_ + + // Such character 1+ times, followed by a Unicode period. All 1+ times. + '+[\\.\\uFF0E\\u3002\\uFF61])+' + + // And same thing but without a period in the end + goog.format.InternationalizedEmailAddress.EAI_LABEL_CHAR_REGEXP_STR_ + + '{2,63}'; + + +/** + * Match string for address separators. This list is the result of the + * discussion in b/16241003. + * @type {string} + * @private + */ +goog.format.InternationalizedEmailAddress.ADDRESS_SEPARATORS_ = + ',' + // U+002C ( , ) COMMA + ';' + // U+003B ( ; ) SEMICOLON + '\u055D' + // ( Õ ) ARMENIAN COMMA + '\u060C' + // ( Ø ) ARABIC COMMA + '\u1363' + // ( ᣠ) ETHIOPIC COMMA + '\u1802' + // ( á ) MONGOLIAN COMMA + '\u1808' + // ( á ) MONGOLIAN MANCHU COMMA + '\u2E41' + // ( â¹ ) REVERSED COMMA + '\u3001' + // ( ã ) IDEOGRAPHIC COMMA + '\uFF0C' + // ( ï¼ ) FULLWIDTH COMMA + '\u061B' + // ( âØâ ) ARABIC SEMICOLON + '\u1364' + // ( ᤠ) ETHIOPIC SEMICOLON + '\uFF1B' + // ( ï¼ ) FULLWIDTH SEMICOLON + '\uFF64' + // ( 、 ) HALFWIDTH IDEOGRAPHIC COMMA + '\u104A'; // ( á ) MYANMAR SIGN LITTLE SECTION + + +/** + * Match string for characters that, when in a display name, require it to be + * quoted. + * @type {string} + * @private + */ +goog.format.InternationalizedEmailAddress.CHARS_REQUIRE_QUOTES_ = + goog.format.EmailAddress.SPECIAL_CHARS + + goog.format.InternationalizedEmailAddress.ADDRESS_SEPARATORS_; + + +/** + * A RegExp to match the local part of an EAI email address. + * @private {!RegExp} + */ +goog.format.InternationalizedEmailAddress.EAI_LOCAL_PART_ = + new RegExp('^' + + goog.format.InternationalizedEmailAddress.EAI_LOCAL_PART_REGEXP_STR_ + + '$'); + + +/** + * A RegExp to match the domain part of an EAI email address. + * @private {!RegExp} + */ +goog.format.InternationalizedEmailAddress.EAI_DOMAIN_PART_ = + new RegExp('^' + + goog.format.InternationalizedEmailAddress.EAI_DOMAIN_PART_REGEXP_STR_ + + '$'); + + +/** + * A RegExp to match an EAI email address. + * @private {!RegExp} + */ +goog.format.InternationalizedEmailAddress.EAI_EMAIL_ADDRESS_ = + new RegExp('^' + + goog.format.InternationalizedEmailAddress.EAI_LOCAL_PART_REGEXP_STR_ + + '@' + + goog.format.InternationalizedEmailAddress.EAI_DOMAIN_PART_REGEXP_STR_ + + '$'); + + +/** + * Checks if the provided string is a valid local part (part before the '@') of + * an EAI email address. + * @param {string} str The local part to check. + * @return {boolean} Whether the provided string is a valid local part. + */ +goog.format.InternationalizedEmailAddress.isValidLocalPartSpec = function(str) { + if (!goog.isDefAndNotNull(str)) { + return false; + } + return goog.format.InternationalizedEmailAddress.EAI_LOCAL_PART_.test(str); +}; + + +/** + * Checks if the provided string is a valid domain part (part after the '@') of + * an EAI email address. + * @param {string} str The domain part to check. + * @return {boolean} Whether the provided string is a valid domain part. + */ +goog.format.InternationalizedEmailAddress.isValidDomainPartSpec = + function(str) { + if (!goog.isDefAndNotNull(str)) { + return false; + } + return goog.format.InternationalizedEmailAddress.EAI_DOMAIN_PART_.test(str); +}; + + +/** @override */ +goog.format.InternationalizedEmailAddress.prototype.isValid = function() { + return goog.format.InternationalizedEmailAddress.isValidAddrSpec( + this.address); +}; + + +/** + * Checks if the provided string is a valid email address. Supports both + * simple email addresses (address specs) and addresses that contain display + * names. + * @param {string} str The email address to check. + * @return {boolean} Whether the provided string is a valid address. + */ +goog.format.InternationalizedEmailAddress.isValidAddress = function(str) { + if (!goog.isDefAndNotNull(str)) { + return false; + } + return goog.format.InternationalizedEmailAddress.parse(str).isValid(); +}; + + +/** + * Checks if the provided string is a valid address spec ([email protected]). + * @param {string} str The email address to check. + * @return {boolean} Whether the provided string is a valid address spec. + */ +goog.format.InternationalizedEmailAddress.isValidAddrSpec = function(str) { + if (!goog.isDefAndNotNull(str)) { + return false; + } + + // This is a fairly naive implementation, but it covers 99% of use cases. + // For more details, see http://en.wikipedia.org/wiki/Email_address#Syntax + return goog.format.InternationalizedEmailAddress.EAI_EMAIL_ADDRESS_.test(str); +}; + + +/** + * Parses a string containing email addresses of the form + * "name" <address> into an array of email addresses. + * @param {string} str The address list. + * @return {!Array<!goog.format.EmailAddress>} The parsed emails. + */ +goog.format.InternationalizedEmailAddress.parseList = function(str) { + return goog.format.EmailAddress.parseListInternal( + str, goog.format.InternationalizedEmailAddress.parse, + goog.format.InternationalizedEmailAddress.isAddressSeparator); +}; + + +/** + * Parses an email address of the form "name" <address> into + * an email address. + * @param {string} addr The address string. + * @return {!goog.format.EmailAddress} The parsed address. + */ +goog.format.InternationalizedEmailAddress.parse = function(addr) { + return goog.format.EmailAddress.parseInternal( + addr, goog.format.InternationalizedEmailAddress); +}; + + +/** + * @param {string} ch The character to test. + * @return {boolean} Whether the provided character is an address separator. + */ +goog.format.InternationalizedEmailAddress.isAddressSeparator = function(ch) { + return goog.string.contains( + goog.format.InternationalizedEmailAddress.ADDRESS_SEPARATORS_, ch); +}; + + +/** + * Return the address in a standard format: + * - remove extra spaces. + * - Surround name with quotes if it contains special characters. + * @return {string} The cleaned address. + * @override + */ +goog.format.InternationalizedEmailAddress.prototype.toString = function() { + return this.toStringInternal( + goog.format.InternationalizedEmailAddress.CHARS_REQUIRE_QUOTES_); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/format/jsonprettyprinter.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/format/jsonprettyprinter.js b/externs/GCL/externs/goog/format/jsonprettyprinter.js new file mode 100644 index 0000000..15e2cd2 --- /dev/null +++ b/externs/GCL/externs/goog/format/jsonprettyprinter.js @@ -0,0 +1,414 @@ +// Copyright 2010 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 Creates a string of a JSON object, properly indented for + * display. + * + */ + +goog.provide('goog.format.JsonPrettyPrinter'); +goog.provide('goog.format.JsonPrettyPrinter.HtmlDelimiters'); +goog.provide('goog.format.JsonPrettyPrinter.TextDelimiters'); + +goog.require('goog.json'); +goog.require('goog.json.Serializer'); +goog.require('goog.string'); +goog.require('goog.string.StringBuffer'); +goog.require('goog.string.format'); + + + +/** + * Formats a JSON object as a string, properly indented for display. Supports + * displaying the string as text or html. Users can also specify their own + * set of delimiters for different environments. For example, the JSON object: + * + * <code>{"a": 1, "b": {"c": null, "d": true, "e": [1, 2]}}</code> + * + * Will be displayed like this: + * + * <code>{ + * "a": 1, + * "b": { + * "c": null, + * "d": true, + * "e": [ + * 1, + * 2 + * ] + * } + * }</code> + * @param {goog.format.JsonPrettyPrinter.TextDelimiters} delimiters Container + * for the various strings to use to delimit objects, arrays, newlines, and + * other pieces of the output. + * @constructor + */ +goog.format.JsonPrettyPrinter = function(delimiters) { + + /** + * The set of characters to use as delimiters. + * @type {goog.format.JsonPrettyPrinter.TextDelimiters} + * @private + */ + this.delimiters_ = delimiters || + new goog.format.JsonPrettyPrinter.TextDelimiters(); + + /** + * Used to serialize property names and values. + * @type {goog.json.Serializer} + * @private + */ + this.jsonSerializer_ = new goog.json.Serializer(); +}; + + +/** + * Formats a JSON object as a string, properly indented for display. + * @param {*} json The object to pretty print. It could be a JSON object, a + * string representing a JSON object, or any other type. + * @return {string} Returns a string of the JSON object, properly indented for + * display. + */ +goog.format.JsonPrettyPrinter.prototype.format = function(json) { + // If input is undefined, null, or empty, return an empty string. + if (!goog.isDefAndNotNull(json)) { + return ''; + } + if (goog.isString(json)) { + if (goog.string.isEmptyOrWhitespace(json)) { + return ''; + } + // Try to coerce a string into a JSON object. + json = goog.json.parse(json); + } + var outputBuffer = new goog.string.StringBuffer(); + this.printObject_(json, outputBuffer, 0); + return outputBuffer.toString(); +}; + + +/** + * Formats a property value based on the type of the propery. + * @param {*} val The object to format. + * @param {goog.string.StringBuffer} outputBuffer The buffer to write the + * response to. + * @param {number} indent The number of spaces to indent each line of the + * output. + * @private + */ +goog.format.JsonPrettyPrinter.prototype.printObject_ = function(val, + outputBuffer, indent) { + var typeOf = goog.typeOf(val); + switch (typeOf) { + case 'null': + case 'boolean': + case 'number': + case 'string': + // "null", "boolean", "number" and "string" properties are printed + // directly to the output. + this.printValue_( + /** @type {null|string|boolean|number} */ (val), + typeOf, outputBuffer); + break; + case 'array': + // Example of how an array looks when formatted + // (using the default delimiters): + // [ + // 1, + // 2, + // 3 + // ] + outputBuffer.append(this.delimiters_.arrayStart); + var i = 0; + // Iterate through the array and format each element. + for (i = 0; i < val.length; i++) { + if (i > 0) { + // There are multiple elements, add a comma to separate them. + outputBuffer.append(this.delimiters_.propertySeparator); + } + outputBuffer.append(this.delimiters_.lineBreak); + this.printSpaces_(indent + this.delimiters_.indent, outputBuffer); + this.printObject_(val[i], outputBuffer, + indent + this.delimiters_.indent); + } + // If there are no properties in this object, don't put a line break + // between the beginning "[" and ending "]", so the output of an empty + // array looks like <code>[]</code>. + if (i > 0) { + outputBuffer.append(this.delimiters_.lineBreak); + this.printSpaces_(indent, outputBuffer); + } + outputBuffer.append(this.delimiters_.arrayEnd); + break; + case 'object': + // Example of how an object looks when formatted + // (using the default delimiters): + // { + // "a": 1, + // "b": 2, + // "c": "3" + // } + outputBuffer.append(this.delimiters_.objectStart); + var propertyCount = 0; + // Iterate through the object and display each property. + for (var name in val) { + if (!val.hasOwnProperty(name)) { + continue; + } + if (propertyCount > 0) { + // There are multiple properties, add a comma to separate them. + outputBuffer.append(this.delimiters_.propertySeparator); + } + outputBuffer.append(this.delimiters_.lineBreak); + this.printSpaces_(indent + this.delimiters_.indent, outputBuffer); + this.printName_(name, outputBuffer); + outputBuffer.append(this.delimiters_.nameValueSeparator, + this.delimiters_.space); + this.printObject_(val[name], outputBuffer, + indent + this.delimiters_.indent); + propertyCount++; + } + // If there are no properties in this object, don't put a line break + // between the beginning "{" and ending "}", so the output of an empty + // object looks like <code>{}</code>. + if (propertyCount > 0) { + outputBuffer.append(this.delimiters_.lineBreak); + this.printSpaces_(indent, outputBuffer); + } + outputBuffer.append(this.delimiters_.objectEnd); + break; + // Other types, such as "function", aren't expected in JSON, and their + // behavior is undefined. In these cases, just print an empty string to the + // output buffer. This allows the pretty printer to continue while still + // outputing well-formed JSON. + default: + this.printValue_('', 'unknown', outputBuffer); + } +}; + + +/** + * Prints a property name to the output. + * @param {string} name The property name. + * @param {goog.string.StringBuffer} outputBuffer The buffer to write the + * response to. + * @private + */ +goog.format.JsonPrettyPrinter.prototype.printName_ = function(name, + outputBuffer) { + outputBuffer.append(this.delimiters_.preName, + this.jsonSerializer_.serialize(name), this.delimiters_.postName); +}; + + +/** + * Prints a property name to the output. + * @param {string|boolean|number|null} val The property value. + * @param {string} typeOf The type of the value. Used to customize + * value-specific css in the display. This allows clients to distinguish + * between different types in css. For example, the client may define two + * classes: "goog-jsonprettyprinter-propertyvalue-string" and + * "goog-jsonprettyprinter-propertyvalue-number" to assign a different color + * to string and number values. + * @param {goog.string.StringBuffer} outputBuffer The buffer to write the + * response to. + * @private + */ +goog.format.JsonPrettyPrinter.prototype.printValue_ = function(val, + typeOf, outputBuffer) { + outputBuffer.append(goog.string.format(this.delimiters_.preValue, typeOf), + this.jsonSerializer_.serialize(val), + goog.string.format(this.delimiters_.postValue, typeOf)); +}; + + +/** + * Print a number of space characters to the output. + * @param {number} indent The number of spaces to indent the line. + * @param {goog.string.StringBuffer} outputBuffer The buffer to write the + * response to. + * @private + */ +goog.format.JsonPrettyPrinter.prototype.printSpaces_ = function(indent, + outputBuffer) { + outputBuffer.append(goog.string.repeat(this.delimiters_.space, indent)); +}; + + + +/** + * A container for the delimiting characters used to display the JSON string + * to a text display. Each delimiter is a publicly accessible property of + * the object, which makes it easy to tweak delimiters to specific environments. + * @constructor + */ +goog.format.JsonPrettyPrinter.TextDelimiters = function() { +}; + + +/** + * Represents a space character in the output. Used to indent properties a + * certain number of spaces, and to separate property names from property + * values. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.space = ' '; + + +/** + * Represents a newline character in the output. Used to begin a new line. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.lineBreak = '\n'; + + +/** + * Represents the start of an object in the output. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.objectStart = '{'; + + +/** + * Represents the end of an object in the output. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.objectEnd = '}'; + + +/** + * Represents the start of an array in the output. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.arrayStart = '['; + + +/** + * Represents the end of an array in the output. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.arrayEnd = ']'; + + +/** + * Represents the string used to separate properties in the output. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.propertySeparator = ','; + + +/** + * Represents the string used to separate property names from property values in + * the output. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.nameValueSeparator = ':'; + + +/** + * A string that's placed before a property name in the output. Useful for + * wrapping a property name in an html tag. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.preName = ''; + + +/** + * A string that's placed after a property name in the output. Useful for + * wrapping a property name in an html tag. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.postName = ''; + + +/** + * A string that's placed before a property value in the output. Useful for + * wrapping a property value in an html tag. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.preValue = ''; + + +/** + * A string that's placed after a property value in the output. Useful for + * wrapping a property value in an html tag. + * @type {string} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.postValue = ''; + + +/** + * Represents the number of spaces to indent each sub-property of the JSON. + * @type {number} + */ +goog.format.JsonPrettyPrinter.TextDelimiters.prototype.indent = 2; + + + +/** + * A container for the delimiting characters used to display the JSON string + * to an HTML <code><pre></code> or <code><code></code> element. + * @constructor + * @extends {goog.format.JsonPrettyPrinter.TextDelimiters} + * @final + */ +goog.format.JsonPrettyPrinter.HtmlDelimiters = function() { + goog.format.JsonPrettyPrinter.TextDelimiters.call(this); +}; +goog.inherits(goog.format.JsonPrettyPrinter.HtmlDelimiters, + goog.format.JsonPrettyPrinter.TextDelimiters); + + +/** + * A <code>span</code> tag thats placed before a property name. Used to style + * property names with CSS. + * @type {string} + * @override + */ +goog.format.JsonPrettyPrinter.HtmlDelimiters.prototype.preName = + '<span class="' + + goog.getCssName('goog-jsonprettyprinter-propertyname') + + '">'; + + +/** + * A closing <code>span</code> tag that's placed after a property name. + * @type {string} + * @override + */ +goog.format.JsonPrettyPrinter.HtmlDelimiters.prototype.postName = '</span>'; + + +/** + * A <code>span</code> tag thats placed before a property value. Used to style + * property value with CSS. The span tag's class is in the format + * goog-jsonprettyprinter-propertyvalue-{TYPE}, where {TYPE} is the JavaScript + * type of the object (the {TYPE} parameter is obtained from goog.typeOf). This + * can be used to style different value types. + * @type {string} + * @override + */ +goog.format.JsonPrettyPrinter.HtmlDelimiters.prototype.preValue = + '<span class="' + + goog.getCssName('goog-jsonprettyprinter-propertyvalue') + + '-%s">'; + + +/** + * A closing <code>span</code> tag that's placed after a property value. + * @type {string} + * @override + */ +goog.format.JsonPrettyPrinter.HtmlDelimiters.prototype.postValue = '</span>'; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/fs/entry.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/fs/entry.js b/externs/GCL/externs/goog/fs/entry.js new file mode 100644 index 0000000..8143daa --- /dev/null +++ b/externs/GCL/externs/goog/fs/entry.js @@ -0,0 +1,272 @@ +// Copyright 2011 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 Wrappers for HTML5 Entry objects. These are all in the same + * file to avoid circular dependency issues. + * + * When adding or modifying functionality in this namespace, be sure to update + * the mock counterparts in goog.testing.fs. + * + */ +goog.provide('goog.fs.DirectoryEntry'); +goog.provide('goog.fs.DirectoryEntry.Behavior'); +goog.provide('goog.fs.Entry'); +goog.provide('goog.fs.FileEntry'); + + + +/** + * The interface for entries in the filesystem. + * @interface + */ +goog.fs.Entry = function() {}; + + +/** + * @return {boolean} Whether or not this entry is a file. + */ +goog.fs.Entry.prototype.isFile = function() {}; + + +/** + * @return {boolean} Whether or not this entry is a directory. + */ +goog.fs.Entry.prototype.isDirectory = function() {}; + + +/** + * @return {string} The name of this entry. + */ +goog.fs.Entry.prototype.getName = function() {}; + + +/** + * @return {string} The full path to this entry. + */ +goog.fs.Entry.prototype.getFullPath = function() {}; + + +/** + * @return {!goog.fs.FileSystem} The filesystem backing this entry. + */ +goog.fs.Entry.prototype.getFileSystem = function() {}; + + +/** + * Retrieves the last modified date for this entry. + * + * @return {!goog.async.Deferred} The deferred Date for this entry. If an error + * occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.Entry.prototype.getLastModified = function() {}; + + +/** + * Retrieves the metadata for this entry. + * + * @return {!goog.async.Deferred} The deferred Metadata for this entry. If an + * error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.Entry.prototype.getMetadata = function() {}; + + +/** + * Move this entry to a new location. + * + * @param {!goog.fs.DirectoryEntry} parent The new parent directory. + * @param {string=} opt_newName The new name of the entry. If omitted, the entry + * retains its original name. + * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileEntry} or + * {@link goog.fs.DirectoryEntry} for the new entry. If an error occurs, the + * errback is called with a {@link goog.fs.Error}. + */ +goog.fs.Entry.prototype.moveTo = function(parent, opt_newName) {}; + + +/** + * Copy this entry to a new location. + * + * @param {!goog.fs.DirectoryEntry} parent The new parent directory. + * @param {string=} opt_newName The name of the new entry. If omitted, the new + * entry has the same name as the original. + * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileEntry} or + * {@link goog.fs.DirectoryEntry} for the new entry. If an error occurs, the + * errback is called with a {@link goog.fs.Error}. + */ +goog.fs.Entry.prototype.copyTo = function(parent, opt_newName) {}; + + +/** + * Wrap an HTML5 entry object in an appropriate subclass instance. + * + * @param {!Entry} entry The underlying Entry object. + * @return {!goog.fs.Entry} The appropriate subclass wrapper. + * @protected + */ +goog.fs.Entry.prototype.wrapEntry = function(entry) {}; + + +/** + * Get the URL for this file. + * + * @param {string=} opt_mimeType The MIME type that will be served for the URL. + * @return {string} The URL. + */ +goog.fs.Entry.prototype.toUrl = function(opt_mimeType) {}; + + +/** + * Get the URI for this file. + * + * @deprecated Use {@link #toUrl} instead. + * @param {string=} opt_mimeType The MIME type that will be served for the URI. + * @return {string} The URI. + */ +goog.fs.Entry.prototype.toUri = function(opt_mimeType) {}; + + +/** + * Remove this entry. + * + * @return {!goog.async.Deferred} A deferred object. If the removal succeeds, + * the callback is called with true. If an error occurs, the errback is + * called a {@link goog.fs.Error}. + */ +goog.fs.Entry.prototype.remove = function() {}; + + +/** + * Gets the parent directory. + * + * @return {!goog.async.Deferred} The deferred {@link goog.fs.DirectoryEntry}. + * If an error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.Entry.prototype.getParent = function() {}; + + + +/** + * A directory in a local FileSystem. + * + * @interface + * @extends {goog.fs.Entry} + */ +goog.fs.DirectoryEntry = function() {}; + + +/** + * Behaviors for getting files and directories. + * @enum {number} + */ +goog.fs.DirectoryEntry.Behavior = { + /** + * Get the file if it exists, error out if it doesn't. + */ + DEFAULT: 1, + /** + * Get the file if it exists, create it if it doesn't. + */ + CREATE: 2, + /** + * Error out if the file exists, create it if it doesn't. + */ + CREATE_EXCLUSIVE: 3 +}; + + +/** + * Get a file in the directory. + * + * @param {string} path The path to the file, relative to this directory. + * @param {goog.fs.DirectoryEntry.Behavior=} opt_behavior The behavior for + * handling an existing file, or the lack thereof. + * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileEntry}. If an + * error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.DirectoryEntry.prototype.getFile = function(path, opt_behavior) {}; + + +/** + * Get a directory within this directory. + * + * @param {string} path The path to the directory, relative to this directory. + * @param {goog.fs.DirectoryEntry.Behavior=} opt_behavior The behavior for + * handling an existing directory, or the lack thereof. + * @return {!goog.async.Deferred} The deferred {@link goog.fs.DirectoryEntry}. + * If an error occurs, the errback is called a {@link goog.fs.Error}. + */ +goog.fs.DirectoryEntry.prototype.getDirectory = function(path, opt_behavior) {}; + + +/** + * Opens the directory for the specified path, creating the directory and any + * intermediate directories as necessary. + * + * @param {string} path The directory path to create. May be absolute or + * relative to the current directory. The parent directory ".." and current + * directory "." are supported. + * @return {!goog.async.Deferred} A deferred {@link goog.fs.DirectoryEntry} for + * the requested path. If an error occurs, the errback is called with a + * {@link goog.fs.Error}. + */ +goog.fs.DirectoryEntry.prototype.createPath = function(path) {}; + + +/** + * Gets a list of all entries in this directory. + * + * @return {!goog.async.Deferred} The deferred list of {@link goog.fs.Entry} + * results. If an error occurs, the errback is called with a + * {@link goog.fs.Error}. + */ +goog.fs.DirectoryEntry.prototype.listDirectory = function() {}; + + +/** + * Removes this directory and all its contents. + * + * @return {!goog.async.Deferred} A deferred object. If the removal succeeds, + * the callback is called with true. If an error occurs, the errback is + * called a {@link goog.fs.Error}. + */ +goog.fs.DirectoryEntry.prototype.removeRecursively = function() {}; + + + +/** + * A file in a local filesystem. + * + * @interface + * @extends {goog.fs.Entry} + */ +goog.fs.FileEntry = function() {}; + + +/** + * Create a writer for writing to the file. + * + * @return {!goog.async.Deferred<!goog.fs.FileWriter>} If an error occurs, the + * errback is called with a {@link goog.fs.Error}. + */ +goog.fs.FileEntry.prototype.createWriter = function() {}; + + +/** + * Get the file contents as a File blob. + * + * @return {!goog.async.Deferred<!File>} If an error occurs, the errback is + * called with a {@link goog.fs.Error}. + */ +goog.fs.FileEntry.prototype.file = function() {}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/fs/entryimpl.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/fs/entryimpl.js b/externs/GCL/externs/goog/fs/entryimpl.js new file mode 100644 index 0000000..a4cbe7a --- /dev/null +++ b/externs/GCL/externs/goog/fs/entryimpl.js @@ -0,0 +1,404 @@ +// Copyright 2013 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 Concrete implementations of the + * goog.fs.DirectoryEntry, and goog.fs.FileEntry interfaces. + */ +goog.provide('goog.fs.DirectoryEntryImpl'); +goog.provide('goog.fs.EntryImpl'); +goog.provide('goog.fs.FileEntryImpl'); + +goog.require('goog.array'); +goog.require('goog.async.Deferred'); +goog.require('goog.fs.DirectoryEntry'); +goog.require('goog.fs.Entry'); +goog.require('goog.fs.Error'); +goog.require('goog.fs.FileEntry'); +goog.require('goog.fs.FileWriter'); +goog.require('goog.functions'); +goog.require('goog.string'); + + + +/** + * Base class for concrete implementations of goog.fs.Entry. + * @param {!goog.fs.FileSystem} fs The wrapped filesystem. + * @param {!Entry} entry The underlying Entry object. + * @constructor + * @implements {goog.fs.Entry} + */ +goog.fs.EntryImpl = function(fs, entry) { + /** + * The wrapped filesystem. + * + * @type {!goog.fs.FileSystem} + * @private + */ + this.fs_ = fs; + + /** + * The underlying Entry object. + * + * @type {!Entry} + * @private + */ + this.entry_ = entry; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.isFile = function() { + return this.entry_.isFile; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.isDirectory = function() { + return this.entry_.isDirectory; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.getName = function() { + return this.entry_.name; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.getFullPath = function() { + return this.entry_.fullPath; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.getFileSystem = function() { + return this.fs_; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.getLastModified = function() { + return this.getMetadata().addCallback(function(metadata) { + return metadata.modificationTime; + }); +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.getMetadata = function() { + var d = new goog.async.Deferred(); + + this.entry_.getMetadata( + function(metadata) { d.callback(metadata); }, + goog.bind(function(err) { + var msg = 'retrieving metadata for ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.moveTo = function(parent, opt_newName) { + var d = new goog.async.Deferred(); + this.entry_.moveTo( + parent.dir_, opt_newName, + goog.bind(function(entry) { d.callback(this.wrapEntry(entry)); }, this), + goog.bind(function(err) { + var msg = 'moving ' + this.getFullPath() + ' into ' + + parent.getFullPath() + + (opt_newName ? ', renaming to ' + opt_newName : ''); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.copyTo = function(parent, opt_newName) { + var d = new goog.async.Deferred(); + this.entry_.copyTo( + parent.dir_, opt_newName, + goog.bind(function(entry) { d.callback(this.wrapEntry(entry)); }, this), + goog.bind(function(err) { + var msg = 'copying ' + this.getFullPath() + ' into ' + + parent.getFullPath() + + (opt_newName ? ', renaming to ' + opt_newName : ''); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.wrapEntry = function(entry) { + return entry.isFile ? + new goog.fs.FileEntryImpl(this.fs_, /** @type {!FileEntry} */ (entry)) : + new goog.fs.DirectoryEntryImpl( + this.fs_, /** @type {!DirectoryEntry} */ (entry)); +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.toUrl = function(opt_mimeType) { + return this.entry_.toURL(opt_mimeType); +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.toUri = goog.fs.EntryImpl.prototype.toUrl; + + +/** @override */ +goog.fs.EntryImpl.prototype.remove = function() { + var d = new goog.async.Deferred(); + this.entry_.remove( + goog.bind(d.callback, d, true /* result */), + goog.bind(function(err) { + var msg = 'removing ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.EntryImpl.prototype.getParent = function() { + var d = new goog.async.Deferred(); + this.entry_.getParent( + goog.bind(function(parent) { + d.callback(new goog.fs.DirectoryEntryImpl(this.fs_, parent)); + }, this), + goog.bind(function(err) { + var msg = 'getting parent of ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + + +/** + * A directory in a local FileSystem. + * + * This should not be instantiated directly. Instead, it should be accessed via + * {@link goog.fs.FileSystem#getRoot} or + * {@link goog.fs.DirectoryEntry#getDirectoryEntry}. + * + * @param {!goog.fs.FileSystem} fs The wrapped filesystem. + * @param {!DirectoryEntry} dir The underlying DirectoryEntry object. + * @constructor + * @extends {goog.fs.EntryImpl} + * @implements {goog.fs.DirectoryEntry} + * @final + */ +goog.fs.DirectoryEntryImpl = function(fs, dir) { + goog.fs.DirectoryEntryImpl.base(this, 'constructor', fs, dir); + + /** + * The underlying DirectoryEntry object. + * + * @type {!DirectoryEntry} + * @private + */ + this.dir_ = dir; +}; +goog.inherits(goog.fs.DirectoryEntryImpl, goog.fs.EntryImpl); + + +/** @override */ +goog.fs.DirectoryEntryImpl.prototype.getFile = function(path, opt_behavior) { + var d = new goog.async.Deferred(); + this.dir_.getFile( + path, this.getOptions_(opt_behavior), + goog.bind(function(entry) { + d.callback(new goog.fs.FileEntryImpl(this.fs_, entry)); + }, this), + goog.bind(function(err) { + var msg = 'loading file ' + path + ' from ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.DirectoryEntryImpl.prototype.getDirectory = + function(path, opt_behavior) { + var d = new goog.async.Deferred(); + this.dir_.getDirectory( + path, this.getOptions_(opt_behavior), + goog.bind(function(entry) { + d.callback(new goog.fs.DirectoryEntryImpl(this.fs_, entry)); + }, this), + goog.bind(function(err) { + var msg = 'loading directory ' + path + ' from ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.DirectoryEntryImpl.prototype.createPath = function(path) { + // If the path begins at the root, reinvoke createPath on the root directory. + if (goog.string.startsWith(path, '/')) { + var root = this.getFileSystem().getRoot(); + if (this.getFullPath() != root.getFullPath()) { + return root.createPath(path); + } + } + + // Filter out any empty path components caused by '//' or a leading slash. + var parts = goog.array.filter(path.split('/'), goog.functions.identity); + + /** + * @param {goog.fs.DirectoryEntryImpl} dir + * @return {!goog.async.Deferred} + */ + function getNextDirectory(dir) { + if (!parts.length) { + return goog.async.Deferred.succeed(dir); + } + + var def; + var nextDir = parts.shift(); + + if (nextDir == '..') { + def = dir.getParent(); + } else if (nextDir == '.') { + def = goog.async.Deferred.succeed(dir); + } else { + def = dir.getDirectory(nextDir, goog.fs.DirectoryEntry.Behavior.CREATE); + } + return def.addCallback(getNextDirectory); + } + + return getNextDirectory(this); +}; + + +/** @override */ +goog.fs.DirectoryEntryImpl.prototype.listDirectory = function() { + var d = new goog.async.Deferred(); + var reader = this.dir_.createReader(); + var results = []; + + var errorCallback = goog.bind(function(err) { + var msg = 'listing directory ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this); + + var successCallback = goog.bind(function(entries) { + if (entries.length) { + for (var i = 0, entry; entry = entries[i]; i++) { + results.push(this.wrapEntry(entry)); + } + reader.readEntries(successCallback, errorCallback); + } else { + d.callback(results); + } + }, this); + + reader.readEntries(successCallback, errorCallback); + return d; +}; + + +/** @override */ +goog.fs.DirectoryEntryImpl.prototype.removeRecursively = function() { + var d = new goog.async.Deferred(); + this.dir_.removeRecursively( + goog.bind(d.callback, d, true /* result */), + goog.bind(function(err) { + var msg = 'removing ' + this.getFullPath() + ' recursively'; + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** + * Converts a value in the Behavior enum into an options object expected by the + * File API. + * + * @param {goog.fs.DirectoryEntry.Behavior=} opt_behavior The behavior for + * existing files. + * @return {!Object<boolean>} The options object expected by the File API. + * @private + */ +goog.fs.DirectoryEntryImpl.prototype.getOptions_ = function(opt_behavior) { + if (opt_behavior == goog.fs.DirectoryEntry.Behavior.CREATE) { + return {'create': true}; + } else if (opt_behavior == goog.fs.DirectoryEntry.Behavior.CREATE_EXCLUSIVE) { + return {'create': true, 'exclusive': true}; + } else { + return {}; + } +}; + + + +/** + * A file in a local filesystem. + * + * This should not be instantiated directly. Instead, it should be accessed via + * {@link goog.fs.DirectoryEntry#getFile}. + * + * @param {!goog.fs.FileSystem} fs The wrapped filesystem. + * @param {!FileEntry} file The underlying FileEntry object. + * @constructor + * @extends {goog.fs.EntryImpl} + * @implements {goog.fs.FileEntry} + * @final + */ +goog.fs.FileEntryImpl = function(fs, file) { + goog.fs.FileEntryImpl.base(this, 'constructor', fs, file); + + /** + * The underlying FileEntry object. + * + * @type {!FileEntry} + * @private + */ + this.file_ = file; +}; +goog.inherits(goog.fs.FileEntryImpl, goog.fs.EntryImpl); + + +/** @override */ +goog.fs.FileEntryImpl.prototype.createWriter = function() { + var d = new goog.async.Deferred(); + this.file_.createWriter( + function(w) { d.callback(new goog.fs.FileWriter(w)); }, + goog.bind(function(err) { + var msg = 'creating writer for ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; + + +/** @override */ +goog.fs.FileEntryImpl.prototype.file = function() { + var d = new goog.async.Deferred(); + this.file_.file( + function(f) { d.callback(f); }, + goog.bind(function(err) { + var msg = 'getting file for ' + this.getFullPath(); + d.errback(new goog.fs.Error(err, msg)); + }, this)); + return d; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/fs/error3.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/fs/error3.js b/externs/GCL/externs/goog/fs/error3.js new file mode 100644 index 0000000..3a54f28 --- /dev/null +++ b/externs/GCL/externs/goog/fs/error3.js @@ -0,0 +1,181 @@ +// Copyright 2011 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 A wrapper for the HTML5 FileError object. + * + */ + +goog.provide('goog.fs.Error'); +goog.provide('goog.fs.Error.ErrorCode'); + +goog.require('goog.debug.Error'); +goog.require('goog.object'); +goog.require('goog.string'); + + + +/** + * A filesystem error. Since the filesystem API is asynchronous, stack traces + * are less useful for identifying where errors come from, so this includes a + * large amount of metadata in the message. + * + * @param {!DOMError} error + * @param {string} action The action being undertaken when the error was raised. + * @constructor + * @extends {goog.debug.Error} + * @final + */ +goog.fs.Error = function(error, action) { + /** @type {string} */ + this.name; + + /** + * @type {goog.fs.Error.ErrorCode} + * @deprecated Use the 'name' or 'message' field instead. + */ + this.code; + + if (goog.isDef(error.name)) { + this.name = error.name; + // TODO(user): Remove warning suppression after JSCompiler stops + // firing a spurious warning here. + /** @suppress {deprecated} */ + this.code = goog.fs.Error.getCodeFromName_(error.name); + } else { + this.code = error.code; + this.name = goog.fs.Error.getNameFromCode_(error.code); + } + goog.fs.Error.base(this, 'constructor', + goog.string.subs('%s %s', this.name, action)); +}; +goog.inherits(goog.fs.Error, goog.debug.Error); + + +/** + * Names of errors that may be thrown by the File API, the File System API, or + * the File Writer API. + * + * @see http://dev.w3.org/2006/webapi/FileAPI/#ErrorAndException + * @see http://www.w3.org/TR/file-system-api/#definitions + * @see http://dev.w3.org/2009/dap/file-system/file-writer.html#definitions + * @enum {string} + */ +goog.fs.Error.ErrorName = { + ABORT: 'AbortError', + ENCODING: 'EncodingError', + INVALID_MODIFICATION: 'InvalidModificationError', + INVALID_STATE: 'InvalidStateError', + NOT_FOUND: 'NotFoundError', + NOT_READABLE: 'NotReadableError', + NO_MODIFICATION_ALLOWED: 'NoModificationAllowedError', + PATH_EXISTS: 'PathExistsError', + QUOTA_EXCEEDED: 'QuotaExceededError', + SECURITY: 'SecurityError', + SYNTAX: 'SyntaxError', + TYPE_MISMATCH: 'TypeMismatchError' +}; + + +/** + * Error codes for file errors. + * @see http://www.w3.org/TR/file-system-api/#idl-def-FileException + * + * @enum {number} + * @deprecated Use the 'name' or 'message' attribute instead. + */ +goog.fs.Error.ErrorCode = { + NOT_FOUND: 1, + SECURITY: 2, + ABORT: 3, + NOT_READABLE: 4, + ENCODING: 5, + NO_MODIFICATION_ALLOWED: 6, + INVALID_STATE: 7, + SYNTAX: 8, + INVALID_MODIFICATION: 9, + QUOTA_EXCEEDED: 10, + TYPE_MISMATCH: 11, + PATH_EXISTS: 12 +}; + + +/** + * @param {goog.fs.Error.ErrorCode} code + * @return {string} name + * @private + */ +goog.fs.Error.getNameFromCode_ = function(code) { + var name = goog.object.findKey(goog.fs.Error.NameToCodeMap_, function(c) { + return code == c; + }); + if (!goog.isDef(name)) { + throw new Error('Invalid code: ' + code); + } + return name; +}; + + +/** + * Returns the code that corresponds to the given name. + * @param {string} name + * @return {goog.fs.Error.ErrorCode} code + * @private + */ +goog.fs.Error.getCodeFromName_ = function(name) { + return goog.fs.Error.NameToCodeMap_[name]; +}; + + +/** + * Mapping from error names to values from the ErrorCode enum. + * @see http://www.w3.org/TR/file-system-api/#definitions. + * @private {!Object<string, goog.fs.Error.ErrorCode>} + */ +goog.fs.Error.NameToCodeMap_ = goog.object.create( + goog.fs.Error.ErrorName.ABORT, + goog.fs.Error.ErrorCode.ABORT, + + goog.fs.Error.ErrorName.ENCODING, + goog.fs.Error.ErrorCode.ENCODING, + + goog.fs.Error.ErrorName.INVALID_MODIFICATION, + goog.fs.Error.ErrorCode.INVALID_MODIFICATION, + + goog.fs.Error.ErrorName.INVALID_STATE, + goog.fs.Error.ErrorCode.INVALID_STATE, + + goog.fs.Error.ErrorName.NOT_FOUND, + goog.fs.Error.ErrorCode.NOT_FOUND, + + goog.fs.Error.ErrorName.NOT_READABLE, + goog.fs.Error.ErrorCode.NOT_READABLE, + + goog.fs.Error.ErrorName.NO_MODIFICATION_ALLOWED, + goog.fs.Error.ErrorCode.NO_MODIFICATION_ALLOWED, + + goog.fs.Error.ErrorName.PATH_EXISTS, + goog.fs.Error.ErrorCode.PATH_EXISTS, + + goog.fs.Error.ErrorName.QUOTA_EXCEEDED, + goog.fs.Error.ErrorCode.QUOTA_EXCEEDED, + + goog.fs.Error.ErrorName.SECURITY, + goog.fs.Error.ErrorCode.SECURITY, + + goog.fs.Error.ErrorName.SYNTAX, + goog.fs.Error.ErrorCode.SYNTAX, + + goog.fs.Error.ErrorName.TYPE_MISMATCH, + goog.fs.Error.ErrorCode.TYPE_MISMATCH); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/fs/filereader.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/fs/filereader.js b/externs/GCL/externs/goog/fs/filereader.js new file mode 100644 index 0000000..14d5245 --- /dev/null +++ b/externs/GCL/externs/goog/fs/filereader.js @@ -0,0 +1,288 @@ +// Copyright 2011 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 A wrapper for the HTML5 FileReader object. + * + */ + +goog.provide('goog.fs.FileReader'); +goog.provide('goog.fs.FileReader.EventType'); +goog.provide('goog.fs.FileReader.ReadyState'); + +goog.require('goog.async.Deferred'); +goog.require('goog.events.EventTarget'); +goog.require('goog.fs.Error'); +goog.require('goog.fs.ProgressEvent'); + + + +/** + * An object for monitoring the reading of files. This emits ProgressEvents of + * the types listed in {@link goog.fs.FileReader.EventType}. + * + * @constructor + * @extends {goog.events.EventTarget} + * @final + */ +goog.fs.FileReader = function() { + goog.fs.FileReader.base(this, 'constructor'); + + /** + * The underlying FileReader object. + * + * @type {!FileReader} + * @private + */ + this.reader_ = new FileReader(); + + this.reader_.onloadstart = goog.bind(this.dispatchProgressEvent_, this); + this.reader_.onprogress = goog.bind(this.dispatchProgressEvent_, this); + this.reader_.onload = goog.bind(this.dispatchProgressEvent_, this); + this.reader_.onabort = goog.bind(this.dispatchProgressEvent_, this); + this.reader_.onerror = goog.bind(this.dispatchProgressEvent_, this); + this.reader_.onloadend = goog.bind(this.dispatchProgressEvent_, this); +}; +goog.inherits(goog.fs.FileReader, goog.events.EventTarget); + + +/** + * Possible states for a FileReader. + * + * @enum {number} + */ +goog.fs.FileReader.ReadyState = { + /** + * The object has been constructed, but there is no pending read. + */ + INIT: 0, + /** + * Data is being read. + */ + LOADING: 1, + /** + * The data has been read from the file, the read was aborted, or an error + * occurred. + */ + DONE: 2 +}; + + +/** + * Events emitted by a FileReader. + * + * @enum {string} + */ +goog.fs.FileReader.EventType = { + /** + * Emitted when the reading begins. readyState will be LOADING. + */ + LOAD_START: 'loadstart', + /** + * Emitted when progress has been made in reading the file. readyState will be + * LOADING. + */ + PROGRESS: 'progress', + /** + * Emitted when the data has been successfully read. readyState will be + * LOADING. + */ + LOAD: 'load', + /** + * Emitted when the reading has been aborted. readyState will be LOADING. + */ + ABORT: 'abort', + /** + * Emitted when an error is encountered or the reading has been aborted. + * readyState will be LOADING. + */ + ERROR: 'error', + /** + * Emitted when the reading is finished, whether successfully or not. + * readyState will be DONE. + */ + LOAD_END: 'loadend' +}; + + +/** + * Abort the reading of the file. + */ +goog.fs.FileReader.prototype.abort = function() { + try { + this.reader_.abort(); + } catch (e) { + throw new goog.fs.Error(e, 'aborting read'); + } +}; + + +/** + * @return {goog.fs.FileReader.ReadyState} The current state of the FileReader. + */ +goog.fs.FileReader.prototype.getReadyState = function() { + return /** @type {goog.fs.FileReader.ReadyState} */ (this.reader_.readyState); +}; + + +/** + * @return {*} The result of the file read. + */ +goog.fs.FileReader.prototype.getResult = function() { + return this.reader_.result; +}; + + +/** + * @return {goog.fs.Error} The error encountered while reading, if any. + */ +goog.fs.FileReader.prototype.getError = function() { + return this.reader_.error && + new goog.fs.Error(this.reader_.error, 'reading file'); +}; + + +/** + * Wrap a progress event emitted by the underlying file reader and re-emit it. + * + * @param {!ProgressEvent} event The underlying event. + * @private + */ +goog.fs.FileReader.prototype.dispatchProgressEvent_ = function(event) { + this.dispatchEvent(new goog.fs.ProgressEvent(event, this)); +}; + + +/** @override */ +goog.fs.FileReader.prototype.disposeInternal = function() { + goog.fs.FileReader.base(this, 'disposeInternal'); + delete this.reader_; +}; + + +/** + * Starts reading a blob as a binary string. + * @param {!Blob} blob The blob to read. + */ +goog.fs.FileReader.prototype.readAsBinaryString = function(blob) { + this.reader_.readAsBinaryString(blob); +}; + + +/** + * Reads a blob as a binary string. + * @param {!Blob} blob The blob to read. + * @return {!goog.async.Deferred} The deferred Blob contents as a binary string. + * If an error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.FileReader.readAsBinaryString = function(blob) { + var reader = new goog.fs.FileReader(); + var d = goog.fs.FileReader.createDeferred_(reader); + reader.readAsBinaryString(blob); + return d; +}; + + +/** + * Starts reading a blob as an array buffer. + * @param {!Blob} blob The blob to read. + */ +goog.fs.FileReader.prototype.readAsArrayBuffer = function(blob) { + this.reader_.readAsArrayBuffer(blob); +}; + + +/** + * Reads a blob as an array buffer. + * @param {!Blob} blob The blob to read. + * @return {!goog.async.Deferred} The deferred Blob contents as an array buffer. + * If an error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.FileReader.readAsArrayBuffer = function(blob) { + var reader = new goog.fs.FileReader(); + var d = goog.fs.FileReader.createDeferred_(reader); + reader.readAsArrayBuffer(blob); + return d; +}; + + +/** + * Starts reading a blob as text. + * @param {!Blob} blob The blob to read. + * @param {string=} opt_encoding The name of the encoding to use. + */ +goog.fs.FileReader.prototype.readAsText = function(blob, opt_encoding) { + this.reader_.readAsText(blob, opt_encoding); +}; + + +/** + * Reads a blob as text. + * @param {!Blob} blob The blob to read. + * @param {string=} opt_encoding The name of the encoding to use. + * @return {!goog.async.Deferred} The deferred Blob contents as text. + * If an error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.FileReader.readAsText = function(blob, opt_encoding) { + var reader = new goog.fs.FileReader(); + var d = goog.fs.FileReader.createDeferred_(reader); + reader.readAsText(blob, opt_encoding); + return d; +}; + + +/** + * Starts reading a blob as a data URL. + * @param {!Blob} blob The blob to read. + */ +goog.fs.FileReader.prototype.readAsDataUrl = function(blob) { + this.reader_.readAsDataURL(blob); +}; + + +/** + * Reads a blob as a data URL. + * @param {!Blob} blob The blob to read. + * @return {!goog.async.Deferred} The deferred Blob contents as a data URL. + * If an error occurs, the errback is called with a {@link goog.fs.Error}. + */ +goog.fs.FileReader.readAsDataUrl = function(blob) { + var reader = new goog.fs.FileReader(); + var d = goog.fs.FileReader.createDeferred_(reader); + reader.readAsDataUrl(blob); + return d; +}; + + +/** + * Creates a new deferred object for the results of a read method. + * @param {goog.fs.FileReader} reader The reader to create a deferred for. + * @return {!goog.async.Deferred} The deferred results. + * @private + */ +goog.fs.FileReader.createDeferred_ = function(reader) { + var deferred = new goog.async.Deferred(); + reader.listen(goog.fs.FileReader.EventType.LOAD_END, + goog.partial(function(d, r, e) { + var result = r.getResult(); + var error = r.getError(); + if (result != null && !error) { + d.callback(result); + } else { + d.errback(error); + } + r.dispose(); + }, deferred, reader)); + return deferred; +};
