Comparing version 1.2.2 to 1.2.3
53
index.js
var domSerialize = require('serialize-dom') | ||
, nodeAt = require('./lib/ops/node-at') | ||
, pathTo = require('./lib/path-to') | ||
, Changeset = require('changesets').Changeset | ||
, ManipulateText = require('./lib/ops/manipulate-text') | ||
@@ -16,6 +20,7 @@ exports.create = function(initialData) { | ||
exports.transform = function(ops1, ops2, side) { | ||
unpackOps(ops1).forEach(function(op1) { | ||
return unpackOps(ops1).map(function(op1) { | ||
unpackOps(ops2).forEach(function(op2) { | ||
op1.transformAgainst(op2, ('left'==side)) | ||
}) | ||
return op1 | ||
}) | ||
@@ -25,10 +30,50 @@ } | ||
exports.compose = function(ops1, ops2) { | ||
exports.transform(ops2, ops1) | ||
//exports.transform(ops2, ops1) | ||
return ops1.concat(ops2) | ||
} | ||
exports.transformCursor = function(cursor, op) { | ||
// https://developer.mozilla.org/en-US/docs/Web/API/Range/setStart | ||
exports.transformCursor = function(range, ops, rootNode) { | ||
range = range.cloneRange() | ||
if(rootNode.contains(range.startContainer)) { | ||
var cs = Changeset.create() | ||
.retain(range.startOffset) | ||
.insert('|') | ||
.retain(range.startContainer.nodeValue.length-range.startOffset) | ||
.end() | ||
.pack() | ||
var cursorOps = [new ManipulateText(pathTo(range.startContainer, rootNode), cs)] | ||
cursorOps = exports.transform(cursorOps, ops, 'right') | ||
var cursorOp = cursorOps[0] | ||
var length = countInitialRetains(cursorOp.diff) | ||
if(cursorOp.path === null) range.collapse(false) | ||
else range.setStart(nodeAt(cursorOp.path, rootNode), length) | ||
} | ||
if(rootNode.contains(range.endContainer)) { | ||
var cs = Changeset.create() | ||
.retain(range.endOffset) | ||
.insert('|') | ||
.retain(range.endContainer.nodeValue.length-range.endOffset) | ||
.end() | ||
.pack() | ||
var cursorOps = [new ManipulateText(pathTo(range.endContainer, rootNode), cs)] | ||
cursorOps = exports.transform(cursorOps, ops, 'right') | ||
var cursorOp = cursorOps[0] | ||
var length = countInitialRetains(cursorOp.diff) | ||
if(cursorOp.path === null) range.collapse(true) | ||
else range.setEnd(nodeAt(cursorOp.path, rootNode), length) | ||
} | ||
return range | ||
} | ||
function countInitialRetains(cs) { | ||
var length = 0 | ||
var ops = Changeset.unpack(cs) | ||
for(var i=0; i<ops.length; i++) { | ||
if(ops[i].input === ops[i].output) length += ops[i].length | ||
else break | ||
} | ||
return length | ||
} | ||
exports.serialize = function(snapshot) { | ||
@@ -35,0 +80,0 @@ return domSerialize(snapshot) |
@@ -5,3 +5,7 @@ var Manipulate = require('./ops/manipulate') | ||
var isPrefixOf = require('./ops/is-prefix') | ||
var pathTo = require('./path-to') | ||
var serialize = require('serialize-dom') | ||
var Changeset = require('changesets').Changeset | ||
, diff_match_patch = require('diff_match_patch').diff_match_patch | ||
, diffEngine = new diff_match_patch | ||
@@ -169,3 +173,5 @@ exports.import = summaryToOplist | ||
summary.characterDataChanged.forEach(function(node) { | ||
oplist.push(new ManipulateText(pathTo(node, rootNode), node.nodeValue)) // XXX: diff! | ||
var diff = diffEngine.diff_main(summary.getOldCharacterData(node), node.nodeValue) | ||
, changeset = Changeset.fromDiff(diff).pack() | ||
oplist.push(new ManipulateText(pathTo(node, rootNode), changeset)) | ||
}) | ||
@@ -181,24 +187,2 @@ } | ||
function pathTo(node, root) { | ||
if(!root) throw new Error('No root node specified.') | ||
if(node === root) return [] | ||
if(!root.contains(node)) { | ||
throw new Error('Cannot determine path. Node is not a descendant of root node.') | ||
} | ||
// The number of older siblings equals my index in the list of childNodes | ||
var myIndex = 0, n = node | ||
while(n.previousSibling) { | ||
n = n.previousSibling | ||
myIndex++ | ||
} | ||
var parentPath = pathTo(node.parentNode, root) | ||
parentPath.push(myIndex) | ||
return parentPath | ||
} | ||
function sortOps(op1, op2) { | ||
@@ -205,0 +189,0 @@ var path1 = (op1.path || op1.to || op1.from).map(strPad.bind(null, '00000')).join('') // XXX: Hard limit: Can't correctly sort ops with path elements longer than 5 digits |
var Manipulate = require('./manipulate') | ||
, Move = require('./move') | ||
, nodeAt = require('./node-at') | ||
, changesets = require('changesets') | ||
@@ -15,15 +16,17 @@ // Paths are arrays, where [] is the root node | ||
ManipulateText.prototype.transformAgainst = function (op) { | ||
ManipulateText.prototype.transformAgainst = function (op, left) { | ||
if(!this.path) return | ||
if(op instanceof Move) { | ||
return Manipulate.prototype.transformAgainst.call(this, op) | ||
} | ||
if(op instanceof ManipulateText) { | ||
// XXX: text transform | ||
if(op instanceof ManipulateText && op.path.join() == this.path.join()) { | ||
this.diff = changesets.transform(this.diff, op.diff, left? 'left': 'right') | ||
} | ||
} | ||
ManipulateText.prototype.apply = function (rootNode, index) { | ||
ManipulateText.prototype.apply = function (rootNode, index, dry) { | ||
if(!this.path || dry) return | ||
var targetNode = nodeAt(this.path, rootNode) | ||
targetNode.nodeValue = this.diff // XXX: Preliminary, we need diffs! | ||
targetNode.nodeValue = changesets.apply(targetNode.nodeValue, this.diff) | ||
} |
@@ -18,3 +18,3 @@ var Move = require('./move') | ||
Manipulate.prototype.transformAgainst = function (op, left) { | ||
if(op instanceof Move) { | ||
if(op instanceof Move && this.path) { | ||
var path = this.path.slice(0) | ||
@@ -50,2 +50,3 @@ , level | ||
Manipulate.prototype.apply = function (rootNode, index) { | ||
if(!this.path) return | ||
var myNode = nodeAt(this.path, rootNode) | ||
@@ -52,0 +53,0 @@ |
{ | ||
"name": "dom-ot", | ||
"version": "1.2.2", | ||
"version": "1.2.3", | ||
"description": "Operational transform library for DOM operations (conforms to shareJS' spec)", | ||
@@ -11,2 +11,4 @@ "main": "index.js", | ||
"serialize-dom": "3.x" | ||
, "changesets": "0.4.x" | ||
, "diff_match_patch": "0.1.x" | ||
}, | ||
@@ -13,0 +15,0 @@ "devDependencies": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27800
17
691
3
+ Addedchangesets@0.4.x
+ Addeddiff_match_patch@0.1.x
+ Addedchangesets@0.4.0(transitive)
+ Addeddiff_match_patch@0.1.1(transitive)