Merge pull request #121 from jgable/filterPriority

Filter priorities
This commit is contained in:
Hannah Wolfe 2013-06-09 12:12:04 -07:00
commit 1df9b6e90a
3 changed files with 92 additions and 14 deletions

View File

@ -2,10 +2,11 @@
"use strict"; "use strict";
var _ = require('underscore'), var _ = require('underscore'),
defaultCoreFilterPriority = 4,
coreFilters; coreFilters;
coreFilters = function (ghost) { coreFilters = function (ghost) {
ghost.registerFilter('ghostNavItems', function (args) { ghost.registerFilter('ghostNavItems', defaultCoreFilterPriority, function (args) {
var selectedItem; var selectedItem;
// Set the nav items based on the config // Set the nav items based on the config

View File

@ -18,8 +18,18 @@
ExampleFilter = require('../content/plugins/exampleFilters'), ExampleFilter = require('../content/plugins/exampleFilters'),
Ghost, Ghost,
instance, instance,
defaults,
statuses; statuses;
// ## Default values
/**
* A hash of default values to use instead of 'magic' numbers/strings.
* @type {Object}
*/
defaults = {
filterPriority: 5,
maxPriority: 9
};
// ## Article Statuses // ## Article Statuses
/** /**
@ -121,14 +131,20 @@
/** /**
* @param {string} name * @param {string} name
* @param {integer} priority
* @param {Function} fn * @param {Function} fn
*/ */
Ghost.prototype.registerFilter = function (name, fn) { Ghost.prototype.registerFilter = function (name, priority, fn) {
if (!this.filterCallbacks.hasOwnProperty(name)) { // Curry the priority optional parameter to a default of 5
this.filterCallbacks[name] = []; if (_.isFunction(priority)) {
fn = priority;
priority = defaults.filterPriority;
} }
console.log('registering filter for ', name);
this.filterCallbacks[name].push(fn); this.filterCallbacks[name] = this.filterCallbacks[name] || {};
this.filterCallbacks[name][priority] = this.filterCallbacks[name][priority] || [];
this.filterCallbacks[name][priority].push(fn);
}; };
/** /**
@ -138,17 +154,25 @@
* @return {method} callback * @return {method} callback
*/ */
Ghost.prototype.doFilter = function (name, args, callback) { Ghost.prototype.doFilter = function (name, args, callback) {
var fn; var callbacks = this.filterCallbacks[name];
if (this.filterCallbacks.hasOwnProperty(name)) { // Bug out early if no callbacks by that name
for (fn in this.filterCallbacks[name]) { if (!callbacks) {
if (this.filterCallbacks[name].hasOwnProperty(fn)) { return callback(args);
console.log('doing filter for ', name);
args = this.filterCallbacks[name][fn](args);
}
}
} }
_.times(defaults.maxPriority + 1, function (priority) {
// Bug out if no handlers on this priority
if (!_.isArray(callbacks[priority])) {
return;
}
// Call each handler for this priority level
_.each(callbacks[priority], function (filterHandler) {
args = filterHandler(args);
});
});
callback(args); callback(args);
}; };
@ -180,5 +204,8 @@
}; };
}; };
// TODO: Expose the defaults for other people to see/manipulate as a static value?
// Ghost.defaults = defaults;
module.exports = Ghost; module.exports = Ghost;
}()); }());

View File

@ -46,6 +46,56 @@
}); });
it("can register filters with specific priority", function () {
var ghost = new Ghost(),
filterName = 'test',
filterPriority = 9,
testFilterHandler = sinon.spy();
ghost.registerFilter(filterName, filterPriority, testFilterHandler);
should.exist(ghost.filterCallbacks[filterName]);
should.exist(ghost.filterCallbacks[filterName][filterPriority]);
ghost.filterCallbacks[filterName][filterPriority].should.include(testFilterHandler);
});
it("can register filters with default priority", function () {
var ghost = new Ghost(),
filterName = 'test',
defaultPriority = 5,
testFilterHandler = sinon.spy();
ghost.registerFilter(filterName, testFilterHandler);
should.exist(ghost.filterCallbacks[filterName]);
should.exist(ghost.filterCallbacks[filterName][defaultPriority]);
ghost.filterCallbacks[filterName][defaultPriority].should.include(testFilterHandler);
});
it("executes filters in priority order", function (done) {
var ghost = new Ghost(),
filterName = 'testpriority',
testFilterHandler1 = sinon.spy(),
testFilterHandler2 = sinon.spy(),
testFilterHandler3 = sinon.spy();
ghost.registerFilter(filterName, 0, testFilterHandler1);
ghost.registerFilter(filterName, 2, testFilterHandler2);
ghost.registerFilter(filterName, 9, testFilterHandler3);
ghost.doFilter(filterName, null, function () {
testFilterHandler1.calledBefore(testFilterHandler2).should.equal(true);
testFilterHandler2.calledBefore(testFilterHandler3).should.equal(true);
testFilterHandler3.called.should.equal(true);
done();
});
});
}); });
}()); }());