summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/MochiKit/Text.js
Side-by-side diff
Diffstat (limited to 'frontend/gamma/js/MochiKit/Text.js') (more/less context) (show whitespace changes)
-rw-r--r--frontend/gamma/js/MochiKit/Text.js349
1 files changed, 159 insertions, 190 deletions
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
@@ -9,5 +9,5 @@ See <http://mochikit.com/> for documentation, downloads, license, etc.
***/
-MochiKit.Base._module('Text', '1.5', ['Base', 'Format']);
+MochiKit.Base.module(MochiKit, 'Text', '1.5', ['Base', 'Format']);
/**
@@ -23,5 +23,5 @@ MochiKit.Base._module('Text', '1.5', ['Base', 'Format']);
MochiKit.Text.startsWith = function (substr, str) {
return str != null && substr != null && str.indexOf(substr) == 0;
-}
+};
/**
@@ -38,5 +38,5 @@ MochiKit.Text.endsWith = function (substr, str) {
return str != null && substr != null &&
str.lastIndexOf(substr) == Math.max(str.length - substr.length, 0);
-}
+};
/**
@@ -52,5 +52,5 @@ MochiKit.Text.endsWith = function (substr, str) {
MochiKit.Text.contains = function (substr, str) {
return str != null && substr != null && str.indexOf(substr) >= 0;
-}
+};
/**
@@ -72,5 +72,5 @@ MochiKit.Text.padLeft = function (str, minLength, fillChar) {
}
return str;
-}
+};
/**
@@ -92,5 +92,5 @@ MochiKit.Text.padRight = function (str, minLength, fillChar) {
}
return str;
-}
+};
/**
@@ -120,27 +120,53 @@ MochiKit.Text.truncate = function (str, maxLength, tail) {
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;
+};
/**
@@ -159,5 +185,5 @@ MochiKit.Text.splitJoin = function (func, str, separator) {
*/
MochiKit.Text.formatter = function (pattern, locale) {
- if (typeof(locale) == "undefined") {
+ if (locale == null) {
locale = MochiKit.Format.formatLocale();
} else if (typeof(locale) == "string") {
@@ -176,6 +202,6 @@ MochiKit.Text.formatter = function (pattern, locale) {
}
return res.join("");
- }
-}
+ };
+};
/**
@@ -194,5 +220,5 @@ MochiKit.Text.format = function (pattern/*, ...*/) {
var func = MochiKit.Text.formatter(pattern);
return func.apply(this, MochiKit.Base.extend([], arguments, 1));
-}
+};
/**
@@ -206,9 +232,11 @@ MochiKit.Text.format = function (pattern/*, ...*/) {
*
* @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++) {
@@ -217,5 +245,5 @@ MochiKit.Text.formatValue = function (spec, value, locale) {
}
}
- if (typeof(locale) == "undefined") {
+ if (locale == null) {
locale = MochiKit.Format.formatLocale();
} else if (typeof(locale) == "string") {
@@ -223,5 +251,8 @@ MochiKit.Text.formatValue = function (spec, value, locale) {
}
var str = "";
- if (spec.numeric) {
+ if (spec.type == "number") {
+ if (value instanceof Number) {
+ value = value.valueOf();
+ }
if (typeof(value) != "number" || isNaN(value)) {
str = "";
@@ -231,6 +262,5 @@ MochiKit.Text.formatValue = function (spec, value, locale) {
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 === "%") {
@@ -255,5 +285,5 @@ MochiKit.Text.formatValue = function (spec, value, locale) {
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;
}
@@ -265,5 +295,5 @@ MochiKit.Text.formatValue = function (spec, value, locale) {
str = MochiKit.Base.repr(value);
} else {
- str = (value == null) ? "null" : value.toString();
+ str = (value == null) ? "" : value.toString();
}
str = self.truncate(str, spec.precision);
@@ -275,5 +305,5 @@ MochiKit.Text.formatValue = function (spec, value, locale) {
}
return str;
-}
+};
/**
@@ -285,14 +315,14 @@ 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);
@@ -302,7 +332,7 @@ 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;
@@ -310,5 +340,5 @@ MochiKit.Text._localizeNumber = function (num, locale, grouping) {
}
return whole + res;
-}
+};
/**
@@ -325,42 +355,30 @@ 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 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, 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) != "}") {
+ 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, pos, msg);
- }
- parts.push(pattern.substring(start, pos + 1));
- start = pos + 2;
- pos++;
+ 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;
-}
+};
/**
@@ -378,38 +396,28 @@ 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") {
+ var v = info.path[i];
// TODO: replace with MochiKit.Format.strip?
- e = e.replace(/^\s+/, "").replace(/\s+$/, "");
- if (e == "" && info.path.length == 1) {
- e = 0;
- } else if (e == "") {
+ 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 (DIGITS.test(e)) {
- e = parseInt(e);
- }
+ } 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;
-}
+};
/**
@@ -425,79 +433,50 @@ MochiKit.Text._parseFormat = function (pattern, startPos, endPos) {
*/
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;
-}
+};
/**
@@ -511,6 +490,6 @@ MochiKit.Text._parseFormatFlags = function (pattern, startPos, endPos) {
*/
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) {
@@ -519,23 +498,13 @@ MochiKit.Text._truncToPercent = function (value, precision) {
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);
- }
- return str;
+ 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 (frac.length <= 0) ? whole : whole + "." + frac;
+};
/**
@@ -559,11 +528,11 @@ MochiKit.Text.FormatPatternError = function (pattern, pos, message) {
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__) {