-
Notifications
You must be signed in to change notification settings - Fork 1
/
JSRulez.js
100 lines (88 loc) · 3.77 KB
/
JSRulez.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
* JSRulez v0.2.1RC
* Copyright (C) 2012 Gianfranco Cecconi
*
* MIT LICENCE
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
"use strict";
define([ "underscore", "backbone" ], function(_, Backbone) {
var RulesEngine = function (inputRules) {
var normaliseRules = function () {
_.each(rules, function (rule) {
if (typeof(rule.priority) === "undefined")
rule.priority = 0;
if (typeof(rule.events) === "undefined")
rule.events = [ ];
if (rule.events.length === 0)
rule.events.push("_");
rule.events = _.uniq(rule.events);
if (typeof(rule.condition) === "undefined")
rule.condition = function () { return true; };
if (typeof(rule.action) === "undefined")
rule.action = function () { };
if (typeof(rule.breakFlow) === "undefined")
rule.breakFlow = false;
});
};
var rulesAppearRight = function () {
return _.all(rules, function (rule) {
/* A rule is well formed if it has priority, condition and action.
* priority must be an integer, positive or negative.
* condition and action must be functions
* Rules can also have a 'name' but it is not mandatory */
return (typeof(rule.priority) === "number") && (Math.round(rule.priority) === rule.priority) &&
(Object.prototype.toString.call(rule.events) === "[object Array]") &&
(typeof(rule.condition) === "function") &&
(typeof(rule.action) === "function") &&
(typeof(rule.breakFlow) === "boolean");
});
};
var run = function (context, eventName) {
if (typeof(context) === "undefined") context = { };
var keepGoing = true;
for (var priority = minPriority; keepGoing && (priority <= maxPriority); priority++)
_.each(_.filter(rules, function (rule) { return rule.priority === priority; }), function (rule) {
if (keepGoing && (rule.events.indexOf(eventName) !== -1) && (rule.condition(context))) {
keepGoing = !rule.breakFlow;
rule.action(context);
};
});
};
var runAll = function (context) {
this.trigger("_", context);
};
var rules = inputRules;
normaliseRules();
if(!rulesAppearRight()) {
return undefined;
};
var minPriority = _.min(_.map(rules, function (r) { return r.priority; }));
var maxPriority = _.max(_.map(rules, function (r) { return r.priority; }));
var rulesEngine = { runAll: runAll };
_.extend(rulesEngine, Backbone.Events);
_.each(_.uniq(_.reduce(_.map(rules, function (rule) { return rule.events; }), function (memo, eventArray) { return memo.concat(eventArray); }, [ ])), function (eventName) {
rulesEngine.on(eventName, function (context) { run(context, eventName) });
});
return rulesEngine;
};
return { RulesEngine: RulesEngine };
});