/**
* Number utilities.
+ * @deprecated Use WoltLab/WCF/NumberUtil
*/
WCF.Number = {
/**
/**
* String utilities.
+ * @deprecated Use WoltLab/WCF/StringUtil
*/
WCF.String = {
/**
--- /dev/null
+/**
+ * Provides helper functions for Number handling.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/NumberUtil
+ */
+define([], function() {
+ "use strict";
+
+ /**
+ * @constructor
+ */
+ function NumberUtil() { };
+ NumberUtil.prototype = {
+ /**
+ * Decimal adjustment of a number.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
+ * @param {Number} value The number.
+ * @param {Integer} exp The exponent (the 10 logarithm of the adjustment base).
+ * @returns {Number} The adjusted value.
+ */
+ round: function (value, exp) {
+ // If the exp is undefined or zero...
+ if (typeof exp === 'undefined' || +exp === 0) {
+ return Math.round(value);
+ }
+ value = +value;
+ exp = +exp;
+
+ // If the value is not a number or the exp is not an integer...
+ if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
+ return NaN;
+ }
+
+ // Shift
+ value = value.toString().split('e');
+ value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
+
+ // Shift back
+ value = value.toString().split('e');
+ return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
+ }
+ };
+
+ return new NumberUtil();
+});
--- /dev/null
+/**
+ * Provides helper functions for String handling.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/StringUtil
+ */
+define(['Language', './NumberUtil'], function(Language, NumberUtil) {
+ "use strict";
+
+ /**
+ * @constructor
+ */
+ function StringUtil() { };
+ StringUtil.prototype = {
+ /**
+ * Adds thousands separators to a given number.
+ *
+ * @see http://stackoverflow.com/a/6502556/782822
+ * @param {*} number
+ * @return {String}
+ */
+ addThousandsSeparator: function(number) {
+ // Fetch Language, as it cannot be provided because of a circular dependency
+ if (Language === undefined) Language = require('Language');
+
+ return String(number).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g, '$1' + Language.get('wcf.global.thousandsSeparator'));
+ },
+
+ /**
+ * Escapes special HTML-characters within a string
+ *
+ * @param {*} string
+ * @return {String}
+ */
+ escapeHTML: function (string) {
+ return String(string).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
+ },
+
+ /**
+ * Escapes a String to work with RegExp.
+ *
+ * @see https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/regexp.js#L25
+ * @param {*} string
+ * @return {String}
+ */
+ escapeRegExp: function(string) {
+ return String(string).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+ },
+
+ /**
+ * Rounds number to given count of floating point digits, localizes decimal-point and inserts thousands separators.
+ *
+ * @param {*} number
+ * @param {int} decimalPlaces The number of decimal places to leave after rounding.
+ * @return {String}
+ */
+ formatNumeric: function(number, decimalPlaces) {
+ // Fetch Language, as it cannot be provided because of a circular dependency
+ if (Language === undefined) Language = require('Language');
+
+ number = String(NumberUtil.round(number, decimalPlaces || -2));
+ var numberParts = number.split('.');
+
+ number = this.addThousandsSeparator(numberParts[0]);
+ if (numberParts.length > 1) number += Language.get('wcf.global.decimalPoint') + numberParts[1];
+
+ number = number.replace('-', '\u2212');
+
+ return number;
+ },
+
+ /**
+ * Makes a string's first character lowercase.
+ *
+ * @param {*} string
+ * @return {String}
+ */
+ lcfirst: function(string) {
+ return String(string).substring(0, 1).toLowerCase() + string.substring(1);
+ },
+
+ /**
+ * Makes a string's first character uppercase.
+ *
+ * @param {*} string
+ * @return {String}
+ */
+ ucfirst: function(string) {
+ return String(string).substring(0, 1).toUpperCase() + string.substring(1);
+ },
+
+ /**
+ * Unescapes special HTML-characters within a string.
+ *
+ * @param {*} string
+ * @return {String}
+ */
+ unescapeHTML: function (string) {
+ return String(string).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
+ }
+ };
+
+ return new StringUtil();
+});
+ "}"
+ "return (looped ? result : " + ($5 || "''") + "); })()"
}
-| '{lang}' CHUNK_STAR '{/lang}' -> "WCF.Language.get(" + $2 + ")"
-| '{' VARIABLE '}' -> "WCF.String.escapeHTML(" + $2 + ")"
-| '{#' VARIABLE '}' -> "WCF.String.formatNumeric(" + $2 + ")"
+| '{lang}' CHUNK_STAR '{/lang}' -> "Language.get(" + $2 + ")"
+| '{' VARIABLE '}' -> "StringUtil.escapeHTML(" + $2 + ")"
+| '{#' VARIABLE '}' -> "StringUtil.formatNumeric(" + $2 + ")"
| '{@' VARIABLE '}' -> $2
| '{ldelim}' -> "'{'"
| '{rdelim}' -> "'}'"
break;
case 23:
-this.$ = "WCF.Language.get(" + $$[$0-1] + ")";
+this.$ = "Language.get(" + $$[$0-1] + ")";
break;
case 24:
-this.$ = "WCF.String.escapeHTML(" + $$[$0-1] + ")";
+this.$ = "StringUtil.escapeHTML(" + $$[$0-1] + ")";
break;
case 25:
-this.$ = "WCF.String.formatNumeric(" + $$[$0-1] + ")";
+this.$ = "StringUtil.formatNumeric(" + $$[$0-1] + ")";
break;
case 26:
this.$ = $$[$0-1];
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLab/WCF/Template
*/
-define(['./Template.grammar'], function(parser) {
+define(['./Template.grammar', './StringUtil', 'Language'], function(parser, StringUtil, Language) {
"use strict";
// work around bug in AMD module generation of Jison
* @constructor
*/
function Template(template) {
+ // Fetch Language, as it cannot be provided because of a circular dependency
+ if (Language === undefined) Language = require('Language');
+
if (!(this instanceof Template)) {
return new Template(template);
}
+ "v.__wcf = window.WCF; v.__window = window;\n"
+ "return " + template;
- this.fetch = new Function("v", template).bind(null);
+ this.fetch = new Function("StringUtil", "Language", "v", template).bind(null, StringUtil, Language);
}
catch (e) {
console.debug(e.message);