Code coverage report for lib/script/index.js

Statements: 75.71% (53 / 70)      Branches: 77.78% (14 / 18)      Functions: 63.64% (14 / 22)      Lines: 80.65% (50 / 62)      Ignored: none     

All files » lib/script/ » index.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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159            1   5 5   5     5       5 5   1 5 5 5 5 5 5     5   5         4 4                           4                             1   6 19   8     1 9   34 20     14         6     6       6   1 3 3     6   8 8   8 7   7       6                         1                                     1   11 11 8 6 19 11     3      
 
// TODO: refactor me
 
/**
 */
 
function boundScript(script) {
 
  var run  = script.run;
  var refs = script.refs;
 
  return {
    refs: refs,
    evaluate: function(view) {
      return run.call(view);
    },
    watch: function(view, listener) {
 
      var currentValue;
      var locked = false;
 
      function now() {
        Iif (locked) return this;
        locked = true;
        var oldValue = currentValue;
        listener(currentValue = run.call(view), oldValue);
        locked = false;
        return this;
      }
 
      var dispose;
 
      if (!refs.length) return {
        dispose: function() {},
        trigger: now
      };
 
      Eif (refs.length === 1) {
        dispose = view.watch(refs[0], now).dispose;
      } else {
 
        var bindings = [];
 
        for (var i = refs.length; i--;) {
          bindings.push(view.watch(refs[i], now));
        }
 
        dispose = function() {
          for (var i = bindings.length; i--;) bindings[i].dispose();
        };
      }
 
      return {
        dispose: dispose,
        trigger: function() {
          now();
          return this;
        }
      };
    }
  };
}
 
/**
 * scripts combined with strings. defined within attributes usually
 */
 
function bufferedScript(values, view) {
 
  var scripts = values.filter(function(value) {
    return typeof value !== "string";
  }).map(function(script) {
    return script;
  });
 
  function evaluate(view) {
    return values.map(function(script) {
 
      if (typeof script === "string") {
        return script;
      }
 
      return script.run.call(view);
 
    }).join("");
  }
 
  return {
    buffered: true,
    evaluate: function(view) {
      return evaluate(view);
    },
    watch: function(view, listener) {
 
      var bindings = [];
 
      function now() {
        listener(evaluate(view));
        return this;
      }
 
      for (var i = scripts.length; i--;) {
 
        var script = scripts[i];
        Iif (!script.refs) continue;
 
        for (var j = script.refs.length; j--;) {
          var ref = script.refs[j];
 
          bindings.push(view.watch(ref, now));
        }
      }
 
      return {
        trigger: now,
        dispose: function() {
          for (var i = bindings.length; i--;) bindings[i].dispose();
        }
      };
    }
  };
}
 
/**
 */
 
function staticScript(value, view) {
  return {
    watch: function(view, listener) {
      return {
        trigger: function() {
          listener(value);
          return this;
        },
        dispose: function() {
 
        }
      };
    }
  };
}
 
/**
 */
 
module.exports = function(value) {
 
  Iif (typeof value !== "object") return staticScript(value);
  if (value.length) {
    if (value.length === 1) return boundScript(value[0].value);
    return bufferedScript(value.map(function(v) {
      if (typeof v === "object") return v.value;
      return v;
    }));
  } else {
    return boundScript(value);
  }
};