--- qunit-1.11.0.js 2013-02-09 10:22:32.000000000 -0500 +++ qunit-chrome-1.11.0.js 2013-02-12 07:44:05.000000000 -0500 @@ -6,8 +6,75 @@ * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license + * Modified for Firefox extension chrome window usage by Anthony Cassandra. */ +//---------------------------------------- +// Special Variables and Functions for Firefox Extension Usage + +// This should be set to false for most normal browser-based usages, but +// should be true if you want to include this as part of a Firefox extension +// executing javascript in chrome code and displaying in a XUL window. +// +var QU_ISCHROME = true; + +// For use in generating HTML elements when QU_ISCHROME = true +var QU_HTMLNS = "http://www.w3.org/1999/xhtml"; + +// Alternative to createElement() that correct namespace is used. +function QU_createElement( tagName ) +{ + if ( QU_ISCHROME ) + return document.createElementNS( QU_HTMLNS, "html:"+tagName ); + else + return document.createElement( tagName ); +} + +// Alternative to assigning the 'innerHTML' property of a node, +// this converts the HTML fragment into a proper DOM object and appends +// it to the node. +// +function QU_setInnerHTML( parent, childHtmlFragment ) +{ + if ( QU_ISCHROME ) + { + while (parent.firstChild) + parent.removeChild(parent.firstChild); + parent.appendChild(Components.classes["@mozilla.org/feed-unescapehtml;1"] + .getService(Components.interfaces.nsIScriptableUnescapeHTML) + .parseFragment( childHtmlFragment, false, null, parent)); + } + else + parent.innerHTML = childHtmlFragment; +} + +// Alternative to using the 'innerHTML' property as a value, this converts +// DONE into the HTML fragment and returns it as a string. +// +function QU_getInnerHTML( node ) +{ + if ( QU_ISCHROME ) + { + var serializer = new XMLSerializer(); + var text = ""; + var children = node.childNodes; + for (var i = 0; i < children.length; i++) + { + var child = children[i]; + text += serializer.serializeToString(child); + } + return text; + } + + else + return node.innerHTML; +} + +//---------------------------------------- +// Beginning of main QUnit code + +// Wrapper to allow easily switching between chrome and non-chrome versions. + (function( window ) { var QUnit, @@ -97,15 +164,14 @@ tests = id( "qunit-tests" ); if ( tests ) { - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml; + b = QU_createElement( "strong" ); + QU_setInnerHTML( b, this.nameHtml ); // `a` initialized at top of scope - a = document.createElement( "a" ); - a.innerHTML = "Rerun"; + a = QU_createElement( "a" ); + QU_setInnerHTML( a, "Rerun" ); a.href = QUnit.url({ testNumber: this.testNumber }); - - li = document.createElement( "li" ); + li = QU_createElement( "li" ); li.appendChild( b ); li.appendChild( a ); li.className = "running"; @@ -115,7 +181,8 @@ } }, setup: function() { - if ( this.module !== config.previousModule ) { + // CHANGED: arc + if ( ! this.module || (this.module !== config.previousModule )) { if ( config.previousModule ) { runLoggingCallbacks( "moduleDone", QUnit, { name: config.previousModule, @@ -171,7 +238,8 @@ var running = id( "qunit-testresult" ); if ( running ) { - running.innerHTML = "Running:
" + this.nameHtml; + // CHANGED: arc + QU_setInnerHTML( running, "
Running: " + this.nameHtml ); } if ( this.async ) { @@ -240,15 +308,15 @@ config.moduleStats.all += this.assertions.length; if ( tests ) { - ol = document.createElement( "ol" ); + ol = QU_createElement( "ol" ); ol.className = "qunit-assert-list"; for ( i = 0; i < this.assertions.length; i++ ) { assertion = this.assertions[i]; - li = document.createElement( "li" ); + li = QU_createElement( "li" ); li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); + QU_setInnerHTML( li, assertion.message || ( assertion.result ? "okay" : "failed" ) ); ol.appendChild( li ); if ( assertion.result ) { @@ -274,8 +342,8 @@ } // `b` initialized at top of scope - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + b = QU_createElement( "strong" ); + QU_setInnerHTML( b, this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")" ); addEvent(b, "click", function() { var next = b.parentNode.lastChild, @@ -294,9 +362,9 @@ }); // `time` initialized at top of scope - time = document.createElement( "span" ); + time = QU_createElement( "span" ); time.className = "runtime"; - time.innerHTML = this.runtime + " ms"; + QU_setInnerHTML( time, this.runtime + " ms" ); // `li` initialized at top of scope li = id( this.id ); @@ -426,6 +494,8 @@ } else { return config.current.expected; } + // ADDED: arc + return config.current.expected; }, start: function( count ) { @@ -770,7 +840,11 @@ // Exact match of the module name config.module = urlParams.module; - config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; + // ADDED: arc + if ( urlParams.testNumber ) + config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; + // ADDED: arc + else config.testNumber = null; // Figure out if we're running the tests from a server or not QUnit.isLocal = location.protocol === "file:"; @@ -802,12 +876,12 @@ qunit = id( "qunit" ); if ( qunit ) { - qunit.innerHTML = + QU_setInnerHTML( qunit, "

" + escapeText( document.title ) + "

" + "

" + "
" + "

" + - "
    "; + "
      " ); } tests = id( "qunit-tests" ); @@ -815,7 +889,7 @@ result = id( "qunit-testresult" ); if ( tests ) { - tests.innerHTML = ""; + QU_setInnerHTML( tests, "" ); } if ( banner ) { @@ -827,11 +901,11 @@ } if ( tests ) { - result = document.createElement( "p" ); + result = QU_createElement( "p" ); result.id = "qunit-testresult"; result.className = "result"; tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...
       "; + QU_setInnerHTML( result, "Running...
       " ); } }, @@ -839,7 +913,7 @@ reset: function() { var fixture = id( "qunit-fixture" ); if ( fixture ) { - fixture.innerHTML = config.fixture; + QU_setInnerHTML( fixture, config.fixture ); } }, @@ -1090,20 +1164,19 @@ // `userAgent` initialized at top of scope userAgent = id( "qunit-userAgent" ); if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; + QU_setInnerHTML( userAgent, navigator.userAgent ); } - // `banner` initialized at top of scope - banner = id( "qunit-header" ); + banner = id( "qunit-header" ); if ( banner ) { - banner.innerHTML = "" + banner.innerHTML + " "; + QU_setInnerHTML( banner, '' + QU_getInnerHTML(banner) + " " ); } // `toolbar` initialized at top of scope toolbar = id( "qunit-testrunner-toolbar" ); if ( toolbar ) { // `filter` initialized at top of scope - filter = document.createElement( "input" ); + filter = QU_createElement( "input" ); filter.type = "checkbox"; filter.id = "qunit-filter-pass"; @@ -1135,14 +1208,14 @@ toolbar.appendChild( filter ); // `label` initialized at top of scope - label = document.createElement( "label" ); + label = QU_createElement( "label" ); label.setAttribute( "for", "qunit-filter-pass" ); label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); - label.innerHTML = "Hide passed tests"; + QU_setInnerHTML( label, "Hide passed tests" ); toolbar.appendChild( label ); - urlConfigCheckboxesContainer = document.createElement("span"); - urlConfigCheckboxesContainer.innerHTML = urlConfigHtml; + urlConfigCheckboxesContainer = QU_createElement("span"); + QU_setInnerHTML( urlConfigCheckboxesContainer, urlConfigHtml ); urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input"); // For oldIE support: // * Add handlers to the individual elements instead of the container @@ -1157,9 +1230,9 @@ toolbar.appendChild( urlConfigCheckboxesContainer ); if (numModules > 1) { - moduleFilter = document.createElement( 'span' ); + moduleFilter = QU_createElement( 'span' ); moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' ); - moduleFilter.innerHTML = moduleFilterHtml; + QU_setInnerHTML( moduleFilter, moduleFilterHtml ); addEvent( moduleFilter.lastChild, "change", function() { var selectBox = moduleFilter.getElementsByTagName("select")[0], selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); @@ -1173,7 +1246,7 @@ // `main` initialized at top of scope main = id( "qunit-fixture" ); if ( main ) { - config.fixture = main.innerHTML; + config.fixture = QU_getInnerHTML(main); } if ( config.autostart ) { @@ -1251,7 +1324,7 @@ } if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; + QU_setInnerHTML( id( "qunit-testresult" ), html ); } if ( config.altertitle && typeof document !== "undefined" && document.title ) { @@ -1292,10 +1365,17 @@ var include, filter = config.filter && config.filter.toLowerCase(), module = config.module && config.module.toLowerCase(), - fullName = (test.module + ": " + test.testName).toLowerCase(); + + // CHANGED: arc + fullName = ( test.module + ? (test.module + ": " + test.testName).toLowerCase() + : ("unknown: " + test.testName).toLowerCase()); // Internally-generated tests are always valid - if ( test.callback && test.callback.validTest === validTest ) { + // CHANGED: arc + if ( test.callback + && test.callback.validTest + && ( test.callback.validTest === validTest )) { delete test.callback.validTest; return true; } @@ -1361,11 +1441,14 @@ // hopefully one day Safari provides actual stacktraces // exclude useless self-reference for generated Error objects if ( /qunit.js$/.test( e.sourceURL ) ) { - return; + // CHANGED: arc + return "dummy"; } // for actual exceptions, this is useful return e.sourceURL + ":" + e.line; } + // ADDED: arc + return "dummy"; } function sourceFromStacktrace( offset ) { try { @@ -1397,6 +1480,8 @@ case '&': return '&'; } + // ADDED: arc + return s; }); } @@ -1577,6 +1662,8 @@ return callbacks[ prop ]; // or undefined } } + // ADDED: arc + return "dummy"; } // the real equiv function