summaryrefslogtreecommitdiff
path: root/lib/ot/wrapped-operation.js
diff options
context:
space:
mode:
authorWu Cheng-Han2015-07-11 12:43:08 +0800
committerWu Cheng-Han2015-07-11 12:43:08 +0800
commit556338a9c6964d110c1351a402b425c71c2571fa (patch)
treed5b6d2071e554e65c7bfaa4f2c84ddb034598e01 /lib/ot/wrapped-operation.js
parent4702b83adc35f384e214a2a6e9199d08e4494093 (diff)
Added support of operational transformation
Diffstat (limited to 'lib/ot/wrapped-operation.js')
-rw-r--r--lib/ot/wrapped-operation.js80
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/ot/wrapped-operation.js b/lib/ot/wrapped-operation.js
new file mode 100644
index 00000000..91050f4e
--- /dev/null
+++ b/lib/ot/wrapped-operation.js
@@ -0,0 +1,80 @@
+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;
+} \ No newline at end of file