From f348ca8f5e118c19002b8ccfc966c168040e6cd5 Mon Sep 17 00:00:00 2001
From: Kevin Jahns <kevin.jahns@rwth-aachen.de>
Date: Sat, 16 Aug 2014 06:20:45 +0200
Subject: [PATCH] fixed README

---
 README.md                         | 4 ++--
 build/node/Types/TextTypes.js     | 2 +-
 build/node/Types/TextTypes.js.map | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 25581d66..d69f4aaf 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,8 @@ Yatta! provides similar functionality as [ShareJs](https://github.com/share/Shar
 but does not require you to understand how the internals work. The predefined data structures provide a simple API to access your shared data structures.
 
 Predefined data structures:
-* Text - [Collaborative Text Editing Example](./examples/TextEditing/)
-* Json - [example](./examples/Json/)
+* Text - [Collaborative Text Editing Example](http://dadamonad.github.io/Yatta/examples/TextEditing/) and [example code](./examples/TextEditing/)
+* Json - [example code](./examples/Json/)
 * XML (coming soon)
 
 Unlike other frameworks, Yatta! supports P2P message propagation and is not bound to a specific communication protocol.
diff --git a/build/node/Types/TextTypes.js b/build/node/Types/TextTypes.js
index 08c0f8da..673d9f53 100644
--- a/build/node/Types/TextTypes.js
+++ b/build/node/Types/TextTypes.js
@@ -1,2 +1,2 @@
-(function(){var e,t={}.hasOwnProperty,n=function(e,n){function r(){this.constructor=e}for(var i in n)t.call(n,i)&&(e[i]=n[i]);return r.prototype=n.prototype,e.prototype=new r,e.__super__=n.prototype,e};e=require("./StructuredTypes"),module.exports=function(t){var r,i,o,l,s,a;return s=e(t),a=s.types,l=s.parser,r=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return n(t,e),t}(a.Delete),l.TextDelete=l.Delete,i=function(e){function t(e,n,r,i,o){if(this.content=e,null==r||null==i)throw new Error("You must define prev, and next for TextInsert-types!");t.__super__.constructor.call(this,n,r,i,o)}return n(t,e),t.prototype.getLength=function(){return this.isDeleted()?0:this.content.length},t.prototype.val=function(){return this.isDeleted()?"":this.content},t.prototype._encode=function(){var e;return e={type:"TextInsert",content:this.content,uid:this.getUid(),prev:this.prev_cl.getUid(),next:this.next_cl.getUid()},null!=this.origin&&this.origin!==this.prev_cl&&(e.origin=this.origin.getUid()),e},t}(a.Insert),l.TextInsert=function(e){var t,n,r,o,l;return t=e.content,l=e.uid,o=e.prev,n=e.next,r=e.origin,new i(t,l,o,n,r)},o=function(e){function o(e,t,n,r,i,l){o.__super__.constructor.call(this,e,t,n,r,i,l)}return n(o,e),o.prototype.insertText=function(e,n){var r,o,l,s,a,u;for(o=this.getOperationByPosition(e),u=[],s=0,a=n.length;a>s;s++)r=n[s],l=new i(r,void 0,o.prev_cl,o),u.push(t.addOperation(l).execute());return u},o.prototype.deleteText=function(e,n){var i,o,l,s,u,c;for(s=this.getOperationByPosition(e),o=[],c=[],l=u=0;n>=0?n>u:u>n;l=n>=0?++u:--u){for(i=t.addOperation(new r(void 0,s)).execute(),s=s.next_cl;s.isDeleted()&&!(s instanceof a.Delimiter);){if(s instanceof a.Delimiter)throw new Error("You can't delete more than there is..");s=s.next_cl}if(o.push(i._encode()),s instanceof a.Delimiter)break;c.push(void 0)}return c},o.prototype.replaceText=function(e){var n;if(null!=this.replace_manager)return n=t.addOperation(new o(void 0)).execute(),n.insertText(0,e),this.replace_manager.replace(n);throw new Error("This type is currently not maintained by a ReplaceManager!")},o.prototype.val=function(){var e,t;return e=function(){var e,n,r,i;for(r=this.toArray(),i=[],e=0,n=r.length;n>e;e++)t=r[e],i.push(null!=t.val?t.val():"");return i}.call(this),e.join("")},o.prototype.setReplaceManager=function(e){return this.saveOperation("replace_manager",e),this.validateSavedOperations},o.prototype.bind=function(e){var n;return n=this,e.value=this.val(),this.on("insert",function(r,i){var o,l,s,a;return i.creator!==t.getUserId()?(s=i.getPosition(),o=function(e){return s>=e?e:e+=1},l=o(e.selectionStart),a=o(e.selectionEnd),e.value=n.val(),e.setSelectionRange(l,a)):void 0}),this.on("delete",function(t,r){var i,o,l,s;return l=r.getPosition(),i=function(e){return l>e?e:e-=1},o=i(e.selectionStart),s=i(e.selectionEnd),e.value=n.val(),e.setSelectionRange(o,s)}),e.onkeypress=function(t){var r,i,o;return r=String.fromCharCode(t.keyCode),r.length>0?(console.log(r),o=Math.min(e.selectionStart,e.selectionEnd),i=Math.abs(e.selectionEnd-e.selectionStart),n.deleteText(o,i),n.insertText(o,r)):t.preventDefault()},e.onkeydown=function(t){var r,i,o,l,s;if(l=Math.min(e.selectionStart,e.selectionEnd),i=Math.abs(e.selectionEnd-e.selectionStart),null!=t.keyCode&&8===t.keyCode){if(i>0)n.deleteText(l,i);else if(null!=t.ctrlKey&&t.ctrlKey){for(s=e.value,o=l,r=0,l>0&&(o--,r++);o>0&&" "!==s[o]&&"\n"!==s[o];)o--,r++;n.deleteText(o,l-o),e.setSelectionRange(o,o)}else n.deleteText(l-1,1);return t.preventDefault()}return null!=t.keyCode&&46===t.keyCode?(i>0?n.deleteText(l,i):n.deleteText(l,1),t.preventDefault()):void 0}},o.prototype._encode=function(){var e;return e={type:"Word",uid:this.getUid(),beginning:this.beginning.getUid(),end:this.end.getUid()},null!=this.prev_cl&&(e.prev=this.prev_cl.getUid()),null!=this.next_cl&&(e.next=this.next_cl.getUid()),null!=this.origin&&this.origin!==this.prev_cl&&(e.origin=this.origin.getUid()),e},o}(a.ListManager),l.Word=function(e){var t,n,r,i,l,s;return s=e.uid,t=e.beginning,n=e.end,l=e.prev,r=e.next,i=e.origin,new o(s,t,n,l,r,i)},a.TextInsert=i,a.TextDelete=r,a.Word=o,s}}).call(this);
+(function(){var e,t={}.hasOwnProperty,n=function(e,n){function r(){this.constructor=e}for(var i in n)t.call(n,i)&&(e[i]=n[i]);return r.prototype=n.prototype,e.prototype=new r,e.__super__=n.prototype,e};e=require("./StructuredTypes"),module.exports=function(t){var r,i,o,l,s,a;return s=e(t),a=s.types,l=s.parser,r=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return n(t,e),t}(a.Delete),l.TextDelete=l.Delete,i=function(e){function t(e,n,r,i,o){if(this.content=e,null==r||null==i)throw new Error("You must define prev, and next for TextInsert-types!");t.__super__.constructor.call(this,n,r,i,o)}return n(t,e),t.prototype.getLength=function(){return this.isDeleted()?0:this.content.length},t.prototype.val=function(){return this.isDeleted()?"":this.content},t.prototype._encode=function(){var e;return e={type:"TextInsert",content:this.content,uid:this.getUid(),prev:this.prev_cl.getUid(),next:this.next_cl.getUid()},null!=this.origin&&this.origin!==this.prev_cl&&(e.origin=this.origin.getUid()),e},t}(a.Insert),l.TextInsert=function(e){var t,n,r,o,l;return t=e.content,l=e.uid,o=e.prev,n=e.next,r=e.origin,new i(t,l,o,n,r)},o=function(e){function o(e,t,n,r,i,l){o.__super__.constructor.call(this,e,t,n,r,i,l)}return n(o,e),o.prototype.insertText=function(e,n){var r,o,l,s,a,u;for(o=this.getOperationByPosition(e),u=[],s=0,a=n.length;a>s;s++)r=n[s],l=new i(r,void 0,o.prev_cl,o),u.push(t.addOperation(l).execute());return u},o.prototype.deleteText=function(e,n){var i,o,l,s,u,c;for(s=this.getOperationByPosition(e),o=[],c=[],l=u=0;n>=0?n>u:u>n;l=n>=0?++u:--u){for(i=t.addOperation(new r(void 0,s)).execute(),s=s.next_cl;s.isDeleted()&&!(s instanceof a.Delimiter);){if(s instanceof a.Delimiter)throw new Error("You can't delete more than there is..");s=s.next_cl}if(o.push(i._encode()),s instanceof a.Delimiter)break;c.push(void 0)}return c},o.prototype.replaceText=function(e){var n;if(null!=this.replace_manager)return n=t.addOperation(new o(void 0)).execute(),n.insertText(0,e),this.replace_manager.replace(n);throw new Error("This type is currently not maintained by a ReplaceManager!")},o.prototype.val=function(){var e,t;return e=function(){var e,n,r,i;for(r=this.toArray(),i=[],e=0,n=r.length;n>e;e++)t=r[e],i.push(null!=t.val?t.val():"");return i}.call(this),e.join("")},o.prototype.setReplaceManager=function(e){return this.saveOperation("replace_manager",e),this.validateSavedOperations},o.prototype.bind=function(e){var t;return t=this,e.value=this.val(),this.on("insert",function(n,r){var i,o,l,s;return l=r.getPosition(),i=function(e){return l>=e?e:e+=1},o=i(e.selectionStart),s=i(e.selectionEnd),e.value=t.val(),e.setSelectionRange(o,s)}),this.on("delete",function(n,r){var i,o,l,s;return l=r.getPosition(),i=function(e){return l>e?e:e-=1},o=i(e.selectionStart),s=i(e.selectionEnd),e.value=t.val(),e.setSelectionRange(o,s)}),e.onkeypress=function(n){var r,i,o,l;return r=String.fromCharCode(n.keyCode),r.length>0?(console.log(r),l=Math.min(e.selectionStart,e.selectionEnd),i=Math.abs(e.selectionEnd-e.selectionStart),t.deleteText(l,i),t.insertText(l,r),o=l+r.length,e.setSelectionRange(o,o),n.preventDefault()):n.preventDefault()},e.onkeydown=function(n){var r,i,o,l,s;if(l=Math.min(e.selectionStart,e.selectionEnd),i=Math.abs(e.selectionEnd-e.selectionStart),null!=n.keyCode&&8===n.keyCode){if(i>0)t.deleteText(l,i);else if(null!=n.ctrlKey&&n.ctrlKey){for(s=e.value,o=l,r=0,l>0&&(o--,r++);o>0&&" "!==s[o]&&"\n"!==s[o];)o--,r++;t.deleteText(o,l-o),e.setSelectionRange(o,o)}else t.deleteText(l-1,1);return n.preventDefault()}return null!=n.keyCode&&46===n.keyCode?(i>0?t.deleteText(l,i):t.deleteText(l,1),n.preventDefault()):void 0}},o.prototype._encode=function(){var e;return e={type:"Word",uid:this.getUid(),beginning:this.beginning.getUid(),end:this.end.getUid()},null!=this.prev_cl&&(e.prev=this.prev_cl.getUid()),null!=this.next_cl&&(e.next=this.next_cl.getUid()),null!=this.origin&&this.origin!==this.prev_cl&&(e.origin=this.origin.getUid()),e},o}(a.ListManager),l.Word=function(e){var t,n,r,i,l,s;return s=e.uid,t=e.beginning,n=e.end,l=e.prev,r=e.next,i=e.origin,new o(s,t,n,l,r,i)},a.TextInsert=i,a.TextDelete=r,a.Word=o,s}}).call(this);
 //# sourceMappingURL=../Types/TextTypes.js.map
\ No newline at end of file
diff --git a/build/node/Types/TextTypes.js.map b/build/node/Types/TextTypes.js.map
index 2d0b5be5..75f997c2 100755
--- a/build/node/Types/TextTypes.js.map
+++ b/build/node/Types/TextTypes.js.map
@@ -1 +1 @@
-{"version":3,"file":"Types/TextTypes.js","sources":["Types/TextTypes.coffee"],"names":[],"mappings":"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","sourcesContent":["structured_types_uninitialized = require \"./StructuredTypes\"\n\nmodule.exports = (HB)->\n  structured_types = structured_types_uninitialized HB\n  types = structured_types.types\n  parser = structured_types.parser\n\n  #\n  # At the moment TextDelete type equals the Delete type in BasicTypes.\n  # @see BasicTypes.Delete\n  #\n  class TextDelete extends types.Delete\n  parser[\"TextDelete\"] = parser[\"Delete\"]\n\n  #\n  #  Extends the basic Insert type to an operation that holds a text value\n  #\n  class TextInsert extends types.Insert\n    #\n    # @param {String} content The content of this Insert-type Operation. Usually you restrict the length of content to size 1\n    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.\n    #\n    constructor: (@content, uid, prev, next, origin)->\n      if not (prev? and next?)\n        throw new Error \"You must define prev, and next for TextInsert-types!\"\n      super uid, prev, next, origin\n    #\n    # Retrieve the effective length of the $content of this operation.\n    #\n    getLength: ()->\n      if @isDeleted()\n        0\n      else\n        @content.length\n\n    #\n    # The result will be concatenated with the results from the other insert operations\n    # in order to retrieve the content of the engine.\n    # @see HistoryBuffer.toExecutedArray\n    #\n    val: (current_position)->\n      if @isDeleted()\n        \"\"\n      else\n        @content\n\n    #\n    # Convert all relevant information of this operation to the json-format.\n    # This result can be send to other clients.\n    #\n    _encode: ()->\n      json =\n        {\n          'type': \"TextInsert\"\n          'content': @content\n          'uid' : @getUid()\n          'prev': @prev_cl.getUid()\n          'next': @next_cl.getUid()\n        }\n      if @origin? and @origin isnt @prev_cl\n        json[\"origin\"] = @origin.getUid()\n      json\n\n  parser[\"TextInsert\"] = (json)->\n    {\n      'content' : content\n      'uid' : uid\n      'prev': prev\n      'next': next\n      'origin' : origin\n    } = json\n    new TextInsert content, uid, prev, next, origin\n\n  #\n  # Handles a Text-like data structures with support for insertText/deleteText at a word-position.\n  #\n  class Word extends types.ListManager\n\n    #\n    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.\n    #\n    constructor: (uid, beginning, end, prev, next, origin)->\n      super uid, beginning, end, prev, next, origin\n\n    #\n    # Inserts a string into the word\n    #\n    insertText: (position, content)->\n      o = @getOperationByPosition position\n      for c in content\n        op = new TextInsert c, undefined, o.prev_cl, o\n        HB.addOperation(op).execute()\n\n    #\n    # Deletes a part of the word.\n    #\n    deleteText: (position, length)->\n      o = @getOperationByPosition position\n\n      delete_ops = []\n      for i in [0...length]\n        d = HB.addOperation(new TextDelete undefined, o).execute()\n        o = o.next_cl\n        while o.isDeleted() and not (o instanceof types.Delimiter)\n          if o instanceof types.Delimiter\n            throw new Error \"You can't delete more than there is..\"\n          o = o.next_cl\n        delete_ops.push d._encode()\n        if o instanceof types.Delimiter\n          break\n\n\n    #\n    # Replace the content of this word with another one. Concurrent replacements are not merged!\n    # Only one of the replacements will be used.\n    #\n    # Can only be used if the ReplaceManager was set!\n    # @see Word.setReplaceManager\n    #\n    replaceText: (text)->\n      if @replace_manager?\n        word = HB.addOperation(new Word undefined).execute()\n        word.insertText 0, text\n        @replace_manager.replace(word)\n      else\n        throw new Error \"This type is currently not maintained by a ReplaceManager!\"\n\n    #\n    # @returns [Json] A Json object.\n    #\n    val: ()->\n      c = for o in @toArray()\n        if o.val?\n          o.val()\n        else\n          \"\"\n      c.join('')\n\n    #\n    # In most cases you would embed a Word in a Replaceable, wich is handled by the ReplaceManager in order\n    # to provide replace functionality.\n    #\n    setReplaceManager: (op)->\n      @saveOperation 'replace_manager', op\n      @validateSavedOperations\n\n    #\n    # Bind this Word to a textfield.\n    #\n    bind: (textfield)->\n      word = @\n      textfield.value = @val()\n\n      @on \"insert\", (event, op)->\n        if op.creator isnt HB.getUserId()\n          o_pos = op.getPosition()\n          fix = (cursor)->\n            if cursor <= o_pos\n              cursor\n            else\n              cursor += 1\n              cursor\n          left = fix textfield.selectionStart\n          right = fix textfield.selectionEnd\n\n          textfield.value = word.val()\n          textfield.setSelectionRange left, right\n\n\n      @on \"delete\", (event, op)->\n        o_pos = op.getPosition()\n        fix = (cursor)->\n          if cursor < o_pos\n            cursor\n          else\n            cursor -= 1\n            cursor\n        left = fix textfield.selectionStart\n        right = fix textfield.selectionEnd\n\n        textfield.value = word.val()\n        textfield.setSelectionRange left, right\n\n      # consume all text-insert changes.\n      textfield.onkeypress = (event)->\n        char = String.fromCharCode event.keyCode\n        if char.length > 0\n          console.log char\n          pos = Math.min textfield.selectionStart, textfield.selectionEnd\n          diff = Math.abs(textfield.selectionEnd - textfield.selectionStart)\n          word.deleteText pos, diff\n          word.insertText pos, char\n        else\n          event.preventDefault()\n\n      #\n      # consume deletes. Note that\n      #   chrome: won't consume deletions on keypress event.\n      #   keyCode is deprecated. BUT: I don't see another way.\n      #     since event.key is not implemented in the current version of chrome.\n      #     Every browser supports keyCode. Let's stick with it for now..\n      #\n      textfield.onkeydown = (event)->\n        pos = Math.min textfield.selectionStart, textfield.selectionEnd\n        diff = Math.abs(textfield.selectionEnd - textfield.selectionStart)\n        if event.keyCode? and event.keyCode is 8\n          if diff > 0\n            word.deleteText pos, diff\n          else\n            if event.ctrlKey? and event.ctrlKey\n              val = textfield.value\n              new_pos = pos\n              del_length = 0\n              if pos > 0\n                new_pos--\n                del_length++\n              while new_pos > 0 and val[new_pos] isnt \" \" and val[new_pos] isnt '\\n'\n                new_pos--\n                del_length++\n              word.deleteText new_pos, (pos-new_pos)\n              textfield.setSelectionRange new_pos, new_pos\n            else\n              word.deleteText (pos-1), 1\n          event.preventDefault()\n        else if event.keyCode? and event.keyCode is 46\n          if diff > 0\n            word.deleteText pos, diff\n          else\n            word.deleteText pos, 1\n          event.preventDefault()\n\n\n\n    #\n    # Encode this operation in such a way that it can be parsed by remote peers.\n    #\n    _encode: ()->\n      json = {\n        'type': \"Word\"\n        'uid' : @getUid()\n        'beginning' : @beginning.getUid()\n        'end' : @end.getUid()\n      }\n      if @prev_cl?\n        json['prev'] = @prev_cl.getUid()\n      if @next_cl?\n        json['next'] = @next_cl.getUid()\n      if @origin? and @origin isnt @prev_cl\n        json[\"origin\"] = @origin.getUid()\n      json\n\n  parser['Word'] = (json)->\n    {\n      'uid' : uid\n      'beginning' : beginning\n      'end' : end\n      'prev': prev\n      'next': next\n      'origin' : origin\n    } = json\n    new Word uid, beginning, end, prev, next, origin\n\n  types['TextInsert'] = TextInsert\n  types['TextDelete'] = TextDelete\n  types['Word'] = Word\n  structured_types\n\n\n"],"sourceRoot":"/source/"}
\ No newline at end of file
+{"version":3,"file":"Types/TextTypes.js","sources":["Types/TextTypes.coffee"],"names":[],"mappings":"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","sourcesContent":["structured_types_uninitialized = require \"./StructuredTypes\"\n\nmodule.exports = (HB)->\n  structured_types = structured_types_uninitialized HB\n  types = structured_types.types\n  parser = structured_types.parser\n\n  #\n  # At the moment TextDelete type equals the Delete type in BasicTypes.\n  # @see BasicTypes.Delete\n  #\n  class TextDelete extends types.Delete\n  parser[\"TextDelete\"] = parser[\"Delete\"]\n\n  #\n  #  Extends the basic Insert type to an operation that holds a text value\n  #\n  class TextInsert extends types.Insert\n    #\n    # @param {String} content The content of this Insert-type Operation. Usually you restrict the length of content to size 1\n    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.\n    #\n    constructor: (@content, uid, prev, next, origin)->\n      if not (prev? and next?)\n        throw new Error \"You must define prev, and next for TextInsert-types!\"\n      super uid, prev, next, origin\n    #\n    # Retrieve the effective length of the $content of this operation.\n    #\n    getLength: ()->\n      if @isDeleted()\n        0\n      else\n        @content.length\n\n    #\n    # The result will be concatenated with the results from the other insert operations\n    # in order to retrieve the content of the engine.\n    # @see HistoryBuffer.toExecutedArray\n    #\n    val: (current_position)->\n      if @isDeleted()\n        \"\"\n      else\n        @content\n\n    #\n    # Convert all relevant information of this operation to the json-format.\n    # This result can be send to other clients.\n    #\n    _encode: ()->\n      json =\n        {\n          'type': \"TextInsert\"\n          'content': @content\n          'uid' : @getUid()\n          'prev': @prev_cl.getUid()\n          'next': @next_cl.getUid()\n        }\n      if @origin? and @origin isnt @prev_cl\n        json[\"origin\"] = @origin.getUid()\n      json\n\n  parser[\"TextInsert\"] = (json)->\n    {\n      'content' : content\n      'uid' : uid\n      'prev': prev\n      'next': next\n      'origin' : origin\n    } = json\n    new TextInsert content, uid, prev, next, origin\n\n  #\n  # Handles a Text-like data structures with support for insertText/deleteText at a word-position.\n  #\n  class Word extends types.ListManager\n\n    #\n    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.\n    #\n    constructor: (uid, beginning, end, prev, next, origin)->\n      super uid, beginning, end, prev, next, origin\n\n    #\n    # Inserts a string into the word\n    #\n    insertText: (position, content)->\n      o = @getOperationByPosition position\n      for c in content\n        op = new TextInsert c, undefined, o.prev_cl, o\n        HB.addOperation(op).execute()\n\n    #\n    # Deletes a part of the word.\n    #\n    deleteText: (position, length)->\n      o = @getOperationByPosition position\n\n      delete_ops = []\n      for i in [0...length]\n        d = HB.addOperation(new TextDelete undefined, o).execute()\n        o = o.next_cl\n        while o.isDeleted() and not (o instanceof types.Delimiter)\n          if o instanceof types.Delimiter\n            throw new Error \"You can't delete more than there is..\"\n          o = o.next_cl\n        delete_ops.push d._encode()\n        if o instanceof types.Delimiter\n          break\n\n\n    #\n    # Replace the content of this word with another one. Concurrent replacements are not merged!\n    # Only one of the replacements will be used.\n    #\n    # Can only be used if the ReplaceManager was set!\n    # @see Word.setReplaceManager\n    #\n    replaceText: (text)->\n      if @replace_manager?\n        word = HB.addOperation(new Word undefined).execute()\n        word.insertText 0, text\n        @replace_manager.replace(word)\n      else\n        throw new Error \"This type is currently not maintained by a ReplaceManager!\"\n\n    #\n    # @returns [Json] A Json object.\n    #\n    val: ()->\n      c = for o in @toArray()\n        if o.val?\n          o.val()\n        else\n          \"\"\n      c.join('')\n\n    #\n    # In most cases you would embed a Word in a Replaceable, wich is handled by the ReplaceManager in order\n    # to provide replace functionality.\n    #\n    setReplaceManager: (op)->\n      @saveOperation 'replace_manager', op\n      @validateSavedOperations\n\n    #\n    # Bind this Word to a textfield.\n    #\n    bind: (textfield)->\n      word = @\n      textfield.value = @val()\n\n      @on \"insert\", (event, op)->\n        o_pos = op.getPosition()\n        fix = (cursor)->\n          if cursor <= o_pos\n            cursor\n          else\n            cursor += 1\n            cursor\n        left = fix textfield.selectionStart\n        right = fix textfield.selectionEnd\n\n        textfield.value = word.val()\n        textfield.setSelectionRange left, right\n\n\n      @on \"delete\", (event, op)->\n        o_pos = op.getPosition()\n        fix = (cursor)->\n          if cursor < o_pos\n            cursor\n          else\n            cursor -= 1\n            cursor\n        left = fix textfield.selectionStart\n        right = fix textfield.selectionEnd\n\n        textfield.value = word.val()\n        textfield.setSelectionRange left, right\n\n      # consume all text-insert changes.\n      textfield.onkeypress = (event)->\n        char = String.fromCharCode event.keyCode\n        if char.length > 0\n          console.log char\n          pos = Math.min textfield.selectionStart, textfield.selectionEnd\n          diff = Math.abs(textfield.selectionEnd - textfield.selectionStart)\n          word.deleteText (pos), diff\n          word.insertText pos, char\n          new_pos = pos + char.length\n          textfield.setSelectionRange new_pos, new_pos\n          event.preventDefault()\n        else\n          event.preventDefault()\n\n      #\n      # consume deletes. Note that\n      #   chrome: won't consume deletions on keypress event.\n      #   keyCode is deprecated. BUT: I don't see another way.\n      #     since event.key is not implemented in the current version of chrome.\n      #     Every browser supports keyCode. Let's stick with it for now..\n      #\n      textfield.onkeydown = (event)->\n        pos = Math.min textfield.selectionStart, textfield.selectionEnd\n        diff = Math.abs(textfield.selectionEnd - textfield.selectionStart)\n        if event.keyCode? and event.keyCode is 8\n          if diff > 0\n            word.deleteText pos, diff\n          else\n            if event.ctrlKey? and event.ctrlKey\n              val = textfield.value\n              new_pos = pos\n              del_length = 0\n              if pos > 0\n                new_pos--\n                del_length++\n              while new_pos > 0 and val[new_pos] isnt \" \" and val[new_pos] isnt '\\n'\n                new_pos--\n                del_length++\n              word.deleteText new_pos, (pos-new_pos)\n              textfield.setSelectionRange new_pos, new_pos\n            else\n              word.deleteText (pos-1), 1\n          event.preventDefault()\n        else if event.keyCode? and event.keyCode is 46\n          if diff > 0\n            word.deleteText pos, diff\n          else\n            word.deleteText pos, 1\n          event.preventDefault()\n\n\n\n    #\n    # Encode this operation in such a way that it can be parsed by remote peers.\n    #\n    _encode: ()->\n      json = {\n        'type': \"Word\"\n        'uid' : @getUid()\n        'beginning' : @beginning.getUid()\n        'end' : @end.getUid()\n      }\n      if @prev_cl?\n        json['prev'] = @prev_cl.getUid()\n      if @next_cl?\n        json['next'] = @next_cl.getUid()\n      if @origin? and @origin isnt @prev_cl\n        json[\"origin\"] = @origin.getUid()\n      json\n\n  parser['Word'] = (json)->\n    {\n      'uid' : uid\n      'beginning' : beginning\n      'end' : end\n      'prev': prev\n      'next': next\n      'origin' : origin\n    } = json\n    new Word uid, beginning, end, prev, next, origin\n\n  types['TextInsert'] = TextInsert\n  types['TextDelete'] = TextDelete\n  types['Word'] = Word\n  structured_types\n\n\n"],"sourceRoot":"/source/"}
\ No newline at end of file