atom-patch
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -83,5 +83,4 @@ 'use strict'; | ||
}; | ||
if (this.currentNode.newText != null) { | ||
change.newText = this.currentNode.newText; | ||
} | ||
if (this.currentNode.newText != null) change.newText = this.currentNode.newText; | ||
if (this.currentNode.oldText != null) change.oldText = this.currentNode.oldText; | ||
@@ -134,2 +133,7 @@ changes.push(change); | ||
}, { | ||
key: 'getOldText', | ||
value: function getOldText() { | ||
return this.currentNode.oldText; | ||
} | ||
}, { | ||
key: 'insertSpliceBoundary', | ||
@@ -185,3 +189,5 @@ value: function insertSpliceBoundary(boundaryOutputPosition, spliceStartNode) { | ||
this.currentNode.isChangeEnd = true; | ||
var newText = this.rightAncestor.newText; | ||
var _rightAncestor = this.rightAncestor; | ||
var newText = _rightAncestor.newText; | ||
var oldText = _rightAncestor.oldText; | ||
@@ -193,2 +199,7 @@ if (newText != null) { | ||
} | ||
if (oldText != null) { | ||
var boundaryIndex = (0, _textHelpers.characterIndexForPoint)(oldText, (0, _pointHelpers.traversalDistance)(boundaryOutputPosition, this.leftAncestorOutputPosition)); | ||
this.currentNode.oldText = oldText.substring(0, boundaryIndex); | ||
this.rightAncestor.oldText = oldText.substring(boundaryIndex); | ||
} | ||
} | ||
@@ -195,0 +206,0 @@ |
@@ -26,2 +26,3 @@ "use strict"; | ||
this.newText = null; | ||
this.oldText = null; | ||
}; | ||
@@ -28,0 +29,0 @@ |
@@ -21,2 +21,4 @@ 'use strict'; | ||
var _serialization = require('./serialization'); | ||
var Patch = (function () { | ||
@@ -36,5 +38,6 @@ _createClass(Patch, null, [{ | ||
var newExtent = _changes$i.newExtent; | ||
var oldText = _changes$i.oldText; | ||
var newText = _changes$i.newText; | ||
composedPatch.splice(newStart, oldExtent, newExtent, { text: newText }); | ||
composedPatch.splice(newStart, oldExtent, newExtent, { oldText: oldText, newText: newText }); | ||
} | ||
@@ -48,5 +51,6 @@ } else { | ||
var newExtent = _changes$i2.newExtent; | ||
var oldText = _changes$i2.oldText; | ||
var newText = _changes$i2.newText; | ||
composedPatch.splice(oldStart, oldExtent, newExtent, { text: newText }); | ||
composedPatch.splice(oldStart, oldExtent, newExtent, { oldText: oldText, newText: newText }); | ||
} | ||
@@ -56,4 +60,36 @@ } | ||
return composedPatch.getChanges(); | ||
return new Patch({ cachedChanges: composedPatch.getChanges() }); | ||
} | ||
}, { | ||
key: 'invert', | ||
value: function invert(patch) { | ||
var invertedChanges = patch.getChanges().map(function (change) { | ||
return { | ||
oldStart: change.newStart, newStart: change.oldStart, | ||
oldExtent: change.newExtent, newExtent: change.oldExtent, | ||
oldText: change.newText, newText: change.oldText | ||
}; | ||
}); | ||
return new Patch({ cachedChanges: invertedChanges }); | ||
} | ||
}, { | ||
key: 'hunk', | ||
value: function hunk(change) { | ||
var changes = [{ | ||
oldStart: change.newStart, | ||
newStart: change.newStart, | ||
oldExtent: change.oldExtent, | ||
newExtent: change.newExtent, | ||
oldText: change.oldText, | ||
newText: change.newText | ||
}]; | ||
return new Patch({ cachedChanges: changes }); | ||
} | ||
}, { | ||
key: 'deserialize', | ||
value: function deserialize(serializedChanges) { | ||
return new Patch({ serializedChanges: serializedChanges }); | ||
} | ||
}]); | ||
@@ -69,6 +105,27 @@ | ||
this.iterator = this.buildIterator(); | ||
this.cachedChanges = null; | ||
this.cachedChanges = params.cachedChanges; | ||
this.serializedChanges = params.serializedChanges; | ||
if (params.cachedChanges || params.serializedChanges) { | ||
this.freeze(); | ||
} | ||
} | ||
_createClass(Patch, [{ | ||
key: 'serialize', | ||
value: function serialize() { | ||
if (this.serializedChanges == null) { | ||
this.serializedChanges = (0, _serialization.serializeChanges)(this.getChanges()); | ||
this.freeze(); | ||
} | ||
return this.serializedChanges; | ||
} | ||
}, { | ||
key: 'freeze', | ||
value: function freeze() { | ||
this.splice = function () { | ||
throw new Error("Cannot splice into a read-only Patch!"); | ||
}; | ||
} | ||
}, { | ||
key: 'buildIterator', | ||
@@ -124,8 +181,10 @@ value: function buildIterator() { | ||
key: 'spliceWithText', | ||
value: function spliceWithText(newStart, oldExtent, newText, options) { | ||
this.splice(newStart, oldExtent, (0, _textHelpers.getExtent)(newText), { text: newText }); | ||
value: function spliceWithText(newStart, oldText, newText) { | ||
this.splice(newStart, (0, _textHelpers.getExtent)(oldText), (0, _textHelpers.getExtent)(newText), { oldText: oldText, newText: newText }); | ||
} | ||
}, { | ||
key: 'splice', | ||
value: function splice(newStart, oldExtent, newExtent, options) { | ||
value: function splice(newStart, oldExtent, newExtent) { | ||
var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; | ||
if ((0, _pointHelpers.isZero)(oldExtent) && (0, _pointHelpers.isZero)(newExtent)) return; | ||
@@ -145,2 +204,7 @@ | ||
endNode.outputExtent = (0, _pointHelpers.traverse)(newEnd, (0, _pointHelpers.traversalDistance)(endNode.outputExtent, endNode.outputLeftExtent)); | ||
endNode.outputLeftExtent = newEnd; | ||
if (options.newText != null) endNode.newText = options.newText; | ||
if (options.oldText != null) endNode.oldText = this.replaceChangedText(options.oldText, startNode, endNode); | ||
startNode.right = null; | ||
@@ -150,11 +214,6 @@ startNode.inputExtent = startNode.inputLeftExtent; | ||
endNode.outputExtent = (0, _pointHelpers.traverse)(newEnd, (0, _pointHelpers.traversalDistance)(endNode.outputExtent, endNode.outputLeftExtent)); | ||
endNode.outputLeftExtent = newEnd; | ||
endNode.newText = options && options.text; | ||
if (endNode.isChangeStart) { | ||
var rightAncestor = this.bubbleNodeDown(endNode); | ||
if (endNode.newText != null) { | ||
rightAncestor.newText = endNode.newText + rightAncestor.newText; | ||
} | ||
if (endNode.newText != null) rightAncestor.newText = endNode.newText + rightAncestor.newText; | ||
if (endNode.oldText != null) rightAncestor.oldText = endNode.oldText + rightAncestor.oldText; | ||
this.deleteNode(endNode); | ||
@@ -168,5 +227,4 @@ } else if ((0, _pointHelpers.compare)(endNode.outputLeftExtent, startNode.outputLeftExtent) === 0 && (0, _pointHelpers.compare)(endNode.inputLeftExtent, startNode.inputLeftExtent) === 0) { | ||
var rightAncestor = this.bubbleNodeDown(startNode) || this.root; | ||
if (startNode.newText != null) { | ||
rightAncestor.newText = startNode.newText + rightAncestor.newText; | ||
} | ||
if (startNode.newText != null) rightAncestor.newText = startNode.newText + rightAncestor.newText; | ||
if (startNode.oldText != null) rightAncestor.oldText = startNode.oldText + rightAncestor.oldText; | ||
this.deleteNode(startNode); | ||
@@ -178,6 +236,53 @@ } | ||
}, { | ||
key: 'replaceChangedText', | ||
value: function replaceChangedText(oldText, startNode, endNode) { | ||
var replacedText = ""; | ||
var lastChangeEnd = _pointHelpers.ZERO_POINT; | ||
for (var change of this.changesForSubtree(startNode.right)) { | ||
if (change.start) { | ||
replacedText += oldText.substring((0, _textHelpers.characterIndexForPoint)(oldText, lastChangeEnd), (0, _textHelpers.characterIndexForPoint)(oldText, change.start)); | ||
} else if (change.end) { | ||
replacedText += change.oldText; | ||
lastChangeEnd = change.end; | ||
} | ||
} | ||
if (endNode.oldText == null) { | ||
replacedText += oldText.substring((0, _textHelpers.characterIndexForPoint)(oldText, lastChangeEnd)); | ||
} else { | ||
replacedText += endNode.oldText; | ||
} | ||
return replacedText; | ||
} | ||
}, { | ||
key: 'changesForSubtree', | ||
value: function changesForSubtree(node) { | ||
var outputDistance = arguments.length <= 1 || arguments[1] === undefined ? _pointHelpers.ZERO_POINT : arguments[1]; | ||
var changes = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; | ||
if (node == null) return changes; | ||
this.changesForSubtree(node.left, outputDistance, changes); | ||
var change = {}; | ||
var outputLeftExtent = (0, _pointHelpers.traverse)(outputDistance, node.outputLeftExtent); | ||
if (node.isChangeStart) change.start = outputLeftExtent; | ||
if (node.isChangeEnd) { | ||
change.end = outputLeftExtent; | ||
change.oldText = node.oldText; | ||
} | ||
changes.push(change); | ||
this.changesForSubtree(node.right, outputLeftExtent, changes); | ||
return changes; | ||
} | ||
}, { | ||
key: 'getChanges', | ||
value: function getChanges() { | ||
if (this.cachedChanges == null) { | ||
this.cachedChanges = this.iterator.getChanges(); | ||
if (this.serializedChanges == null) { | ||
this.cachedChanges = this.iterator.getChanges(); | ||
} else { | ||
this.cachedChanges = (0, _serialization.deserializeChanges)(this.serializedChanges); | ||
} | ||
} | ||
@@ -184,0 +289,0 @@ |
{ | ||
"name": "atom-patch", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "A data structure to efficiently represent the results of applying patches.", | ||
@@ -5,0 +5,0 @@ "main": "dist/patch.js", |
# atom-patch [![Build Status](https://travis-ci.org/atom/atom-patch.svg?branch=master)](https://travis-ci.org/atom/atom-patch) | ||
This data structure efficiently represents a transformation from input to output text, and it's useful for aggregating and combining changes that occur at different points in time and space. | ||
## Contributing | ||
```bash | ||
# clone this repository | ||
git clone https://github.com/atom/atom-patch | ||
cd atom-patch | ||
npm install | ||
``` | ||
Use `npm test` or `npm run tdd` to run the test suite. | ||
### Recompiling Patch's Flatbuffer Schema | ||
`Patch` uses [flat buffers](https://google.github.io/flatbuffers/) to represent its serialized state. If you want to make any change to the underlying schema you have to download and compile `flatc` first: | ||
```bash | ||
# clone flatbuffers repository and checkout the version tested with this library | ||
git clone https://github.com/google/flatbuffers | ||
git checkout 959866b | ||
# compile flatbuffers | ||
pushd flatbuffers/build/XCode/ | ||
xcodebuild | ||
popd | ||
``` | ||
This will create a `flatc` executable in flatbuffers top level directory. You can recompile `src/serialization-schema.fbs` by running: | ||
```bash | ||
cd atom-patch | ||
../flatbuffers/flatc -o src --js serialization-schema.fbs | ||
``` | ||
After you do that, please make sure to to change the generated file's last line to: | ||
```diff | ||
// Exports for Node.js and RequireJS | ||
- this.Serialization = Serialization; | ||
+ module.exports = Serialization; | ||
``` | ||
Please, note that we have included a patched version of the flatbuffers javascript library under vendor/flatbuffers.js because the original one has the same problem. |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
75247
14
2121
48
1