Comparing version 1.0.1 to 1.1.0
46
index.js
@@ -0,3 +1,3 @@ | ||
var domSerialize = require('dom-serializer') | ||
exports.create = function(initialData) { | ||
@@ -8,11 +8,13 @@ | ||
exports.apply = function(snapshot, ops) { | ||
ops | ||
unpackOps(ops) | ||
.forEach(function(op) { | ||
op.apply(snapshot) | ||
}) | ||
return snapshot | ||
} | ||
exports.transform = function(ops1, ops2, side) { | ||
ops1.forEach(function(op1) { | ||
ops2.forEach(function(op2) { | ||
unpackOps(ops1).forEach(function(op1) { | ||
unpackOps(ops2).forEach(function(op2) { | ||
op1.transformAgainst(op2, ('left'==side)) | ||
@@ -23,6 +25,40 @@ }) | ||
exports.compose = function(op1, op2) { | ||
exports.compose = function(ops1, ops2) { | ||
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.serialize = function(snapshot) { | ||
return domSerialize(snapshot) | ||
} | ||
exports.deserialize = function(data) { | ||
if('undefined' == typeof document) { | ||
}else{ | ||
var div = document.createElement('div') | ||
div.innerHTML = data | ||
return div.firstChild | ||
} | ||
} | ||
function unpackOps(unpackOps) { | ||
return unpackOps.map(function(op) { | ||
switch(op.type) { | ||
case 'Move': | ||
return new exports.Move(op.from, op.to, op.element) | ||
case 'Manipulate': | ||
return new exports.Manipulate(op.path, op.prop, op.value) | ||
case 'ManipulateText': | ||
return new exports.ManipulateText(op.path, op.diff) | ||
default: | ||
throw new Error('Unknown op type: '+op.type) | ||
} | ||
}) | ||
} | ||
exports.Move = require('./lib/index').Move | ||
@@ -29,0 +65,0 @@ exports.Manipulate = require('./lib/index').Manipulate |
var Manipulate = require('./ops/manipulate') | ||
var ManipulateText = require('./ops/manipulate-text') | ||
var Move = require('./ops/move') | ||
var isPrefixOf = require('./ops/is-prefix') | ||
var serialize = require('dom-serializer') | ||
exports.import = summaryToOplist | ||
@@ -64,4 +67,12 @@ | ||
.forEach(function(node) { | ||
oplist.push(new Move(null, pathTo(node, rootNode), node.cloneNode())) | ||
oplist.push(new Move(null, pathTo(node, rootNode), serialize(node))) | ||
}) | ||
oplist = oplist.filter(function(op1) { | ||
// Don't insert this node if its parent is already being inserted | ||
return !oplist.some(function(op2) { | ||
if(op2 === op1) return false | ||
return isPrefixOf(op2.to, op1.to) | ||
}) | ||
}) | ||
} | ||
@@ -88,3 +99,3 @@ | ||
} | ||
oplist.push(new Move(oldPath, null, node.cloneNode())) | ||
oplist.push(new Move(oldPath, null, serialize(node))) | ||
}) | ||
@@ -112,3 +123,3 @@ } | ||
} | ||
oplist.push(new Move(oldPath, pathTo(node, rootNode), node.cloneNode())) | ||
oplist.push(new Move(oldPath, pathTo(node, rootNode), serialize(node))) | ||
}) | ||
@@ -115,0 +126,0 @@ } |
@@ -1,2 +0,2 @@ | ||
var isDescendantOf = require('./is-descendant') | ||
var isPrefixOf = require('./is-prefix') | ||
module.exports = function isYoungerSiblingOf(path1, path2) { | ||
@@ -9,3 +9,3 @@ // check if they are on the same tree level | ||
parent.pop() | ||
if(!isDescendantOf(path2, parent)) return false | ||
if(!isPrefixOf(parent, path2)) return false | ||
@@ -12,0 +12,0 @@ // check if path1 is younger than path2 |
var Manipulate = require('./manipulate') | ||
, Move = require('./move') | ||
, nodeAt = require('./node-at') | ||
// Paths are arrays, where [0] is the root node | ||
// Paths are arrays, where [] is the root node | ||
@@ -9,2 +10,3 @@ function ManipulateText(path, diff) { | ||
this.diff = diff | ||
this.type = 'ManipulateText' | ||
} | ||
@@ -11,0 +13,0 @@ |
var Move = require('./move') | ||
, isYoungerSiblingOf = require('./is-youngerSibling') | ||
, isPrefixOf = require('./is-prefix') | ||
, nodeAt = require('./node-at') | ||
@@ -10,2 +11,3 @@ | ||
this.value = value | ||
this.type = 'Manipulate' | ||
} | ||
@@ -15,11 +17,16 @@ | ||
Manipulate.prototype.transformAgainst = function (op) { | ||
Manipulate.prototype.transformAgainst = function (op, left) { | ||
if(op instanceof Move) { | ||
var path = this.path.slice(0) | ||
if (op.from) { | ||
if (op.from == this.path) | ||
this.path = op.to.concat() // go with the flow man. | ||
if (isPrefixOf(op.from, this.path)) { | ||
if(op.to) | ||
path = Array.prototype.concat(op.to, this.path.slice(op.from.length)) // go with the flow man. | ||
else | ||
path = null | ||
} | ||
if (isYoungerSiblingOf(this.path, op.from)) | ||
this.path[this.path.length-1]-- // (shift to left) | ||
path[this.path.length-1]-- // (shift to left) | ||
} | ||
@@ -29,4 +36,9 @@ | ||
if (isYoungerSiblingOf(this.path, op.to)) | ||
this.path[this.path.length-1]++ // (shift to right) | ||
path[this.path.length-1]++ // (shift to right) | ||
if(isPrefixOf(op.to, this.path)) | ||
if(!left) path[op.to.length-1]++ // right side's gotta budge | ||
} | ||
this.path = path | ||
} | ||
@@ -41,3 +53,3 @@ } | ||
myNode.setAttribute(this.prop, this.value )// XXX: This is preliminary, 'til we know the nature of mutation summary's records | ||
myNode.setAttribute(this.prop, this.value) | ||
} |
var isYoungerSiblingOf = require('./is-youngerSibling') | ||
, isDescendantOf = require('./is-descendant') | ||
, isPrefixOf = require('./is-prefix') | ||
, nodeAt = require('./node-at') | ||
@@ -10,3 +10,3 @@ | ||
// If to is null, it's a removal | ||
// element will hold the element to insert (or remove if you need invertabilty) | ||
// element will hold the html to insert (or remove if you need invertabilty) | ||
function Move(from, to, element/*(optional)*/) { | ||
@@ -16,2 +16,3 @@ this.from = from | ||
this.element = element | ||
this.type = 'Move' | ||
} | ||
@@ -22,2 +23,4 @@ module.exports = Move | ||
if(op instanceof Move) { | ||
var from = this.from && this.from.slice(0) | ||
, to = this.to && this.to.slice(0) | ||
@@ -27,15 +30,19 @@ if(this.from) { | ||
if(op.from) { | ||
if (isDescendantOf(this.from, op.from)) | ||
this.from = Array.prototype.concat.call(op.to, this.from.slice(op.from.length)) // change from to be descendant of op.to instead of in op.from | ||
if (isPrefixOf(op.from, this.from)) { | ||
if(op.to) | ||
from = Array.prototype.concat.call(op.to, this.from.slice(op.from.length)) // change from to be descendant of op.to instead of in op.from | ||
else | ||
from = null | ||
} | ||
if (isYoungerSiblingOf(this.from, op.from)) | ||
this.from[this.from.length-1]-- // (shift to left) | ||
from[this.from.length-1]-- // (shift to left) | ||
} | ||
if(op.to) { | ||
if (op.from == this.from && op.to != this.to) // XXX: Prolly not correct. | ||
this.from = Array.prototype.concat.call(op.to) // so effectively, op has no effect | ||
if (isYoungerSiblingOf(this.from, op.to)) | ||
from[this.from.length-1]++ // (shift to right) | ||
if (isYoungerSiblingOf(this.from, op.to)) | ||
this.from[this.from.length-1]++ // (shift to right) | ||
if(isPrefixOf(op.to, this.from)) | ||
if(!left) from[op.to.length-1]++ | ||
} | ||
@@ -46,16 +53,27 @@ | ||
if (this.to) { | ||
if(op.from) { | ||
if (isYoungerSiblingOf(this.to, op.from)) | ||
to[this.to.length-1]-- // (shift to left) | ||
if (isPrefixOf(op.from, this.to) && op.from.length < this.to.length) { | ||
if(op.to) | ||
to = Array.prototype.concat.call(op.to, this.to.slice(op.from.length)) | ||
else | ||
to = null | ||
} | ||
} | ||
if(op.to) { | ||
if (isYoungerSiblingOf(this.to, op.to)) | ||
this.from[this.from.length-1]++ // (shift to right) | ||
to[this.to.length-1]++ // (shift to right) | ||
if (this.to == op.to) { | ||
if(!left) this.to[this.to.length-1]++ // the right side 's got to budge | ||
} | ||
if(isPrefixOf(op.to, this.to)) | ||
if(!left) to[op.to.length-1]++ // the right side's gotta budge | ||
} | ||
if(op.from) { | ||
if (isYoungerSiblingOf(this.to, op.from)) | ||
this.from[this.from.length-1]-- // (shift to left) | ||
} | ||
} | ||
this.from = from | ||
this.to = to | ||
} | ||
@@ -72,3 +90,5 @@ } | ||
} else { | ||
myNode = this.element // XXX: Unserialization needed. probably. | ||
var tempDiv = rootNode.ownerDocument.createElement('div') | ||
tempDiv.innerHTML = this.element // Unserialize | ||
myNode = tempDiv.firstChild | ||
} | ||
@@ -75,0 +95,0 @@ |
{ | ||
"name": "dom-ot", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Operational transform library for DOM operations (conforms to shareJS' spec)", | ||
@@ -9,4 +9,16 @@ "main": "index.js", | ||
}, | ||
"dependencies": { | ||
"dom-serializer": "0.1.x" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^10.1.0", | ||
"chai": "^2.3.0", | ||
"mocha": "^2.2.4", | ||
"mocha-phantomjs": "^3.5.3", | ||
"phantomjs": "^1.9.17", | ||
"mutation-summary": "0.x" | ||
}, | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "browserify test/tests.js > test/bundle.js && mocha-phantomjs test/index.html", | ||
"dist": "browserify index.js -s domOT > bundle.js" | ||
}, | ||
@@ -18,4 +30,3 @@ "repository": { | ||
"keywords": [ | ||
"operational", | ||
"transformation", | ||
"operational transformation", | ||
"ot", | ||
@@ -22,0 +33,0 @@ "dom" |
# dom-ot | ||
The DOM changes. You can [capture](https://github.com/marcelklehr/mutation-summary) those changes and [sync](https://github.com/marcelklehr/gulf) multiple documents in real-time using this library to transform the changes. | ||
## Install | ||
``` | ||
npm install dom-ot | ||
``` | ||
## Operations | ||
@@ -5,0 +11,0 @@ ``` |
Sorry, the diff of this file is not supported yet
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
561
0
29
21075
1
6
14
+ Addeddom-serializer@0.1.x
+ Addeddom-serializer@0.1.1(transitive)
+ Addeddomelementtype@1.3.1(transitive)
+ Addedentities@1.1.2(transitive)