diff --git a/src/static/js/AttributeManager.js b/src/static/js/AttributeManager.js index 6e3a2490a..3ea2b6dab 100644 --- a/src/static/js/AttributeManager.js +++ b/src/static/js/AttributeManager.js @@ -2,6 +2,23 @@ var Changeset = require('./Changeset'); var ChangesetUtils = require('./ChangesetUtils'); var _ = require('./underscore'); +var lineMarkerAttribute = 'lmkr'; + +// If one of these attributes are set to the first character of a +// line it is considered as a line attribute marker i.e. attributes +// set on this marker are applied to the whole line. +// The list attribute is only maintained for compatibility reasons +var lineAttributes = [lineMarkerAttribute,'list']; + +/* + The Attribute manager builds changesets based on a SkipList + for setting and removing range or line-based Attributes. + + @param rep the SkipList to be used + @param applyChangesetCallback this callback will be called + once a changeset has been built. +*/ + var AttributeManager = function(rep, applyChangesetCallback) { this.rep = rep; @@ -10,30 +27,39 @@ var AttributeManager = function(rep, applyChangesetCallback) // If the first char in a line has one of the following attributes // it will be considered as a line marker - this.lineAttributes = ['list']; }; AttributeManager.prototype = _(AttributeManager.prototype).extend({ applyChangeset: function(changeset){ + if(!this.applyChangesetCallback) return changeset; + var cs = changeset.toString(); if (!Changeset.isIdentity(cs)) { this.applyChangesetCallback(cs); } + + return changeset; }, + /* + Returns if the line already has a line marker + @param lineNum: the number of the line + */ lineHasMarker: function(lineNum){ - // get "list" attribute of first char of line var that = this; - return _.find(this.lineAttributes, function(attribute){ + return _.find(lineAttributes, function(attribute){ return that.getAttributeOnLine(lineNum, attribute) != ''; }) !== undefined; - - }, + /* + Gets a specified attribute on a line + @param lineNum: the number of the line to set the attribute for + @param attributeKey: the name of the attribute to get, e.g. list + */ getAttributeOnLine: function(lineNum, attributeName){ // get `attributeName` attribute of first char of line var aline = this.rep.alines[lineNum]; @@ -71,6 +97,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({ builder.insert('*', [ ['author', this.author], ['insertorder', 'first'], + [lineMarkerAttribute, '1'], [attributeName, attributeValue] ], this.rep.apool); } diff --git a/src/static/js/AttributePool.js b/src/static/js/AttributePool.js index a9245daf8..f5990c07d 100644 --- a/src/static/js/AttributePool.js +++ b/src/static/js/AttributePool.js @@ -22,6 +22,12 @@ * limitations under the License. */ +/* + An AttributePool maintains a mapping from [key,value] Pairs called + Attributes to Numbers (unsigened integers) and vice versa. These numbers are + used to reference Attributes in Changesets. +*/ + var AttributePool = function () { this.numToAttrib = {}; // e.g. {0: ['foo','bar']} this.attribToNum = {}; // e.g. {'foo,bar': 0}