Add WoltLab/WCF/{Number,String}Util
authorTim Düsterhus <duesterhus@woltlab.com>
Mon, 18 May 2015 16:25:01 +0000 (18:25 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Mon, 18 May 2015 16:30:54 +0000 (18:30 +0200)
wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/js/WoltLab/WCF/NumberUtil.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLab/WCF/StringUtil.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLab/WCF/Template.grammar.jison
wcfsetup/install/files/js/WoltLab/WCF/Template.grammar.js
wcfsetup/install/files/js/WoltLab/WCF/Template.js

index 732f1c1629642fb8ab5965ac04350008b8d47f40..e42aea85dc210ce9f85710896f04a2b733a5b47f 100755 (executable)
@@ -3724,6 +3724,7 @@ WCF.MultipleLanguageInput = Class.extend({
 
 /**
  * Number utilities.
+ * @deprecated Use WoltLab/WCF/NumberUtil
  */
 WCF.Number = {
        /**
@@ -3742,6 +3743,7 @@ WCF.Number = {
 
 /**
  * String utilities.
+ * @deprecated Use WoltLab/WCF/StringUtil
  */
 WCF.String = {
        /**
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/NumberUtil.js b/wcfsetup/install/files/js/WoltLab/WCF/NumberUtil.js
new file mode 100644 (file)
index 0000000..403681d
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * 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();
+});
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/StringUtil.js b/wcfsetup/install/files/js/WoltLab/WCF/StringUtil.js
new file mode 100644 (file)
index 0000000..8196b91
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ * 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, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+               },
+               
+               /**
+                * 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(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
+               }
+       };
+       
+       return new StringUtil();
+});
index 45dcf1366ee2ef4f9b7b9d5c6a961e61ad0078f9..3cd2176a00b7b9bd099a8da34f0143b335934622 100644 (file)
@@ -124,9 +124,9 @@ COMMAND:
                + "}"
                + "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}' -> "'}'"
index 1868e8d438edb082627924d35b2779879b480fef..4dad8f39805b62421951e9602a59dc529cff8f1f 100644 (file)
@@ -87,13 +87,13 @@ case 22:
        
 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];
index cf8d1c5b9529f53a56afa2676230f07ef712a1d7..2ce9afd4d9694248dd2e547e490dbd81d37e3f59 100644 (file)
@@ -9,7 +9,7 @@
  * @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
@@ -27,6 +27,9 @@ define(['./Template.grammar'], function(parser) {
         * @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);
                }
@@ -39,7 +42,7 @@ define(['./Template.grammar'], function(parser) {
                        + "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);