Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

substitute.js 5.6KB

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