testing observers, refactoring some Basic Types
This commit is contained in:
		
							parent
							
								
									21f7350c4d
								
							
						
					
					
						commit
						cacfb54d5e
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -4,3 +4,5 @@
 | 
				
			|||||||
.directory
 | 
					.directory
 | 
				
			||||||
.c9
 | 
					.c9
 | 
				
			||||||
myftppass
 | 
					myftppass
 | 
				
			||||||
 | 
					.codio
 | 
				
			||||||
 | 
					.settings
 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -0,0 +1,209 @@
 | 
				
			|||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var HistoryBuffer,
 | 
				
			||||||
 | 
					    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HistoryBuffer = (function() {
 | 
				
			||||||
 | 
					    function HistoryBuffer(user_id) {
 | 
				
			||||||
 | 
					      this.user_id = user_id;
 | 
				
			||||||
 | 
					      this.emptyGarbage = __bind(this.emptyGarbage, this);
 | 
				
			||||||
 | 
					      this.operation_counter = {};
 | 
				
			||||||
 | 
					      this.buffer = {};
 | 
				
			||||||
 | 
					      this.change_listeners = [];
 | 
				
			||||||
 | 
					      this.garbage = [];
 | 
				
			||||||
 | 
					      this.trash = [];
 | 
				
			||||||
 | 
					      this.performGarbageCollection = true;
 | 
				
			||||||
 | 
					      this.garbageCollectTimeout = 1000;
 | 
				
			||||||
 | 
					      this.reserved_identifier_counter = 0;
 | 
				
			||||||
 | 
					      setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.emptyGarbage = function() {
 | 
				
			||||||
 | 
					      var o, _i, _len, _ref;
 | 
				
			||||||
 | 
					      _ref = this.garbage;
 | 
				
			||||||
 | 
					      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					        o = _ref[_i];
 | 
				
			||||||
 | 
					        if (typeof o.cleanup === "function") {
 | 
				
			||||||
 | 
					          o.cleanup();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.garbage = this.trash;
 | 
				
			||||||
 | 
					      this.trash = [];
 | 
				
			||||||
 | 
					      if (this.garbageCollectTimeout !== -1) {
 | 
				
			||||||
 | 
					        this.garbageCollectTimeoutId = setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return void 0;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.getUserId = function() {
 | 
				
			||||||
 | 
					      return this.user_id;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.addToGarbageCollector = function() {
 | 
				
			||||||
 | 
					      var o, _i, _len, _results;
 | 
				
			||||||
 | 
					      if (this.performGarbageCollection) {
 | 
				
			||||||
 | 
					        _results = [];
 | 
				
			||||||
 | 
					        for (_i = 0, _len = arguments.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					          o = arguments[_i];
 | 
				
			||||||
 | 
					          if (o != null) {
 | 
				
			||||||
 | 
					            _results.push(this.garbage.push(o));
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            _results.push(void 0);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return _results;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.stopGarbageCollection = function() {
 | 
				
			||||||
 | 
					      this.performGarbageCollection = false;
 | 
				
			||||||
 | 
					      this.setManualGarbageCollect();
 | 
				
			||||||
 | 
					      this.garbage = [];
 | 
				
			||||||
 | 
					      return this.trash = [];
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.setManualGarbageCollect = function() {
 | 
				
			||||||
 | 
					      this.garbageCollectTimeout = -1;
 | 
				
			||||||
 | 
					      clearTimeout(this.garbageCollectTimeoutId);
 | 
				
			||||||
 | 
					      return this.garbageCollectTimeoutId = void 0;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.setGarbageCollectTimeout = function(garbageCollectTimeout) {
 | 
				
			||||||
 | 
					      this.garbageCollectTimeout = garbageCollectTimeout;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.getReservedUniqueIdentifier = function() {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        creator: '_',
 | 
				
			||||||
 | 
					        op_number: "_" + (this.reserved_identifier_counter++),
 | 
				
			||||||
 | 
					        doSync: false
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.getOperationCounter = function(user_id) {
 | 
				
			||||||
 | 
					      var ctn, res, user, _ref;
 | 
				
			||||||
 | 
					      if (user_id == null) {
 | 
				
			||||||
 | 
					        res = {};
 | 
				
			||||||
 | 
					        _ref = this.operation_counter;
 | 
				
			||||||
 | 
					        for (user in _ref) {
 | 
				
			||||||
 | 
					          ctn = _ref[user];
 | 
				
			||||||
 | 
					          res[user] = ctn;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return res;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return this.operation_counter[user_id];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype._encode = function(state_vector) {
 | 
				
			||||||
 | 
					      var json, o, o_json, o_next, o_number, o_prev, u_name, unknown, user, _ref;
 | 
				
			||||||
 | 
					      if (state_vector == null) {
 | 
				
			||||||
 | 
					        state_vector = {};
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      json = [];
 | 
				
			||||||
 | 
					      unknown = function(user, o_number) {
 | 
				
			||||||
 | 
					        if ((user == null) || (o_number == null)) {
 | 
				
			||||||
 | 
					          throw new Error("dah!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return (state_vector[user] == null) || state_vector[user] <= o_number;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      _ref = this.buffer;
 | 
				
			||||||
 | 
					      for (u_name in _ref) {
 | 
				
			||||||
 | 
					        user = _ref[u_name];
 | 
				
			||||||
 | 
					        for (o_number in user) {
 | 
				
			||||||
 | 
					          o = user[o_number];
 | 
				
			||||||
 | 
					          if (o.uid.doSync && unknown(u_name, o_number)) {
 | 
				
			||||||
 | 
					            o_json = o._encode();
 | 
				
			||||||
 | 
					            if (o.next_cl != null) {
 | 
				
			||||||
 | 
					              o_next = o.next_cl;
 | 
				
			||||||
 | 
					              while ((o_next.next_cl != null) && unknown(o_next.uid.creator, o_next.uid.op_number)) {
 | 
				
			||||||
 | 
					                o_next = o_next.next_cl;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              o_json.next = o_next.getUid();
 | 
				
			||||||
 | 
					            } else if (o.prev_cl != null) {
 | 
				
			||||||
 | 
					              o_prev = o.prev_cl;
 | 
				
			||||||
 | 
					              while ((o_prev.prev_cl != null) && unknown(o_prev.uid.creator, o_prev.uid.op_number)) {
 | 
				
			||||||
 | 
					                o_prev = o_prev.prev_cl;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              o_json.prev = o_prev.getUid();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            json.push(o_json);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return json;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.getNextOperationIdentifier = function(user_id) {
 | 
				
			||||||
 | 
					      var uid;
 | 
				
			||||||
 | 
					      if (user_id == null) {
 | 
				
			||||||
 | 
					        user_id = this.user_id;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (this.operation_counter[user_id] == null) {
 | 
				
			||||||
 | 
					        this.operation_counter[user_id] = 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      uid = {
 | 
				
			||||||
 | 
					        'creator': user_id,
 | 
				
			||||||
 | 
					        'op_number': this.operation_counter[user_id],
 | 
				
			||||||
 | 
					        'doSync': true
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      this.operation_counter[user_id]++;
 | 
				
			||||||
 | 
					      return uid;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.getOperation = function(uid) {
 | 
				
			||||||
 | 
					      var _ref;
 | 
				
			||||||
 | 
					      if (uid.uid != null) {
 | 
				
			||||||
 | 
					        uid = uid.uid;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return (_ref = this.buffer[uid.creator]) != null ? _ref[uid.op_number] : void 0;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.addOperation = function(o) {
 | 
				
			||||||
 | 
					      if (this.buffer[o.uid.creator] == null) {
 | 
				
			||||||
 | 
					        this.buffer[o.uid.creator] = {};
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (this.buffer[o.uid.creator][o.uid.op_number] != null) {
 | 
				
			||||||
 | 
					        throw new Error("You must not overwrite operations!");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.buffer[o.uid.creator][o.uid.op_number] = o;
 | 
				
			||||||
 | 
					      if (this.number_of_operations_added_to_HB == null) {
 | 
				
			||||||
 | 
					        this.number_of_operations_added_to_HB = 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this.number_of_operations_added_to_HB++;
 | 
				
			||||||
 | 
					      return o;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.removeOperation = function(o) {
 | 
				
			||||||
 | 
					      var _ref;
 | 
				
			||||||
 | 
					      return (_ref = this.buffer[o.uid.creator]) != null ? delete _ref[o.uid.op_number] : void 0;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HistoryBuffer.prototype.addToCounter = function(o) {
 | 
				
			||||||
 | 
					      var _results;
 | 
				
			||||||
 | 
					      if (this.operation_counter[o.uid.creator] == null) {
 | 
				
			||||||
 | 
					        this.operation_counter[o.uid.creator] = 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (typeof o.uid.op_number === 'number' && o.uid.creator !== this.getUserId()) {
 | 
				
			||||||
 | 
					        if (o.uid.op_number === this.operation_counter[o.uid.creator]) {
 | 
				
			||||||
 | 
					          this.operation_counter[o.uid.creator]++;
 | 
				
			||||||
 | 
					          _results = [];
 | 
				
			||||||
 | 
					          while (this.getOperation({
 | 
				
			||||||
 | 
					              creator: o.uid.creator,
 | 
				
			||||||
 | 
					              op_number: this.operation_counter[o.uid.creator]
 | 
				
			||||||
 | 
					            }) != null) {
 | 
				
			||||||
 | 
					            _results.push(this.operation_counter[o.uid.creator]++);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return _results;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return HistoryBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = HistoryBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=HistoryBuffer.js.map
 | 
				
			||||||
							
								
								
									
										458
									
								
								build/node/Types/BasicTypes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										458
									
								
								build/node/Types/BasicTypes.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,458 @@
 | 
				
			|||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var __slice = [].slice,
 | 
				
			||||||
 | 
					    __hasProp = {}.hasOwnProperty,
 | 
				
			||||||
 | 
					    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = function(HB) {
 | 
				
			||||||
 | 
					    var Delete, Delimiter, ImmutableObject, Insert, Operation, execution_listener, parser;
 | 
				
			||||||
 | 
					    parser = {};
 | 
				
			||||||
 | 
					    execution_listener = [];
 | 
				
			||||||
 | 
					    Operation = (function() {
 | 
				
			||||||
 | 
					      function Operation(uid) {
 | 
				
			||||||
 | 
					        this.is_deleted = false;
 | 
				
			||||||
 | 
					        this.garbage_collected = false;
 | 
				
			||||||
 | 
					        this.event_listeners = [];
 | 
				
			||||||
 | 
					        if (uid != null) {
 | 
				
			||||||
 | 
					          this.uid = uid;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.type = "Insert";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.observe = function(f) {
 | 
				
			||||||
 | 
					        return this.event_listeners.push(f);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.unobserve = function(f) {
 | 
				
			||||||
 | 
					        return this.event_listeners.filter(function(g) {
 | 
				
			||||||
 | 
					          return f !== g;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.deleteAllObservers = function() {
 | 
				
			||||||
 | 
					        return this.event_listeners = [];
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.callEvent = function() {
 | 
				
			||||||
 | 
					        return this.forwardEvent.apply(this, [this].concat(__slice.call(arguments)));
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.forwardEvent = function() {
 | 
				
			||||||
 | 
					        var args, f, op, _i, _len, _ref, _results;
 | 
				
			||||||
 | 
					        op = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
 | 
				
			||||||
 | 
					        _ref = this.event_listeners;
 | 
				
			||||||
 | 
					        _results = [];
 | 
				
			||||||
 | 
					        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					          f = _ref[_i];
 | 
				
			||||||
 | 
					          _results.push(f.call.apply(f, [op].concat(__slice.call(args))));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return _results;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.isDeleted = function() {
 | 
				
			||||||
 | 
					        return this.is_deleted;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.applyDelete = function(garbagecollect) {
 | 
				
			||||||
 | 
					        if (garbagecollect == null) {
 | 
				
			||||||
 | 
					          garbagecollect = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!this.garbage_collected) {
 | 
				
			||||||
 | 
					          this.is_deleted = true;
 | 
				
			||||||
 | 
					          if (garbagecollect) {
 | 
				
			||||||
 | 
					            this.garbage_collected = true;
 | 
				
			||||||
 | 
					            return HB.addToGarbageCollector(this);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        HB.removeOperation(this);
 | 
				
			||||||
 | 
					        return this.deleteAllObservers();
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.setParent = function(parent) {
 | 
				
			||||||
 | 
					        this.parent = parent;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.getParent = function() {
 | 
				
			||||||
 | 
					        return this.parent;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.getUid = function() {
 | 
				
			||||||
 | 
					        return this.uid;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.dontSync = function() {
 | 
				
			||||||
 | 
					        return this.uid.doSync = false;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.execute = function() {
 | 
				
			||||||
 | 
					        var l, _i, _len;
 | 
				
			||||||
 | 
					        this.is_executed = true;
 | 
				
			||||||
 | 
					        if (this.uid == null) {
 | 
				
			||||||
 | 
					          this.uid = HB.getNextOperationIdentifier();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        HB.addOperation(this);
 | 
				
			||||||
 | 
					        for (_i = 0, _len = execution_listener.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					          l = execution_listener[_i];
 | 
				
			||||||
 | 
					          l(this._encode());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.saveOperation = function(name, op) {
 | 
				
			||||||
 | 
					        if ((op != null ? op.execute : void 0) != null) {
 | 
				
			||||||
 | 
					          return this[name] = op;
 | 
				
			||||||
 | 
					        } else if (op != null) {
 | 
				
			||||||
 | 
					          if (this.unchecked == null) {
 | 
				
			||||||
 | 
					            this.unchecked = {};
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return this.unchecked[name] = op;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Operation.prototype.validateSavedOperations = function() {
 | 
				
			||||||
 | 
					        var name, op, op_uid, success, uninstantiated, _ref;
 | 
				
			||||||
 | 
					        uninstantiated = {};
 | 
				
			||||||
 | 
					        success = this;
 | 
				
			||||||
 | 
					        _ref = this.unchecked;
 | 
				
			||||||
 | 
					        for (name in _ref) {
 | 
				
			||||||
 | 
					          op_uid = _ref[name];
 | 
				
			||||||
 | 
					          op = HB.getOperation(op_uid);
 | 
				
			||||||
 | 
					          if (op) {
 | 
				
			||||||
 | 
					            this[name] = op;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            uninstantiated[name] = op_uid;
 | 
				
			||||||
 | 
					            success = false;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        delete this.unchecked;
 | 
				
			||||||
 | 
					        if (!success) {
 | 
				
			||||||
 | 
					          this.unchecked = uninstantiated;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return success;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return Operation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })();
 | 
				
			||||||
 | 
					    Delete = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(Delete, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function Delete(uid, deletes) {
 | 
				
			||||||
 | 
					        this.saveOperation('deletes', deletes);
 | 
				
			||||||
 | 
					        Delete.__super__.constructor.call(this, uid);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delete.prototype.type = "Delete";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delete.prototype._encode = function() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          'type': "Delete",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'deletes': this.deletes.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delete.prototype.execute = function() {
 | 
				
			||||||
 | 
					        if (this.validateSavedOperations()) {
 | 
				
			||||||
 | 
					          this.deletes.applyDelete(this);
 | 
				
			||||||
 | 
					          return Delete.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return Delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(Operation);
 | 
				
			||||||
 | 
					    parser['Delete'] = function(o) {
 | 
				
			||||||
 | 
					      var deletes_uid, uid;
 | 
				
			||||||
 | 
					      uid = o['uid'], deletes_uid = o['deletes'];
 | 
				
			||||||
 | 
					      return new Delete(uid, deletes_uid);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Insert = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(Insert, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function Insert(uid, prev_cl, next_cl, origin) {
 | 
				
			||||||
 | 
					        this.saveOperation('prev_cl', prev_cl);
 | 
				
			||||||
 | 
					        this.saveOperation('next_cl', next_cl);
 | 
				
			||||||
 | 
					        if (origin != null) {
 | 
				
			||||||
 | 
					          this.saveOperation('origin', origin);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.saveOperation('origin', prev_cl);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Insert.__super__.constructor.call(this, uid);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.type = "Insert";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.applyDelete = function(o) {
 | 
				
			||||||
 | 
					        var callLater, garbagecollect, _ref;
 | 
				
			||||||
 | 
					        if (this.deleted_by == null) {
 | 
				
			||||||
 | 
					          this.deleted_by = [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        callLater = false;
 | 
				
			||||||
 | 
					        if ((this.parent != null) && !this.isDeleted() && (o != null)) {
 | 
				
			||||||
 | 
					          callLater = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (o != null) {
 | 
				
			||||||
 | 
					          this.deleted_by.push(o);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        garbagecollect = false;
 | 
				
			||||||
 | 
					        if (!((this.prev_cl != null) && (this.next_cl != null)) || this.prev_cl.isDeleted()) {
 | 
				
			||||||
 | 
					          garbagecollect = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Insert.__super__.applyDelete.call(this, garbagecollect);
 | 
				
			||||||
 | 
					        if (callLater) {
 | 
				
			||||||
 | 
					          this.parent.callEvent([
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "insert",
 | 
				
			||||||
 | 
					              position: this.getPosition(),
 | 
				
			||||||
 | 
					              object: this.parent,
 | 
				
			||||||
 | 
					              changed_by: o.uid.creator
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) {
 | 
				
			||||||
 | 
					          return this.next_cl.applyDelete();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        var d, o, _i, _len, _ref, _ref1;
 | 
				
			||||||
 | 
					        if ((_ref = this.prev_cl) != null ? _ref.isDeleted() : void 0) {
 | 
				
			||||||
 | 
					          _ref1 = this.deleted_by;
 | 
				
			||||||
 | 
					          for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					            d = _ref1[_i];
 | 
				
			||||||
 | 
					            d.cleanup();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          o = this.next_cl;
 | 
				
			||||||
 | 
					          while (o.type !== "Delimiter") {
 | 
				
			||||||
 | 
					            if (o.origin === this) {
 | 
				
			||||||
 | 
					              o.origin = this.prev_cl;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            o = o.next_cl;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.prev_cl.next_cl = this.next_cl;
 | 
				
			||||||
 | 
					          this.next_cl.prev_cl = this.prev_cl;
 | 
				
			||||||
 | 
					          return Insert.__super__.cleanup.apply(this, arguments);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.getDistanceToOrigin = function() {
 | 
				
			||||||
 | 
					        var d, o;
 | 
				
			||||||
 | 
					        d = 0;
 | 
				
			||||||
 | 
					        o = this.prev_cl;
 | 
				
			||||||
 | 
					        while (true) {
 | 
				
			||||||
 | 
					          if (this.origin === o) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          d++;
 | 
				
			||||||
 | 
					          o = o.prev_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return d;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.execute = function() {
 | 
				
			||||||
 | 
					        var distance_to_origin, i, o;
 | 
				
			||||||
 | 
					        if (!this.validateSavedOperations()) {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          if (this.prev_cl != null) {
 | 
				
			||||||
 | 
					            distance_to_origin = this.getDistanceToOrigin();
 | 
				
			||||||
 | 
					            o = this.prev_cl.next_cl;
 | 
				
			||||||
 | 
					            i = distance_to_origin;
 | 
				
			||||||
 | 
					            while (true) {
 | 
				
			||||||
 | 
					              if (o !== this.next_cl) {
 | 
				
			||||||
 | 
					                if (o.getDistanceToOrigin() === i) {
 | 
				
			||||||
 | 
					                  if (o.uid.creator < this.uid.creator) {
 | 
				
			||||||
 | 
					                    this.prev_cl = o;
 | 
				
			||||||
 | 
					                    distance_to_origin = i + 1;
 | 
				
			||||||
 | 
					                  } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                } else if (o.getDistanceToOrigin() < i) {
 | 
				
			||||||
 | 
					                  if (i - distance_to_origin <= o.getDistanceToOrigin()) {
 | 
				
			||||||
 | 
					                    this.prev_cl = o;
 | 
				
			||||||
 | 
					                    distance_to_origin = i + 1;
 | 
				
			||||||
 | 
					                  } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                i++;
 | 
				
			||||||
 | 
					                o = o.next_cl;
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            this.next_cl = this.prev_cl.next_cl;
 | 
				
			||||||
 | 
					            this.prev_cl.next_cl = this;
 | 
				
			||||||
 | 
					            this.next_cl.prev_cl = this;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.setParent(this.prev_cl.getParent());
 | 
				
			||||||
 | 
					          Insert.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					          this.callOperationSpecificEvents();
 | 
				
			||||||
 | 
					          return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.callOperationSpecificEvents = function() {
 | 
				
			||||||
 | 
					        var _ref;
 | 
				
			||||||
 | 
					        return (_ref = this.parent) != null ? _ref.callEvent([
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            type: "insert",
 | 
				
			||||||
 | 
					            position: this.getPosition(),
 | 
				
			||||||
 | 
					            object: this.parent,
 | 
				
			||||||
 | 
					            changed_by: this.uid.creator
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ]) : void 0;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Insert.prototype.getPosition = function() {
 | 
				
			||||||
 | 
					        var position, prev;
 | 
				
			||||||
 | 
					        position = 0;
 | 
				
			||||||
 | 
					        prev = this.prev_cl;
 | 
				
			||||||
 | 
					        while (true) {
 | 
				
			||||||
 | 
					          if (prev instanceof Delimiter) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (!prev.isDeleted()) {
 | 
				
			||||||
 | 
					            position++;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          prev = prev.prev_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return position;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return Insert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(Operation);
 | 
				
			||||||
 | 
					    ImmutableObject = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(ImmutableObject, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function ImmutableObject(uid, content, prev, next, origin) {
 | 
				
			||||||
 | 
					        this.content = content;
 | 
				
			||||||
 | 
					        ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ImmutableObject.prototype.type = "ImmutableObject";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ImmutableObject.prototype.val = function() {
 | 
				
			||||||
 | 
					        return this.content;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ImmutableObject.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': "ImmutableObject",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'content': this.content
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        if (this.prev_cl != null) {
 | 
				
			||||||
 | 
					          json['prev'] = this.prev_cl.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.next_cl != null) {
 | 
				
			||||||
 | 
					          json['next'] = this.next_cl.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.origin != null) {
 | 
				
			||||||
 | 
					          json["origin"] = this.origin().getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return ImmutableObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(Operation);
 | 
				
			||||||
 | 
					    parser['ImmutableObject'] = function(json) {
 | 
				
			||||||
 | 
					      var content, next, origin, prev, uid;
 | 
				
			||||||
 | 
					      uid = json['uid'], content = json['content'], prev = json['prev'], next = json['next'], origin = json['origin'];
 | 
				
			||||||
 | 
					      return new ImmutableObject(uid, content, prev, next, origin);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Delimiter = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(Delimiter, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function Delimiter(uid, prev_cl, next_cl, origin) {
 | 
				
			||||||
 | 
					        this.saveOperation('prev_cl', prev_cl);
 | 
				
			||||||
 | 
					        this.saveOperation('next_cl', next_cl);
 | 
				
			||||||
 | 
					        this.saveOperation('origin', prev_cl);
 | 
				
			||||||
 | 
					        Delimiter.__super__.constructor.call(this, uid);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delimiter.prototype.type = "Delimiter";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delimiter.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        var o;
 | 
				
			||||||
 | 
					        Delimiter.__super__.applyDelete.call(this);
 | 
				
			||||||
 | 
					        o = this.next_cl;
 | 
				
			||||||
 | 
					        while (o != null) {
 | 
				
			||||||
 | 
					          o.applyDelete();
 | 
				
			||||||
 | 
					          o = o.next_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return void 0;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delimiter.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return Delimiter.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delimiter.prototype.execute = function() {
 | 
				
			||||||
 | 
					        var _ref, _ref1;
 | 
				
			||||||
 | 
					        if (((_ref = this.unchecked) != null ? _ref['next_cl'] : void 0) != null) {
 | 
				
			||||||
 | 
					          return Delimiter.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					        } else if ((_ref1 = this.unchecked) != null ? _ref1['prev_cl'] : void 0) {
 | 
				
			||||||
 | 
					          if (this.validateSavedOperations()) {
 | 
				
			||||||
 | 
					            if (this.prev_cl.next_cl != null) {
 | 
				
			||||||
 | 
					              throw new Error("Probably duplicated operations");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            this.prev_cl.next_cl = this;
 | 
				
			||||||
 | 
					            return Delimiter.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else if ((this.prev_cl != null) && (this.prev_cl.next_cl == null)) {
 | 
				
			||||||
 | 
					          delete this.prev_cl.unchecked.next_cl;
 | 
				
			||||||
 | 
					          this.prev_cl.next_cl = this;
 | 
				
			||||||
 | 
					          return Delimiter.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					        } else if ((this.prev_cl != null) || (this.next_cl != null) || true) {
 | 
				
			||||||
 | 
					          return Delimiter.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Delimiter.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var _ref, _ref1;
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          'type': "Delimiter",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'prev': (_ref = this.prev_cl) != null ? _ref.getUid() : void 0,
 | 
				
			||||||
 | 
					          'next': (_ref1 = this.next_cl) != null ? _ref1.getUid() : void 0
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return Delimiter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(Operation);
 | 
				
			||||||
 | 
					    parser['Delimiter'] = function(json) {
 | 
				
			||||||
 | 
					      var next, prev, uid;
 | 
				
			||||||
 | 
					      uid = json['uid'], prev = json['prev'], next = json['next'];
 | 
				
			||||||
 | 
					      return new Delimiter(uid, prev, next);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      'types': {
 | 
				
			||||||
 | 
					        'Delete': Delete,
 | 
				
			||||||
 | 
					        'Insert': Insert,
 | 
				
			||||||
 | 
					        'Delimiter': Delimiter,
 | 
				
			||||||
 | 
					        'Operation': Operation,
 | 
				
			||||||
 | 
					        'ImmutableObject': ImmutableObject
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      'parser': parser,
 | 
				
			||||||
 | 
					      'execution_listener': execution_listener
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=../Types/BasicTypes.js.map
 | 
				
			||||||
							
								
								
									
										1
									
								
								build/node/Types/BasicTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/node/Types/BasicTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										246
									
								
								build/node/Types/JsonTypes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								build/node/Types/JsonTypes.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,246 @@
 | 
				
			|||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var text_types_uninitialized,
 | 
				
			||||||
 | 
					    __hasProp = {}.hasOwnProperty,
 | 
				
			||||||
 | 
					    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  text_types_uninitialized = require("./TextTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = function(HB) {
 | 
				
			||||||
 | 
					    var JsonType, createJsonTypeWrapper, parser, text_types, types;
 | 
				
			||||||
 | 
					    text_types = text_types_uninitialized(HB);
 | 
				
			||||||
 | 
					    types = text_types.types;
 | 
				
			||||||
 | 
					    parser = text_types.parser;
 | 
				
			||||||
 | 
					    createJsonTypeWrapper = function(_jsonType) {
 | 
				
			||||||
 | 
					      var JsonTypeWrapper;
 | 
				
			||||||
 | 
					      JsonTypeWrapper = (function() {
 | 
				
			||||||
 | 
					        function JsonTypeWrapper(jsonType) {
 | 
				
			||||||
 | 
					          var name, obj, _fn, _ref;
 | 
				
			||||||
 | 
					          _ref = jsonType.map;
 | 
				
			||||||
 | 
					          _fn = function(name, obj) {
 | 
				
			||||||
 | 
					            return Object.defineProperty(JsonTypeWrapper.prototype, name, {
 | 
				
			||||||
 | 
					              get: function() {
 | 
				
			||||||
 | 
					                var x;
 | 
				
			||||||
 | 
					                x = obj.val();
 | 
				
			||||||
 | 
					                if (x instanceof JsonType) {
 | 
				
			||||||
 | 
					                  return createJsonTypeWrapper(x);
 | 
				
			||||||
 | 
					                } else if (x instanceof types.ImmutableObject) {
 | 
				
			||||||
 | 
					                  return x.val();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  return x;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              set: function(o) {
 | 
				
			||||||
 | 
					                var o_name, o_obj, overwrite, _results;
 | 
				
			||||||
 | 
					                overwrite = jsonType.val(name);
 | 
				
			||||||
 | 
					                if (o.constructor === {}.constructor && overwrite instanceof types.Operation) {
 | 
				
			||||||
 | 
					                  _results = [];
 | 
				
			||||||
 | 
					                  for (o_name in o) {
 | 
				
			||||||
 | 
					                    o_obj = o[o_name];
 | 
				
			||||||
 | 
					                    _results.push(overwrite.val(o_name, o_obj, 'immutable'));
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                  return _results;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  return jsonType.val(name, o, 'immutable');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              enumerable: true,
 | 
				
			||||||
 | 
					              configurable: false
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          for (name in _ref) {
 | 
				
			||||||
 | 
					            obj = _ref[name];
 | 
				
			||||||
 | 
					            _fn(name, obj);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return JsonTypeWrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      })();
 | 
				
			||||||
 | 
					      return new JsonTypeWrapper(_jsonType);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    JsonType = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(JsonType, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function JsonType() {
 | 
				
			||||||
 | 
					        return JsonType.__super__.constructor.apply(this, arguments);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.type = "JsonType";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        return JsonType.__super__.applyDelete.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return JsonType.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.toJson = function() {
 | 
				
			||||||
 | 
					        var json, name, o, that, val;
 | 
				
			||||||
 | 
					        if ((this.bound_json == null) || (Object.observe == null) || true) {
 | 
				
			||||||
 | 
					          val = this.val();
 | 
				
			||||||
 | 
					          json = {};
 | 
				
			||||||
 | 
					          for (name in val) {
 | 
				
			||||||
 | 
					            o = val[name];
 | 
				
			||||||
 | 
					            if (o == null) {
 | 
				
			||||||
 | 
					              json[name] = o;
 | 
				
			||||||
 | 
					            } else if (o.constructor === {}.constructor) {
 | 
				
			||||||
 | 
					              json[name] = this.val(name).toJson();
 | 
				
			||||||
 | 
					            } else if (o instanceof types.Operation) {
 | 
				
			||||||
 | 
					              while (o instanceof types.Operation) {
 | 
				
			||||||
 | 
					                o = o.val();
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              json[name] = o;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              json[name] = o;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.bound_json = json;
 | 
				
			||||||
 | 
					          if (Object.observe != null) {
 | 
				
			||||||
 | 
					            that = this;
 | 
				
			||||||
 | 
					            Object.observe(this.bound_json, function(events) {
 | 
				
			||||||
 | 
					              var event, _i, _len, _results;
 | 
				
			||||||
 | 
					              _results = [];
 | 
				
			||||||
 | 
					              for (_i = 0, _len = events.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					                event = events[_i];
 | 
				
			||||||
 | 
					                if ((event.changed_by == null) && (event.type === "add" || (event.type = "update"))) {
 | 
				
			||||||
 | 
					                  _results.push(that.val(event.name, event.object[event.name]));
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  _results.push(void 0);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              return _results;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            this.observe(function(events) {
 | 
				
			||||||
 | 
					              var event, notifier, oldVal, _i, _len, _results;
 | 
				
			||||||
 | 
					              _results = [];
 | 
				
			||||||
 | 
					              for (_i = 0, _len = events.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					                event = events[_i];
 | 
				
			||||||
 | 
					                if (event.created_ !== HB.getUserId()) {
 | 
				
			||||||
 | 
					                  notifier = Object.getNotifier(that.bound_json);
 | 
				
			||||||
 | 
					                  oldVal = that.bound_json[event.name];
 | 
				
			||||||
 | 
					                  if (oldVal != null) {
 | 
				
			||||||
 | 
					                    notifier.performChange('update', function() {
 | 
				
			||||||
 | 
					                      return that.bound_json[event.name] = that.val(event.name);
 | 
				
			||||||
 | 
					                    }, that.bound_json);
 | 
				
			||||||
 | 
					                    _results.push(notifier.notify({
 | 
				
			||||||
 | 
					                      object: that.bound_json,
 | 
				
			||||||
 | 
					                      type: 'update',
 | 
				
			||||||
 | 
					                      name: event.name,
 | 
				
			||||||
 | 
					                      oldValue: oldVal,
 | 
				
			||||||
 | 
					                      changed_by: event.changed_by
 | 
				
			||||||
 | 
					                    }));
 | 
				
			||||||
 | 
					                  } else {
 | 
				
			||||||
 | 
					                    notifier.performChange('add', function() {
 | 
				
			||||||
 | 
					                      return that.bound_json[event.name] = that.val(event.name);
 | 
				
			||||||
 | 
					                    }, that.bound_json);
 | 
				
			||||||
 | 
					                    _results.push(notifier.notify({
 | 
				
			||||||
 | 
					                      object: that.bound_json,
 | 
				
			||||||
 | 
					                      type: 'add',
 | 
				
			||||||
 | 
					                      name: event.name,
 | 
				
			||||||
 | 
					                      oldValue: oldVal,
 | 
				
			||||||
 | 
					                      changed_by: event.changed_by
 | 
				
			||||||
 | 
					                    }));
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  _results.push(void 0);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              return _results;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this.bound_json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.mutable_default = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.setMutableDefault = function(mutable) {
 | 
				
			||||||
 | 
					        if (mutable === true || mutable === 'mutable') {
 | 
				
			||||||
 | 
					          JsonType.prototype.mutable_default = true;
 | 
				
			||||||
 | 
					        } else if (mutable === false || mutable === 'immutable') {
 | 
				
			||||||
 | 
					          JsonType.prototype.mutable_default = false;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          throw new Error('Set mutable either "mutable" or "immutable"!');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return 'OK';
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype.val = function(name, content, mutable) {
 | 
				
			||||||
 | 
					        var json, n, o, word;
 | 
				
			||||||
 | 
					        if ((name != null) && arguments.length > 1) {
 | 
				
			||||||
 | 
					          if (mutable != null) {
 | 
				
			||||||
 | 
					            if (mutable === true || mutable === 'mutable') {
 | 
				
			||||||
 | 
					              mutable = true;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              mutable = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            mutable = this.mutable_default;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (typeof content === 'function') {
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					          } else if ((content == null) || (((!mutable) || typeof content === 'number') && content.constructor !== Object)) {
 | 
				
			||||||
 | 
					            return JsonType.__super__.val.call(this, name, (new types.ImmutableObject(void 0, content)).execute());
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            if (typeof content === 'string') {
 | 
				
			||||||
 | 
					              word = (new types.WordType(void 0)).execute();
 | 
				
			||||||
 | 
					              word.insertText(0, content);
 | 
				
			||||||
 | 
					              return JsonType.__super__.val.call(this, name, word);
 | 
				
			||||||
 | 
					            } else if (content.constructor === Object) {
 | 
				
			||||||
 | 
					              json = new JsonType().execute();
 | 
				
			||||||
 | 
					              for (n in content) {
 | 
				
			||||||
 | 
					                o = content[n];
 | 
				
			||||||
 | 
					                json.val(n, o, mutable);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              return JsonType.__super__.val.call(this, name, json);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return JsonType.__super__.val.call(this, name, content);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Object.defineProperty(JsonType.prototype, 'value', {
 | 
				
			||||||
 | 
					        get: function() {
 | 
				
			||||||
 | 
					          return createJsonTypeWrapper(this);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        set: function(o) {
 | 
				
			||||||
 | 
					          var o_name, o_obj, _results;
 | 
				
			||||||
 | 
					          if (o.constructor === {}.constructor) {
 | 
				
			||||||
 | 
					            _results = [];
 | 
				
			||||||
 | 
					            for (o_name in o) {
 | 
				
			||||||
 | 
					              o_obj = o[o_name];
 | 
				
			||||||
 | 
					              _results.push(this.val(o_name, o_obj, 'immutable'));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return _results;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            throw new Error("You must only set Object values!");
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      JsonType.prototype._encode = function() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          'type': "JsonType",
 | 
				
			||||||
 | 
					          'uid': this.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return JsonType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.MapManager);
 | 
				
			||||||
 | 
					    parser['JsonType'] = function(json) {
 | 
				
			||||||
 | 
					      var uid;
 | 
				
			||||||
 | 
					      uid = json['uid'];
 | 
				
			||||||
 | 
					      return new JsonType(uid);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    types['JsonType'] = JsonType;
 | 
				
			||||||
 | 
					    return text_types;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=../Types/JsonTypes.js.map
 | 
				
			||||||
							
								
								
									
										1
									
								
								build/node/Types/JsonTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/node/Types/JsonTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										401
									
								
								build/node/Types/StructuredTypes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										401
									
								
								build/node/Types/StructuredTypes.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,401 @@
 | 
				
			|||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var basic_types_uninitialized,
 | 
				
			||||||
 | 
					    __hasProp = {}.hasOwnProperty,
 | 
				
			||||||
 | 
					    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  basic_types_uninitialized = require("./BasicTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = function(HB) {
 | 
				
			||||||
 | 
					    var AddName, ListManager, MapManager, ReplaceManager, Replaceable, basic_types, parser, types;
 | 
				
			||||||
 | 
					    basic_types = basic_types_uninitialized(HB);
 | 
				
			||||||
 | 
					    types = basic_types.types;
 | 
				
			||||||
 | 
					    parser = basic_types.parser;
 | 
				
			||||||
 | 
					    MapManager = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(MapManager, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function MapManager(uid) {
 | 
				
			||||||
 | 
					        this.map = {};
 | 
				
			||||||
 | 
					        MapManager.__super__.constructor.call(this, uid);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MapManager.prototype.type = "MapManager";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MapManager.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        var name, p, _ref;
 | 
				
			||||||
 | 
					        _ref = this.map;
 | 
				
			||||||
 | 
					        for (name in _ref) {
 | 
				
			||||||
 | 
					          p = _ref[name];
 | 
				
			||||||
 | 
					          p.applyDelete();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return MapManager.__super__.applyDelete.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MapManager.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return MapManager.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MapManager.prototype.val = function(name, content) {
 | 
				
			||||||
 | 
					        var o, obj, qqq, result, x, _ref, _ref1;
 | 
				
			||||||
 | 
					        if (content != null) {
 | 
				
			||||||
 | 
					          if (this.map[name] == null) {
 | 
				
			||||||
 | 
					            (new AddName(void 0, this, name)).execute();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (this.map[name] === null) {
 | 
				
			||||||
 | 
					            qqq = this;
 | 
				
			||||||
 | 
					            x = new AddName(void 0, this, name);
 | 
				
			||||||
 | 
					            x.execute();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.map[name].replace(content);
 | 
				
			||||||
 | 
					          return this;
 | 
				
			||||||
 | 
					        } else if (name != null) {
 | 
				
			||||||
 | 
					          obj = (_ref = this.map[name]) != null ? _ref.val() : void 0;
 | 
				
			||||||
 | 
					          if (obj instanceof types.ImmutableObject) {
 | 
				
			||||||
 | 
					            return obj.val();
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            return obj;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          result = {};
 | 
				
			||||||
 | 
					          _ref1 = this.map;
 | 
				
			||||||
 | 
					          for (name in _ref1) {
 | 
				
			||||||
 | 
					            o = _ref1[name];
 | 
				
			||||||
 | 
					            obj = o.val();
 | 
				
			||||||
 | 
					            if (obj instanceof types.ImmutableObject || obj instanceof MapManager) {
 | 
				
			||||||
 | 
					              obj = obj.val();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            result[name] = obj;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return MapManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Operation);
 | 
				
			||||||
 | 
					    AddName = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(AddName, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function AddName(uid, map_manager, name) {
 | 
				
			||||||
 | 
					        this.name = name;
 | 
				
			||||||
 | 
					        this.saveOperation('map_manager', map_manager);
 | 
				
			||||||
 | 
					        AddName.__super__.constructor.call(this, uid);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      AddName.prototype.type = "AddName";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      AddName.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        return AddName.__super__.applyDelete.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      AddName.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return AddName.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      AddName.prototype.execute = function() {
 | 
				
			||||||
 | 
					        var beg, clone, end, event_properties, event_this, uid_beg, uid_end, uid_r, _base;
 | 
				
			||||||
 | 
					        if (!this.validateSavedOperations()) {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          clone = function(o) {
 | 
				
			||||||
 | 
					            var name, p, value;
 | 
				
			||||||
 | 
					            p = {};
 | 
				
			||||||
 | 
					            for (name in o) {
 | 
				
			||||||
 | 
					              value = o[name];
 | 
				
			||||||
 | 
					              p[name] = value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return p;
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          uid_r = clone(this.map_manager.getUid());
 | 
				
			||||||
 | 
					          uid_r.doSync = false;
 | 
				
			||||||
 | 
					          uid_r.op_number = "_" + uid_r.op_number + "_RM_" + this.name;
 | 
				
			||||||
 | 
					          if (HB.getOperation(uid_r) == null) {
 | 
				
			||||||
 | 
					            uid_beg = clone(uid_r);
 | 
				
			||||||
 | 
					            uid_beg.op_number = "" + uid_r.op_number + "_beginning";
 | 
				
			||||||
 | 
					            uid_end = clone(uid_r);
 | 
				
			||||||
 | 
					            uid_end.op_number = "" + uid_r.op_number + "_end";
 | 
				
			||||||
 | 
					            beg = (new types.Delimiter(uid_beg, void 0, uid_end)).execute();
 | 
				
			||||||
 | 
					            end = (new types.Delimiter(uid_end, beg, void 0)).execute();
 | 
				
			||||||
 | 
					            event_properties = {
 | 
				
			||||||
 | 
					              name: this.name
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            event_this = this.map_manager;
 | 
				
			||||||
 | 
					            this.map_manager.map[this.name] = new ReplaceManager(event_properties, event_this, uid_r, beg, end);
 | 
				
			||||||
 | 
					            this.map_manager.map[this.name].setParent(this.map_manager, this.name);
 | 
				
			||||||
 | 
					            ((_base = this.map_manager.map[this.name]).add_name_ops != null ? _base.add_name_ops : _base.add_name_ops = []).push(this);
 | 
				
			||||||
 | 
					            this.map_manager.map[this.name].execute();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return AddName.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      AddName.prototype._encode = function() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          'type': "AddName",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'map_manager': this.map_manager.getUid(),
 | 
				
			||||||
 | 
					          'name': this.name
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return AddName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Operation);
 | 
				
			||||||
 | 
					    parser['AddName'] = function(json) {
 | 
				
			||||||
 | 
					      var map_manager, name, uid;
 | 
				
			||||||
 | 
					      map_manager = json['map_manager'], uid = json['uid'], name = json['name'];
 | 
				
			||||||
 | 
					      return new AddName(uid, map_manager, name);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    ListManager = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(ListManager, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function ListManager(uid, beginning, end, prev, next, origin) {
 | 
				
			||||||
 | 
					        if ((beginning != null) && (end != null)) {
 | 
				
			||||||
 | 
					          this.saveOperation('beginning', beginning);
 | 
				
			||||||
 | 
					          this.saveOperation('end', end);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.beginning = new types.Delimiter(void 0, void 0, void 0);
 | 
				
			||||||
 | 
					          this.end = new types.Delimiter(void 0, this.beginning, void 0);
 | 
				
			||||||
 | 
					          this.beginning.next_cl = this.end;
 | 
				
			||||||
 | 
					          this.beginning.execute();
 | 
				
			||||||
 | 
					          this.end.execute();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ListManager.__super__.constructor.call(this, uid, prev, next, origin);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ListManager.prototype.type = "ListManager";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ListManager.prototype.execute = function() {
 | 
				
			||||||
 | 
					        if (this.validateSavedOperations()) {
 | 
				
			||||||
 | 
					          this.beginning.setParent(this);
 | 
				
			||||||
 | 
					          this.end.setParent(this);
 | 
				
			||||||
 | 
					          return ListManager.__super__.execute.apply(this, arguments);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ListManager.prototype.getLastOperation = function() {
 | 
				
			||||||
 | 
					        return this.end.prev_cl;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ListManager.prototype.getFirstOperation = function() {
 | 
				
			||||||
 | 
					        return this.beginning.next_cl;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ListManager.prototype.toArray = function() {
 | 
				
			||||||
 | 
					        var o, result;
 | 
				
			||||||
 | 
					        o = this.beginning.next_cl;
 | 
				
			||||||
 | 
					        result = [];
 | 
				
			||||||
 | 
					        while (o !== this.end) {
 | 
				
			||||||
 | 
					          result.push(o);
 | 
				
			||||||
 | 
					          o = o.next_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ListManager.prototype.getOperationByPosition = function(position) {
 | 
				
			||||||
 | 
					        var o;
 | 
				
			||||||
 | 
					        o = this.beginning.next_cl;
 | 
				
			||||||
 | 
					        if ((position > 0 || o.isDeleted()) && !(o instanceof types.Delimiter)) {
 | 
				
			||||||
 | 
					          while (o.isDeleted() && !(o instanceof types.Delimiter)) {
 | 
				
			||||||
 | 
					            o = o.next_cl;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          while (true) {
 | 
				
			||||||
 | 
					            if (o instanceof types.Delimiter) {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (position <= 0 && !o.isDeleted()) {
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            o = o.next_cl;
 | 
				
			||||||
 | 
					            if (!o.isDeleted()) {
 | 
				
			||||||
 | 
					              position -= 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return o;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return ListManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Operation);
 | 
				
			||||||
 | 
					    ReplaceManager = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(ReplaceManager, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function ReplaceManager(event_porperties, event_this, uid, beginning, end, prev, next, origin) {
 | 
				
			||||||
 | 
					        this.event_porperties = event_porperties;
 | 
				
			||||||
 | 
					        this.event_this = event_this;
 | 
				
			||||||
 | 
					        ReplaceManager.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype.type = "ReplaceManager";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        var o, _i, _len, _ref;
 | 
				
			||||||
 | 
					        o = this.beginning;
 | 
				
			||||||
 | 
					        while (o != null) {
 | 
				
			||||||
 | 
					          o.applyDelete();
 | 
				
			||||||
 | 
					          o = o.next_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.add_name_ops != null) {
 | 
				
			||||||
 | 
					          _ref = this.add_name_ops;
 | 
				
			||||||
 | 
					          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					            o = _ref[_i];
 | 
				
			||||||
 | 
					            o.applyDelete();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ReplaceManager.__super__.applyDelete.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return ReplaceManager.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype.callEventDecorator = function(events) {
 | 
				
			||||||
 | 
					        var event, name, prop, _i, _len, _ref;
 | 
				
			||||||
 | 
					        if (!this.isDeleted()) {
 | 
				
			||||||
 | 
					          _ref = this.event_porperties;
 | 
				
			||||||
 | 
					          for (name in _ref) {
 | 
				
			||||||
 | 
					            prop = _ref[name];
 | 
				
			||||||
 | 
					            for (_i = 0, _len = events.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					              event = events[_i];
 | 
				
			||||||
 | 
					              event[name] = prop;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.event_this.callEvent(events);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return void 0;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype.replace = function(content, replaceable_uid) {
 | 
				
			||||||
 | 
					        var o;
 | 
				
			||||||
 | 
					        o = this.getLastOperation();
 | 
				
			||||||
 | 
					        (new Replaceable(content, this, replaceable_uid, o, o.next_cl)).execute();
 | 
				
			||||||
 | 
					        return void 0;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype.val = function() {
 | 
				
			||||||
 | 
					        var o;
 | 
				
			||||||
 | 
					        o = this.getLastOperation();
 | 
				
			||||||
 | 
					        return typeof o.val === "function" ? o.val() : void 0;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ReplaceManager.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': "ReplaceManager",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'beginning': this.beginning.getUid(),
 | 
				
			||||||
 | 
					          'end': this.end.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        if ((this.prev_cl != null) && (this.next_cl != null)) {
 | 
				
			||||||
 | 
					          json['prev'] = this.prev_cl.getUid();
 | 
				
			||||||
 | 
					          json['next'] = this.next_cl.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.origin != null) {
 | 
				
			||||||
 | 
					          json["origin"] = this.origin().getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return ReplaceManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(ListManager);
 | 
				
			||||||
 | 
					    parser["ReplaceManager"] = function(json) {
 | 
				
			||||||
 | 
					      var beginning, end, next, origin, prev, uid;
 | 
				
			||||||
 | 
					      uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], beginning = json['beginning'], end = json['end'];
 | 
				
			||||||
 | 
					      return new ReplaceManager(uid, beginning, end, prev, next, origin);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Replaceable = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(Replaceable, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function Replaceable(content, parent, uid, prev, next, origin) {
 | 
				
			||||||
 | 
					        this.saveOperation('content', content);
 | 
				
			||||||
 | 
					        this.saveOperation('parent', parent);
 | 
				
			||||||
 | 
					        if (!((prev != null) && (next != null))) {
 | 
				
			||||||
 | 
					          throw new Error("You must define prev, and next for Replaceable-types!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Replaceable.__super__.constructor.call(this, uid, prev, next, origin);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Replaceable.prototype.type = "Replaceable";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Replaceable.prototype.val = function() {
 | 
				
			||||||
 | 
					        return this.content;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Replaceable.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        if (this.content != null) {
 | 
				
			||||||
 | 
					          if (this.next_cl.type !== "Delimiter") {
 | 
				
			||||||
 | 
					            this.content.deleteAllObservers();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.content.applyDelete();
 | 
				
			||||||
 | 
					          this.content.dontSync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.content = null;
 | 
				
			||||||
 | 
					        return Replaceable.__super__.applyDelete.apply(this, arguments);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Replaceable.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return Replaceable.__super__.cleanup.apply(this, arguments);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Replaceable.prototype.callOperationSpecificEvents = function() {
 | 
				
			||||||
 | 
					        var old_value;
 | 
				
			||||||
 | 
					        if (this.next_cl.type === "Delimiter" && this.prev_cl.type !== "Delimiter") {
 | 
				
			||||||
 | 
					          old_value = this.prev_cl.content;
 | 
				
			||||||
 | 
					          this.prev_cl.applyDelete();
 | 
				
			||||||
 | 
					          this.parent.callEventDecorator([
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "update",
 | 
				
			||||||
 | 
					              changed_by: this.uid.creator,
 | 
				
			||||||
 | 
					              oldValue: old_value
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ]);
 | 
				
			||||||
 | 
					        } else if (this.next_cl.type !== "Delimiter") {
 | 
				
			||||||
 | 
					          this.applyDelete();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.parent.callEventDecorator([
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              type: "add",
 | 
				
			||||||
 | 
					              changed_by: this.uid.creator
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return void 0;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Replaceable.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json, _ref;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': "Replaceable",
 | 
				
			||||||
 | 
					          'content': (_ref = this.content) != null ? _ref.getUid() : void 0,
 | 
				
			||||||
 | 
					          'ReplaceManager': this.parent.getUid(),
 | 
				
			||||||
 | 
					          'prev': this.prev_cl.getUid(),
 | 
				
			||||||
 | 
					          'next': this.next_cl.getUid(),
 | 
				
			||||||
 | 
					          'uid': this.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        if ((this.origin != null) && this.origin !== this.prev_cl) {
 | 
				
			||||||
 | 
					          json["origin"] = this.origin.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return Replaceable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Insert);
 | 
				
			||||||
 | 
					    parser["Replaceable"] = function(json) {
 | 
				
			||||||
 | 
					      var content, next, origin, parent, prev, uid;
 | 
				
			||||||
 | 
					      content = json['content'], parent = json['ReplaceManager'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'];
 | 
				
			||||||
 | 
					      return new Replaceable(content, parent, uid, prev, next, origin);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    types['ListManager'] = ListManager;
 | 
				
			||||||
 | 
					    types['MapManager'] = MapManager;
 | 
				
			||||||
 | 
					    types['ReplaceManager'] = ReplaceManager;
 | 
				
			||||||
 | 
					    types['Replaceable'] = Replaceable;
 | 
				
			||||||
 | 
					    return basic_types;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=../Types/StructuredTypes.js.map
 | 
				
			||||||
							
								
								
									
										1
									
								
								build/node/Types/StructuredTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/node/Types/StructuredTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										342
									
								
								build/node/Types/TextTypes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								build/node/Types/TextTypes.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,342 @@
 | 
				
			|||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var structured_types_uninitialized,
 | 
				
			||||||
 | 
					    __hasProp = {}.hasOwnProperty,
 | 
				
			||||||
 | 
					    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  structured_types_uninitialized = require("./StructuredTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = function(HB) {
 | 
				
			||||||
 | 
					    var TextDelete, TextInsert, WordType, parser, structured_types, types;
 | 
				
			||||||
 | 
					    structured_types = structured_types_uninitialized(HB);
 | 
				
			||||||
 | 
					    types = structured_types.types;
 | 
				
			||||||
 | 
					    parser = structured_types.parser;
 | 
				
			||||||
 | 
					    TextDelete = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(TextDelete, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function TextDelete() {
 | 
				
			||||||
 | 
					        return TextDelete.__super__.constructor.apply(this, arguments);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return TextDelete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Delete);
 | 
				
			||||||
 | 
					    parser["TextDelete"] = parser["Delete"];
 | 
				
			||||||
 | 
					    TextInsert = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(TextInsert, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function TextInsert(content, uid, prev, next, origin) {
 | 
				
			||||||
 | 
					        var _ref;
 | 
				
			||||||
 | 
					        if (content != null ? (_ref = content.uid) != null ? _ref.creator : void 0 : void 0) {
 | 
				
			||||||
 | 
					          this.saveOperation('content', content);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.content = content;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!((prev != null) && (next != null))) {
 | 
				
			||||||
 | 
					          throw new Error("You must define prev, and next for TextInsert-types!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        TextInsert.__super__.constructor.call(this, uid, prev, next, origin);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextInsert.prototype.type = "TextInsert";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextInsert.prototype.getLength = function() {
 | 
				
			||||||
 | 
					        if (this.isDeleted()) {
 | 
				
			||||||
 | 
					          return 0;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return this.content.length;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextInsert.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        TextInsert.__super__.applyDelete.apply(this, arguments);
 | 
				
			||||||
 | 
					        if (this.content instanceof types.Operation) {
 | 
				
			||||||
 | 
					          this.content.applyDelete();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this.content = null;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextInsert.prototype.execute = function() {
 | 
				
			||||||
 | 
					        if (!this.validateSavedOperations()) {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          if (this.content instanceof types.Operation) {
 | 
				
			||||||
 | 
					            this.content.insert_parent = this;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return TextInsert.__super__.execute.call(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextInsert.prototype.val = function(current_position) {
 | 
				
			||||||
 | 
					        if (this.isDeleted() || (this.content == null)) {
 | 
				
			||||||
 | 
					          return "";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return this.content;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextInsert.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json, _ref;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': "TextInsert",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'prev': this.prev_cl.getUid(),
 | 
				
			||||||
 | 
					          'next': this.next_cl.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        if (((_ref = this.content) != null ? _ref.getUid : void 0) != null) {
 | 
				
			||||||
 | 
					          json['content'] = this.content.getUid();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          json['content'] = this.content;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.origin !== this.prev_cl) {
 | 
				
			||||||
 | 
					          json["origin"] = this.origin.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return TextInsert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Insert);
 | 
				
			||||||
 | 
					    parser["TextInsert"] = function(json) {
 | 
				
			||||||
 | 
					      var content, next, origin, prev, uid;
 | 
				
			||||||
 | 
					      content = json['content'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'];
 | 
				
			||||||
 | 
					      return new TextInsert(content, uid, prev, next, origin);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    WordType = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(WordType, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function WordType(uid, beginning, end, prev, next, origin) {
 | 
				
			||||||
 | 
					        WordType.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.type = "WordType";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.applyDelete = function() {
 | 
				
			||||||
 | 
					        var o;
 | 
				
			||||||
 | 
					        o = this.beginning;
 | 
				
			||||||
 | 
					        while (o != null) {
 | 
				
			||||||
 | 
					          o.applyDelete();
 | 
				
			||||||
 | 
					          o = o.next_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return WordType.__super__.applyDelete.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return WordType.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.push = function(content) {
 | 
				
			||||||
 | 
					        return this.insertAfter(this.end.prev_cl, content);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.insertAfter = function(left, content) {
 | 
				
			||||||
 | 
					        var c, right, tmp, _i, _len;
 | 
				
			||||||
 | 
					        while (left.isDeleted()) {
 | 
				
			||||||
 | 
					          left = left.prev_cl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        right = left.next_cl;
 | 
				
			||||||
 | 
					        if (content.type != null) {
 | 
				
			||||||
 | 
					          (new TextInsert(content, void 0, left, right)).execute();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          for (_i = 0, _len = content.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					            c = content[_i];
 | 
				
			||||||
 | 
					            tmp = (new TextInsert(c, void 0, left, right)).execute();
 | 
				
			||||||
 | 
					            left = tmp;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.insertText = function(position, content) {
 | 
				
			||||||
 | 
					        var ith, left;
 | 
				
			||||||
 | 
					        ith = this.getOperationByPosition(position);
 | 
				
			||||||
 | 
					        left = ith.prev_cl;
 | 
				
			||||||
 | 
					        return this.insertAfter(left, content);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.deleteText = function(position, length) {
 | 
				
			||||||
 | 
					        var d, delete_ops, i, o, _i;
 | 
				
			||||||
 | 
					        o = this.getOperationByPosition(position);
 | 
				
			||||||
 | 
					        delete_ops = [];
 | 
				
			||||||
 | 
					        for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
 | 
				
			||||||
 | 
					          if (o instanceof types.Delimiter) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          d = (new TextDelete(void 0, o)).execute();
 | 
				
			||||||
 | 
					          o = o.next_cl;
 | 
				
			||||||
 | 
					          while (!(o instanceof types.Delimiter) && o.isDeleted()) {
 | 
				
			||||||
 | 
					            o = o.next_cl;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          delete_ops.push(d._encode());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.val = function() {
 | 
				
			||||||
 | 
					        var c, o;
 | 
				
			||||||
 | 
					        c = (function() {
 | 
				
			||||||
 | 
					          var _i, _len, _ref, _results;
 | 
				
			||||||
 | 
					          _ref = this.toArray();
 | 
				
			||||||
 | 
					          _results = [];
 | 
				
			||||||
 | 
					          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					            o = _ref[_i];
 | 
				
			||||||
 | 
					            if (o.val != null) {
 | 
				
			||||||
 | 
					              _results.push(o.val());
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              _results.push("");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return _results;
 | 
				
			||||||
 | 
					        }).call(this);
 | 
				
			||||||
 | 
					        return c.join('');
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.toString = function() {
 | 
				
			||||||
 | 
					        return this.val();
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype.bind = function(textfield) {
 | 
				
			||||||
 | 
					        var word;
 | 
				
			||||||
 | 
					        word = this;
 | 
				
			||||||
 | 
					        textfield.value = this.val();
 | 
				
			||||||
 | 
					        this.on("insert", function(event, op) {
 | 
				
			||||||
 | 
					          var fix, left, o_pos, right;
 | 
				
			||||||
 | 
					          o_pos = op.getPosition();
 | 
				
			||||||
 | 
					          fix = function(cursor) {
 | 
				
			||||||
 | 
					            if (cursor <= o_pos) {
 | 
				
			||||||
 | 
					              return cursor;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              cursor += 1;
 | 
				
			||||||
 | 
					              return cursor;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          left = fix(textfield.selectionStart);
 | 
				
			||||||
 | 
					          right = fix(textfield.selectionEnd);
 | 
				
			||||||
 | 
					          textfield.value = word.val();
 | 
				
			||||||
 | 
					          return textfield.setSelectionRange(left, right);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.on("delete", function(event, op) {
 | 
				
			||||||
 | 
					          var fix, left, o_pos, right;
 | 
				
			||||||
 | 
					          o_pos = op.getPosition();
 | 
				
			||||||
 | 
					          fix = function(cursor) {
 | 
				
			||||||
 | 
					            if (cursor < o_pos) {
 | 
				
			||||||
 | 
					              return cursor;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              cursor -= 1;
 | 
				
			||||||
 | 
					              return cursor;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          left = fix(textfield.selectionStart);
 | 
				
			||||||
 | 
					          right = fix(textfield.selectionEnd);
 | 
				
			||||||
 | 
					          textfield.value = word.val();
 | 
				
			||||||
 | 
					          return textfield.setSelectionRange(left, right);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        textfield.onkeypress = function(event) {
 | 
				
			||||||
 | 
					          var char, diff, new_pos, pos;
 | 
				
			||||||
 | 
					          char = null;
 | 
				
			||||||
 | 
					          if (event.key != null) {
 | 
				
			||||||
 | 
					            if (event.charCode === 32) {
 | 
				
			||||||
 | 
					              char = " ";
 | 
				
			||||||
 | 
					            } else if (event.keyCode === 13) {
 | 
				
			||||||
 | 
					              char = '\n';
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              char = event.key;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            char = String.fromCharCode(event.keyCode);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (char.length > 0) {
 | 
				
			||||||
 | 
					            pos = Math.min(textfield.selectionStart, textfield.selectionEnd);
 | 
				
			||||||
 | 
					            diff = Math.abs(textfield.selectionEnd - textfield.selectionStart);
 | 
				
			||||||
 | 
					            word.deleteText(pos, diff);
 | 
				
			||||||
 | 
					            word.insertText(pos, char);
 | 
				
			||||||
 | 
					            new_pos = pos + char.length;
 | 
				
			||||||
 | 
					            textfield.setSelectionRange(new_pos, new_pos);
 | 
				
			||||||
 | 
					            return event.preventDefault();
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            return event.preventDefault();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        textfield.onpaste = function(event) {
 | 
				
			||||||
 | 
					          return event.preventDefault();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        textfield.oncut = function(event) {
 | 
				
			||||||
 | 
					          return event.preventDefault();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        return textfield.onkeydown = function(event) {
 | 
				
			||||||
 | 
					          var del_length, diff, new_pos, pos, val;
 | 
				
			||||||
 | 
					          pos = Math.min(textfield.selectionStart, textfield.selectionEnd);
 | 
				
			||||||
 | 
					          diff = Math.abs(textfield.selectionEnd - textfield.selectionStart);
 | 
				
			||||||
 | 
					          if ((event.keyCode != null) && event.keyCode === 8) {
 | 
				
			||||||
 | 
					            if (diff > 0) {
 | 
				
			||||||
 | 
					              word.deleteText(pos, diff);
 | 
				
			||||||
 | 
					              textfield.setSelectionRange(pos, pos);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              if ((event.ctrlKey != null) && event.ctrlKey) {
 | 
				
			||||||
 | 
					                val = textfield.value;
 | 
				
			||||||
 | 
					                new_pos = pos;
 | 
				
			||||||
 | 
					                del_length = 0;
 | 
				
			||||||
 | 
					                if (pos > 0) {
 | 
				
			||||||
 | 
					                  new_pos--;
 | 
				
			||||||
 | 
					                  del_length++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                while (new_pos > 0 && val[new_pos] !== " " && val[new_pos] !== '\n') {
 | 
				
			||||||
 | 
					                  new_pos--;
 | 
				
			||||||
 | 
					                  del_length++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                word.deleteText(new_pos, pos - new_pos);
 | 
				
			||||||
 | 
					                textfield.setSelectionRange(new_pos, new_pos);
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                word.deleteText(pos - 1, 1);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return event.preventDefault();
 | 
				
			||||||
 | 
					          } else if ((event.keyCode != null) && event.keyCode === 46) {
 | 
				
			||||||
 | 
					            if (diff > 0) {
 | 
				
			||||||
 | 
					              word.deleteText(pos, diff);
 | 
				
			||||||
 | 
					              textfield.setSelectionRange(pos, pos);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              word.deleteText(pos, 1);
 | 
				
			||||||
 | 
					              textfield.setSelectionRange(pos, pos);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return event.preventDefault();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      WordType.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': "WordType",
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'beginning': this.beginning.getUid(),
 | 
				
			||||||
 | 
					          'end': this.end.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        if (this.prev_cl != null) {
 | 
				
			||||||
 | 
					          json['prev'] = this.prev_cl.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.next_cl != null) {
 | 
				
			||||||
 | 
					          json['next'] = this.next_cl.getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.origin != null) {
 | 
				
			||||||
 | 
					          json["origin"] = this.origin().getUid();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return WordType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.ListManager);
 | 
				
			||||||
 | 
					    parser['WordType'] = function(json) {
 | 
				
			||||||
 | 
					      var beginning, end, next, origin, prev, uid;
 | 
				
			||||||
 | 
					      uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin'];
 | 
				
			||||||
 | 
					      return new WordType(uid, beginning, end, prev, next, origin);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    types['TextInsert'] = TextInsert;
 | 
				
			||||||
 | 
					    types['TextDelete'] = TextDelete;
 | 
				
			||||||
 | 
					    types['WordType'] = WordType;
 | 
				
			||||||
 | 
					    return structured_types;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=../Types/TextTypes.js.map
 | 
				
			||||||
							
								
								
									
										1
									
								
								build/node/Types/TextTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/node/Types/TextTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										409
									
								
								build/node/Types/XmlTypes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										409
									
								
								build/node/Types/XmlTypes.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,409 @@
 | 
				
			|||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var dont_proxy, json_types_uninitialized, proxy_token, _proxy,
 | 
				
			||||||
 | 
					    __hasProp = {}.hasOwnProperty,
 | 
				
			||||||
 | 
					    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  json_types_uninitialized = require("./JsonTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  proxy_token = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dont_proxy = function(f) {
 | 
				
			||||||
 | 
					    var e;
 | 
				
			||||||
 | 
					    proxy_token = true;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      f();
 | 
				
			||||||
 | 
					    } catch (_error) {
 | 
				
			||||||
 | 
					      e = _error;
 | 
				
			||||||
 | 
					      proxy_token = false;
 | 
				
			||||||
 | 
					      throw new Error(e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return proxy_token = false;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _proxy = function(f_name, f) {
 | 
				
			||||||
 | 
					    var old_f;
 | 
				
			||||||
 | 
					    old_f = this[f_name];
 | 
				
			||||||
 | 
					    if (old_f != null) {
 | 
				
			||||||
 | 
					      return this[f_name] = function() {
 | 
				
			||||||
 | 
					        var args, that, _ref;
 | 
				
			||||||
 | 
					        if (!proxy_token && !((_ref = this._yatta) != null ? _ref.isDeleted() : void 0)) {
 | 
				
			||||||
 | 
					          that = this;
 | 
				
			||||||
 | 
					          args = arguments;
 | 
				
			||||||
 | 
					          return dont_proxy(function() {
 | 
				
			||||||
 | 
					            f.apply(that, args);
 | 
				
			||||||
 | 
					            return old_f.apply(that, args);
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return old_f.apply(this, arguments);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (typeof Element !== "undefined" && Element !== null) {
 | 
				
			||||||
 | 
					    Element.prototype._proxy = _proxy;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = function(HB) {
 | 
				
			||||||
 | 
					    var TextNodeType, XmlType, json_types, parser, types;
 | 
				
			||||||
 | 
					    json_types = json_types_uninitialized(HB);
 | 
				
			||||||
 | 
					    types = json_types.types;
 | 
				
			||||||
 | 
					    parser = json_types.parser;
 | 
				
			||||||
 | 
					    XmlType = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(XmlType, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function XmlType(uid, tagname, attributes, elements, xml) {
 | 
				
			||||||
 | 
					        var attr, d, element, i, n, word, _i, _j, _len, _ref, _ref1, _ref2;
 | 
				
			||||||
 | 
					        this.tagname = tagname;
 | 
				
			||||||
 | 
					        this.xml = xml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* In case you make this instanceof Insert again
 | 
				
			||||||
 | 
					        if prev? and (not next?) and prev.type?
 | 
				
			||||||
 | 
					           * adjust what you actually mean. you want to insert after prev, then
 | 
				
			||||||
 | 
					           * next is not defined. but we only insert after non-deleted elements.
 | 
				
			||||||
 | 
					           * This is also handled in TextInsert.
 | 
				
			||||||
 | 
					          while prev.isDeleted()
 | 
				
			||||||
 | 
					            prev = prev.prev_cl
 | 
				
			||||||
 | 
					          next = prev.next_cl
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        XmlType.__super__.constructor.call(this, uid);
 | 
				
			||||||
 | 
					        if (((_ref = this.xml) != null ? _ref._yatta : void 0) != null) {
 | 
				
			||||||
 | 
					          d = new types.Delete(void 0, this.xml._yatta);
 | 
				
			||||||
 | 
					          HB.addOperation(d).execute();
 | 
				
			||||||
 | 
					          this.xml._yatta = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ((attributes != null) && (elements != null)) {
 | 
				
			||||||
 | 
					          this.saveOperation('attributes', attributes);
 | 
				
			||||||
 | 
					          this.saveOperation('elements', elements);
 | 
				
			||||||
 | 
					        } else if ((attributes == null) && (elements == null)) {
 | 
				
			||||||
 | 
					          this.attributes = new types.JsonType();
 | 
				
			||||||
 | 
					          this.attributes.setMutableDefault('immutable');
 | 
				
			||||||
 | 
					          HB.addOperation(this.attributes).execute();
 | 
				
			||||||
 | 
					          this.elements = new types.WordType();
 | 
				
			||||||
 | 
					          this.elements.parent = this;
 | 
				
			||||||
 | 
					          HB.addOperation(this.elements).execute();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          throw new Error("Either define attribute and elements both, or none of them");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.xml != null) {
 | 
				
			||||||
 | 
					          this.tagname = this.xml.tagName;
 | 
				
			||||||
 | 
					          for (i = _i = 0, _ref1 = this.xml.attributes.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
 | 
				
			||||||
 | 
					            attr = xml.attributes[i];
 | 
				
			||||||
 | 
					            this.attributes.val(attr.name, attr.value);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          _ref2 = this.xml.childNodes;
 | 
				
			||||||
 | 
					          for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
 | 
				
			||||||
 | 
					            n = _ref2[_j];
 | 
				
			||||||
 | 
					            if (n.nodeType === n.TEXT_NODE) {
 | 
				
			||||||
 | 
					              word = new TextNodeType(void 0, n);
 | 
				
			||||||
 | 
					              HB.addOperation(word).execute();
 | 
				
			||||||
 | 
					              this.elements.push(word);
 | 
				
			||||||
 | 
					            } else if (n.nodeType === n.ELEMENT_NODE) {
 | 
				
			||||||
 | 
					              element = new XmlType(void 0, void 0, void 0, void 0, n);
 | 
				
			||||||
 | 
					              HB.addOperation(element).execute();
 | 
				
			||||||
 | 
					              this.elements.push(element);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              throw new Error("I don't know Node-type " + n.nodeType + "!!");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.setXmlProxy();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        void 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.type = "XmlType";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.applyDelete = function(op) {
 | 
				
			||||||
 | 
					        if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
 | 
				
			||||||
 | 
					          return this.insert_parent.applyDelete(op);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.attributes.applyDelete();
 | 
				
			||||||
 | 
					          this.elements.applyDelete();
 | 
				
			||||||
 | 
					          return XmlType.__super__.applyDelete.apply(this, arguments);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.cleanup = function() {
 | 
				
			||||||
 | 
					        return XmlType.__super__.cleanup.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.setXmlProxy = function() {
 | 
				
			||||||
 | 
					        var findNode, insertBefore, removeChild, renewClassList, that;
 | 
				
			||||||
 | 
					        this.xml._yatta = this;
 | 
				
			||||||
 | 
					        that = this;
 | 
				
			||||||
 | 
					        this.elements.on('insert', function(event, op) {
 | 
				
			||||||
 | 
					          var newNode, right, rightNode;
 | 
				
			||||||
 | 
					          if (op.creator !== HB.getUserId() && this === that.elements) {
 | 
				
			||||||
 | 
					            newNode = op.content.val();
 | 
				
			||||||
 | 
					            right = op.next_cl;
 | 
				
			||||||
 | 
					            while ((right != null) && right.isDeleted()) {
 | 
				
			||||||
 | 
					              right = right.next_cl;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            rightNode = null;
 | 
				
			||||||
 | 
					            if (right.type !== 'Delimiter') {
 | 
				
			||||||
 | 
					              rightNode = right.val().val();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that.xml.insertBefore(newNode, rightNode);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.elements.on('delete', function(event, op) {
 | 
				
			||||||
 | 
					          var del_op, deleted;
 | 
				
			||||||
 | 
					          del_op = op.deleted_by[0];
 | 
				
			||||||
 | 
					          if ((del_op != null) && del_op.creator !== HB.getUserId() && this === that.elements) {
 | 
				
			||||||
 | 
					            deleted = op.content.val();
 | 
				
			||||||
 | 
					            return dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that.xml.removeChild(deleted);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.attributes.on(['add', 'update'], function(event, property_name, op) {
 | 
				
			||||||
 | 
					          if (op.creator !== HB.getUserId() && this === that.attributes) {
 | 
				
			||||||
 | 
					            return dont_proxy(function() {
 | 
				
			||||||
 | 
					              var newval;
 | 
				
			||||||
 | 
					              newval = op.val().val();
 | 
				
			||||||
 | 
					              if (newval != null) {
 | 
				
			||||||
 | 
					                return that.xml.setAttribute(property_name, op.val().val());
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                return that.xml.removeAttribute(property_name);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        findNode = function(child) {
 | 
				
			||||||
 | 
					          var elem;
 | 
				
			||||||
 | 
					          if (child == null) {
 | 
				
			||||||
 | 
					            throw new Error("you must specify a parameter!");
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          child = child._yatta;
 | 
				
			||||||
 | 
					          elem = that.elements.beginning.next_cl;
 | 
				
			||||||
 | 
					          while (elem.type !== 'Delimiter' && elem.content !== child) {
 | 
				
			||||||
 | 
					            elem = elem.next_cl;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (elem.type === 'Delimiter') {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            return elem;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        insertBefore = function(insertedNode_s, adjacentNode) {
 | 
				
			||||||
 | 
					          var child, element, inserted_nodes, next, prev, _results;
 | 
				
			||||||
 | 
					          next = null;
 | 
				
			||||||
 | 
					          if (adjacentNode != null) {
 | 
				
			||||||
 | 
					            next = findNode(adjacentNode);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          prev = null;
 | 
				
			||||||
 | 
					          if (next) {
 | 
				
			||||||
 | 
					            prev = next.prev_cl;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            prev = this._yatta.elements.end.prev_cl;
 | 
				
			||||||
 | 
					            while (prev.isDeleted()) {
 | 
				
			||||||
 | 
					              prev = prev.prev_cl;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          inserted_nodes = null;
 | 
				
			||||||
 | 
					          if (insertedNode_s.nodeType === insertedNode_s.DOCUMENT_FRAGMENT_NODE) {
 | 
				
			||||||
 | 
					            child = insertedNode_s.lastChild;
 | 
				
			||||||
 | 
					            _results = [];
 | 
				
			||||||
 | 
					            while (child != null) {
 | 
				
			||||||
 | 
					              element = new XmlType(void 0, void 0, void 0, void 0, child);
 | 
				
			||||||
 | 
					              HB.addOperation(element).execute();
 | 
				
			||||||
 | 
					              that.elements.insertAfter(prev, element);
 | 
				
			||||||
 | 
					              _results.push(child = child.previousSibling);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return _results;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            element = new XmlType(void 0, void 0, void 0, void 0, insertedNode_s);
 | 
				
			||||||
 | 
					            HB.addOperation(element).execute();
 | 
				
			||||||
 | 
					            return that.elements.insertAfter(prev, element);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        this.xml._proxy('insertBefore', insertBefore);
 | 
				
			||||||
 | 
					        this.xml._proxy('appendChild', insertBefore);
 | 
				
			||||||
 | 
					        this.xml._proxy('removeAttribute', function(name) {
 | 
				
			||||||
 | 
					          return that.attributes.val(name, void 0);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.xml._proxy('setAttribute', function(name, value) {
 | 
				
			||||||
 | 
					          return that.attributes.val(name, value);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        renewClassList = function(newclass) {
 | 
				
			||||||
 | 
					          var dont_do_it, elem, value, _i, _len;
 | 
				
			||||||
 | 
					          dont_do_it = false;
 | 
				
			||||||
 | 
					          if (newclass != null) {
 | 
				
			||||||
 | 
					            for (_i = 0, _len = this.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					              elem = this[_i];
 | 
				
			||||||
 | 
					              if (newclass === elem) {
 | 
				
			||||||
 | 
					                dont_do_it = true;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          value = Array.prototype.join.call(this, " ");
 | 
				
			||||||
 | 
					          if ((newclass != null) && !dont_do_it) {
 | 
				
			||||||
 | 
					            value += " " + newclass;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return that.attributes.val('class', value);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        _proxy.call(this.xml.classList, 'add', renewClassList);
 | 
				
			||||||
 | 
					        _proxy.call(this.xml.classList, 'remove', renewClassList);
 | 
				
			||||||
 | 
					        this.xml.__defineSetter__('className', function(val) {
 | 
				
			||||||
 | 
					          return this.setAttribute('class', val);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.xml.__defineGetter__('className', function() {
 | 
				
			||||||
 | 
					          return that.attributes.val('class');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.xml.__defineSetter__('textContent', function(val) {
 | 
				
			||||||
 | 
					          var elem, remove, text_node;
 | 
				
			||||||
 | 
					          elem = that.xml.firstChild;
 | 
				
			||||||
 | 
					          while (elem != null) {
 | 
				
			||||||
 | 
					            remove = elem;
 | 
				
			||||||
 | 
					            elem = elem.nextSibling;
 | 
				
			||||||
 | 
					            that.xml.removeChild(remove);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (val !== "") {
 | 
				
			||||||
 | 
					            text_node = document.createTextNode(val);
 | 
				
			||||||
 | 
					            return that.xml.appendChild(text_node);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        removeChild = function(node) {
 | 
				
			||||||
 | 
					          var d, elem;
 | 
				
			||||||
 | 
					          elem = findNode(node);
 | 
				
			||||||
 | 
					          if (!elem) {
 | 
				
			||||||
 | 
					            throw new Error("You are only allowed to delete existing (direct) child elements!");
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          d = new types.Delete(void 0, elem);
 | 
				
			||||||
 | 
					          HB.addOperation(d).execute();
 | 
				
			||||||
 | 
					          return node._yatta = null;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        this.xml._proxy('removeChild', removeChild);
 | 
				
			||||||
 | 
					        return this.xml._proxy('replaceChild', function(insertedNode, replacedNode) {
 | 
				
			||||||
 | 
					          insertBefore.call(this, insertedNode, replacedNode);
 | 
				
			||||||
 | 
					          return removeChild.call(this, replacedNode);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.val = function(enforce) {
 | 
				
			||||||
 | 
					        var a, attr, attr_name, e, n, text_node, value;
 | 
				
			||||||
 | 
					        if (enforce == null) {
 | 
				
			||||||
 | 
					          enforce = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (typeof document !== "undefined" && document !== null) {
 | 
				
			||||||
 | 
					          if ((this.xml == null) || enforce) {
 | 
				
			||||||
 | 
					            this.xml = document.createElement(this.tagname);
 | 
				
			||||||
 | 
					            attr = this.attributes.val();
 | 
				
			||||||
 | 
					            for (attr_name in attr) {
 | 
				
			||||||
 | 
					              value = attr[attr_name];
 | 
				
			||||||
 | 
					              if (value != null) {
 | 
				
			||||||
 | 
					                a = document.createAttribute(attr_name);
 | 
				
			||||||
 | 
					                a.value = value;
 | 
				
			||||||
 | 
					                this.xml.setAttributeNode(a);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            e = this.elements.beginning.next_cl;
 | 
				
			||||||
 | 
					            while (e.type !== "Delimiter") {
 | 
				
			||||||
 | 
					              n = e.content;
 | 
				
			||||||
 | 
					              if (!e.isDeleted() && (e.content != null)) {
 | 
				
			||||||
 | 
					                if (n.type === "XmlType") {
 | 
				
			||||||
 | 
					                  this.xml.appendChild(n.val(enforce));
 | 
				
			||||||
 | 
					                } else if (n.type === "TextNodeType") {
 | 
				
			||||||
 | 
					                  text_node = n.val();
 | 
				
			||||||
 | 
					                  this.xml.appendChild(text_node);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  throw new Error("Internal structure cannot be transformed to dom");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              e = e.next_cl;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.setXmlProxy();
 | 
				
			||||||
 | 
					          return this.xml;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.execute = function() {
 | 
				
			||||||
 | 
					        return XmlType.__super__.execute.call(this);
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /*
 | 
				
			||||||
 | 
					        if not @validateSavedOperations()
 | 
				
			||||||
 | 
					          return false
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					          return true
 | 
				
			||||||
 | 
					       */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype.getParent = function() {
 | 
				
			||||||
 | 
					        return this.parent;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XmlType.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': this.type,
 | 
				
			||||||
 | 
					          'attributes': this.attributes.getUid(),
 | 
				
			||||||
 | 
					          'elements': this.elements.getUid(),
 | 
				
			||||||
 | 
					          'tagname': this.tagname,
 | 
				
			||||||
 | 
					          'uid': this.getUid()
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return XmlType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.Insert);
 | 
				
			||||||
 | 
					    parser['XmlType'] = function(json) {
 | 
				
			||||||
 | 
					      var attributes, elements, tagname, uid;
 | 
				
			||||||
 | 
					      uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'];
 | 
				
			||||||
 | 
					      return new XmlType(uid, tagname, attributes, elements, void 0);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    TextNodeType = (function(_super) {
 | 
				
			||||||
 | 
					      __extends(TextNodeType, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      function TextNodeType(uid, content) {
 | 
				
			||||||
 | 
					        var d;
 | 
				
			||||||
 | 
					        if (content._yatta != null) {
 | 
				
			||||||
 | 
					          d = new types.Delete(void 0, content._yatta);
 | 
				
			||||||
 | 
					          HB.addOperation(d).execute();
 | 
				
			||||||
 | 
					          content._yatta = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        content._yatta = this;
 | 
				
			||||||
 | 
					        TextNodeType.__super__.constructor.call(this, uid, content);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextNodeType.prototype.applyDelete = function(op) {
 | 
				
			||||||
 | 
					        if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
 | 
				
			||||||
 | 
					          return this.insert_parent.applyDelete(op);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return TextNodeType.__super__.applyDelete.apply(this, arguments);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextNodeType.prototype.type = "TextNodeType";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TextNodeType.prototype._encode = function() {
 | 
				
			||||||
 | 
					        var json;
 | 
				
			||||||
 | 
					        json = {
 | 
				
			||||||
 | 
					          'type': this.type,
 | 
				
			||||||
 | 
					          'uid': this.getUid(),
 | 
				
			||||||
 | 
					          'content': this.content.textContent
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return TextNodeType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    })(types.ImmutableObject);
 | 
				
			||||||
 | 
					    parser['TextNodeType'] = function(json) {
 | 
				
			||||||
 | 
					      var content, textnode, uid;
 | 
				
			||||||
 | 
					      uid = json['uid'], content = json['content'];
 | 
				
			||||||
 | 
					      textnode = document.createTextNode(content);
 | 
				
			||||||
 | 
					      return new TextNodeType(uid, textnode);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    types['XmlType'] = XmlType;
 | 
				
			||||||
 | 
					    return json_types;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=../Types/XmlTypes.js.map
 | 
				
			||||||
							
								
								
									
										1
									
								
								build/node/Types/XmlTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/node/Types/XmlTypes.js.map
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -1,5 +1,7 @@
 | 
				
			|||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var Engine, HistoryBuffer, Yatta, adaptConnector, json_types_uninitialized;
 | 
					  var Engine, HistoryBuffer, adaptConnector, createYatta, json_types_uninitialized,
 | 
				
			||||||
 | 
					    __hasProp = {}.hasOwnProperty,
 | 
				
			||||||
 | 
					    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  json_types_uninitialized = require("./Types/JsonTypes");
 | 
					  json_types_uninitialized = require("./Types/JsonTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -9,89 +11,35 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  adaptConnector = require("./ConnectorAdapter");
 | 
					  adaptConnector = require("./ConnectorAdapter");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Yatta = (function() {
 | 
					  createYatta = function(connector) {
 | 
				
			||||||
    function Yatta(connector) {
 | 
					    var HB, Yatta, type_manager, types, user_id;
 | 
				
			||||||
      var beg, end, first_word, type_manager, uid_beg, uid_end, user_id;
 | 
					    user_id = connector.id;
 | 
				
			||||||
      this.connector = connector;
 | 
					    HB = new HistoryBuffer(user_id);
 | 
				
			||||||
      user_id = this.connector.id;
 | 
					    type_manager = json_types_uninitialized(HB);
 | 
				
			||||||
      this.HB = new HistoryBuffer(user_id);
 | 
					    types = type_manager.types;
 | 
				
			||||||
      type_manager = json_types_uninitialized(this.HB);
 | 
					    Yatta = (function(_super) {
 | 
				
			||||||
      this.types = type_manager.types;
 | 
					      __extends(Yatta, _super);
 | 
				
			||||||
      this.engine = new Engine(this.HB, type_manager.parser);
 | 
					 | 
				
			||||||
      this.HB.engine = this.engine;
 | 
					 | 
				
			||||||
      adaptConnector(this.connector, this.engine, this.HB, type_manager.execution_listener);
 | 
					 | 
				
			||||||
      first_word = new this.types.JsonType(this.HB.getReservedUniqueIdentifier()).execute();
 | 
					 | 
				
			||||||
      uid_beg = this.HB.getReservedUniqueIdentifier();
 | 
					 | 
				
			||||||
      uid_end = this.HB.getReservedUniqueIdentifier();
 | 
					 | 
				
			||||||
      beg = (new this.types.Delimiter(uid_beg, void 0, uid_end)).execute();
 | 
					 | 
				
			||||||
      end = (new this.types.Delimiter(uid_end, beg, void 0)).execute();
 | 
					 | 
				
			||||||
      this.root_element = (new this.types.ReplaceManager(void 0, this.HB.getReservedUniqueIdentifier(), beg, end)).execute();
 | 
					 | 
				
			||||||
      this.root_element.replace(first_word, this.HB.getReservedUniqueIdentifier());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Yatta.prototype.getSharedObject = function() {
 | 
					      function Yatta() {
 | 
				
			||||||
      return this.root_element.val();
 | 
					        this.connector = connector;
 | 
				
			||||||
    };
 | 
					        this.HB = HB;
 | 
				
			||||||
 | 
					        this.types = types;
 | 
				
			||||||
 | 
					        this.engine = new Engine(this.HB, type_manager.parser);
 | 
				
			||||||
 | 
					        adaptConnector(this.connector, this.engine, this.HB, type_manager.execution_listener);
 | 
				
			||||||
 | 
					        Yatta.__super__.constructor.apply(this, arguments);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Yatta.prototype.getConnector = function() {
 | 
					      Yatta.prototype.getConnector = function() {
 | 
				
			||||||
        return this.connector;
 | 
					        return this.connector;
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Yatta.prototype.getHistoryBuffer = function() {
 | 
					 | 
				
			||||||
      return this.HB;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Yatta.prototype.setMutableDefault = function(mutable) {
 | 
					 | 
				
			||||||
      return this.getSharedObject().setMutableDefault(mutable);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Yatta.prototype.getUserId = function() {
 | 
					 | 
				
			||||||
      return this.HB.getUserId();
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Yatta.prototype.toJson = function() {
 | 
					 | 
				
			||||||
      return this.getSharedObject().toJson();
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Yatta.prototype.val = function() {
 | 
					 | 
				
			||||||
      var _ref;
 | 
					 | 
				
			||||||
      return (_ref = this.getSharedObject()).val.apply(_ref, arguments);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Yatta.prototype.on = function() {
 | 
					 | 
				
			||||||
      var _ref;
 | 
					 | 
				
			||||||
      return (_ref = this.getSharedObject()).on.apply(_ref, arguments);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Yatta.prototype.deleteListener = function() {
 | 
					 | 
				
			||||||
      var _ref;
 | 
					 | 
				
			||||||
      return (_ref = this.getSharedObject()).deleteListener.apply(_ref, arguments);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Object.defineProperty(Yatta.prototype, 'value', {
 | 
					 | 
				
			||||||
      get: function() {
 | 
					 | 
				
			||||||
        return this.getSharedObject().value;
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      set: function(o) {
 | 
					 | 
				
			||||||
        var o_name, o_obj, _results;
 | 
					 | 
				
			||||||
        if (o.constructor === {}.constructor) {
 | 
					 | 
				
			||||||
          _results = [];
 | 
					 | 
				
			||||||
          for (o_name in o) {
 | 
					 | 
				
			||||||
            o_obj = o[o_name];
 | 
					 | 
				
			||||||
            _results.push(this.val(o_name, o_obj, 'immutable'));
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          return _results;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          throw new Error("You must only set Object values!");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return Yatta;
 | 
					      return Yatta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  })();
 | 
					    })(types.JsonType);
 | 
				
			||||||
 | 
					    return new Yatta(HB.getReservedUniqueIdentifier()).execute();
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  module.exports = Yatta;
 | 
					  module.exports = createYatta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((typeof window !== "undefined" && window !== null) && (window.Yatta == null)) {
 | 
					  if ((typeof window !== "undefined" && window !== null) && (window.Yatta == null)) {
 | 
				
			||||||
    window.Yatta = Yatta;
 | 
					    window.Yatta = Yatta;
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -13,12 +13,13 @@
 | 
				
			|||||||
    mocha.ui('bdd');
 | 
					    mocha.ui('bdd');
 | 
				
			||||||
    mocha.reporter('html');
 | 
					    mocha.reporter('html');
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <!--script src="TextYatta_test.js"></script-->
 | 
					  <script src="TextYatta_test.js"></script>
 | 
				
			||||||
  <script src="JsonYatta_test.js"></script>
 | 
					  <script src="JsonYatta_test.js"></script>
 | 
				
			||||||
  <!--script src="XmlYatta_test_browser.js"></script-->
 | 
					  <!--script src="XmlYatta_test_browser.js"></script-->
 | 
				
			||||||
  <script>
 | 
					  <script>
 | 
				
			||||||
    //mocha.checkLeaks();
 | 
					    //mocha.checkLeaks();
 | 
				
			||||||
    //mocha.run();
 | 
					    //mocha.run();
 | 
				
			||||||
 | 
					    window.onerror = null;
 | 
				
			||||||
    if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
 | 
					    if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
 | 
				
			||||||
    else { mocha.run(); }
 | 
					    else { mocha.run(); }
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
 | 
				
			|||||||
@ -178,7 +178,7 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -359,7 +359,7 @@ E.g.: let x = {a:[]}. Then x.a.push 1 wouldn't change anything</p>
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -139,7 +139,7 @@ console.log(w.newProperty == "Awesome") # true!</code></pre>
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -389,7 +389,7 @@ yatta.bind(textbox);</code></pre>
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,12 @@
 | 
				
			|||||||
          <td>Defined in:</td>
 | 
					          <td>Defined in:</td>
 | 
				
			||||||
          <td>lib/Yatta.coffee</td>
 | 
					          <td>lib/Yatta.coffee</td>
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>Inherits:</td>
 | 
				
			||||||
 | 
					          <td>
 | 
				
			||||||
 | 
					            types.JsonType
 | 
				
			||||||
 | 
					          </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
      </table>
 | 
					      </table>
 | 
				
			||||||
      <h2>Overview</h2>
 | 
					      <h2>Overview</h2>
 | 
				
			||||||
      <div class='docstring'>
 | 
					      <div class='docstring'>
 | 
				
			||||||
@ -47,17 +53,6 @@ Known values that are supported:</p><ul>
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
      <h2>Instance Method Summary</h2>
 | 
					      <h2>Instance Method Summary</h2>
 | 
				
			||||||
      <ul class='summary'>
 | 
					      <ul class='summary'>
 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#getSharedObject-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(?)
 | 
					 | 
				
			||||||
<b>getSharedObject</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					  <li>
 | 
				
			||||||
    <span class='signature'>
 | 
					    <span class='signature'>
 | 
				
			||||||
      <a href='#getConnector-dynamic'>
 | 
					      <a href='#getConnector-dynamic'>
 | 
				
			||||||
@ -66,85 +61,6 @@ Known values that are supported:</p><ul>
 | 
				
			|||||||
<b>getConnector</b><span>()</span>
 | 
					<b>getConnector</b><span>()</span>
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
    </span>
 | 
					    </span>
 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
      Get the initialized connector. 
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#getHistoryBuffer-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>getHistoryBuffer</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#setMutableDefault-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>setMutableDefault</b><span>(mutable)</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#getUserId-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>getUserId</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
      Get the UserId from the HistoryBuffer object. 
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#toJson-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>toJson</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#val-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>val</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#observe-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>observe</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
  </li>
 | 
					 | 
				
			||||||
  <li>
 | 
					 | 
				
			||||||
    <span class='signature'>
 | 
					 | 
				
			||||||
      <a href='#unobserve-dynamic'>
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>unobserve</b><span>()</span>
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </span>
 | 
					 | 
				
			||||||
    <span class='desc'>
 | 
					    <span class='desc'>
 | 
				
			||||||
    </span>
 | 
					    </span>
 | 
				
			||||||
  </li>
 | 
					  </li>
 | 
				
			||||||
@ -155,7 +71,7 @@ Known values that are supported:</p><ul>
 | 
				
			|||||||
    <p class='signature' id='constructor-dynamic'>
 | 
					    <p class='signature' id='constructor-dynamic'>
 | 
				
			||||||
      #
 | 
					      #
 | 
				
			||||||
(void)
 | 
					(void)
 | 
				
			||||||
<b>constructor</b><span>(connector)</span>
 | 
					<b>constructor</b><span>()</span>
 | 
				
			||||||
      <br>
 | 
					      <br>
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <div class='tags'>
 | 
					    <div class='tags'>
 | 
				
			||||||
@ -187,27 +103,6 @@ Known values that are supported:</p><ul>
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
      <h2>Instance Method Details</h2>
 | 
					      <h2>Instance Method Details</h2>
 | 
				
			||||||
      <div class='methods'>
 | 
					      <div class='methods'>
 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='getSharedObject-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(?)
 | 
					 | 
				
			||||||
<b>getSharedObject</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>Returns:</h3>
 | 
					 | 
				
			||||||
  <ul class='return'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <span class='type'></span>
 | 
					 | 
				
			||||||
      (
 | 
					 | 
				
			||||||
        <tt>?</tt>
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      —
 | 
					 | 
				
			||||||
      <span class='desc'>JsonType </span>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					  <div class='method_details'>
 | 
				
			||||||
    <p class='signature' id='getConnector-dynamic'>
 | 
					    <p class='signature' id='getConnector-dynamic'>
 | 
				
			||||||
      #
 | 
					      #
 | 
				
			||||||
@ -215,127 +110,12 @@ Known values that are supported:</p><ul>
 | 
				
			|||||||
<b>getConnector</b><span>()</span>
 | 
					<b>getConnector</b><span>()</span>
 | 
				
			||||||
      <br>
 | 
					      <br>
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <div class='docstring'>
 | 
					    
 | 
				
			||||||
  <p>Get the initialized connector.</p>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<div class='tags'>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='getHistoryBuffer-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>getHistoryBuffer</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>See also:</h3>
 | 
					 | 
				
			||||||
  <ul class='see'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a href='HistoryBuffer'>HistoryBuffer</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='setMutableDefault-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>setMutableDefault</b><span>(mutable)</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>See also:</h3>
 | 
					 | 
				
			||||||
  <ul class='see'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a href='JsonType.setMutableDefault'>JsonType.setMutableDefault</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='getUserId-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>getUserId</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='docstring'>
 | 
					 | 
				
			||||||
  <p>Get the UserId from the HistoryBuffer object.
 | 
					 | 
				
			||||||
In most cases this will be the same as the user_id value with which
 | 
					 | 
				
			||||||
Yatta was initialized (Depending on the HistoryBuffer implementation).</p>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<div class='tags'>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='toJson-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>toJson</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>See also:</h3>
 | 
					 | 
				
			||||||
  <ul class='see'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a href='JsonType.toJson'>JsonType.toJson</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='val-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>val</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>See also:</h3>
 | 
					 | 
				
			||||||
  <ul class='see'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a href='JsonType.val'>JsonType.val</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='observe-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>observe</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>See also:</h3>
 | 
					 | 
				
			||||||
  <ul class='see'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a href='Operation.on'>Operation.on</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <div class='method_details'>
 | 
					 | 
				
			||||||
    <p class='signature' id='unobserve-dynamic'>
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
(void)
 | 
					 | 
				
			||||||
<b>unobserve</b><span>()</span>
 | 
					 | 
				
			||||||
      <br>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <div class='tags'>
 | 
					 | 
				
			||||||
  <h3>See also:</h3>
 | 
					 | 
				
			||||||
  <ul class='see'>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a href='Operation.deleteListener'>Operation.deleteListener</a>
 | 
					 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -65,6 +65,10 @@
 | 
				
			|||||||
          <a href='class/Yatta.html' target='main'>
 | 
					          <a href='class/Yatta.html' target='main'>
 | 
				
			||||||
            Yatta
 | 
					            Yatta
 | 
				
			||||||
          </a>
 | 
					          </a>
 | 
				
			||||||
 | 
					          <small class='parent'>
 | 
				
			||||||
 | 
					            <
 | 
				
			||||||
 | 
					            types.JsonType
 | 
				
			||||||
 | 
					          </small>
 | 
				
			||||||
          <small class='namespace'>
 | 
					          <small class='namespace'>
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
 | 
				
			|||||||
</ul>
 | 
					</ul>
 | 
				
			||||||
<h2 id="support">Support</h2><p>Please report <em>any</em> issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!
 | 
					<h2 id="support">Support</h2><p>Please report <em>any</em> issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!
 | 
				
			||||||
I would appreciate if developers gave me feedback on how <em>convenient</em> the framework is, and if it is easy to use. Particularly the XML-support may not support every DOM-methods - if you encounter a method that does not cause any change on other peers,
 | 
					I would appreciate if developers gave me feedback on how <em>convenient</em> the framework is, and if it is easy to use. Particularly the XML-support may not support every DOM-methods - if you encounter a method that does not cause any change on other peers,
 | 
				
			||||||
please state function name, and sample parameters. However, there are browser-specific features, that Yatta won't support.</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="mailto:kevin.jahns@rwth-aachen.de">kevin.jahns@rwth-aachen.de</a>
 | 
					please state function name, and sample parameters. However, there are browser-specific features, that Yatta won't support.</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="mailto:kevin.jahns@rwth-aachen.de">kevin.jahns@rwth-aachen.de</a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -85,7 +85,7 @@ please state function name, and sample parameters. However, there are browser-sp
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -106,7 +106,7 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -72,7 +72,7 @@
 | 
				
			|||||||
</dl>
 | 
					</dl>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,7 @@
 | 
				
			|||||||
</dl>
 | 
					</dl>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@
 | 
				
			|||||||
      </table>
 | 
					      </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@
 | 
				
			|||||||
      </table>
 | 
					      </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@
 | 
				
			|||||||
      </table>
 | 
					      </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@
 | 
				
			|||||||
      </table>
 | 
					      </table>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -34,16 +34,6 @@
 | 
				
			|||||||
          <td>Defined in:</td>
 | 
					          <td>Defined in:</td>
 | 
				
			||||||
          <td>lib</td>
 | 
					          <td>lib</td>
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
          <td>
 | 
					 | 
				
			||||||
            Classes:
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
          <td>
 | 
					 | 
				
			||||||
            <a href='../../class/Yatta.html'>
 | 
					 | 
				
			||||||
              Yatta
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
      </table>
 | 
					      </table>
 | 
				
			||||||
      <h2>Variables Summary</h2>
 | 
					      <h2>Variables Summary</h2>
 | 
				
			||||||
      <dl class='constants'>
 | 
					      <dl class='constants'>
 | 
				
			||||||
@ -52,13 +42,39 @@
 | 
				
			|||||||
    =
 | 
					    =
 | 
				
			||||||
  </dt>
 | 
					  </dt>
 | 
				
			||||||
  <dd>
 | 
					  <dd>
 | 
				
			||||||
    <pre><code class='coffeescript'>Yatta</code></pre>
 | 
					    <pre><code class='coffeescript'>createYatta</code></pre>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  </dd>
 | 
					  </dd>
 | 
				
			||||||
</dl>
 | 
					</dl>
 | 
				
			||||||
 | 
					      <h2>Method Summary</h2>
 | 
				
			||||||
 | 
					      <ul class='summary'>
 | 
				
			||||||
 | 
					  <li>
 | 
				
			||||||
 | 
					    <span class='signature'>
 | 
				
			||||||
 | 
					      <a href='#createYatta-'>
 | 
				
			||||||
 | 
					        ~
 | 
				
			||||||
 | 
					(void)
 | 
				
			||||||
 | 
					<b>createYatta</b><span>(connector)</span>
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </span>
 | 
				
			||||||
 | 
					    <span class='desc'>
 | 
				
			||||||
 | 
					    </span>
 | 
				
			||||||
 | 
					  </li>
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					      <h2>Method Details</h2>
 | 
				
			||||||
 | 
					      <div class='methods'>
 | 
				
			||||||
 | 
					  <div class='method_details'>
 | 
				
			||||||
 | 
					    <p class='signature' id='createYatta-'>
 | 
				
			||||||
 | 
					      ~
 | 
				
			||||||
 | 
					(void)
 | 
				
			||||||
 | 
					<b>createYatta</b><span>(connector)</span>
 | 
				
			||||||
 | 
					      <br>
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div id='footer'>
 | 
					    <div id='footer'>
 | 
				
			||||||
  December 17, 14 22:46:39 by
 | 
					  December 22, 14 14:36:45 by
 | 
				
			||||||
  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
					  <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
 | 
				
			||||||
    Codo
 | 
					    Codo
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
window.searchData = [{"t":"JsonTypeWrapper","p":"class/JsonTypeWrapper.html"},{"t":"JsonType","p":"class/JsonType.html"},{"t":"WordType","p":"class/WordType.html"},{"t":"Yatta","p":"class/Yatta.html"},{"t":"lib/ConnectorAdapter.coffee","p":"file/lib/ConnectorAdapter.coffee.html"},{"t":"lib/Engine.coffee","p":"file/lib/Engine.coffee.html"},{"t":"lib/HistoryBuffer.coffee","p":"file/lib/HistoryBuffer.coffee.html"},{"t":"lib/Types/BasicTypes.coffee","p":"file/lib/Types/BasicTypes.coffee.html"},{"t":"lib/Types/JsonTypes.coffee","p":"file/lib/Types/JsonTypes.coffee.html"},{"t":"lib/Types/StructuredTypes.coffee","p":"file/lib/Types/StructuredTypes.coffee.html"},{"t":"lib/Types/TextTypes.coffee","p":"file/lib/Types/TextTypes.coffee.html"},{"t":"lib/Yatta.coffee","p":"file/lib/Yatta.coffee.html"},{"t":"README.md","p":"extra/README.md.html"},{"t":"LICENSE.txt","p":"extra/LICENSE.txt.html"},{"t":"JsonType#_encode","p":"class/JsonType.html#_encode-dynamic"},{"t":"WordType#_encode","p":"class/WordType.html#_encode-dynamic"},{"t":"lib/ConnectorAdapter.coffee~adaptConnector","p":"file/lib/ConnectorAdapter.coffee.html#adaptConnector-"},{"t":"WordType#applyDelete","p":"class/WordType.html#applyDelete-dynamic"},{"t":"JsonType#applyDelete","p":"class/JsonType.html#applyDelete-dynamic"},{"t":"WordType#bind","p":"class/WordType.html#bind-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#deleteText","p":"class/WordType.html#deleteText-dynamic"},{"t":"Yatta#getConnector","p":"class/Yatta.html#getConnector-dynamic"},{"t":"Yatta#getHistoryBuffer","p":"class/Yatta.html#getHistoryBuffer-dynamic"},{"t":"Yatta#getSharedObject","p":"class/Yatta.html#getSharedObject-dynamic"},{"t":"Yatta#getUserId","p":"class/Yatta.html#getUserId-dynamic"},{"t":"WordType#insertAfter","p":"class/WordType.html#insertAfter-dynamic"},{"t":"WordType#insertText","p":"class/WordType.html#insertText-dynamic"},{"t":"Yatta#observe","p":"class/Yatta.html#observe-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"Yatta#setMutableDefault","p":"class/Yatta.html#setMutableDefault-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"JsonType#toJson","p":"class/JsonType.html#toJson-dynamic"},{"t":"Yatta#toJson","p":"class/Yatta.html#toJson-dynamic"},{"t":"WordType#toString","p":"class/WordType.html#toString-dynamic"},{"t":"Yatta#unobserve","p":"class/Yatta.html#unobserve-dynamic"},{"t":"Yatta#val","p":"class/Yatta.html#val-dynamic"},{"t":"WordType#val","p":"class/WordType.html#val-dynamic"},{"t":"JsonType#val","p":"class/JsonType.html#val-dynamic"}]
 | 
					window.searchData = [{"t":"JsonTypeWrapper","p":"class/JsonTypeWrapper.html"},{"t":"JsonType","p":"class/JsonType.html"},{"t":"WordType","p":"class/WordType.html"},{"t":"Yatta","p":"class/Yatta.html"},{"t":"lib/ConnectorAdapter.coffee","p":"file/lib/ConnectorAdapter.coffee.html"},{"t":"lib/Engine.coffee","p":"file/lib/Engine.coffee.html"},{"t":"lib/HistoryBuffer.coffee","p":"file/lib/HistoryBuffer.coffee.html"},{"t":"lib/Types/BasicTypes.coffee","p":"file/lib/Types/BasicTypes.coffee.html"},{"t":"lib/Types/JsonTypes.coffee","p":"file/lib/Types/JsonTypes.coffee.html"},{"t":"lib/Types/StructuredTypes.coffee","p":"file/lib/Types/StructuredTypes.coffee.html"},{"t":"lib/Types/TextTypes.coffee","p":"file/lib/Types/TextTypes.coffee.html"},{"t":"lib/Yatta.coffee","p":"file/lib/Yatta.coffee.html"},{"t":"README.md","p":"extra/README.md.html"},{"t":"LICENSE.txt","p":"extra/LICENSE.txt.html"},{"t":"WordType#_encode","p":"class/WordType.html#_encode-dynamic"},{"t":"JsonType#_encode","p":"class/JsonType.html#_encode-dynamic"},{"t":"lib/ConnectorAdapter.coffee~adaptConnector","p":"file/lib/ConnectorAdapter.coffee.html#adaptConnector-"},{"t":"JsonType#applyDelete","p":"class/JsonType.html#applyDelete-dynamic"},{"t":"WordType#applyDelete","p":"class/WordType.html#applyDelete-dynamic"},{"t":"WordType#bind","p":"class/WordType.html#bind-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"lib/Yatta.coffee~createYatta","p":"file/lib/Yatta.coffee.html#createYatta-"},{"t":"WordType#deleteText","p":"class/WordType.html#deleteText-dynamic"},{"t":"Yatta#getConnector","p":"class/Yatta.html#getConnector-dynamic"},{"t":"WordType#insertAfter","p":"class/WordType.html#insertAfter-dynamic"},{"t":"WordType#insertText","p":"class/WordType.html#insertText-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"JsonType#toJson","p":"class/JsonType.html#toJson-dynamic"},{"t":"WordType#toString","p":"class/WordType.html#toString-dynamic"},{"t":"WordType#val","p":"class/WordType.html#val-dynamic"},{"t":"JsonType#val","p":"class/JsonType.html#val-dynamic"}]
 | 
				
			||||||
@ -29,14 +29,6 @@
 | 
				
			|||||||
        <input type='text'>
 | 
					        <input type='text'>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <ul>
 | 
					      <ul>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/JsonType.html#_encode-dynamic' target='main' title='_encode'>
 | 
					 | 
				
			||||||
            #_encode
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (JsonType)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
 | 
					          <a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
 | 
				
			||||||
            #_encode
 | 
					            #_encode
 | 
				
			||||||
@ -45,6 +37,14 @@
 | 
				
			|||||||
            (WordType)
 | 
					            (WordType)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <a href='class/JsonType.html#_encode-dynamic' target='main' title='_encode'>
 | 
				
			||||||
 | 
					            #_encode
 | 
				
			||||||
 | 
					          </a>
 | 
				
			||||||
 | 
					          <small>
 | 
				
			||||||
 | 
					            (JsonType)
 | 
				
			||||||
 | 
					          </small>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='file/lib/ConnectorAdapter.coffee.html#adaptConnector-' target='main' title='adaptConnector'>
 | 
					          <a href='file/lib/ConnectorAdapter.coffee.html#adaptConnector-' target='main' title='adaptConnector'>
 | 
				
			||||||
            ~adaptConnector
 | 
					            ~adaptConnector
 | 
				
			||||||
@ -53,14 +53,6 @@
 | 
				
			|||||||
            (lib/ConnectorAdapter.coffee)
 | 
					            (lib/ConnectorAdapter.coffee)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
 | 
					 | 
				
			||||||
            #applyDelete
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (WordType)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
 | 
					          <a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
 | 
				
			||||||
            #applyDelete
 | 
					            #applyDelete
 | 
				
			||||||
@ -69,6 +61,14 @@
 | 
				
			|||||||
            (JsonType)
 | 
					            (JsonType)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
 | 
				
			||||||
 | 
					            #applyDelete
 | 
				
			||||||
 | 
					          </a>
 | 
				
			||||||
 | 
					          <small>
 | 
				
			||||||
 | 
					            (WordType)
 | 
				
			||||||
 | 
					          </small>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
 | 
					          <a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
 | 
				
			||||||
            #bind
 | 
					            #bind
 | 
				
			||||||
@ -101,6 +101,14 @@
 | 
				
			|||||||
            (Yatta)
 | 
					            (Yatta)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
 | 
				
			||||||
 | 
					            #constructor
 | 
				
			||||||
 | 
					          </a>
 | 
				
			||||||
 | 
					          <small>
 | 
				
			||||||
 | 
					            (JsonTypeWrapper)
 | 
				
			||||||
 | 
					          </small>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
 | 
					          <a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
 | 
				
			||||||
            #constructor
 | 
					            #constructor
 | 
				
			||||||
@ -110,11 +118,11 @@
 | 
				
			|||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
 | 
					          <a href='file/lib/Yatta.coffee.html#createYatta-' target='main' title='createYatta'>
 | 
				
			||||||
            #constructor
 | 
					            ~createYatta
 | 
				
			||||||
          </a>
 | 
					          </a>
 | 
				
			||||||
          <small>
 | 
					          <small>
 | 
				
			||||||
            (JsonTypeWrapper)
 | 
					            (lib/Yatta.coffee)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
@ -133,30 +141,6 @@
 | 
				
			|||||||
            (Yatta)
 | 
					            (Yatta)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
 | 
					 | 
				
			||||||
            #getHistoryBuffer
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#getSharedObject-dynamic' target='main' title='getSharedObject'>
 | 
					 | 
				
			||||||
            #getSharedObject
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#getUserId-dynamic' target='main' title='getUserId'>
 | 
					 | 
				
			||||||
            #getUserId
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#insertAfter-dynamic' target='main' title='insertAfter'>
 | 
					          <a href='class/WordType.html#insertAfter-dynamic' target='main' title='insertAfter'>
 | 
				
			||||||
            #insertAfter
 | 
					            #insertAfter
 | 
				
			||||||
@ -173,14 +157,6 @@
 | 
				
			|||||||
            (WordType)
 | 
					            (WordType)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#observe-dynamic' target='main' title='observe'>
 | 
					 | 
				
			||||||
            #observe
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#push-dynamic' target='main' title='push'>
 | 
					          <a href='class/WordType.html#push-dynamic' target='main' title='push'>
 | 
				
			||||||
            #push
 | 
					            #push
 | 
				
			||||||
@ -189,14 +165,6 @@
 | 
				
			|||||||
            (WordType)
 | 
					            (WordType)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
 | 
					 | 
				
			||||||
            #setMutableDefault
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/JsonType.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
 | 
					          <a href='class/JsonType.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
 | 
				
			||||||
            #setMutableDefault
 | 
					            #setMutableDefault
 | 
				
			||||||
@ -213,14 +181,6 @@
 | 
				
			|||||||
            (JsonType)
 | 
					            (JsonType)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#toJson-dynamic' target='main' title='toJson'>
 | 
					 | 
				
			||||||
            #toJson
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#toString-dynamic' target='main' title='toString'>
 | 
					          <a href='class/WordType.html#toString-dynamic' target='main' title='toString'>
 | 
				
			||||||
            #toString
 | 
					            #toString
 | 
				
			||||||
@ -229,22 +189,6 @@
 | 
				
			|||||||
            (WordType)
 | 
					            (WordType)
 | 
				
			||||||
          </small>
 | 
					          </small>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#unobserve-dynamic' target='main' title='unobserve'>
 | 
					 | 
				
			||||||
            #unobserve
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					 | 
				
			||||||
          <a href='class/Yatta.html#val-dynamic' target='main' title='val'>
 | 
					 | 
				
			||||||
            #val
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
          <small>
 | 
					 | 
				
			||||||
            (Yatta)
 | 
					 | 
				
			||||||
          </small>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
          <a href='class/WordType.html#val-dynamic' target='main' title='val'>
 | 
					          <a href='class/WordType.html#val-dynamic' target='main' title='val'>
 | 
				
			||||||
            #val
 | 
					            #val
 | 
				
			||||||
 | 
				
			|||||||
@ -22,8 +22,17 @@ You don't have to use the proposed user_id.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```js
 | 
					```js
 | 
				
			||||||
      console.log("me is number 2")
 | 
					      // console.log("me is number 1");
 | 
				
			||||||
      yatta = new Y.JsonYatta(2, Connector);
 | 
					      // yatta = new JsonYatta(1, Connector);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Though, it is recommended to use the user_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					      yatta = new Y.JsonYatta(user_id, Connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,18 +16,18 @@ run = require 'gulp-run'
 | 
				
			|||||||
ljs = require 'gulp-ljs'
 | 
					ljs = require 'gulp-ljs'
 | 
				
			||||||
plumber = require 'gulp-plumber'
 | 
					plumber = require 'gulp-plumber'
 | 
				
			||||||
mochaPhantomJS = require 'gulp-mocha-phantomjs'
 | 
					mochaPhantomJS = require 'gulp-mocha-phantomjs'
 | 
				
			||||||
 | 
					cache = require 'gulp-cached'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'default', ['lint', 'browser', 'test', 'literate', 'lib', 'codo']
 | 
					gulp.task 'default', ['deploy']
 | 
				
			||||||
gulp.task 'build', ['lint', 'browser']
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
files =
 | 
					files =
 | 
				
			||||||
  lib : ['./lib/**/*.coffee']
 | 
					  lib : ['./lib/**/*.coffee']
 | 
				
			||||||
  build : ['./build/**']
 | 
					  build : ['./build/**']
 | 
				
			||||||
  browser : './lib/Yatta.coffee'
 | 
					  browser : './lib/Yatta.coffee'
 | 
				
			||||||
  #test : ['./test/**/*_test.coffee']
 | 
					  #test : ['./test/**/*_test.coffee']
 | 
				
			||||||
  test : ['./test/JsonYatta_test.coffee']
 | 
					  test : ['./test/JsonYatta_test.coffee', './test/TextYatta_test.coffee']
 | 
				
			||||||
  gulp : ['./gulpfile.coffee']
 | 
					  gulp : ['./gulpfile.coffee']
 | 
				
			||||||
  examples : ['./examples/**/*.js']
 | 
					  examples : ['./examples/**/*.js']
 | 
				
			||||||
  other: ['./lib/**/*']
 | 
					  other: ['./lib/**/*']
 | 
				
			||||||
@ -37,7 +37,7 @@ for name,file_list of files
 | 
				
			|||||||
  if name isnt 'build'
 | 
					  if name isnt 'build'
 | 
				
			||||||
    files.all = files.all.concat file_list
 | 
					    files.all = files.all.concat file_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'lib', ->
 | 
					gulp.task 'deploy_nodejs', ->
 | 
				
			||||||
  gulp.src files.lib
 | 
					  gulp.src files.lib
 | 
				
			||||||
    .pipe sourcemaps.init()
 | 
					    .pipe sourcemaps.init()
 | 
				
			||||||
    .pipe coffee()
 | 
					    .pipe coffee()
 | 
				
			||||||
@ -45,7 +45,9 @@ gulp.task 'lib', ->
 | 
				
			|||||||
    .pipe gulp.dest 'build/node/'
 | 
					    .pipe gulp.dest 'build/node/'
 | 
				
			||||||
    .pipe gulpif '!**/', git.add({args : "-A"})
 | 
					    .pipe gulpif '!**/', git.add({args : "-A"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'browser', ->
 | 
					gulp.task 'deploy', ['mocha', 'build_browser', 'deploy_nodejs', 'lint', 'phantom_test', 'codo']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gulp.task 'build_browser', ->
 | 
				
			||||||
  gulp.src files.browser, { read: false }
 | 
					  gulp.src files.browser, { read: false }
 | 
				
			||||||
    .pipe plumber()
 | 
					    .pipe plumber()
 | 
				
			||||||
    .pipe browserify
 | 
					    .pipe browserify
 | 
				
			||||||
@ -69,12 +71,12 @@ gulp.task 'browser', ->
 | 
				
			|||||||
      extname: ".js"
 | 
					      extname: ".js"
 | 
				
			||||||
    .pipe gulp.dest './build/test'
 | 
					    .pipe gulp.dest './build/test'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'browser_test_watch', ['browser'], ->
 | 
					gulp.task 'watch', ['build_browser','mocha'], ->
 | 
				
			||||||
  gulp.watch files.all, ['browser']
 | 
					  gulp.watch files.all, ['build_browser', 'mocha']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					gulp.task 'mocha', ->
 | 
				
			||||||
gulp.task 'test', ->
 | 
					 | 
				
			||||||
  gulp.src files.test, { read: false }
 | 
					  gulp.src files.test, { read: false }
 | 
				
			||||||
 | 
					    .pipe plumber()
 | 
				
			||||||
    .pipe mocha {reporter : 'list'}
 | 
					    .pipe mocha {reporter : 'list'}
 | 
				
			||||||
    .pipe ignore.include '**/*.coffee'
 | 
					    .pipe ignore.include '**/*.coffee'
 | 
				
			||||||
    .pipe browserify
 | 
					    .pipe browserify
 | 
				
			||||||
@ -95,11 +97,6 @@ gulp.task 'lint', ->
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    .pipe coffeelint.reporter()
 | 
					    .pipe coffeelint.reporter()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'watch', ['default'], ->
 | 
					 | 
				
			||||||
  gulp.watch files.lib, ['build', 'test']
 | 
					 | 
				
			||||||
  gulp.watch files.test, ['test']
 | 
					 | 
				
			||||||
  gulp.watch files.examples, ['literate']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gulp.task 'phantom_watch', ['phantom_test'], ->
 | 
					gulp.task 'phantom_watch', ['phantom_test'], ->
 | 
				
			||||||
  gulp.watch files.all, ['phantom_test']
 | 
					  gulp.watch files.all, ['phantom_test']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -112,14 +109,11 @@ gulp.task 'literate', ->
 | 
				
			|||||||
    .pipe gulp.dest 'examples/'
 | 
					    .pipe gulp.dest 'examples/'
 | 
				
			||||||
    .pipe gulpif '!**/', git.add({args : "-A"})
 | 
					    .pipe gulpif '!**/', git.add({args : "-A"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'upload', [], ()->
 | 
					 | 
				
			||||||
  run('scp -r ./build ./examples jahns@manet.informatik.rwth-aachen.de:/home/jahns/public_html/collaborative_preview/').exec()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gulp.task 'codo', [], ()->
 | 
					gulp.task 'codo', [], ()->
 | 
				
			||||||
  command = 'codo -o "./doc" --name "Yatta!" --readme "README.md" --undocumented false --private true --title "Yatta! API" ./lib - LICENSE.txt '
 | 
					  command = 'codo -o "./doc" --name "Yatta!" --readme "README.md" --undocumented false --private true --title "Yatta! API" ./lib - LICENSE.txt '
 | 
				
			||||||
  run(command).exec()
 | 
					  run(command).exec()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gulp.task 'phantom_test', ['browser'], ()->
 | 
					gulp.task 'phantom_test', ['build_browser'], ()->
 | 
				
			||||||
  gulp.src 'build/test/index.html'
 | 
					  gulp.src 'build/test/index.html'
 | 
				
			||||||
    .pipe mochaPhantomJS()
 | 
					    .pipe mochaPhantomJS()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,7 @@ module.exports = (HB)->
 | 
				
			|||||||
    # @overload unobserve(event, f)
 | 
					    # @overload unobserve(event, f)
 | 
				
			||||||
    #   @param f     {Function} The function that you want to delete 
 | 
					    #   @param f     {Function} The function that you want to delete 
 | 
				
			||||||
    unobserve: (f)->
 | 
					    unobserve: (f)->
 | 
				
			||||||
      @event_listeners.filter (g)->
 | 
					      @event_listeners = @event_listeners.filter (g)->
 | 
				
			||||||
        f isnt g
 | 
					        f isnt g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
@ -59,7 +59,7 @@ module.exports = (HB)->
 | 
				
			|||||||
    #
 | 
					    #
 | 
				
			||||||
    # Fire an event.
 | 
					    # Fire an event.
 | 
				
			||||||
    # TODO: Do something with timeouts. You don't want this to fire for every operation (e.g. insert).
 | 
					    # TODO: Do something with timeouts. You don't want this to fire for every operation (e.g. insert).
 | 
				
			||||||
    #
 | 
					    # TODO: do you need callEvent+forwardEvent? Only one suffices probably
 | 
				
			||||||
    callEvent: ()->
 | 
					    callEvent: ()->
 | 
				
			||||||
      @forwardEvent @, arguments...
 | 
					      @forwardEvent @, arguments...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -215,8 +215,10 @@ module.exports = (HB)->
 | 
				
			|||||||
    #
 | 
					    #
 | 
				
			||||||
    execute: ()->
 | 
					    execute: ()->
 | 
				
			||||||
      if @validateSavedOperations()
 | 
					      if @validateSavedOperations()
 | 
				
			||||||
 | 
					        res = super
 | 
				
			||||||
 | 
					        if res
 | 
				
			||||||
          @deletes.applyDelete @
 | 
					          @deletes.applyDelete @
 | 
				
			||||||
        super
 | 
					        res
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        false
 | 
					        false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -275,7 +277,12 @@ module.exports = (HB)->
 | 
				
			|||||||
        garbagecollect = true
 | 
					        garbagecollect = true
 | 
				
			||||||
      super garbagecollect
 | 
					      super garbagecollect
 | 
				
			||||||
      if callLater
 | 
					      if callLater
 | 
				
			||||||
        @parent.callEvent "delete", @, o
 | 
					        @parent.callEvent [
 | 
				
			||||||
 | 
					              type: "insert"
 | 
				
			||||||
 | 
					              position: @getPosition()
 | 
				
			||||||
 | 
					              object: @parent # TODO: You can combine getPosition + getParent in a more efficient manner! (only left Delimiter will hold @parent)
 | 
				
			||||||
 | 
					              changed_by: o.uid.creator
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
      if @next_cl?.isDeleted()
 | 
					      if @next_cl?.isDeleted()
 | 
				
			||||||
        # garbage collect next_cl
 | 
					        # garbage collect next_cl
 | 
				
			||||||
        @next_cl.applyDelete()
 | 
					        @next_cl.applyDelete()
 | 
				
			||||||
@ -317,8 +324,7 @@ module.exports = (HB)->
 | 
				
			|||||||
    #
 | 
					    #
 | 
				
			||||||
    # @private
 | 
					    # @private
 | 
				
			||||||
    # Include this operation in the associative lists.
 | 
					    # Include this operation in the associative lists.
 | 
				
			||||||
    # @param fire_event {boolean} Whether to fire the insert-event.
 | 
					    execute: ()->
 | 
				
			||||||
    execute: (fire_event = true)->
 | 
					 | 
				
			||||||
      if not @validateSavedOperations()
 | 
					      if not @validateSavedOperations()
 | 
				
			||||||
        return false
 | 
					        return false
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
@ -336,7 +342,8 @@ module.exports = (HB)->
 | 
				
			|||||||
          #         therefore $this would be always to the right of o3
 | 
					          #         therefore $this would be always to the right of o3
 | 
				
			||||||
          # case 2: $origin < $o.origin
 | 
					          # case 2: $origin < $o.origin
 | 
				
			||||||
          #         if current $this insert_position > $o origin: $this ins
 | 
					          #         if current $this insert_position > $o origin: $this ins
 | 
				
			||||||
          #         else $insert_position will not change (maybe we encounter case 1 later, then this will be to the right of $o)
 | 
					          #         else $insert_position will not change
 | 
				
			||||||
 | 
					          #         (maybe we encounter case 1 later, then this will be to the right of $o)
 | 
				
			||||||
          # case 3: $origin > $o.origin
 | 
					          # case 3: $origin > $o.origin
 | 
				
			||||||
          #         $this insert_position is to the left of $o (forever!)
 | 
					          #         $this insert_position is to the left of $o (forever!)
 | 
				
			||||||
          while true
 | 
					          while true
 | 
				
			||||||
@ -369,13 +376,20 @@ module.exports = (HB)->
 | 
				
			|||||||
          @prev_cl.next_cl = @
 | 
					          @prev_cl.next_cl = @
 | 
				
			||||||
          @next_cl.prev_cl = @
 | 
					          @next_cl.prev_cl = @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        parent = @prev_cl?.getParent()
 | 
					        @setParent @prev_cl.getParent() # do Insertions always have a parent?
 | 
				
			||||||
        super # notify the execution_listeners
 | 
					        super # notify the execution_listeners
 | 
				
			||||||
        if parent? and fire_event
 | 
					        @callOperationSpecificEvents()
 | 
				
			||||||
          @setParent parent
 | 
					 | 
				
			||||||
          @parent.callEvent "insert", @
 | 
					 | 
				
			||||||
        @
 | 
					        @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    callOperationSpecificEvents: ()->
 | 
				
			||||||
 | 
					      @parent?.callEvent [
 | 
				
			||||||
 | 
					        type: "insert"
 | 
				
			||||||
 | 
					        position: @getPosition()
 | 
				
			||||||
 | 
					        object: @parent
 | 
				
			||||||
 | 
					        changed_by: @uid.creator
 | 
				
			||||||
 | 
					        value: @content
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Compute the position of this operation.
 | 
					    # Compute the position of this operation.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
 | 
				
			|||||||
@ -148,30 +148,31 @@ module.exports = (HB)->
 | 
				
			|||||||
              if not event.changed_by? and (event.type is "add" or event.type = "update")
 | 
					              if not event.changed_by? and (event.type is "add" or event.type = "update")
 | 
				
			||||||
                # this event is not created by Yatta.
 | 
					                # this event is not created by Yatta.
 | 
				
			||||||
                that.val(event.name, event.object[event.name])
 | 
					                that.val(event.name, event.object[event.name])
 | 
				
			||||||
          that.observe (event_name, property_name, op)->
 | 
					          @observe (events)->
 | 
				
			||||||
            if this is that and op.uid.creator isnt HB.getUserId()
 | 
					            for event in events
 | 
				
			||||||
 | 
					              if event.created_ isnt HB.getUserId()
 | 
				
			||||||
                notifier = Object.getNotifier(that.bound_json)
 | 
					                notifier = Object.getNotifier(that.bound_json)
 | 
				
			||||||
              oldVal = that.bound_json[property_name]
 | 
					                oldVal = that.bound_json[event.name]
 | 
				
			||||||
                if oldVal?
 | 
					                if oldVal?
 | 
				
			||||||
                  notifier.performChange 'update', ()->
 | 
					                  notifier.performChange 'update', ()->
 | 
				
			||||||
                    that.bound_json[property_name] = that.val(property_name)
 | 
					                      that.bound_json[event.name] = that.val(event.name)
 | 
				
			||||||
                    , that.bound_json
 | 
					                    , that.bound_json
 | 
				
			||||||
                  notifier.notify
 | 
					                  notifier.notify
 | 
				
			||||||
                    object: that.bound_json
 | 
					                    object: that.bound_json
 | 
				
			||||||
                    type: 'update'
 | 
					                    type: 'update'
 | 
				
			||||||
                  name: property_name
 | 
					                    name: event.name
 | 
				
			||||||
                    oldValue: oldVal
 | 
					                    oldValue: oldVal
 | 
				
			||||||
                  changed_by: op.uid.creator
 | 
					                    changed_by: event.changed_by
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                  notifier.performChange 'add', ()->
 | 
					                  notifier.performChange 'add', ()->
 | 
				
			||||||
                    that.bound_json[property_name] = that.val(property_name)
 | 
					                      that.bound_json[event.name] = that.val(event.name)
 | 
				
			||||||
                    , that.bound_json
 | 
					                    , that.bound_json
 | 
				
			||||||
                  notifier.notify
 | 
					                  notifier.notify
 | 
				
			||||||
                    object: that.bound_json
 | 
					                    object: that.bound_json
 | 
				
			||||||
                    type: 'add'
 | 
					                    type: 'add'
 | 
				
			||||||
                  name: property_name
 | 
					                    name: event.name
 | 
				
			||||||
                    oldValue: oldVal
 | 
					                    oldValue: oldVal
 | 
				
			||||||
                  changed_by: op.uid.creator
 | 
					                    changed_by:event.changed_by
 | 
				
			||||||
      @bound_json
 | 
					      @bound_json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
 | 
				
			|||||||
@ -110,7 +110,10 @@ module.exports = (HB)->
 | 
				
			|||||||
          uid_end.op_number = "#{uid_r.op_number}_end"
 | 
					          uid_end.op_number = "#{uid_r.op_number}_end"
 | 
				
			||||||
          beg = (new types.Delimiter uid_beg, undefined, uid_end).execute()
 | 
					          beg = (new types.Delimiter uid_beg, undefined, uid_end).execute()
 | 
				
			||||||
          end = (new types.Delimiter uid_end, beg, undefined).execute()
 | 
					          end = (new types.Delimiter uid_end, beg, undefined).execute()
 | 
				
			||||||
          @map_manager.map[@name] = new ReplaceManager uid_r, beg, end
 | 
					          event_properties =
 | 
				
			||||||
 | 
					            name: @name
 | 
				
			||||||
 | 
					          event_this = @map_manager
 | 
				
			||||||
 | 
					          @map_manager.map[@name] = new ReplaceManager event_properties, event_this, uid_r, beg, end
 | 
				
			||||||
          @map_manager.map[@name].setParent @map_manager, @name
 | 
					          @map_manager.map[@name].setParent @map_manager, @name
 | 
				
			||||||
          (@map_manager.map[@name].add_name_ops ?= []).push @
 | 
					          (@map_manager.map[@name].add_name_ops ?= []).push @
 | 
				
			||||||
          @map_manager.map[@name].execute()
 | 
					          @map_manager.map[@name].execute()
 | 
				
			||||||
@ -192,19 +195,24 @@ module.exports = (HB)->
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Retrieves the x-th not deleted element.
 | 
					    # Retrieves the x-th not deleted element.
 | 
				
			||||||
 | 
					    # e.g. "abc" : the 1th character is "a"
 | 
				
			||||||
 | 
					    # the 0th character is the left Delimiter
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    getOperationByPosition: (position)->
 | 
					    getOperationByPosition: (position)->
 | 
				
			||||||
      o = @beginning.next_cl
 | 
					      o = @beginning
 | 
				
			||||||
      if (position > 0 or o.isDeleted()) and not (o instanceof types.Delimiter)
 | 
					 | 
				
			||||||
        while o.isDeleted() and not (o instanceof types.Delimiter)
 | 
					 | 
				
			||||||
          # find first non deleted op
 | 
					 | 
				
			||||||
          o = o.next_cl
 | 
					 | 
				
			||||||
      while true
 | 
					      while true
 | 
				
			||||||
        # find the i-th op
 | 
					        # find the i-th op
 | 
				
			||||||
          if o instanceof types.Delimiter
 | 
					        if o instanceof types.Delimiter and o.prev_cl?
 | 
				
			||||||
 | 
					          # the user or you gave a position parameter that is to big
 | 
				
			||||||
 | 
					          # for the current array. Therefore we reach a Delimiter.
 | 
				
			||||||
 | 
					          # Then, we'll just return the last character.
 | 
				
			||||||
 | 
					          o = o.prev_cl
 | 
				
			||||||
 | 
					          while o.isDeleted() or not (o instanceof types.Delimiter)
 | 
				
			||||||
 | 
					            o = o.prev_cl
 | 
				
			||||||
          break
 | 
					          break
 | 
				
			||||||
        if position <= 0 and not o.isDeleted()
 | 
					        if position <= 0 and not o.isDeleted()
 | 
				
			||||||
          break
 | 
					          break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        o = o.next_cl
 | 
					        o = o.next_cl
 | 
				
			||||||
        if not o.isDeleted()
 | 
					        if not o.isDeleted()
 | 
				
			||||||
          position -= 1
 | 
					          position -= 1
 | 
				
			||||||
@ -220,12 +228,14 @@ module.exports = (HB)->
 | 
				
			|||||||
  #
 | 
					  #
 | 
				
			||||||
  class ReplaceManager extends ListManager
 | 
					  class ReplaceManager extends ListManager
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
 | 
					    # @param {Object} event_properties Decorates the event that is thrown by the RM
 | 
				
			||||||
 | 
					    # @param {Object} event_this The object on which the event shall be executed
 | 
				
			||||||
    # @param {Operation} initial_content Initialize this with a Replaceable that holds the initial_content.
 | 
					    # @param {Operation} initial_content Initialize this with a Replaceable that holds the initial_content.
 | 
				
			||||||
    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
 | 
					    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
 | 
				
			||||||
    # @param {Delimiter} beginning Reference or Object.
 | 
					    # @param {Delimiter} beginning Reference or Object.
 | 
				
			||||||
    # @param {Delimiter} end Reference or Object.
 | 
					    # @param {Delimiter} end Reference or Object.
 | 
				
			||||||
    # constructor: (uid, beginning, end, prev, next, origin)->
 | 
					    constructor: (@event_porperties, @event_this, uid, beginning, end, prev, next, origin)->
 | 
				
			||||||
    #  super uid, beginning, end, prev, next, origin
 | 
					      super uid, beginning, end, prev, next, origin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    type: "ReplaceManager"
 | 
					    type: "ReplaceManager"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -243,6 +253,21 @@ module.exports = (HB)->
 | 
				
			|||||||
    cleanup: ()->
 | 
					    cleanup: ()->
 | 
				
			||||||
      super()
 | 
					      super()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # This doesn't throw the same events as the ListManager. Therefore, the
 | 
				
			||||||
 | 
					    # Replaceables also not throw the same events.
 | 
				
			||||||
 | 
					    # So, ReplaceManager and ListManager both implement
 | 
				
			||||||
 | 
					    # these functions that are called when an Insertion is executed (at the end).
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    callEventDecorator: (events)->
 | 
				
			||||||
 | 
					      if not @isDeleted()
 | 
				
			||||||
 | 
					        for name,prop of @event_porperties
 | 
				
			||||||
 | 
					          for event in events
 | 
				
			||||||
 | 
					            event[name] = prop
 | 
				
			||||||
 | 
					        @event_this.callEvent events
 | 
				
			||||||
 | 
					      undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Replace the existing word with a new word.
 | 
					    # Replace the existing word with a new word.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
@ -278,7 +303,7 @@ module.exports = (HB)->
 | 
				
			|||||||
      if @prev_cl? and @next_cl?
 | 
					      if @prev_cl? and @next_cl?
 | 
				
			||||||
        json['prev'] = @prev_cl.getUid()
 | 
					        json['prev'] = @prev_cl.getUid()
 | 
				
			||||||
        json['next'] = @next_cl.getUid()
 | 
					        json['next'] = @next_cl.getUid()
 | 
				
			||||||
      if @origin? # and @origin isnt @prev_cl
 | 
					      if @origin? # TODO: do this everywhere: and @origin isnt @prev_cl
 | 
				
			||||||
        json["origin"] = @origin().getUid()
 | 
					        json["origin"] = @origin().getUid()
 | 
				
			||||||
      json
 | 
					      json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -334,23 +359,30 @@ module.exports = (HB)->
 | 
				
			|||||||
      super
 | 
					      super
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
 | 
					    # This is called, when the Insert-type was successfully executed.
 | 
				
			||||||
 | 
					    # TODO: consider doing this in a more consistent manner. This could also be
 | 
				
			||||||
 | 
					    # done with execute. But currently, there are no specital Insert-types for ListManager.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    execute: ()->
 | 
					    callOperationSpecificEvents: ()->
 | 
				
			||||||
      if not @validateSavedOperations()
 | 
					 | 
				
			||||||
        return false
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        # only fire 'insert-event' (which will result in addProperty and change events),
 | 
					 | 
				
			||||||
        # when content is added. 
 | 
					 | 
				
			||||||
        # In case of Json, empty content means that this is not the last update,
 | 
					 | 
				
			||||||
        # since content is deleted when 'applyDelete' was exectuted.
 | 
					 | 
				
			||||||
        ins_result = super(@content?) # @content? whether to fire or not
 | 
					 | 
				
			||||||
        if ins_result
 | 
					 | 
				
			||||||
      if @next_cl.type is "Delimiter" and @prev_cl.type isnt "Delimiter"
 | 
					      if @next_cl.type is "Delimiter" and @prev_cl.type isnt "Delimiter"
 | 
				
			||||||
 | 
					        # this replaces another Replaceable
 | 
				
			||||||
 | 
					        old_value = @prev_cl.content
 | 
				
			||||||
        @prev_cl.applyDelete()
 | 
					        @prev_cl.applyDelete()
 | 
				
			||||||
 | 
					        @parent.callEventDecorator [
 | 
				
			||||||
 | 
					          type: "update"
 | 
				
			||||||
 | 
					          changed_by: @uid.creator
 | 
				
			||||||
 | 
					          oldValue: old_value
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
      else if @next_cl.type isnt "Delimiter"
 | 
					      else if @next_cl.type isnt "Delimiter"
 | 
				
			||||||
 | 
					        # This will never be recognized by the user, because another
 | 
				
			||||||
 | 
					        # concurrent operation is set as the current value of the RM
 | 
				
			||||||
        @applyDelete()
 | 
					        @applyDelete()
 | 
				
			||||||
 | 
					      else # prev _and_ next are Delimiters. This is the first created Replaceable in the RM
 | 
				
			||||||
        return ins_result
 | 
					        @parent.callEventDecorator [
 | 
				
			||||||
 | 
					          type: "add"
 | 
				
			||||||
 | 
					          changed_by: @uid.creator
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Encode this operation in such a way that it can be parsed by remote peers.
 | 
					    # Encode this operation in such a way that it can be parsed by remote peers.
 | 
				
			||||||
 | 
				
			|||||||
@ -152,10 +152,10 @@ module.exports = (HB)->
 | 
				
			|||||||
    # @return {WordType} This WordType object.
 | 
					    # @return {WordType} This WordType object.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    insertText: (position, content)->
 | 
					    insertText: (position, content)->
 | 
				
			||||||
      # TODO: getOperationByPosition should return "(i-2)th" character
 | 
					      ith = @getOperationByPosition position
 | 
				
			||||||
      ith = @getOperationByPosition position # the (i-1)th character. e.g. "abc" a is the 0th character
 | 
					      # the (i-1)th character. e.g. "abc" the 1th character is "a"
 | 
				
			||||||
      left = ith.prev_cl # left is the non-deleted charather to the left of ith
 | 
					      # the 0th character is the left Delimiter
 | 
				
			||||||
      @insertAfter left, content
 | 
					      @insertAfter ith, content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # Deletes a part of the word.
 | 
					    # Deletes a part of the word.
 | 
				
			||||||
@ -163,7 +163,7 @@ module.exports = (HB)->
 | 
				
			|||||||
    # @return {WordType} This WordType object
 | 
					    # @return {WordType} This WordType object
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    deleteText: (position, length)->
 | 
					    deleteText: (position, length)->
 | 
				
			||||||
      o = @getOperationByPosition position
 | 
					      o = @getOperationByPosition(position+1) # position 0 in this case is the deletion of the first character
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      delete_ops = []
 | 
					      delete_ops = []
 | 
				
			||||||
      for i in [0...length]
 | 
					      for i in [0...length]
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										113
									
								
								lib/Yatta.coffee
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								lib/Yatta.coffee
									
									
									
									
									
								
							@ -4,107 +4,38 @@ HistoryBuffer = require "./HistoryBuffer"
 | 
				
			|||||||
Engine = require "./Engine"
 | 
					Engine = require "./Engine"
 | 
				
			||||||
adaptConnector = require "./ConnectorAdapter"
 | 
					adaptConnector = require "./ConnectorAdapter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					createYatta = (connector)->
 | 
				
			||||||
# Framework for Json data-structures.
 | 
					  user_id = connector.id # TODO: change to getUniqueId()
 | 
				
			||||||
# Known values that are supported:
 | 
					  HB = new HistoryBuffer user_id
 | 
				
			||||||
# * String
 | 
					  type_manager = json_types_uninitialized HB
 | 
				
			||||||
# * Integer
 | 
					  types = type_manager.types
 | 
				
			||||||
# * Array
 | 
					
 | 
				
			||||||
#
 | 
					  #
 | 
				
			||||||
class Yatta
 | 
					  # Framework for Json data-structures.
 | 
				
			||||||
 | 
					  # Known values that are supported:
 | 
				
			||||||
 | 
					  # * String
 | 
				
			||||||
 | 
					  # * Integer
 | 
				
			||||||
 | 
					  # * Array
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  class Yatta extends types.JsonType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
    # @param {String} user_id Unique id of the peer.
 | 
					    # @param {String} user_id Unique id of the peer.
 | 
				
			||||||
    # @param {Connector} Connector the connector class.
 | 
					    # @param {Connector} Connector the connector class.
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
  constructor: (@connector)->
 | 
					    constructor: ()->
 | 
				
			||||||
    user_id = @connector.id # TODO: change to getUniqueId()
 | 
					      @connector = connector
 | 
				
			||||||
    @HB = new HistoryBuffer user_id
 | 
					      @HB = HB
 | 
				
			||||||
    type_manager = json_types_uninitialized @HB
 | 
					      @types = types
 | 
				
			||||||
    @types = type_manager.types
 | 
					 | 
				
			||||||
      @engine = new Engine @HB, type_manager.parser
 | 
					      @engine = new Engine @HB, type_manager.parser
 | 
				
			||||||
    @HB.engine = @engine # TODO: !! only for debugging
 | 
					 | 
				
			||||||
      adaptConnector @connector, @engine, @HB, type_manager.execution_listener
 | 
					      adaptConnector @connector, @engine, @HB, type_manager.execution_listener
 | 
				
			||||||
    #first_word = 
 | 
					      super
 | 
				
			||||||
    @root_element = new @types.JsonType(@HB.getReservedUniqueIdentifier()).execute()
 | 
					 | 
				
			||||||
    ###
 | 
					 | 
				
			||||||
    uid_beg = @HB.getReservedUniqueIdentifier()
 | 
					 | 
				
			||||||
    uid_end = @HB.getReservedUniqueIdentifier()
 | 
					 | 
				
			||||||
    beg = (new @types.Delimiter uid_beg, undefined, uid_end).execute()
 | 
					 | 
				
			||||||
    end = (new @types.Delimiter uid_end, beg, undefined).execute()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @root_element = (new @types.ReplaceManager @HB.getReservedUniqueIdentifier(), beg, end).execute()
 | 
					 | 
				
			||||||
    @root_element.replace first_word, @HB.getReservedUniqueIdentifier()
 | 
					 | 
				
			||||||
    ###
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # @return JsonType
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  getSharedObject: ()->
 | 
					 | 
				
			||||||
    @root_element
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # Get the initialized connector.
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
    getConnector: ()->
 | 
					    getConnector: ()->
 | 
				
			||||||
      @connector
 | 
					      @connector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #
 | 
					  return new Yatta(HB.getReservedUniqueIdentifier()).execute()
 | 
				
			||||||
  # @see HistoryBuffer
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  getHistoryBuffer: ()->
 | 
					 | 
				
			||||||
    @HB
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #
 | 
					module.exports = createYatta
 | 
				
			||||||
  # @see JsonType.setMutableDefault
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  setMutableDefault: (mutable)->
 | 
					 | 
				
			||||||
    @getSharedObject().setMutableDefault(mutable)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # Get the UserId from the HistoryBuffer object.
 | 
					 | 
				
			||||||
  # In most cases this will be the same as the user_id value with which
 | 
					 | 
				
			||||||
  # Yatta was initialized (Depending on the HistoryBuffer implementation).
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  getUserId: ()->
 | 
					 | 
				
			||||||
    @HB.getUserId()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # @see JsonType.toJson
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  toJson : ()->
 | 
					 | 
				
			||||||
    @getSharedObject().toJson()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # @see JsonType.val
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  val : ()->
 | 
					 | 
				
			||||||
    @getSharedObject().val arguments...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # @see Operation.on
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  observe: ()->
 | 
					 | 
				
			||||||
    @getSharedObject().observe arguments...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # @see Operation.deleteListener
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  unobserve: ()->
 | 
					 | 
				
			||||||
    @getSharedObject().unobserve arguments...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # @see JsonType.value
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  Object.defineProperty Yatta.prototype, 'value',
 | 
					 | 
				
			||||||
    get : -> @getSharedObject().value
 | 
					 | 
				
			||||||
    set : (o)->
 | 
					 | 
				
			||||||
      if o.constructor is {}.constructor
 | 
					 | 
				
			||||||
        for o_name,o_obj of o
 | 
					 | 
				
			||||||
          @val(o_name, o_obj, 'immutable')
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        throw new Error "You must only set Object values!"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = Yatta
 | 
					 | 
				
			||||||
if window? and not window.Yatta?
 | 
					if window? and not window.Yatta?
 | 
				
			||||||
  window.Yatta = Yatta
 | 
					  window.Yatta = createYatta
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,7 @@
 | 
				
			|||||||
    "coffeeify": "^0.6.0",
 | 
					    "coffeeify": "^0.6.0",
 | 
				
			||||||
    "gulp": "^3.8.7",
 | 
					    "gulp": "^3.8.7",
 | 
				
			||||||
    "gulp-browserify": "^0.5.0",
 | 
					    "gulp-browserify": "^0.5.0",
 | 
				
			||||||
 | 
					    "gulp-cached": "^1.0.1",
 | 
				
			||||||
    "gulp-coffee": "^2.1.1",
 | 
					    "gulp-coffee": "^2.1.1",
 | 
				
			||||||
    "gulp-coffeelint": "^0.3.3",
 | 
					    "gulp-coffeelint": "^0.3.3",
 | 
				
			||||||
    "gulp-concat": "^2.3.4",
 | 
					    "gulp-concat": "^2.3.4",
 | 
				
			||||||
@ -57,6 +58,7 @@
 | 
				
			|||||||
    "gulp-run": "^1.6.3",
 | 
					    "gulp-run": "^1.6.3",
 | 
				
			||||||
    "gulp-sourcemaps": "^1.1.1",
 | 
					    "gulp-sourcemaps": "^1.1.1",
 | 
				
			||||||
    "gulp-uglify": "^0.3.1",
 | 
					    "gulp-uglify": "^0.3.1",
 | 
				
			||||||
 | 
					    "gulp-watch": "^3.0.0",
 | 
				
			||||||
    "jquery": "^2.1.1",
 | 
					    "jquery": "^2.1.1",
 | 
				
			||||||
    "mocha": "^1.21.4",
 | 
					    "mocha": "^1.21.4",
 | 
				
			||||||
    "sinon": "^1.10.2",
 | 
					    "sinon": "^1.10.2",
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ class JsonTest extends Test
 | 
				
			|||||||
  type: "JsonTest"
 | 
					  type: "JsonTest"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getRandomRoot: (user_num, root)->
 | 
					  getRandomRoot: (user_num, root)->
 | 
				
			||||||
    root ?= @users[user_num].getSharedObject()
 | 
					    root ?= @users[user_num]
 | 
				
			||||||
    types = @users[user_num].types
 | 
					    types = @users[user_num].types
 | 
				
			||||||
    if _.random(0,1) is 1 # take root
 | 
					    if _.random(0,1) is 1 # take root
 | 
				
			||||||
      root
 | 
					      root
 | 
				
			||||||
@ -98,7 +98,7 @@ describe "JsonFramework", ->
 | 
				
			|||||||
  ###
 | 
					  ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it "has a JsonTypeWrapper", ->
 | 
					  it "has a JsonTypeWrapper", ->
 | 
				
			||||||
    y = this.yTest.getSomeUser().getSharedObject()
 | 
					    y = this.yTest.getSomeUser()
 | 
				
			||||||
    y.val('x',"dtrn", 'immutable')
 | 
					    y.val('x',"dtrn", 'immutable')
 | 
				
			||||||
    y.val('set',{x:"x"}, 'immutable')
 | 
					    y.val('set',{x:"x"}, 'immutable')
 | 
				
			||||||
    w = y.value
 | 
					    w = y.value
 | 
				
			||||||
 | 
				
			|||||||
@ -13,12 +13,12 @@ module.exports = class Test
 | 
				
			|||||||
  constructor: (@name_suffix = "")->
 | 
					  constructor: (@name_suffix = "")->
 | 
				
			||||||
    @number_of_test_cases_multiplier = 1
 | 
					    @number_of_test_cases_multiplier = 1
 | 
				
			||||||
    @repeat_this = 1 * @number_of_test_cases_multiplier
 | 
					    @repeat_this = 1 * @number_of_test_cases_multiplier
 | 
				
			||||||
    @doSomething_amount = 50 + @number_of_test_cases_multiplier
 | 
					    @doSomething_amount = 50 * @number_of_test_cases_multiplier
 | 
				
			||||||
    @number_of_engines = 5 + @number_of_test_cases_multiplier - 1
 | 
					    @number_of_engines = 4 + @number_of_test_cases_multiplier - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @time = 0
 | 
					    @time = 0 # denotes to the time when run was started
 | 
				
			||||||
    @ops = 0
 | 
					    @ops = 0 # number of operations (used with @time)
 | 
				
			||||||
    @time_now = 0
 | 
					    @time_now = 0 # current time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @debug = false
 | 
					    @debug = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -85,11 +85,6 @@ module.exports = class Test
 | 
				
			|||||||
            ops1 = y.deleteText pos, length
 | 
					            ops1 = y.deleteText pos, length
 | 
				
			||||||
          undefined
 | 
					          undefined
 | 
				
			||||||
        types : [types.WordType]
 | 
					        types : [types.WordType]
 | 
				
			||||||
      ,
 | 
					 | 
				
			||||||
        f : (y)=> # REPLACE TEXT
 | 
					 | 
				
			||||||
          y.replaceText @getRandomText()
 | 
					 | 
				
			||||||
          null
 | 
					 | 
				
			||||||
        types: [types.WordType]
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  getRandomRoot: (user_num)->
 | 
					  getRandomRoot: (user_num)->
 | 
				
			||||||
    throw new Error "overwrite me!"
 | 
					    throw new Error "overwrite me!"
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ _         = require("underscore")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
chai.use(sinonChai)
 | 
					chai.use(sinonChai)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Y = require "../lib/index"
 | 
					Yatta = require "../lib/Yatta"
 | 
				
			||||||
Connector = require "../bower_components/connector/lib/test-connector/test-connector.coffee"
 | 
					Connector = require "../bower_components/connector/lib/test-connector/test-connector.coffee"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Test = require "./TestSuite"
 | 
					Test = require "./TestSuite"
 | 
				
			||||||
@ -15,14 +15,17 @@ class TextTest extends Test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  type: "TextTest"
 | 
					  type: "TextTest"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  makeNewUser: (user, conn)->
 | 
					  makeNewUser: (userId)->
 | 
				
			||||||
    super new Y.TextFramework user, conn
 | 
					    conn = new Connector userId
 | 
				
			||||||
 | 
					    y = new Yatta conn
 | 
				
			||||||
 | 
					    y.val("TextTest","","mutable")
 | 
				
			||||||
 | 
					    y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getRandomRoot: (user_num)->
 | 
					  getRandomRoot: (user_num)->
 | 
				
			||||||
    @users[user_num].getSharedObject()
 | 
					    @users[user_num].val("TextTest")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getContent: (user_num)->
 | 
					  getContent: (user_num)->
 | 
				
			||||||
    @users[user_num].val()
 | 
					    @users[user_num].val("TextTest").val()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe "TextFramework", ->
 | 
					describe "TextFramework", ->
 | 
				
			||||||
  beforeEach (done)->
 | 
					  beforeEach (done)->
 | 
				
			||||||
@ -35,13 +38,81 @@ describe "TextFramework", ->
 | 
				
			|||||||
    done()
 | 
					    done()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it "simple multi-char insert", ->
 | 
					  it "simple multi-char insert", ->
 | 
				
			||||||
    u = @yTest.users[0]
 | 
					    u = @yTest.users[0].val("TextTest")
 | 
				
			||||||
    u.insertText 0, "abc"
 | 
					    u.insertText 0, "abc"
 | 
				
			||||||
    u = @yTest.users[1]
 | 
					    u = @yTest.users[1].val("TextTest")
 | 
				
			||||||
    u.insertText 0, "xyz"
 | 
					    u.insertText 0, "xyz"
 | 
				
			||||||
    @yTest.compareAll()
 | 
					    @yTest.compareAll()
 | 
				
			||||||
    expect(u.val()).to.equal("abcxyz")
 | 
					    expect(u.val()).to.equal("abcxyz")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it "Observers work on shared Text (insert type observers, local and foreign)", ->
 | 
				
			||||||
 | 
					    u = @yTest.users[0].val("TextTest","my awesome Text").val("TextTest")
 | 
				
			||||||
 | 
					    @yTest.flushAll()
 | 
				
			||||||
 | 
					    last_task = null
 | 
				
			||||||
 | 
					    observer1 = (changes)->
 | 
				
			||||||
 | 
					      expect(changes.length).to.equal(1)
 | 
				
			||||||
 | 
					      change = changes[0]
 | 
				
			||||||
 | 
					      expect(change.type).to.equal("insert")
 | 
				
			||||||
 | 
					      expect(change.object).to.equal(u)
 | 
				
			||||||
 | 
					      expect(change.value).to.equal("a")
 | 
				
			||||||
 | 
					      expect(change.position).to.equal(1)
 | 
				
			||||||
 | 
					      expect(change.changed_by).to.equal('0')
 | 
				
			||||||
 | 
					      last_task = "observer1"
 | 
				
			||||||
 | 
					    u.observe observer1
 | 
				
			||||||
 | 
					    u.insertText 1, "a"
 | 
				
			||||||
 | 
					    expect(last_task).to.equal("observer1")
 | 
				
			||||||
 | 
					    u.unobserve observer1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    observer2 = (changes)->
 | 
				
			||||||
 | 
					      expect(changes.length).to.equal(1)
 | 
				
			||||||
 | 
					      change = changes[0]
 | 
				
			||||||
 | 
					      expect(change.type).to.equal("insert")
 | 
				
			||||||
 | 
					      expect(change.object).to.equal(u)
 | 
				
			||||||
 | 
					      expect(change.value).to.equal("x")
 | 
				
			||||||
 | 
					      expect(change.position).to.equal(0)
 | 
				
			||||||
 | 
					      expect(change.changed_by).to.equal('1')
 | 
				
			||||||
 | 
					      last_task = "observer2"
 | 
				
			||||||
 | 
					    u.observe observer2
 | 
				
			||||||
 | 
					    v = @yTest.users[1].val("TextTest")
 | 
				
			||||||
 | 
					    v.insertText 0, "x"
 | 
				
			||||||
 | 
					    @yTest.flushAll()
 | 
				
			||||||
 | 
					    expect(last_task).to.equal("observer2")
 | 
				
			||||||
 | 
					    u.unobserve observer2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it "Observers work on shared Text (delete type observers, local and foreign)", ->
 | 
				
			||||||
 | 
					    u = @yTest.users[0].val("TextTest","my awesome Text").val("TextTest")
 | 
				
			||||||
 | 
					    @yTest.flushAll()
 | 
				
			||||||
 | 
					    last_task = null
 | 
				
			||||||
 | 
					    observer1 = (changes)->
 | 
				
			||||||
 | 
					      expect(changes.length).to.equal(1)
 | 
				
			||||||
 | 
					      change = changes[0]
 | 
				
			||||||
 | 
					      expect(change.type).to.equal("delete")
 | 
				
			||||||
 | 
					      expect(change.object).to.equal(u)
 | 
				
			||||||
 | 
					      expect(change.position).to.equal(1)
 | 
				
			||||||
 | 
					      expect(change.length).to.equal(1)
 | 
				
			||||||
 | 
					      expect(change.changed_by).to.equal('0')
 | 
				
			||||||
 | 
					      last_task = "observer1"
 | 
				
			||||||
 | 
					    u.observe observer1
 | 
				
			||||||
 | 
					    u.deleteText 1
 | 
				
			||||||
 | 
					    expect(last_task).to.equal("observer1")
 | 
				
			||||||
 | 
					    u.unobserve observer1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    observer2 = (changes)->
 | 
				
			||||||
 | 
					      expect(changes.length).to.equal(1)
 | 
				
			||||||
 | 
					      change = changes[0]
 | 
				
			||||||
 | 
					      expect(change.type).to.equal("delete")
 | 
				
			||||||
 | 
					      expect(change.object).to.equal(u)
 | 
				
			||||||
 | 
					      expect(change.position).to.equal(0)
 | 
				
			||||||
 | 
					      expect(change.length).to.equal(0)
 | 
				
			||||||
 | 
					      expect(change.changed_by).to.equal('1')
 | 
				
			||||||
 | 
					      last_task = "observer2"
 | 
				
			||||||
 | 
					    u.observe observer2
 | 
				
			||||||
 | 
					    v = @yTest.users[1].val("TextTest")
 | 
				
			||||||
 | 
					    v.deleteText 0
 | 
				
			||||||
 | 
					    @yTest.flushAll()
 | 
				
			||||||
 | 
					    expect(last_task).to.equal("observer2")
 | 
				
			||||||
 | 
					    u.unobserve observer2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it "can handle many engines, many operations, concurrently (random)", ->
 | 
					  it "can handle many engines, many operations, concurrently (random)", ->
 | 
				
			||||||
    @yTest.run()
 | 
					    @yTest.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user