80 lines
No EOL
2 KiB
JavaScript
80 lines
No EOL
2 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;
|
|
} |