jstemplate_example.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright 2006 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License.
  14. /**
  15. * @pageoverview Some logic for the jstemplates test pages.
  16. *
  17. * @author Steffen Meschkat (mesch@google.com)
  18. */
  19. function elem(id) {
  20. return document.getElementById(id);
  21. }
  22. /**
  23. * Are we actively profiling JstProcessor?
  24. * @type boolean
  25. */
  26. var profiling = false;
  27. logHtml = function(html) {
  28. elem('log').innerHTML += html + '<br/>';
  29. };
  30. /**
  31. * Initializer for interactive test: copies the value from the actual
  32. * template HTML into a text area to make the HTML source visible.
  33. */
  34. function jsinit() {
  35. elem('template').value = elem('tc').innerHTML;
  36. }
  37. /**
  38. * Interactive test.
  39. *
  40. * @param {boolean} reprocess If true, reprocesses the output of the
  41. * previous invocation.
  42. */
  43. function jstest(reprocess) {
  44. var jstext = elem('js').value;
  45. var input = jsEval(jstext);
  46. var t;
  47. if (reprocess) {
  48. t = elem('out');
  49. } else {
  50. elem('tc').innerHTML = elem('template').value;
  51. t = jstGetTemplate('t');
  52. elem('out').innerHTML = '';
  53. elem('out').appendChild(t);
  54. }
  55. if (profiling) Profiler.reset();
  56. jstProcess(new JsEvalContext(input), t);
  57. if (profiling) Profiler.dump();
  58. elem('html').value = elem('out').innerHTML;
  59. }
  60. /**
  61. * Performance test: jst initial processing.
  62. *
  63. * @param {Object} data Test data to apply the template to.
  64. */
  65. function perf1(data) {
  66. elem('out').innerHTML = '';
  67. var t = jstGetTemplate('t1');
  68. elem('out').appendChild(t);
  69. if (profiling) Profiler.reset();
  70. jstProcess(new JsEvalContext(data), t);
  71. if (profiling) Profiler.dump();
  72. }
  73. /**
  74. * Performance test: jst reprocessing or previous processing output.
  75. *
  76. * @param {Object} data Test data to apply the template to.
  77. */
  78. function perf1a(data) {
  79. if (profiling) Profiler.reset();
  80. jstProcess(new JsEvalContext(data), elemOrDie('out'));
  81. if (profiling) Profiler.dump();
  82. }
  83. /**
  84. * Performance test: jst initial processing, with display:none during
  85. * processing.
  86. *
  87. * @param {Object} data Test data to apply the template to.
  88. */
  89. function perf1b(data) {
  90. var o = elem('out');
  91. o.innerHTML = '';
  92. var t = jstGetTemplate('t1');
  93. o.appendChild(t);
  94. displayNone(o);
  95. if (profiling) Profiler.reset();
  96. jstProcess(new JsEvalContext(data), t);
  97. if (profiling) Profiler.dump();
  98. displayDefault(o);
  99. }
  100. /**
  101. * Performance test: create output procedurally as string and assign
  102. * to innerHTML.
  103. *
  104. * @param {Object} data Test data to apply the template to.
  105. */
  106. function perf2(data) {
  107. var t = [];
  108. t.push("<table><tr><th>item</th><th>label</th><th>address</th></tr>");
  109. for (var i = 0; i < data.entries.length; ++i) {
  110. var e = data.entries[i];
  111. t.push("<tr><td>" + i + "</td><td>" + e.label + "</td><td>" +
  112. e.address + "</td></tr>");
  113. }
  114. t.push("</table>");
  115. elem("out").innerHTML = t.join('');
  116. }
  117. /**
  118. * A test runner for a test. Does the timing. @constructor
  119. *
  120. * @param {number} times number of iterations the test is executed.
  121. * @param {Function} test The test to execute.
  122. * @param {Function} result Function will be called with the execution
  123. * time as argument.
  124. */
  125. function TestRun(times, test, result) {
  126. this.count_ = 0;
  127. this.times_ = times;
  128. this.test_ = test;
  129. this.result_ = result;
  130. this.start_ = (new Date).valueOf();
  131. this.run_();
  132. }
  133. /**
  134. * Executes the test run.
  135. */
  136. TestRun.prototype.run_ = function() {
  137. if (this.count_ < this.times_) {
  138. this.test_(this.count_);
  139. this.count_ += 1;
  140. objectSetTimeout(this, this.run_, 0);
  141. } else {
  142. this.stop_ = (new Date).valueOf();
  143. this.result_(this.stop_ - this.start_);
  144. }
  145. };
  146. /**
  147. * Creates a testrun function for test count invocations of function
  148. * f, whose runtime will be output to the element with is given in
  149. * result.
  150. *
  151. * @param {Object} data The test data object.
  152. * @param {Function} f
  153. * @param {number} count
  154. * @param {string} result
  155. */
  156. function createTestRun(count, test) {
  157. var data = {
  158. entries: []
  159. };
  160. for (var i = 0; i < count; ++i) {
  161. data.entries.push({ label: "label" + i, address: "address" + i });
  162. }
  163. // This function is passed to the TimeoutSequence, and receives the
  164. // TimeoutSequence as argument on invocation.
  165. return function(s) {
  166. new TestRun(1, function(i) {
  167. window[test](data);
  168. }, function(time) {
  169. elem(test + '-' + count).innerHTML = time + 'ms';
  170. s.run();
  171. });
  172. };
  173. }
  174. /**
  175. * Runs all tests the given number of times. Invoked from the HTML page.
  176. *
  177. * @param {number} count
  178. */
  179. function jsperf(count) {
  180. elemOrDie('log').innerHTML = '';
  181. profiling = !!elemOrDie('profile').checked;
  182. if (profiling && !JstProcessor.profiling_) {
  183. JstProcessor.profiling_ = true;
  184. Profiler.monitorAll(proto(JstProcessor), false);
  185. }
  186. var s = new TimeoutSequence(null, null, true);
  187. s.add(createTestRun(count, "perf1"));
  188. s.add(createTestRun(count, "perf1b"));
  189. s.add(createTestRun(count, "perf1a"));
  190. s.add(createTestRun(count, "perf2"));
  191. s.run();
  192. }
  193. function run(test, count) {
  194. var data = {
  195. entries: []
  196. };
  197. for (var i = 0; i < count; ++i) {
  198. data.entries.push({ label: "label" + i, address: "address" + i });
  199. }
  200. new TestRun(1, function() {
  201. window[test](data);
  202. }, function(time) {
  203. elem(test + '-' + count).innerHTML = time + 'ms';
  204. });
  205. }