You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
5.2 KiB
JavaScript

if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(elt, from) {
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0) from += len;
for (; from < len; from++) {
if (from in this && this[from] === elt) return from;
}
return - 1;
};
}
(function() {
var dependencyStack, global;
global = typeof exports !== "undefined" && exports !== null ? exports : this;
dependencyStack = [];
global.Signal = function(definition) {
var createdSignal, evaluate, value;
value = null;
evaluate = function(observerList) {
var dependency, dependentEvaluate, dependentIndex, methodName, observerTrigger, _fn, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results;
value = definition;
_ref = ["pop", "push", "reverse", "shift", "sort", "splice", "unshift"];
_fn = function(methodName) {
if (definition instanceof Array) {
return createdSignal[methodName] = function() {
var output;
output = definition[methodName].apply(definition, arguments);
createdSignal(definition);
return output;
};
} else {
return delete createdSignal[methodName];
}
};
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
methodName = _ref[_i];
_fn(methodName);
}
if (definition instanceof Object) {
createdSignal.set = function(key, value) {
definition[key] = value;
return createdSignal(definition);
};
} else {
delete createdSignal.set;
}
if (typeof definition === "function") {
_ref1 = evaluate.dependencies;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
dependency = _ref1[_j];
dependentIndex = dependency.dependents.indexOf(evaluate);
dependency.dependents.splice(dependentIndex, 1);
}
evaluate.dependencies = [];
dependencyStack.push(evaluate);
value = definition();
dependencyStack.pop();
}
_ref2 = createdSignal.observers.slice(0);
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
observerTrigger = _ref2[_k];
if ((observerList.indexOf(observerTrigger)) < 0) {
observerList.push(observerTrigger);
}
}
_ref3 = createdSignal.dependents.slice(0);
_results = [];
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
dependentEvaluate = _ref3[_l];
_results.push(dependentEvaluate(observerList));
}
return _results;
};
evaluate.dependencies = [];
evaluate.dependencyType = "signal";
createdSignal = function(newDefinition) {
var dependent, existingDependencyIndex, existingDependentIndex, existingObserveeIndex, existingObserverIndex, observerList, observerTrigger, _i, _len;
if (newDefinition !== void 0) {
definition = newDefinition;
observerList = [];
evaluate(observerList);
for (_i = 0, _len = observerList.length; _i < _len; _i++) {
observerTrigger = observerList[_i];
observerTrigger();
}
return value;
} else {
dependent = dependencyStack[dependencyStack.length - 1];
if ((dependent != null) && dependent.dependencyType === "signal") {
existingDependentIndex = createdSignal.dependents.indexOf(dependent);
if (existingDependentIndex < 0) {
createdSignal.dependents.push(dependent);
}
existingDependencyIndex = dependent.dependencies.indexOf(createdSignal);
if (existingDependencyIndex < 0) {
dependent.dependencies.push(createdSignal);
}
} else if ((dependent != null) && dependent.dependencyType === "observer") {
existingObserverIndex = createdSignal.observers.indexOf(dependent);
if (existingObserverIndex < 0) {
createdSignal.observers.push(dependent);
}
existingObserveeIndex = dependent.observees.indexOf(createdSignal);
if (existingObserveeIndex < 0) {
dependent.observees.push(createdSignal);
}
}
return value;
}
};
createdSignal.dependents = [];
createdSignal.observers = [];
evaluate();
return createdSignal;
};
global.Observer = function(response) {
var createdObserver, trigger;
trigger = function() {
var observee, observerIndex, _i, _len, _ref;
_ref = trigger.observees;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
observee = _ref[_i];
observerIndex = observee.observers.indexOf(trigger);
observee.observers.splice(observerIndex, 1);
}
trigger.observees = [];
dependencyStack.push(trigger);
if (response !== null) {
response();
}
return dependencyStack.pop();
};
trigger.observees = [];
trigger.dependencyType = "observer";
createdObserver = function(newResponse) {
response = newResponse;
trigger();
return null;
};
trigger();
return createdObserver;
};
}).call(this);