80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
if (typeof ot === 'undefined') {
 | 
						|
  // Export for browsers
 | 
						|
  var ot = {};
 | 
						|
}
 | 
						|
 | 
						|
ot.WrappedOperation = (function (global) {
 | 
						|
  'use strict';
 | 
						|
 | 
						|
  // A WrappedOperation contains an operation and corresponing metadata.
 | 
						|
  function WrappedOperation (operation, meta) {
 | 
						|
    this.wrapped = operation;
 | 
						|
    this.meta    = meta;
 | 
						|
  }
 | 
						|
 | 
						|
  WrappedOperation.prototype.apply = function () {
 | 
						|
    return this.wrapped.apply.apply(this.wrapped, arguments);
 | 
						|
  };
 | 
						|
 | 
						|
  WrappedOperation.prototype.invert = function () {
 | 
						|
    var meta = this.meta;
 | 
						|
    return new WrappedOperation(
 | 
						|
      this.wrapped.invert.apply(this.wrapped, arguments),
 | 
						|
      meta && typeof meta === 'object' && typeof meta.invert === 'function' ?
 | 
						|
        meta.invert.apply(meta, arguments) : meta
 | 
						|
    );
 | 
						|
  };
 | 
						|
 | 
						|
  // Copy all properties from source to target.
 | 
						|
  function copy (source, target) {
 | 
						|
    for (var key in source) {
 | 
						|
      if (source.hasOwnProperty(key)) {
 | 
						|
        target[key] = source[key];
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function composeMeta (a, b) {
 | 
						|
    if (a && typeof a === 'object') {
 | 
						|
      if (typeof a.compose === 'function') { return a.compose(b); }
 | 
						|
      var meta = {};
 | 
						|
      copy(a, meta);
 | 
						|
      copy(b, meta);
 | 
						|
      return meta;
 | 
						|
    }
 | 
						|
    return b;
 | 
						|
  }
 | 
						|
 | 
						|
  WrappedOperation.prototype.compose = function (other) {
 | 
						|
    return new WrappedOperation(
 | 
						|
      this.wrapped.compose(other.wrapped),
 | 
						|
      composeMeta(this.meta, other.meta)
 | 
						|
    );
 | 
						|
  };
 | 
						|
 | 
						|
  function transformMeta (meta, operation) {
 | 
						|
    if (meta && typeof meta === 'object') {
 | 
						|
      if (typeof meta.transform === 'function') {
 | 
						|
        return meta.transform(operation);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return meta;
 | 
						|
  }
 | 
						|
 | 
						|
  WrappedOperation.transform = function (a, b) {
 | 
						|
    var transform = a.wrapped.constructor.transform;
 | 
						|
    var pair = transform(a.wrapped, b.wrapped);
 | 
						|
    return [
 | 
						|
      new WrappedOperation(pair[0], transformMeta(a.meta, b.wrapped)),
 | 
						|
      new WrappedOperation(pair[1], transformMeta(b.meta, a.wrapped))
 | 
						|
    ];
 | 
						|
  };
 | 
						|
 | 
						|
  return WrappedOperation;
 | 
						|
 | 
						|
}(this));
 | 
						|
 | 
						|
// Export for CommonJS
 | 
						|
if (typeof module === 'object') {
 | 
						|
  module.exports = ot.WrappedOperation;
 | 
						|
} |