return a new function for each getter

- defines the getters onto a proto
- the function returned has its __proto__ set to our proto

fixes #32
This commit is contained in:
Sean McArthur 2014-07-08 20:43:54 -07:00
parent 3073fa3110
commit 42918337e5
4 changed files with 34 additions and 6 deletions

View file

@ -9,6 +9,7 @@
"indent": 4,
"newcap": true,
"noarg": true,
"proto": true,
"quotmark": "single",
"undef": true,
"unused": "vars",

View file

@ -11,6 +11,11 @@ suite('chalk', function () {
chalk.blue.bgRed.bold('the fox jumps over the lazy dog');
});
var cached = chalk.blue.bgRed.bold;
bench('cached styles', function () {
cached('the fox jumps over the lazy dog');
});
bench('nested styles', function () {
chalk.red('the fox jumps', chalk.underline.bgBlue('over the lazy dog') + '!');
});

View file

@ -7,6 +7,17 @@ var supportsColor = require('supports-color');
var defineProps = Object.defineProperties;
var chalk = module.exports;
function build(_styles) {
var builder = function builder() {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
// __proto__ is used because we must return a function, but there is
// no way to create a function with a different prototype.
builder.__proto__ = proto;
return builder;
}
var styles = (function () {
var ret = {};
@ -17,8 +28,7 @@ var styles = (function () {
ret[key] = {
get: function () {
this._styles.push(key);
return this;
return build(this._styles.concat(key));
}
};
});
@ -26,6 +36,8 @@ var styles = (function () {
return ret;
})();
var proto = defineProps(function chalk() {}, styles);
function applyStyle() {
// support varags, but simply cast to string in case there's only one arg
var str = arguments.length === 1 ? String(arguments[0]) : [].slice.call(arguments).join(' ');
@ -34,7 +46,8 @@ function applyStyle() {
return str;
}
var nestedStyles = applyStyle._styles;
/*jshint validthis: true*/
var nestedStyles = this._styles;
for (var i = 0; i < nestedStyles.length; i++) {
var code = ansiStyles[nestedStyles[i]];
@ -51,11 +64,9 @@ function init() {
var ret = {};
Object.keys(styles).forEach(function (name) {
var style = defineProps(applyStyle, styles);
ret[name] = {
get: function () {
style._styles = [];
return style[name];
return build([name]);
}
};
});

11
test.js
View file

@ -32,6 +32,17 @@ describe('chalk', function () {
assert.equal(chalk.reset(chalk.red.bgGreen.underline('foo') + 'foo'), '\u001b[0m\u001b[4m\u001b[42m\u001b[31mfoo\u001b[39m\u001b[49m\u001b[24mfoo\u001b[0m');
});
it('should be able to cache multiple styles', function() {
var red = chalk.red;
var blue = chalk.blue;
var redBold = red.bold;
var blueBold = blue.bold;
assert.notEqual(red('foo'), blue('foo'));
assert.notEqual(redBold('bar'), blueBold('bar'));
assert.notEqual(blue('baz'), blueBold('baz'));
});
it('should alias gray to grey', function () {
assert.equal(chalk.grey('foo'), '\u001b[90mfoo\u001b[39m');
});