PageRenderTime 33ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/profiles/openatrium/modules/contrib/jquery_ui/jquery.ui/external/qunit/testrunner.js

https://gitlab.com/endomorphosis/aegir
JavaScript | 780 lines | 590 code | 85 blank | 105 comment | 111 complexity | 3814e6fd4adaf15e1597374251a1648f MD5 | raw file
  1. /*
  2. * QUnit - jQuery unit testrunner
  3. *
  4. * http://docs.jquery.com/QUnit
  5. *
  6. * Copyright (c) 2008 John Resig, Jörn Zaefferer
  7. * Dual licensed under the MIT (MIT-LICENSE.txt)
  8. * and GPL (GPL-LICENSE.txt) licenses.
  9. *
  10. * $Id: testrunner.js 6173 2009-02-02 20:09:32Z jeresig $
  11. */
  12. (function($) {
  13. // Tests for equality any JavaScript type and structure without unexpected results.
  14. // Discussions and reference: http://philrathe.com/articles/equiv
  15. // Test suites: http://philrathe.com/tests/equiv
  16. // Author: Philippe Rathé <prathe@gmail.com>
  17. var equiv = function () {
  18. var innerEquiv; // the real equiv function
  19. var callers = []; // stack to decide between skip/abort functions
  20. // Determine what is o.
  21. function hoozit(o) {
  22. if (typeof o === "string") {
  23. return "string";
  24. } else if (typeof o === "boolean") {
  25. return "boolean";
  26. } else if (typeof o === "number") {
  27. if (isNaN(o)) {
  28. return "nan";
  29. } else {
  30. return "number";
  31. }
  32. } else if (typeof o === "undefined") {
  33. return "undefined";
  34. // consider: typeof null === object
  35. } else if (o === null) {
  36. return "null";
  37. // consider: typeof [] === object
  38. } else if (o instanceof Array) {
  39. return "array";
  40. // consider: typeof new Date() === object
  41. } else if (o instanceof Date) {
  42. return "date";
  43. // consider: /./ instanceof Object;
  44. // /./ instanceof RegExp;
  45. // typeof /./ === "function"; // => false in IE and Opera,
  46. // true in FF and Safari
  47. } else if (o instanceof RegExp) {
  48. return "regexp";
  49. } else if (typeof o === "object") {
  50. return "object";
  51. } else if (o instanceof Function) {
  52. return "function";
  53. }
  54. }
  55. // Call the o related callback with the given arguments.
  56. function bindCallbacks(o, callbacks, args) {
  57. var prop = hoozit(o);
  58. if (prop) {
  59. if (hoozit(callbacks[prop]) === "function") {
  60. return callbacks[prop].apply(callbacks, args);
  61. } else {
  62. return callbacks[prop]; // or undefined
  63. }
  64. }
  65. }
  66. var callbacks = function () {
  67. // for string, boolean, number and null
  68. function useStrictEquality(b, a) {
  69. return a === b;
  70. }
  71. return {
  72. "string": useStrictEquality,
  73. "boolean": useStrictEquality,
  74. "number": useStrictEquality,
  75. "null": useStrictEquality,
  76. "undefined": useStrictEquality,
  77. "nan": function (b) {
  78. return isNaN(b);
  79. },
  80. "date": function (b, a) {
  81. return hoozit(b) === "date" && a.valueOf() === b.valueOf();
  82. },
  83. "regexp": function (b, a) {
  84. return hoozit(b) === "regexp" &&
  85. a.source === b.source && // the regex itself
  86. a.global === b.global && // and its modifers (gmi) ...
  87. a.ignoreCase === b.ignoreCase &&
  88. a.multiline === b.multiline;
  89. },
  90. // - skip when the property is a method of an instance (OOP)
  91. // - abort otherwise,
  92. // initial === would have catch identical references anyway
  93. "function": function () {
  94. var caller = callers[callers.length - 1];
  95. return caller !== Object &&
  96. typeof caller !== "undefined";
  97. },
  98. "array": function (b, a) {
  99. var i;
  100. var len;
  101. // b could be an object literal here
  102. if ( ! (hoozit(b) === "array")) {
  103. return false;
  104. }
  105. len = a.length;
  106. if (len !== b.length) { // safe and faster
  107. return false;
  108. }
  109. for (i = 0; i < len; i++) {
  110. if( ! innerEquiv(a[i], b[i])) {
  111. return false;
  112. }
  113. }
  114. return true;
  115. },
  116. "object": function (b, a) {
  117. var i;
  118. var eq = true; // unless we can proove it
  119. var aProperties = [], bProperties = []; // collection of strings
  120. // comparing constructors is more strict than using instanceof
  121. if ( a.constructor !== b.constructor) {
  122. return false;
  123. }
  124. // stack constructor before traversing properties
  125. callers.push(a.constructor);
  126. for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
  127. aProperties.push(i); // collect a's properties
  128. if ( ! innerEquiv(a[i], b[i])) {
  129. eq = false;
  130. }
  131. }
  132. callers.pop(); // unstack, we are done
  133. for (i in b) {
  134. bProperties.push(i); // collect b's properties
  135. }
  136. // Ensures identical properties name
  137. return eq && innerEquiv(aProperties.sort(), bProperties.sort());
  138. }
  139. };
  140. }();
  141. innerEquiv = function () { // can take multiple arguments
  142. var args = Array.prototype.slice.apply(arguments);
  143. if (args.length < 2) {
  144. return true; // end transition
  145. }
  146. return (function (a, b) {
  147. if (a === b) {
  148. return true; // catch the most you can
  149. } else if (typeof a !== typeof b || a === null || b === null || typeof a === "undefined" || typeof b === "undefined") {
  150. return false; // don't lose time with error prone cases
  151. } else {
  152. return bindCallbacks(a, callbacks, [b, a]);
  153. }
  154. // apply transition with (1..n) arguments
  155. })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
  156. };
  157. return innerEquiv;
  158. }(); // equiv
  159. var GETParams = $.map( location.search.slice(1).split('&'), decodeURIComponent ),
  160. ngindex = $.inArray("noglobals", GETParams),
  161. noglobals = ngindex !== -1;
  162. if( noglobals )
  163. GETParams.splice( ngindex, 1 );
  164. var config = {
  165. stats: {
  166. all: 0,
  167. bad: 0
  168. },
  169. queue: [],
  170. // block until document ready
  171. blocking: true,
  172. //restrict modules/tests by get parameters
  173. filters: GETParams,
  174. isLocal: !!(window.location.protocol == 'file:')
  175. };
  176. // public API as global methods
  177. $.extend(window, {
  178. test: test,
  179. module: module,
  180. expect: expect,
  181. ok: ok,
  182. equals: equals,
  183. start: start,
  184. stop: stop,
  185. reset: reset,
  186. isLocal: config.isLocal,
  187. same: function(a, b, message) {
  188. push(equiv(a, b), a, b, message);
  189. },
  190. QUnit: {
  191. equiv: equiv,
  192. ok: ok,
  193. done: function(failures, total){},
  194. log: function(result, message){}
  195. },
  196. // legacy methods below
  197. isSet: isSet,
  198. isObj: isObj,
  199. compare: function() {
  200. throw "compare is deprecated - use same() instead";
  201. },
  202. compare2: function() {
  203. throw "compare2 is deprecated - use same() instead";
  204. },
  205. serialArray: function() {
  206. throw "serialArray is deprecated - use jsDump.parse() instead";
  207. },
  208. q: q,
  209. t: t,
  210. url: url,
  211. triggerEvent: triggerEvent
  212. });
  213. $(window).load(function() {
  214. $('#userAgent').html(navigator.userAgent);
  215. var head = $('<div class="testrunner-toolbar"><label for="filter-pass">Hide passed tests</label></div>').insertAfter("#userAgent");
  216. $('<input type="checkbox" id="filter-pass" />').attr("disabled", true).prependTo(head).click(function() {
  217. $('li.pass')[this.checked ? 'hide' : 'show']();
  218. });
  219. $('<input type="checkbox" id="filter-missing">').attr("disabled", true).appendTo(head).click(function() {
  220. $("li.fail:contains('missing test - untested code is broken code')").parent('ol').parent('li.fail')[this.checked ? 'hide' : 'show']();
  221. });
  222. $("#filter-missing").after('<label for="filter-missing">Hide missing tests (untested code is broken code)</label>');
  223. runTest();
  224. });
  225. function synchronize(callback) {
  226. config.queue.push(callback);
  227. if(!config.blocking) {
  228. process();
  229. }
  230. }
  231. function process() {
  232. while(config.queue.length && !config.blocking) {
  233. config.queue.shift()();
  234. }
  235. }
  236. function stop(timeout) {
  237. config.blocking = true;
  238. if (timeout)
  239. config.timeout = setTimeout(function() {
  240. QUnit.ok( false, "Test timed out" );
  241. start();
  242. }, timeout);
  243. }
  244. function start() {
  245. // A slight delay, to avoid any current callbacks
  246. setTimeout(function() {
  247. if(config.timeout)
  248. clearTimeout(config.timeout);
  249. config.blocking = false;
  250. process();
  251. }, 13);
  252. }
  253. function validTest( name ) {
  254. var i = config.filters.length,
  255. run = false;
  256. if( !i )
  257. return true;
  258. while( i-- ){
  259. var filter = config.filters[i],
  260. not = filter.charAt(0) == '!';
  261. if( not )
  262. filter = filter.slice(1);
  263. if( name.indexOf(filter) != -1 )
  264. return !not;
  265. if( not )
  266. run = true;
  267. }
  268. return run;
  269. }
  270. function runTest() {
  271. config.blocking = false;
  272. var started = +new Date;
  273. config.fixture = document.getElementById('main').innerHTML;
  274. config.ajaxSettings = $.ajaxSettings;
  275. synchronize(function() {
  276. $('<p id="testresult" class="result"/>').html(['Tests completed in ',
  277. +new Date - started, ' milliseconds.<br/>',
  278. '<span class="bad">', config.stats.bad, '</span> tests of <span class="all">', config.stats.all, '</span> failed.']
  279. .join(''))
  280. .appendTo("body");
  281. $("#banner").addClass(config.stats.bad ? "fail" : "pass");
  282. QUnit.done( config.stats.bad, config.stats.all );
  283. });
  284. }
  285. var pollution;
  286. function saveGlobal(){
  287. pollution = [ ];
  288. if( noglobals )
  289. for( var key in window )
  290. pollution.push(key);
  291. }
  292. function checkPollution( name ){
  293. var old = pollution;
  294. saveGlobal();
  295. if( pollution.length > old.length ){
  296. ok( false, "Introduced global variable(s): " + diff(old, pollution).join(", ") );
  297. config.expected++;
  298. }
  299. }
  300. function diff( clean, dirty ){
  301. return $.grep( dirty, function(name){
  302. return $.inArray( name, clean ) == -1;
  303. });
  304. }
  305. function test(name, callback) {
  306. if(config.currentModule)
  307. name = config.currentModule + " module: " + name;
  308. var lifecycle = $.extend({
  309. setup: function() {},
  310. teardown: function() {}
  311. }, config.moduleLifecycle);
  312. if ( !validTest(name) )
  313. return;
  314. synchronize(function() {
  315. config.assertions = [];
  316. config.expected = null;
  317. try {
  318. if( !pollution )
  319. saveGlobal();
  320. lifecycle.setup();
  321. } catch(e) {
  322. QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
  323. }
  324. })
  325. synchronize(function() {
  326. try {
  327. callback();
  328. } catch(e) {
  329. if( typeof console != "undefined" && console.error && console.warn ) {
  330. console.error("Test " + name + " died, exception and test follows");
  331. console.error(e);
  332. console.warn(callback.toString());
  333. }
  334. QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
  335. // else next test will carry the responsibility
  336. saveGlobal();
  337. }
  338. });
  339. synchronize(function() {
  340. try {
  341. checkPollution();
  342. lifecycle.teardown();
  343. } catch(e) {
  344. QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
  345. }
  346. })
  347. synchronize(function() {
  348. try {
  349. reset();
  350. } catch(e) {
  351. if( typeof console != "undefined" && console.error && console.warn ) {
  352. console.error("reset() failed, following Test " + name + ", exception and reset fn follows");
  353. console.error(e);
  354. console.warn(reset.toString());
  355. }
  356. }
  357. if(config.expected && config.expected != config.assertions.length) {
  358. QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
  359. }
  360. var good = 0, bad = 0;
  361. var ol = $("<ol/>").hide();
  362. config.stats.all += config.assertions.length;
  363. for ( var i = 0; i < config.assertions.length; i++ ) {
  364. var assertion = config.assertions[i];
  365. $("<li/>").addClass(assertion.result ? "pass" : "fail").text(assertion.message || "(no message)").appendTo(ol);
  366. assertion.result ? good++ : bad++;
  367. }
  368. config.stats.bad += bad;
  369. var b = $("<strong/>").html(name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + config.assertions.length + ")</b>")
  370. .click(function(){
  371. $(this).next().toggle();
  372. })
  373. .dblclick(function(event) {
  374. var target = $(event.target).filter("strong").clone();
  375. if ( target.length ) {
  376. target.children().remove();
  377. location.href = location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent($.trim(target.text()));
  378. }
  379. });
  380. $("<li/>").addClass(bad ? "fail" : "pass").append(b).append(ol).appendTo("#tests");
  381. if(bad) {
  382. $("#filter-pass").attr("disabled", null);
  383. $("#filter-missing").attr("disabled", null);
  384. }
  385. });
  386. }
  387. // call on start of module test to prepend name to all tests
  388. function module(name, lifecycle) {
  389. config.currentModule = name;
  390. config.moduleLifecycle = lifecycle;
  391. }
  392. /**
  393. * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
  394. */
  395. function expect(asserts) {
  396. config.expected = asserts;
  397. }
  398. /**
  399. * Resets the test setup. Useful for tests that modify the DOM.
  400. */
  401. function reset() {
  402. $("#main").html( config.fixture );
  403. $.event.global = {};
  404. $.ajaxSettings = $.extend({}, config.ajaxSettings);
  405. }
  406. /**
  407. * Asserts true.
  408. * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
  409. */
  410. function ok(a, msg) {
  411. QUnit.log(a, msg);
  412. config.assertions.push({
  413. result: !!a,
  414. message: msg
  415. });
  416. }
  417. /**
  418. * Asserts that two arrays are the same
  419. */
  420. function isSet(a, b, msg) {
  421. function serialArray( a ) {
  422. var r = [];
  423. if ( a && a.length )
  424. for ( var i = 0; i < a.length; i++ ) {
  425. var str = a[i].nodeName;
  426. if ( str ) {
  427. str = str.toLowerCase();
  428. if ( a[i].id )
  429. str += "#" + a[i].id;
  430. } else
  431. str = a[i];
  432. r.push( str );
  433. }
  434. return "[ " + r.join(", ") + " ]";
  435. }
  436. var ret = true;
  437. if ( a && b && a.length != undefined && a.length == b.length ) {
  438. for ( var i = 0; i < a.length; i++ )
  439. if ( a[i] != b[i] )
  440. ret = false;
  441. } else
  442. ret = false;
  443. QUnit.ok( ret, !ret ? (msg + " expected: " + serialArray(b) + " result: " + serialArray(a)) : msg );
  444. }
  445. /**
  446. * Asserts that two objects are equivalent
  447. */
  448. function isObj(a, b, msg) {
  449. var ret = true;
  450. if ( a && b ) {
  451. for ( var i in a )
  452. if ( a[i] != b[i] )
  453. ret = false;
  454. for ( i in b )
  455. if ( a[i] != b[i] )
  456. ret = false;
  457. } else
  458. ret = false;
  459. QUnit.ok( ret, msg );
  460. }
  461. /**
  462. * Returns an array of elements with the given IDs, eg.
  463. * @example q("main", "foo", "bar")
  464. * @result [<div id="main">, <span id="foo">, <input id="bar">]
  465. */
  466. function q() {
  467. var r = [];
  468. for ( var i = 0; i < arguments.length; i++ )
  469. r.push( document.getElementById( arguments[i] ) );
  470. return r;
  471. }
  472. /**
  473. * Asserts that a select matches the given IDs
  474. * @example t("Check for something", "//[a]", ["foo", "baar"]);
  475. * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
  476. */
  477. function t(a,b,c) {
  478. var f = $(b);
  479. var s = "";
  480. for ( var i = 0; i < f.length; i++ )
  481. s += (s && ",") + '"' + f[i].id + '"';
  482. isSet(f, q.apply(q,c), a + " (" + b + ")");
  483. }
  484. /**
  485. * Add random number to url to stop IE from caching
  486. *
  487. * @example url("data/test.html")
  488. * @result "data/test.html?10538358428943"
  489. *
  490. * @example url("data/test.php?foo=bar")
  491. * @result "data/test.php?foo=bar&10538358345554"
  492. */
  493. function url(value) {
  494. return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
  495. }
  496. /**
  497. * Checks that the first two arguments are equal, with an optional message.
  498. * Prints out both actual and expected values.
  499. *
  500. * Prefered to ok( actual == expected, message )
  501. *
  502. * @example equals( $.format("Received {0} bytes.", 2), "Received 2 bytes." );
  503. *
  504. * @param Object actual
  505. * @param Object expected
  506. * @param String message (optional)
  507. */
  508. function equals(actual, expected, message) {
  509. push(expected == actual, actual, expected, message);
  510. }
  511. function push(result, actual, expected, message) {
  512. message = message || (result ? "okay" : "failed");
  513. QUnit.ok( result, result ? message + ": " + expected : message + ", expected: " + jsDump.parse(expected) + " result: " + jsDump.parse(actual) );
  514. }
  515. /**
  516. * Trigger an event on an element.
  517. *
  518. * @example triggerEvent( document.body, "click" );
  519. *
  520. * @param DOMElement elem
  521. * @param String type
  522. */
  523. function triggerEvent( elem, type, event ) {
  524. if ( $.browser.mozilla || $.browser.opera ) {
  525. event = document.createEvent("MouseEvents");
  526. event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
  527. 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  528. elem.dispatchEvent( event );
  529. } else if ( $.browser.msie ) {
  530. elem.fireEvent("on"+type);
  531. }
  532. }
  533. })(jQuery);
  534. /**
  535. * jsDump
  536. * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
  537. * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
  538. * Date: 5/15/2008
  539. * @projectDescription Advanced and extensible data dumping for Javascript.
  540. * @version 1.0.0
  541. * @author Ariel Flesler
  542. * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
  543. */
  544. (function(){
  545. function quote( str ){
  546. return '"' + str.toString().replace(/"/g, '\\"') + '"';
  547. };
  548. function literal( o ){
  549. return o + '';
  550. };
  551. function join( pre, arr, post ){
  552. var s = jsDump.separator(),
  553. base = jsDump.indent();
  554. inner = jsDump.indent(1);
  555. if( arr.join )
  556. arr = arr.join( ',' + s + inner );
  557. if( !arr )
  558. return pre + post;
  559. return [ pre, inner + arr, base + post ].join(s);
  560. };
  561. function array( arr ){
  562. var i = arr.length, ret = Array(i);
  563. this.up();
  564. while( i-- )
  565. ret[i] = this.parse( arr[i] );
  566. this.down();
  567. return join( '[', ret, ']' );
  568. };
  569. var reName = /^function (\w+)/;
  570. var jsDump = window.jsDump = {
  571. parse:function( obj, type ){//type is used mostly internally, you can fix a (custom)type in advance
  572. var parser = this.parsers[ type || this.typeOf(obj) ];
  573. type = typeof parser;
  574. return type == 'function' ? parser.call( this, obj ) :
  575. type == 'string' ? parser :
  576. this.parsers.error;
  577. },
  578. typeOf:function( obj ){
  579. var type = typeof obj,
  580. f = 'function';//we'll use it 3 times, save it
  581. return type != 'object' && type != f ? type :
  582. !obj ? 'null' :
  583. obj.exec ? 'regexp' :// some browsers (FF) consider regexps functions
  584. obj.getHours ? 'date' :
  585. obj.scrollBy ? 'window' :
  586. obj.nodeName == '#document' ? 'document' :
  587. obj.nodeName ? 'node' :
  588. obj.item ? 'nodelist' : // Safari reports nodelists as functions
  589. obj.callee ? 'arguments' :
  590. obj.call || obj.constructor != Array && //an array would also fall on this hack
  591. (obj+'').indexOf(f) != -1 ? f : //IE reports functions like alert, as objects
  592. 'length' in obj ? 'array' :
  593. type;
  594. },
  595. separator:function(){
  596. return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
  597. },
  598. indent:function( extra ){// extra can be a number, shortcut for increasing-calling-decreasing
  599. if( !this.multiline )
  600. return '';
  601. var chr = this.indentChar;
  602. if( this.HTML )
  603. chr = chr.replace(/\t/g,' ').replace(/ /g,'&nbsp;');
  604. return Array( this._depth_ + (extra||0) ).join(chr);
  605. },
  606. up:function( a ){
  607. this._depth_ += a || 1;
  608. },
  609. down:function( a ){
  610. this._depth_ -= a || 1;
  611. },
  612. setParser:function( name, parser ){
  613. this.parsers[name] = parser;
  614. },
  615. // The next 3 are exposed so you can use them
  616. quote:quote,
  617. literal:literal,
  618. join:join,
  619. //
  620. _depth_: 1,
  621. // This is the list of parsers, to modify them, use jsDump.setParser
  622. parsers:{
  623. window: '[Window]',
  624. document: '[Document]',
  625. error:'[ERROR]', //when no parser is found, shouldn't happen
  626. unknown: '[Unknown]',
  627. 'null':'null',
  628. undefined:'undefined',
  629. 'function':function( fn ){
  630. var ret = 'function',
  631. name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
  632. if( name )
  633. ret += ' ' + name;
  634. ret += '(';
  635. ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
  636. return join( ret, this.parse(fn,'functionCode'), '}' );
  637. },
  638. array: array,
  639. nodelist: array,
  640. arguments: array,
  641. object:function( map ){
  642. var ret = [ ];
  643. this.up();
  644. for( var key in map )
  645. ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
  646. this.down();
  647. return join( '{', ret, '}' );
  648. },
  649. node:function( node ){
  650. var open = this.HTML ? '&lt;' : '<',
  651. close = this.HTML ? '&gt;' : '>';
  652. var tag = node.nodeName.toLowerCase(),
  653. ret = open + tag;
  654. for( var a in this.DOMAttrs ){
  655. var val = node[this.DOMAttrs[a]];
  656. if( val )
  657. ret += ' ' + a + '=' + this.parse( val, 'attribute' );
  658. }
  659. return ret + close + open + '/' + tag + close;
  660. },
  661. functionArgs:function( fn ){//function calls it internally, it's the arguments part of the function
  662. var l = fn.length;
  663. if( !l ) return '';
  664. var args = Array(l);
  665. while( l-- )
  666. args[l] = String.fromCharCode(97+l);//97 is 'a'
  667. return ' ' + args.join(', ') + ' ';
  668. },
  669. key:quote, //object calls it internally, the key part of an item in a map
  670. functionCode:'[code]', //function calls it internally, it's the content of the function
  671. attribute:quote, //node calls it internally, it's an html attribute value
  672. string:quote,
  673. date:quote,
  674. regexp:literal, //regex
  675. number:literal,
  676. 'boolean':literal
  677. },
  678. DOMAttrs:{//attributes to dump from nodes, name=>realName
  679. id:'id',
  680. name:'name',
  681. 'class':'className'
  682. },
  683. HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
  684. indentChar:' ',//indentation unit
  685. multiline:true //if true, items in a collection, are separated by a \n, else just a space.
  686. };
  687. })();