UNPKG

state

Version:

First-class states

291 lines (266 loc) 10.4 kB
// Generated by CoffeeScript 1.6.3 (function() { var O, RootState, State, StateExpression, Transition, TransitionExpression, state, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; O = require('omicron'); state = require('./state-function'); State = require('./state'); StateExpression = null; Transition = null; TransitionExpression = null; module.exports = RootState = (function(_super) { var ABSTRACT, CONCLUSIVE, FINAL, VIA_NONE, VIA_PROTO, VIRTUAL, createAccessor, env, evaluateGuard, hasOwn, isArray, isEmpty, rxTransitionArrow, slice, transitionArrowMethods, trim, type; __extends(RootState, _super); rxTransitionArrow = state.rxTransitionArrow, transitionArrowMethods = state.transitionArrowMethods; env = O.env, hasOwn = O.hasOwn, trim = O.trim, type = O.type, isEmpty = O.isEmpty, isArray = O.isArray; slice = Array.prototype.slice; VIRTUAL = RootState.VIRTUAL, ABSTRACT = RootState.ABSTRACT, CONCLUSIVE = RootState.CONCLUSIVE, FINAL = RootState.FINAL; VIA_NONE = RootState.VIA_NONE, VIA_PROTO = RootState.VIA_PROTO; function RootState(owner, expression, accessorName, initialState) { var current, _ref, _ref1; if (owner == null) { owner = {}; } this.accessorName = accessorName != null ? accessorName : accessorName = 'state'; owner[accessorName] = createAccessor(owner, accessorName, this); RootState.__super__.constructor.call(this, owner, '', expression); current = (_ref = (initialState != null ? this.query(initialState) : this.initialSubstate())) != null ? _ref : this; if (current.attributes & ABSTRACT) { current = (_ref1 = current.defaultSubstate()) != null ? _ref1 : current; } if (current.root !== this) { current = current.virtualize(this); } this._current = current; this._transition = null; } createAccessor = function(owner, name, root) { var accessor; accessor = function() { var args, current, input, match, method; input = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; current = root._current || root; if (this === owner) { if (input == null) { return current; } if (typeof input === 'function') { return current.change(input.call(this)); } if (typeof input === 'string' && (match = input.match(rxTransitionArrow)) && (method = transitionArrowMethods[match[1]])) { if (args.length) { return current[method].apply(current, [match[2]].concat(args)); } else { return current[method](match[2]); } } return current.query.apply(current, arguments); } else if ((owner.isPrototypeOf(this)) && ((!hasOwn.call(this, name)) || this[name] === owner[name])) { new RootState(this, null, name, current.path()); return this[name].apply(this, arguments); } }; accessor.isAccessor = true; if (env.debug) { accessor.toString = function() { return "[accessor] -> " + (root._current.path()); }; } return accessor; }; evaluateGuard = function(context, guard, against) { var args, key, result, selector, selectors, value, valueIsFn, _i, _len; if (typeof guard === 'string') { guard = context.guard(guard); } if (!guard) { return true; } args = slice.call(arguments, 1); for (key in guard) { if (!__hasProp.call(guard, key)) continue; value = guard[key]; valueIsFn = typeof value === 'function'; selectors = trim(key).split(/\s*,+\s*/); for (_i = 0, _len = selectors.length; _i < _len; _i++) { selector = selectors[_i]; if (!(context.query(selector, against))) { continue; } result = valueIsFn ? value.apply(context, args) : value; break; } if (!result) { break; } } return !!result; }; RootState.prototype.getTransitionExpression = (function() { var search; search = function(target, origin, subject, ceiling) { var admit, expr, guards, key, release, _ref; while (subject && subject !== ceiling) { _ref = subject.transitions(); for (key in _ref) { if (!__hasProp.call(_ref, key)) continue; expr = _ref[key]; if ((!(guards = expr.guards) || (!(admit = guards.admit) || isEmpty(admit) || evaluateGuard.call(origin, admit, target, origin)) && (!(release = guards.release) || isEmpty(release) || evaluateGuard.call(target, release, origin, target))) && (expr.target ? subject.query(expr.target, target) : subject === target) && (!expr.origin || subject.query(expr.origin, origin))) { return expr; } } if (ceiling == null) { break; } subject = subject.superstate; } }; return function(target, origin) { if (origin == null) { origin = this._current; } return (search(target, origin, target)) || (origin !== target ? search(target, origin, origin) : void 0) || (search(target, origin, target.superstate, this.root)) || (search(target, origin, this.root)) || (!target.isIn(origin) ? search(target, origin, origin.superstate, origin.common(target)) : void 0) || new TransitionExpression; }; })(); RootState.prototype.change = function(target, options) { var admitted, args, current, domain, eventArgs, origin, owner, released, root, s, source, targetOwner, transition, _ref; root = this.root, owner = this.owner; current = this._current; transition = this._transition; origin = (transition != null ? transition.origin : void 0) || current; if (origin.attributes & FINAL) { return null; } if (!(target instanceof State)) { target = target ? origin.query(target) : root; } if (!target) { return null; } targetOwner = target.owner; if (owner !== targetOwner && !targetOwner.isPrototypeOf(owner)) { return null; } if (options != null) { args = (isArray(options)) || (type(options)) === 'arguments' ? options : options.args; if (args != null) { args = slice.call(args); } } while (target.attributes & ABSTRACT) { if (!(target = target.defaultSubstate())) { return null; } } if (!(options != null ? options.forced : void 0)) { released = evaluateGuard(origin, 'release', target); admitted = evaluateGuard(target, 'admit', origin); if (!(released && admitted)) { if (options != null) { if ((_ref = options.failure) != null) { if (typeof _ref.call === "function") { _ref.call(this); } } } return null; } } if ((target != null ? target.root : void 0) !== root) { target = target.virtualize(this); } source = current; domain = source.common(target); s = source; while (s !== domain) { if (s.attributes & CONCLUSIVE) { return null; } s = s.superstate; } if (transition != null) { transition.abort(); } this._transition = transition = new Transition(target, source, this.getTransitionExpression(target, origin)); eventArgs = [transition, args]; source.emit('depart', eventArgs, VIA_PROTO); if (transition.aborted) { this._transition = transition = null; } if (transition) { this._current = transition; transition.emit('enter', VIA_NONE); if (transition.aborted) { this._transition = transition = null; } } s = source; while (transition && s !== domain) { s.emit('exit', eventArgs, VIA_PROTO); transition.superstate = s = s.superstate; if (transition.aborted) { this._transition = transition = null; } } if (transition != null) { transition.callback = function() { var pathToState, ss, substate, _ref1; if (transition.aborted) { transition = null; } if (transition) { s = target; pathToState = []; while (s !== domain) { pathToState.push(s); s = s.superstate; } } s = domain; while (transition && (substate = pathToState.pop())) { transition.superstate = substate; substate.emit('enter', eventArgs, VIA_PROTO); if (transition.aborted) { transition = null; } s = substate; } if (transition) { transition.emit('exit', VIA_NONE); if (transition.aborted) { transition = null; } } if (transition) { this._current = target; target.emit('arrive', eventArgs, VIA_PROTO); s = origin; while (s.attributes & VIRTUAL) { ss = s.superstate; s.destroy(); s = ss; } transition.destroy(); this._transition = transition = null; if (options != null) { if ((_ref1 = options.success) != null) { if (typeof _ref1.call === "function") { _ref1.call(this); } } } return target; } return null; }; } return (transition != null ? transition.start.apply(transition, args) : void 0) || this._current; }; return RootState; })(State); StateExpression = require('./state-expression'); Transition = require('./transition'); TransitionExpression = require('./transition-expression'); }).call(this);