all files / lib/features/rules/ RuleProvider.js

100% Statements 12/12
50% Branches 1/2
100% Functions 5/5
100% Lines 12/12
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                          315×   315×                                                                                                     752×   752× 752×     752×   752×              
import inherits from 'inherits';
 
import CommandInterceptor from '../../command/CommandInterceptor';
 
/**
 * A basic provider that may be extended to implement modeling rules.
 *
 * Extensions should implement the init method to actually add their custom
 * modeling checks. Checks may be added via the #addRule(action, fn) method.
 *
 * @param {EventBus} eventBus
 */
export default function RuleProvider(eventBus) {
  CommandInterceptor.call(this, eventBus);
 
  this.init();
}
 
RuleProvider.$inject = [ 'eventBus' ];
 
inherits(RuleProvider, CommandInterceptor);
 
 
/**
 * Adds a modeling rule for the given action, implemented through
 * a callback function.
 *
 * The function will receive the modeling specific action context
 * to perform its check. It must return `false` to disallow the
 * action from happening or `true` to allow the action.
 *
 * A rule provider may pass over the evaluation to lower priority
 * rules by returning return nothing (or <code>undefined</code>).
 *
 * @example
 *
 * ResizableRules.prototype.init = function() {
 *
 *   \/**
 *    * Return `true`, `false` or nothing to denote
 *    * _allowed_, _not allowed_ and _continue evaluating_.
 *    *\/
 *   this.addRule('shape.resize', function(context) {
 *
 *     var shape = context.shape;
 *
 *     if (!context.newBounds) {
 *       // check general resizability
 *       if (!shape.resizable) {
 *         return false;
 *       }
 *
 *       // not returning anything (read: undefined)
 *       // will continue the evaluation of other rules
 *       // (with lower priority)
 *       return;
 *     } else {
 *       // element must have minimum size of 10*10 points
 *       return context.newBounds.width > 10 && context.newBounds.height > 10;
 *     }
 *   });
 * };
 *
 * @param {String|Array<String>} actions the identifier for the modeling action to check
 * @param {Number} [priority] the priority at which this rule is being applied
 * @param {Function} fn the callback function that performs the actual check
 */
RuleProvider.prototype.addRule = function(actions, priority, fn) {
 
  var self = this;
 
  Eif (typeof actions === 'string') {
    actions = [ actions ];
  }
 
  actions.forEach(function(action) {
 
    self.canExecute(action, priority, function(context, action, event) {
      return fn(context);
    }, true);
  });
};
 
/**
 * Implement this method to add new rules during provider initialization.
 */
RuleProvider.prototype.init = function() {};