weekly release 2.4dev
[moodle.git] / lib / yuilib / 3.7.1 / build / substitute / substitute-debug.js
blobb419e9f823e490f56735308f7d8e7843c2b58502
1 /*
2 YUI 3.7.1 (build 5627)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('substitute', function (Y, NAME) {
9 /**
10  * String variable substitution and string formatting.
11  * If included, the substitute method is added to the YUI instance.
12  *
13  * @module substitute
14  */
16     var L = Y.Lang, DUMP = 'dump', SPACE = ' ', LBRACE = '{', RBRACE = '}',
17                 savedRegExp =  /(~-(\d+)-~)/g, lBraceRegExp = /\{LBRACE\}/g, rBraceRegExp = /\{RBRACE\}/g,
19     /**
20      * The following methods are added to the YUI instance
21      * @class YUI~substitute
22      */
24     /**
25     Does {placeholder} substitution on a string.  The object passed as the
26     second parameter provides values to replace the {placeholder}s.
27     {placeholder} token names must match property names of the object.  For
28     example
30     `var greeting = Y.substitute("Hello, {who}!", { who: "World" });`
32     {placeholder} tokens that are undefined on the object map will be left in
33     tact (leaving unsightly "{placeholder}"s in the output string).  If your
34     replacement strings *should* include curly braces, use `{LBRACE}` and
35     `{RBRACE}` in your object map string value.
37     If a function is passed as a third argument, it will be called for each
38     {placeholder} found.  The {placeholder} name is passed as the first value
39     and the value from the object map is passed as the second.  If the
40     {placeholder} contains a space, the first token will be used to identify
41     the object map property and the remainder will be passed as a third
42     argument to the function.  See below for an example.
43     
44     If the value in the object map for a given {placeholder} is an object and
45     the `dump` module is loaded, the replacement value will be the string
46     result of calling `Y.dump(...)` with the object as input.  Include a
47     numeric second token in the {placeholder} to configure the depth of the call
48     to `Y.dump(...)`, e.g. "{someObject 2}".  See the
49     <a href="../classes/YUI.html#method_dump">`dump`</a> method for details.
51     @method substitute
52     @param {string} s The string that will be modified.
53     @param {object} o An object containing the replacement values.
54     @param {function} f An optional function that can be used to
55                         process each match.  It receives the key,
56                         value, and any extra metadata included with
57                         the key inside of the braces.
58     @param {boolean} recurse if true, the replacement will be recursive,
59                         letting you have replacement tokens in replacement text.
60                         The default is false.
61     @return {string} the substituted string.
63     @example
65         function getAttrVal(key, value, name) {
66             // Return a string describing the named attribute and its value if
67             // the first token is @. Otherwise, return the value from the
68             // replacement object.
69             if (key === "@") {
70                 value += name + " Value: " + myObject.get(name);
71             }
72             return value;
73         }
75         // Assuming myObject.set('foo', 'flowers'),
76         // => "Attr: foo Value: flowers"
77         var attrVal = Y.substitute("{@ foo}", { "@": "Attr: " }, getAttrVal);
78     **/
80     substitute = function(s, o, f, recurse) {
81         var i, j, k, key, v, meta, saved = [], token, dump,
82             lidx = s.length;
84         for (;;) {
85             i = s.lastIndexOf(LBRACE, lidx);
86             if (i < 0) {
87                 break;
88             }
89             j = s.indexOf(RBRACE, i);
90             if (i + 1 >= j) {
91                 break;
92             }
94             //Extract key and meta info
95             token = s.substring(i + 1, j);
96             key = token;
97             meta = null;
98             k = key.indexOf(SPACE);
99             if (k > -1) {
100                 meta = key.substring(k + 1);
101                 key = key.substring(0, k);
102             }
104             // lookup the value
105             v = o[key];
107             // if a substitution function was provided, execute it
108             if (f) {
109                 v = f(key, v, meta);
110             }
112             if (L.isObject(v)) {
113                 if (!Y.dump) {
114                     v = v.toString();
115                 } else {
116                     if (L.isArray(v)) {
117                         v = Y.dump(v, parseInt(meta, 10));
118                     } else {
119                         meta = meta || '';
121                         // look for the keyword 'dump', if found force obj dump
122                         dump = meta.indexOf(DUMP);
123                         if (dump > -1) {
124                             meta = meta.substring(4);
125                         }
127                         // use the toString if it is not the Object toString
128                         // and the 'dump' meta info was not found
129                         if (v.toString === Object.prototype.toString ||
130                             dump > -1) {
131                             v = Y.dump(v, parseInt(meta, 10));
132                         } else {
133                             v = v.toString();
134                         }
135                     }
136                 }
137                         } else if (L.isUndefined(v)) {
138                 // This {block} has no replace string. Save it for later.
139                 v = '~-' + saved.length + '-~';
140                                         saved.push(token);
142                 // break;
143             }
145             s = s.substring(0, i) + v + s.substring(j + 1);
147                         if (!recurse) {
148                                 lidx = i - 1;
149                         } 
150                 }
151                 // restore saved {block}s and escaped braces
153                 return s
154                         .replace(savedRegExp, function (str, p1, p2) {
155                                 return LBRACE + saved[parseInt(p2,10)] + RBRACE;
156                         })
157                         .replace(lBraceRegExp, LBRACE)
158                         .replace(rBraceRegExp, RBRACE)
159                 ;
160         };
162     Y.substitute = substitute;
163     L.substitute = substitute;
167 }, '3.7.1', {"requires": ["yui-base"], "optional": ["dump"]});