123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /**
- * Module dependencies.
- */
- var fs = require('fs')
- , path = require('path')
- , join = path.join
- , debug = require('debug')('mocha:watch');
- /**
- * Ignored directories.
- */
- var ignore = ['node_modules', '.git'];
- /**
- * Escape special characters in the given string of html.
- *
- * @param {String} html
- * @return {String}
- * @api private
- */
- exports.escape = function(html){
- return String(html)
- .replace(/&/g, '&')
- .replace(/"/g, '"')
- .replace(/</g, '<')
- .replace(/>/g, '>');
- };
- /**
- * Array#forEach (<=IE8)
- *
- * @param {Array} array
- * @param {Function} fn
- * @param {Object} scope
- * @api private
- */
- exports.forEach = function(arr, fn, scope){
- for (var i = 0, l = arr.length; i < l; i++)
- fn.call(scope, arr[i], i);
- };
- /**
- * Array#indexOf (<=IE8)
- *
- * @parma {Array} arr
- * @param {Object} obj to find index of
- * @param {Number} start
- * @api private
- */
- exports.indexOf = function(arr, obj, start){
- for (var i = start || 0, l = arr.length; i < l; i++) {
- if (arr[i] === obj)
- return i;
- }
- return -1;
- };
- /**
- * Array#reduce (<=IE8)
- *
- * @param {Array} array
- * @param {Function} fn
- * @param {Object} initial value
- * @api private
- */
- exports.reduce = function(arr, fn, val){
- var rval = val;
- for (var i = 0, l = arr.length; i < l; i++) {
- rval = fn(rval, arr[i], i, arr);
- }
- return rval;
- };
- /**
- * Array#filter (<=IE8)
- *
- * @param {Array} array
- * @param {Function} fn
- * @api private
- */
- exports.filter = function(arr, fn){
- var ret = [];
- for (var i = 0, l = arr.length; i < l; i++) {
- var val = arr[i];
- if (fn(val, i, arr)) ret.push(val);
- }
- return ret;
- };
- /**
- * Object.keys (<=IE8)
- *
- * @param {Object} obj
- * @return {Array} keys
- * @api private
- */
- exports.keys = Object.keys || function(obj) {
- var keys = []
- , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
- for (var key in obj) {
- if (has.call(obj, key)) {
- keys.push(key);
- }
- }
- return keys;
- };
- /**
- * Watch the given `files` for changes
- * and invoke `fn(file)` on modification.
- *
- * @param {Array} files
- * @param {Function} fn
- * @api private
- */
- exports.watch = function(files, fn){
- var options = { interval: 100 };
- files.forEach(function(file){
- debug('file %s', file);
- fs.watchFile(file, options, function(curr, prev){
- if (prev.mtime < curr.mtime) fn(file);
- });
- });
- };
- /**
- * Ignored files.
- */
- function ignored(path){
- return !~ignore.indexOf(path);
- }
- /**
- * Lookup files in the given `dir`.
- *
- * @return {Array}
- * @api private
- */
- exports.files = function(dir, ret){
- ret = ret || [];
- fs.readdirSync(dir)
- .filter(ignored)
- .forEach(function(path){
- path = join(dir, path);
- if (fs.statSync(path).isDirectory()) {
- exports.files(path, ret);
- } else if (path.match(/\.(js|coffee|litcoffee|coffee.md)$/)) {
- ret.push(path);
- }
- });
- return ret;
- };
- /**
- * Compute a slug from the given `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
- exports.slug = function(str){
- return str
- .toLowerCase()
- .replace(/ +/g, '-')
- .replace(/[^-\w]/g, '');
- };
- /**
- * Strip the function definition from `str`,
- * and re-indent for pre whitespace.
- */
- exports.clean = function(str) {
- str = str
- .replace(/^function *\(.*\) *{/, '')
- .replace(/\s+\}$/, '');
- var whitespace = str.match(/^\n?(\s*)/)[1]
- , re = new RegExp('^' + whitespace, 'gm');
- str = str.replace(re, '');
- return exports.trim(str);
- };
- /**
- * Escape regular expression characters in `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
- exports.escapeRegexp = function(str){
- return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
- };
- /**
- * Trim the given `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
- exports.trim = function(str){
- return str.replace(/^\s+|\s+$/g, '');
- };
- /**
- * Parse the given `qs`.
- *
- * @param {String} qs
- * @return {Object}
- * @api private
- */
- exports.parseQuery = function(qs){
- return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
- var i = pair.indexOf('=')
- , key = pair.slice(0, i)
- , val = pair.slice(++i);
- obj[key] = decodeURIComponent(val);
- return obj;
- }, {});
- };
- /**
- * Highlight the given string of `js`.
- *
- * @param {String} js
- * @return {String}
- * @api private
- */
- function highlight(js) {
- return js
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
- .replace(/('.*?')/gm, '<span class="string">$1</span>')
- .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
- .replace(/(\d+)/gm, '<span class="number">$1</span>')
- .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
- .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
- }
- /**
- * Highlight the contents of tag `name`.
- *
- * @param {String} name
- * @api private
- */
- exports.highlightTags = function(name) {
- var code = document.getElementsByTagName(name);
- for (var i = 0, len = code.length; i < len; ++i) {
- code[i].innerHTML = highlight(code[i].innerHTML);
- }
- };
|