diff --git a/core/misc/states.js b/core/misc/states.js index ecb1590..e9bb8d5 100644 --- a/core/misc/states.js +++ b/core/misc/states.js @@ -41,7 +41,7 @@ Drupal.behaviors.states = { * - element: A jQuery object of the dependent element * - state: A State object describing the state that is dependent * - constraints: An object with dependency specifications. Lists all elements - * that this element depends on. It can be nested and contain arbitrary + * that this element depends on. It can be nested and can contain arbitrary * AND and OR clauses. */ states.Dependent = function (args) { @@ -159,7 +159,7 @@ states.Dependent.prototype = { * Triggers change events in case a state changed. */ reevaluate: function () { - // Check whether any constraint for this dependant/state is satisifed. + // Check whether any constraint for this dependent state is satisifed. var value = this.verifyConstraints(this.constraints); // Only invoke a state change event when the value actually changed. @@ -178,32 +178,30 @@ states.Dependent.prototype = { }, /** - * Checks whether a constraint is satisified by evaluating the appropriate - * child constraints. + * Evaluates child constraints to detemine if a constraint is satisfied. * * @param constraints - * An object or an array of constraints. + * A constraint object or an array of constraints. * @param selector * The selector for these constraints. If undefined, there isn't yet a * selector that these constraints apply to. In that case, the keys of the * object are interpreted as the selector if encountered. * * @return - * true or false, depending on whether these constraints are - * satisfied. + * true or false, depending on whether these constraints are satisfied. */ verifyConstraints: function(constraints, selector) { var result = undefined; if ($.isArray(constraints)) { // This constraint is an array (OR or XOR). - var or = $.inArray('xor', constraints) < 0; + var hasXor = $.inArray('xor', constraints) < 0; for (var i = 0, len = constraints.length; i < len; i++) { if (constraints[i] != 'xor') { var constraint = this.checkConstraints(constraints[i], selector, i); - // Return if this is OR and we have a satisfied constraint or if this is - // XOR and we have a second satisfied constraint. - if (constraint && (or || result)) { - return or; + // Return if this is OR and we have a satisfied constraint or if this + // is XOR and we have a second satisfied constraint. + if (constraint && (hasXor || result)) { + return hasXor; } result = result || constraint; } @@ -216,7 +214,9 @@ states.Dependent.prototype = { // This constraint is an object (AND). for (var i in constraints) { result = ternary(result, this.checkConstraints(constraints[i], selector, i)); - if (result === false) return false; // Optimization; result can't get falser anyway. + // False and anything else will evaluate to false, so return when any + // false condition is found. + if (result === false) return false; } } return result; @@ -233,17 +233,19 @@ states.Dependent.prototype = { * selector that this constraint applies to. In that case, the state key is * propagates to a selector and resolving continues. * @param state - * The state to check for this constraint. If undefined, resolving continues. - * If both selector and state aren't undefined and valid non-numeric strings, - * a lookup for the actual value of that selector's state is performed. - * state is /not/ a State object but a pristine state string. + * The state to check for this constraint. If undefined, resolving + * continues. + * If both selector and state aren't undefined and valid non-numeric + * strings, a lookup for the actual value of that selector's state is + * performed. This parameter is not a State object but a pristine state + * string. * * @return * true or false, depending on whether this constraint is satisfied. */ checkConstraints: function(value, selector, state) { - // Normalize the last parameter. If it's non-numeric, we treat it either as a - // selector (in case there isn't one yet) or as a trigger/state. + // Normalize the last parameter. If it's non-numeric, we treat it either as + // a selector (in case there isn't one yet) or as a trigger/state. if (typeof state != 'string' || (/[0-9]/).test(state[0])) { state = undefined; } @@ -265,7 +267,7 @@ states.Dependent.prototype = { }, /** - * Reuses the verify function to gather information about all required triggers. + * Gathers information about all required triggers. */ getDependees: function() { var cache = {}; @@ -274,11 +276,12 @@ states.Dependent.prototype = { var _compare = this.compare; this.compare = function(reference, selector, state) { (cache[selector] || (cache[selector] = [])).push(state.name); - // Return nothing (=== undefined) so that the constraint loops are not broken. + // Return nothing (=== undefined) so that the constraint loops are not + // broken. }; - // This call doesn't actually /verify/ anything but uses the resolving - // mechanism to go through the constraints array, trying to "lookup" each + // This call doesn't actually verify anything but uses the resolving + // mechanism to go through the constraints array, trying to look up each // value. Since we swivelled the compare function, this comparison returns // undefined and lookup continues until the very end. Instead of lookup up // the value, we record that combination of selector and state so that we