diff --git a/lib/reporters/html.js b/lib/reporters/html.js index aa3f81a10a..f09279be20 100644 --- a/lib/reporters/html.js +++ b/lib/reporters/html.js @@ -120,8 +120,6 @@ function HTML(runner, root) { }); runner.on('test end', function(test){ - window.scrollTo(0, document.body.scrollHeight); - // TODO: add to stats var percent = stats.tests / this.total * 100 | 0; if (progress) progress.update(percent).draw(ctx); diff --git a/lib/runner.js b/lib/runner.js index 3607ce40dc..ea0c28f279 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -8,9 +8,7 @@ var EventEmitter = require('events').EventEmitter , Test = require('./test') , utils = require('./utils') , filter = utils.filter - , keys = utils.keys - , noop = function(){} - , immediately = global.setImmediate || process.nextTick; + , keys = utils.keys; /** * Non-enumerable globals. @@ -62,6 +60,14 @@ function Runner(suite) { this.globals(this.globalProps().concat(['errno'])); } +/** + * Wrapper for setImmediate, process.nextTick, or browser polyfill. + * + * @param {Function} fn + * @api private + */ +Runner.immediately = global.setImmediate || process.nextTick; + /** * Inherit from `EventEmitter.prototype`. */ @@ -243,7 +249,7 @@ Runner.prototype.hook = function(name, fn){ }); } - immediately(function(){ + Runner.immediately(function(){ next(0); }); }; diff --git a/lib/utils.js b/lib/utils.js index 3baf12f6a3..2bf0978aa2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -107,7 +107,7 @@ exports.filter = function(arr, fn){ * @api private */ -exports.keys = function(obj) { +exports.keys = Object.keys || function(obj) { var keys = [] , has = Object.prototype.hasOwnProperty // for `window` on <=IE8 diff --git a/support/tail.js b/support/tail.js index 0f9b64a497..7216b998cc 100644 --- a/support/tail.js +++ b/support/tail.js @@ -12,34 +12,6 @@ process.exit = function(status){}; process.stdout = {}; global = window; -/** - * next tick implementation. - */ - -process.nextTick = (function(){ - // postMessage behaves badly on IE8 - if (window.ActiveXObject || !window.postMessage) { - return function(fn){ fn() }; - } - - // based on setZeroTimeout by David Baron - // - http://dbaron.org/log/20100309-faster-timeouts - var timeouts = [] - , name = 'mocha-zero-timeout' - - window.addEventListener('message', function(e){ - if (e.source == window && e.data == name) { - if (e.stopPropagation) e.stopPropagation(); - if (timeouts.length) timeouts.shift()(); - } - }, true); - - return function(fn){ - timeouts.push(fn); - window.postMessage(name, '*'); - } -})(); - /** * Remove uncaughtException listener. */ @@ -72,6 +44,31 @@ process.on = function(e, fn){ var Mocha = window.Mocha = require('mocha'), mocha = window.mocha = new Mocha({ reporter: 'html' }); + var immediateQueue = [] + , immediateTimeout; + + function timeslice() { + var immediateStart = new Date().getTime(); + while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) { + immediateQueue.shift()(); + } + if (immediateQueue.length) { + immediateTimeout = setTimeout(timeslice, 0); + } else { + immediateTimeout = null; + } + } + + /** + * High-performance override of Runner.immediately. + */ + Mocha.Runner.immediately = function(callback) { + immediateQueue.push(callback); + if (!immediateTimeout) { + immediateTimeout = setTimeout(timeslice, 0); + } + }; + /** * Override ui to ensure that the ui functions are initialized. * Normally this would happen in Mocha.prototype.loadFiles.