From 288b8df03a499a2e68ebaad48e687d1eac9df0ff Mon Sep 17 00:00:00 2001 From: Giulio Cesare Solaroli Date: Sat, 17 Mar 2012 21:18:52 +0000 Subject: Merge pull request #34 from gcsolaroli/master Fixed some resources --- (limited to 'frontend/gamma/js/MochiKit/Text.js') diff --git a/frontend/gamma/js/MochiKit/Text.js b/frontend/gamma/js/MochiKit/Text.js index a44f7e4..ff6366d 100644 --- a/frontend/gamma/js/MochiKit/Text.js +++ b/frontend/gamma/js/MochiKit/Text.js @@ -8,7 +8,7 @@ See for documentation, downloads, license, etc. ***/ -MochiKit.Base._module('Text', '1.5', ['Base', 'Format']); +MochiKit.Base.module(MochiKit, 'Text', '1.5', ['Base', 'Format']); /** * Checks if a text string starts with the specified substring. If @@ -22,7 +22,7 @@ MochiKit.Base._module('Text', '1.5', ['Base', 'Format']); */ MochiKit.Text.startsWith = function (substr, str) { return str != null && substr != null && str.indexOf(substr) == 0; -} +}; /** * Checks if a text string ends with the specified substring. If @@ -37,7 +37,7 @@ MochiKit.Text.startsWith = function (substr, str) { MochiKit.Text.endsWith = function (substr, str) { return str != null && substr != null && str.lastIndexOf(substr) == Math.max(str.length - substr.length, 0); -} +}; /** * Checks if a text string contains the specified substring. If @@ -51,7 +51,7 @@ MochiKit.Text.endsWith = function (substr, str) { */ MochiKit.Text.contains = function (substr, str) { return str != null && substr != null && str.indexOf(substr) >= 0; -} +}; /** * Adds a character to the left-hand side of a string until it @@ -71,7 +71,7 @@ MochiKit.Text.padLeft = function (str, minLength, fillChar) { str = fillChar + str; } return str; -} +}; /** * Adds a character to the right-hand side of a string until it @@ -91,7 +91,7 @@ MochiKit.Text.padRight = function (str, minLength, fillChar) { str += fillChar; } return str; -} +}; /** * Returns a truncated copy of a string. If the string is shorter @@ -119,29 +119,55 @@ MochiKit.Text.truncate = function (str, maxLength, tail) { } else { return str.slice(0, maxLength); } -} +}; /** - * Splits a text string, applies a function and joins the results - * back together again. This is a convenience function for calling - * split(), map() and join() separately. It can be used to easily - * trim each line in a text string (using the strip function), or to - * translate a text word-by-word. + * Splits a text string using separator as the split point + * If max is given, at most max splits are done, giving at most + * max + 1 elements in the returned list. * - * @param {Function} func the function to apply * @param {String} str the string to split - * @param {String} [separator] the separator character to use, + * @param {String/RegExp} [separator] the separator char or regexp to use, * defaults to newline + * @param {Number} [max] the maximum number of parts to return + * @return {Array} an array of parts of the string + */ +MochiKit.Text.split = function (str, separator, max) { + if (str == null) { + return str; + } + separator = separator || '\n'; + var bits = str.split(separator); + if ((typeof(max) == "undefined") || max >= bits.length - 1) { + return bits; + } + bits.splice(max, bits.length, bits.slice(max, bits.length).join(separator)); + return bits; +}; + +/** + * Splits a text string using separator as the split point + * If max is given, at most max splits are done, + * using splits from the right * - * @return {String} a string with the joined up results + * @param {String} str the string to split + * @param {String/RegExp} [separator] the separator char or regexp to use, + * defaults to newline + * @param {Number} [max] the maximum number of parts to return + * @return {Array} an array of parts of the string */ -MochiKit.Text.splitJoin = function (func, str, separator) { - if (str == null || str.length == 0) { +MochiKit.Text.rsplit = function (str, separator, max) { + if (str == null) { return str; } - separator = separator || '\n' - return MochiKit.Base.map(func, str.split(separator)).join(separator); -} + separator = separator || '\n'; + var bits = str.split(separator); + if ((typeof(max) == "undefined") || max >= bits.length - 1){ + return bits; + } + bits.splice(0, bits.length-max, bits.slice(0, bits.length-max).join(separator)); + return bits; +}; /** * Creates a formatter function for the specified formatter pattern @@ -158,7 +184,7 @@ MochiKit.Text.splitJoin = function (func, str, separator) { * @throws FormatPatternError if the format pattern was invalid */ MochiKit.Text.formatter = function (pattern, locale) { - if (typeof(locale) == "undefined") { + if (locale == null) { locale = MochiKit.Format.formatLocale(); } else if (typeof(locale) == "string") { locale = MochiKit.Format.formatLocale(locale); @@ -175,8 +201,8 @@ MochiKit.Text.formatter = function (pattern, locale) { } } return res.join(""); - } -} + }; +}; /** * Formats the specified arguments according to a formatter pattern. @@ -193,7 +219,7 @@ MochiKit.Text.formatter = function (pattern, locale) { MochiKit.Text.format = function (pattern/*, ...*/) { var func = MochiKit.Text.formatter(pattern); return func.apply(this, MochiKit.Base.extend([], arguments, 1)); -} +}; /** * Format a value with the specified format specifier. @@ -205,24 +231,29 @@ MochiKit.Text.format = function (pattern/*, ...*/) { * LOCALE.en_US * * @return {String} the formatted output string + * + * @throws FormatPatternError if the format specifier was invalid */ MochiKit.Text.formatValue = function (spec, value, locale) { var self = MochiKit.Text; if (typeof(spec) === "string") { - spec = self._parseFormatFlags(spec, 0, spec.length - 1); + spec = self._parseFormatFlags(spec, 0, spec.length); } for (var i = 0; spec.path != null && i < spec.path.length; i++) { if (value != null) { value = value[spec.path[i]]; } } - if (typeof(locale) == "undefined") { + if (locale == null) { locale = MochiKit.Format.formatLocale(); } else if (typeof(locale) == "string") { locale = MochiKit.Format.formatLocale(locale); } var str = ""; - if (spec.numeric) { + if (spec.type == "number") { + if (value instanceof Number) { + value = value.valueOf(); + } if (typeof(value) != "number" || isNaN(value)) { str = ""; } else if (value === Number.POSITIVE_INFINITY) { @@ -230,8 +261,7 @@ MochiKit.Text.formatValue = function (spec, value, locale) { } else if (value === Number.NEGATIVE_INFINITY) { str = "-\u221e"; } else { - var sign = (spec.sign === "-") ? "" : spec.sign; - sign = (value < 0) ? "-" : sign; + var sign = (value < 0) ? "-" : spec.sign; value = Math.abs(value); if (spec.format === "%") { str = self._truncToPercent(value, spec.precision); @@ -254,7 +284,7 @@ MochiKit.Text.formatValue = function (spec, value, locale) { } else if (spec.padding == "0") { str = self.padLeft(str, spec.width - sign.length, "0"); } - str = self._localizeNumber(str, locale, spec.grouping); + str = self._localizeNumber(str, locale, spec.group); str = sign + str; } if (str !== "" && spec.format === "%") { @@ -264,7 +294,7 @@ MochiKit.Text.formatValue = function (spec, value, locale) { if (spec.format == "r") { str = MochiKit.Base.repr(value); } else { - str = (value == null) ? "null" : value.toString(); + str = (value == null) ? "" : value.toString(); } str = self.truncate(str, spec.precision); } @@ -274,7 +304,7 @@ MochiKit.Text.formatValue = function (spec, value, locale) { str = self.padLeft(str, spec.width); } return str; -} +}; /** * Adjust an already formatted numeric string for locale-specific @@ -284,16 +314,16 @@ MochiKit.Text.formatValue = function (spec, value, locale) { * * @param {String} num the formatted number string * @param {Object} locale the formatting locale to use - * @param {Boolean} grouping the grouping flag + * @param {Boolean} group the grouping flag * * @return {String} the localized number string */ -MochiKit.Text._localizeNumber = function (num, locale, grouping) { +MochiKit.Text._localizeNumber = function (num, locale, group) { var parts = num.split(/\./); var whole = parts[0]; var frac = (parts.length == 1) ? "" : parts[1]; var res = (frac.length > 0) ? locale.decimal : ""; - while (grouping && frac.length > 3) { + while (group && frac.length > 3) { res = res + frac.substring(0, 3) + locale.separator; frac = frac.substring(3); if (whole.charAt(0) == "0") { @@ -301,15 +331,15 @@ MochiKit.Text._localizeNumber = function (num, locale, grouping) { } } if (frac.length > 0) { - res += frac; + res = res + frac; } - while (grouping && whole.length > 3) { + while (group && whole.length > 3) { var pos = whole.length - 3; res = locale.separator + whole.substring(pos) + res; whole = whole.substring((whole.charAt(0) == "0") ? 1 : 0, pos); } return whole + res; -} +}; /** * Parses a format pattern and returns an array of constant strings @@ -324,44 +354,32 @@ MochiKit.Text._localizeNumber = function (num, locale, grouping) { MochiKit.Text._parsePattern = function (pattern) { var self = MochiKit.Text; var parts = []; - var start = 0; - var pos = 0; - for (pos = 0; pos < pattern.length; pos++) { - if (pattern.charAt(pos) == "{") { - if (pos + 1 >= pattern.length) { - var msg = "unescaped { char, should be escaped as {{"; - throw new self.FormatPatternError(pattern, pos, msg); - } else if (pattern.charAt(pos + 1) == "{") { - parts.push(pattern.substring(start, pos + 1)); - start = pos + 2; - pos++; - } else { - if (start < pos) { - parts.push(pattern.substring(start, pos)); - } - start = pattern.indexOf("}", pos) + 1; - if (start <= 0) { - var msg = "unmatched { char, not followed by a } char"; - throw new self.FormatPatternError(pattern, pos, msg); - } - parts.push(self._parseFormat(pattern, pos + 1, start - 1)); - pos = start - 1; - } - } else if (pattern.charAt(pos) == "}") { - if (pos + 1 >= pattern.length || pattern.charAt(pos + 1) != "}") { - var msg = "unescaped } char, should be escaped as }}"; - throw new self.FormatPatternError(pattern, pos, msg); - } - parts.push(pattern.substring(start, pos + 1)); - start = pos + 2; - pos++; + var re = /{[^{}]*}|{{?|}}?/g; + var lastPos = re.lastIndex = 0; + var m; + while ((m = re.exec(pattern)) != null) { + if (lastPos < m.index) { + parts.push(pattern.substring(lastPos, m.index)) + } + var str = m[0]; + lastPos = m.index + str.length; + if (self.startsWith("{", str) && self.endsWith("}", str)) { + parts.push(self._parseFormat(pattern, m.index + 1, lastPos - 1)); + } else if (self.startsWith("{{", str) || self.startsWith("}}", str)) { + parts.push(str.substring(1)); + } else if (self.startsWith("{", str)) { + var msg = "unescaped { char, should be escaped as {{"; + throw new self.FormatPatternError(pattern, m.index, msg); + } else if (self.startsWith("}", str)) { + var msg = "unescaped } char, should be escaped as }}"; + throw new self.FormatPatternError(pattern, m.index, msg); } } - if (start < pos) { - parts.push(pattern.substring(start, pos)); + if (lastPos < pattern.length) { + parts.push(pattern.substring(lastPos)); } return parts; -} +}; /** * Parses a format instruction and returns a format info object. @@ -377,40 +395,30 @@ MochiKit.Text._parsePattern = function (pattern) { MochiKit.Text._parseFormat = function (pattern, startPos, endPos) { var self = MochiKit.Text; var text = pattern.substring(startPos, endPos); - var info; - var pos = text.indexOf(":"); - if (pos == 0) { - info = self._parseFormatFlags(pattern, startPos + 1, endPos); - info.path = [0]; - } else if (pos > 0) { - info = self._parseFormatFlags(pattern, startPos + pos + 1, endPos); - info.path = text.substring(0, pos).split("."); - } else { - info = self._parseFormatFlags(pattern, endPos, endPos); - info.path = text.split("."); - } - var DIGITS = /^\d+$/; + var parts = self.split(text, ":", 1); + var path = parts[0]; + var flagsPos = startPos + path.length + ((parts.length == 1) ? 0 : 1); + var info = self._parseFormatFlags(pattern, flagsPos, endPos); + info.path = (path == "") ? [] : path.split("."); for (var i = 0; i < info.path.length; i++) { - var e = info.path[i]; - if (typeof(e) == "string") { - // TODO: replace with MochiKit.Format.strip? - e = e.replace(/^\s+/, "").replace(/\s+$/, ""); - if (e == "" && info.path.length == 1) { - e = 0; - } else if (e == "") { - var msg = "format value path contains blanks"; - throw new self.FormatPatternError(pattern, startPos, msg); - } else if (DIGITS.test(e)) { - e = parseInt(e); - } + var v = info.path[i]; + // TODO: replace with MochiKit.Format.strip? + v = v.replace(/^\s+/, "").replace(/\s+$/, ""); + if (v == "" && info.path.length == 1) { + v = 0; + } else if (v == "") { + var msg = "format value path contains blanks"; + throw new self.FormatPatternError(pattern, startPos, msg); + } else if (/^\d+$/.test(v)) { + v = parseInt(v, 10); } - info.path[i] = e; + info.path[i] = v; } - if (info.path.length < 0 || typeof(info.path[0]) != "number") { + if (info.path.length <= 0 || typeof(info.path[0]) != "number") { info.path.unshift(0); } return info; -} +}; /** * Parses a string with format flags and returns a format info object. @@ -424,81 +432,52 @@ MochiKit.Text._parseFormat = function (pattern, startPos, endPos) { * @throws FormatPatternError if the format pattern was invalid */ MochiKit.Text._parseFormatFlags = function (pattern, startPos, endPos) { - var self = MochiKit.Text; - var info = { numeric: false, format: "s", width: 0, precision: -1, - align: ">", sign: "-", padding: " ", grouping: false }; + var update = MochiKit.Base.update; + var info = { type: "string", format: "s", width: 0, precision: -1, + align: ">", sign: "", padding: " ", group: false }; // TODO: replace with MochiKit.Format.rstrip? - var flags = pattern.substring(startPos, endPos).replace(/\s+$/, ""); - while (flags.length > 0) { - switch (flags.charAt(0)) { - case ">": - case "<": - info.align = flags.charAt(0); - flags = flags.substring(1); - break; - case "+": - case "-": - case " ": - info.sign = flags.charAt(0); - flags = flags.substring(1); - break; - case ",": - info.grouping = true; - flags = flags.substring(1); - break; - case ".": - var chars = /^\d*/.exec(flags.substring(1))[0]; - info.precision = parseInt(chars); - flags = flags.substring(1 + chars.length); - break; - case "0": - info.padding = flags.charAt(0); - flags = flags.substring(1); - break; - case "1": - case "2": - case "3": - case "4": - case "5": - case "6": - case "7": - case "8": - case "9": - var chars = /^\d*/.exec(flags)[0]; - info.width = parseInt(chars); - flags = flags.substring(chars.length); - break; - case "s": - case "r": - info.format = flags.charAt(0); - flags = flags.substring(1); - break; - case "b": - case "d": - case "o": - case "x": - case "X": - case "f": - case "%": - info.numeric = true; - info.format = flags.charAt(0); - info.radix = 10; - if (info.format === "b") { - info.radix = 2; - } else if (info.format === "o") { - info.radix = 8; - } else if (info.format === "x" || info.format === "X") { - info.radix = 16; - } - flags = flags.substring(1); - break; - default: - var msg = "unsupported format flag: " + flags.charAt(0); - throw new self.FormatPatternError(pattern, startPos, msg); + var text = pattern.substring(startPos, endPos).replace(/\s+$/, ""); + var m = /^([<>+ 0,-]+)?(\d+)?(\.\d*)?([srbdoxXf%])?(.*)$/.exec(text); + var flags = m[1]; + var width = m[2]; + var precision = m[3]; + var type = m[4]; + var unmatched = m[5]; + for (var i = 0; flags && i < flags.length; i++) { + var chr = flags.charAt(i); + if (chr == "<" || chr == ">") { + info.align = chr; + } else if (chr == "+" || chr == "-" || chr == " ") { + info.sign = (chr == "-") ? "" : chr; + } else if (chr == "0") { + info.padding = chr; + } else if (chr == ",") { + info.group = true; } } + if (width) { + info.width = parseInt(width, 10); + } + if (precision && precision.length > 1) { + info.precision = parseInt(precision.substring(1), 10); + } + if (type == "s" || type == "r") { + info.format = type; + } else if (type == "b") { + update(info, { type: "number", format: type, radix: 2 }); + } else if (type == "o") { + update(info, { type: "number", format: type, radix: 8 }); + } else if (type == "x" || type == "X") { + update(info, { type: "number", format: type, radix: 16 }); + } else if (type == "d" || type == "f" || type == "%") { + update(info, { type: "number", format: type, radix: 10 }); + } + if (unmatched) { + var msg = "unsupported format flag: " + unmatched.charAt(0); + throw new MochiKit.Text.FormatPatternError(pattern, startPos, msg); + } return info; -} +}; /** * Formats a value as a percentage. This method avoids multiplication @@ -510,33 +489,23 @@ MochiKit.Text._parseFormatFlags = function (pattern, startPos, endPos) { * @param {Number} precision the number of precision digits */ MochiKit.Text._truncToPercent = function (value, precision) { - // TODO: This can be simplified by using the same helper function - // as roundToFixed now does. + // TODO: This can be simplified by using MochiKit.Format._shiftNumber + // as roundToFixed does. var str; if (precision >= 0) { str = MochiKit.Format.roundToFixed(value, precision + 2); } else { str = (value == null) ? "0" : value.toString(); } - var fracPos = str.indexOf("."); - if (fracPos < 0) { - str = str + "00"; - } else if (fracPos + 3 >= str.length) { - var fraction = str.substring(fracPos + 1); - while (fraction.length < 2) { - fraction = fraction + "0"; - } - str = str.substring(0, fracPos) + fraction; - } else { - var fraction = str.substring(fracPos + 1); - str = str.substring(0, fracPos) + fraction.substring(0, 2) + - "." + fraction.substring(2); - } - while (str.length > 1 && str.charAt(0) == "0" && str.charAt(1) != ".") { - str = str.substring(1); + var arr = MochiKit.Text.split(str, ".", 2); + var frac = MochiKit.Text.padRight(arr[1], 2, "0"); + var whole = arr[0] + frac.substring(0, 2); + frac = frac.substring(2); + while (/^0[0-9]/.test(whole)) { + whole = whole.substring(1); } - return str; -} + return (frac.length <= 0) ? whole : whole + "." + frac; +}; /** * Creates a new format pattern error. @@ -558,13 +527,13 @@ MochiKit.Text.FormatPatternError = function (pattern, pos, message) { this.pattern = pattern; this.pos = pos; this.message = message; -} -MochiKit.Text.FormatPatternError.prototype = - new MochiKit.Base.NamedError("MochiKit.Text.FormatPatternError"); +}; +MochiKit.Text.FormatPatternError.prototype = new MochiKit.Base.NamedError("MochiKit.Text.FormatPatternError"); +MochiKit.Text.FormatPatternError.constructor = MochiKit.Text.FormatPatternError; // -//XXX: Internet Explorer exception handling blows +//XXX: Internet Explorer export fix // if (MochiKit.__export__) { formatter = MochiKit.Text.formatter; -- cgit v0.9.0.2