Compare commits

..

1 Commits

Author SHA1 Message Date
Kevin Jahns
cedcb118c8 v13.0.0-51 -- distribution files 2018-02-07 14:08:56 +01:00
17 changed files with 19640 additions and 180 deletions

View File

@@ -18,7 +18,7 @@ window.undoManager = new Y.utils.UndoManager(window.yXmlType, {
}) })
document.onkeydown = function interceptUndoRedo (e) { document.onkeydown = function interceptUndoRedo (e) {
if (e.keyCode === 90 && (e.metaKey || e.ctrlKey)) { if (e.keyCode === 90 && e.metaKey) {
if (!e.shiftKey) { if (!e.shiftKey) {
window.undoManager.undo() window.undoManager.undo()
} else { } else {

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "yjs", "name": "yjs",
"version": "13.0.0-53", "version": "13.0.0-51",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "yjs", "name": "yjs",
"version": "13.0.0-53", "version": "13.0.0-51",
"description": "A framework for real-time p2p shared editing on any data", "description": "A framework for real-time p2p shared editing on any data",
"main": "./y.node.js", "main": "./y.node.js",
"browser": "./y.js", "browser": "./y.js",

View File

@@ -4,10 +4,8 @@ import { readDeleteSet, writeDeleteSet } from './deleteSet.js'
import BinaryEncoder from '../Binary/Encoder.js' import BinaryEncoder from '../Binary/Encoder.js'
export function fromBinary (y, decoder) { export function fromBinary (y, decoder) {
y.transact(function () { integrateRemoteStructs(y, decoder)
integrateRemoteStructs(y, decoder) readDeleteSet(y, decoder)
readDeleteSet(y, decoder)
})
} }
export function toBinary (y) { export function toBinary (y) {

View File

@@ -51,56 +51,22 @@ export default class Item {
this._parent = null this._parent = null
this._parentSub = null this._parentSub = null
this._deleted = false this._deleted = false
this._redone = null
} }
/** /**
* Create a operation with the same effect (without position effect) * Copy the effect of struct
*/ */
_copy () { _copy (undeleteChildren, copyPosition) {
return new this.constructor() let struct = new this.constructor()
} if (copyPosition) {
/** struct._origin = this._left
* Redo the effect of this operation. struct._left = this._left
*/ struct._right = this
_redo (y) { struct._right_origin = this
if (this._redone !== null) { struct._parent = this._parent
return this._redone struct._parentSub = this._parentSub
} }
let struct = this._copy()
let left = this._left
let right = this
let parent = this._parent
// make sure that parent is redone
if (parent._deleted === true && parent._redone === null) {
parent._redo(y)
}
if (parent._redone !== null) {
parent = parent._redone
// find next cloned items
while (left !== null && left._redone === null) {
left = left._left
}
if (left !== null) {
left = left._redone
}
while (right !== null && right._redone === null) {
right = right._right
}
if (right !== null) {
right = right._redone
}
}
struct._origin = left
struct._left = left
struct._right = right
struct._right_origin = right
struct._parent = parent
struct._parentSub = this._parentSub
struct._integrate(y)
this._redone = struct
return struct return struct
} }
get _lastId () { get _lastId () {
return new ID(this._id.user, this._id.clock + this._length - 1) return new ID(this._id.user, this._id.clock + this._length - 1)
} }

View File

@@ -6,8 +6,8 @@ export default class ItemJSON extends Item {
super() super()
this._content = null this._content = null
} }
_copy () { _copy (undeleteChildren, copyPosition) {
let struct = super._copy() let struct = super._copy(undeleteChildren, copyPosition)
struct._content = this._content struct._content = this._content
return struct return struct
} }

View File

@@ -6,8 +6,8 @@ export default class ItemString extends Item {
super() super()
this._content = null this._content = null
} }
_copy () { _copy (undeleteChildren, copyPosition) {
let struct = super._copy() let struct = super._copy(undeleteChildren, copyPosition)
struct._content = this._content struct._content = this._content
return struct return struct
} }

View File

@@ -79,6 +79,40 @@ export default class Type extends Item {
type = type._parent type = type._parent
} }
} }
_copy (undeleteChildren, copyPosition) {
let copy = super._copy(undeleteChildren, copyPosition)
let map = new Map()
copy._map = map
for (let [key, value] of this._map) {
if (undeleteChildren.has(value) || !value.deleted) {
let _item = value._copy(undeleteChildren, false)
_item._parent = copy
_item._parentSub = key
map.set(key, _item)
}
}
let prevUndeleted = null
copy._start = null
let item = this._start
while (item !== null) {
if (undeleteChildren.has(item) || !item.deleted) {
let _item = item._copy(undeleteChildren, false)
_item._left = prevUndeleted
_item._origin = prevUndeleted
_item._right = null
_item._right_origin = null
_item._parent = copy
if (prevUndeleted === null) {
copy._start = _item
} else {
prevUndeleted._right = _item
}
prevUndeleted = _item
}
item = item._right
}
return copy
}
_transact (f) { _transact (f) {
const y = this._y const y = this._y
if (y !== null) { if (y !== null) {

View File

@@ -20,8 +20,8 @@ export default class YXmlElement extends YXmlFragment {
this._domFilter = arg2 this._domFilter = arg2
} }
} }
_copy () { _copy (undeleteChildren, copyPosition) {
let struct = super._copy() let struct = super._copy(undeleteChildren, copyPosition)
struct.nodeName = this.nodeName struct.nodeName = this.nodeName
return struct return struct
} }
@@ -36,8 +36,7 @@ export default class YXmlElement extends YXmlFragment {
let attributes = new Map() let attributes = new Map()
for (let i = 0; i < dom.attributes.length; i++) { for (let i = 0; i < dom.attributes.length; i++) {
let attr = dom.attributes[i] let attr = dom.attributes[i]
// get attribute via getAttribute for custom element support (some write something different in attr.value) attributes.set(attr.name, attr.value)
attributes.set(attr.name, dom.getAttribute(attr.name))
} }
attributes = this._domFilter(dom, attributes) attributes = this._domFilter(dom, attributes)
attributes.forEach((value, name) => { attributes.forEach((value, name) => {

View File

@@ -14,8 +14,8 @@ export default class YXmlHook extends YMap {
getHook(hookName).fillType(dom, this) getHook(hookName).fillType(dom, this)
} }
} }
_copy () { _copy (undeleteChildren, copyPosition) {
const struct = super._copy() const struct = super._copy(undeleteChildren, copyPosition)
struct.hookName = this.hookName struct.hookName = this.hookName
return struct return struct
} }

View File

@@ -4,12 +4,11 @@ class ReverseOperation {
constructor (y, transaction) { constructor (y, transaction) {
this.created = new Date() this.created = new Date()
const beforeState = transaction.beforeState const beforeState = transaction.beforeState
this.toState = new ID(y.userID, y.ss.getState(y.userID) - 1)
if (beforeState.has(y.userID)) { if (beforeState.has(y.userID)) {
this.toState = new ID(y.userID, y.ss.getState(y.userID) - 1)
this.fromState = new ID(y.userID, beforeState.get(y.userID)) this.fromState = new ID(y.userID, beforeState.get(y.userID))
} else { } else {
this.toState = null this.fromState = this.toState
this.fromState = null
} }
this.deletedStructs = transaction.deletedStructs this.deletedStructs = transaction.deletedStructs
} }
@@ -31,32 +30,28 @@ function applyReverseOperation (y, scope, reverseBuffer) {
while (!performedUndo && reverseBuffer.length > 0) { while (!performedUndo && reverseBuffer.length > 0) {
let undoOp = reverseBuffer.pop() let undoOp = reverseBuffer.pop()
// make sure that it is possible to iterate {from}-{to} // make sure that it is possible to iterate {from}-{to}
if (undoOp.fromState !== null) { y.os.getItemCleanStart(undoOp.fromState)
y.os.getItemCleanStart(undoOp.fromState) y.os.getItemCleanEnd(undoOp.toState)
y.os.getItemCleanEnd(undoOp.toState) y.os.iterate(undoOp.fromState, undoOp.toState, op => {
y.os.iterate(undoOp.fromState, undoOp.toState, op => { if (!op._deleted && isStructInScope(y, op, scope)) {
while (op._deleted && op._redone !== null) { performedUndo = true
op = op._redone op._delete(y)
} }
if (op._deleted === false && isStructInScope(y, op, scope)) { })
performedUndo = true
op._delete(y)
}
})
}
for (let op of undoOp.deletedStructs) { for (let op of undoOp.deletedStructs) {
if ( if (
isStructInScope(y, op, scope) && isStructInScope(y, op, scope) &&
op._parent !== y && op._parent !== y &&
!op._parent._deleted &&
( (
op._id.user !== y.userID || op._parent._id.user !== y.userID ||
undoOp.fromState === null || op._parent._id.clock < undoOp.fromState.clock ||
op._id.clock < undoOp.fromState.clock || op._parent._id.clock > undoOp.fromState.clock
op._id.clock > undoOp.toState.clock
) )
) { ) {
performedUndo = true performedUndo = true
op._redo(y) op = op._copy(undoOp.deletedStructs, true)
op._integrate(y)
} }
} }
} }
@@ -82,12 +77,7 @@ export default class UndoManager {
let lastUndoOp = this._undoBuffer.length > 0 ? this._undoBuffer[this._undoBuffer.length - 1] : null let lastUndoOp = this._undoBuffer.length > 0 ? this._undoBuffer[this._undoBuffer.length - 1] : null
if (lastUndoOp !== null && reverseOperation.created - lastUndoOp.created <= options.captureTimeout) { if (lastUndoOp !== null && reverseOperation.created - lastUndoOp.created <= options.captureTimeout) {
lastUndoOp.created = reverseOperation.created lastUndoOp.created = reverseOperation.created
if (reverseOperation.toState !== null) { lastUndoOp.toState = reverseOperation.toState
lastUndoOp.toState = reverseOperation.toState
if (lastUndoOp.fromState === null) {
lastUndoOp.fromState = reverseOperation.fromState
}
}
reverseOperation.deletedStructs.forEach(lastUndoOp.deletedStructs.add, lastUndoOp.deletedStructs) reverseOperation.deletedStructs.forEach(lastUndoOp.deletedStructs.add, lastUndoOp.deletedStructs)
} else { } else {
this._undoBuffer.push(reverseOperation) this._undoBuffer.push(reverseOperation)

8
y.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

159
y.node.js
View File

@@ -1,7 +1,7 @@
/** /**
* yjs - A framework for real-time p2p shared editing on any data * yjs - A framework for real-time p2p shared editing on any data
* @version v13.0.0-53 * @version v13.0.0-51
* @license MIT * @license MIT
*/ */
@@ -1340,56 +1340,22 @@ class Item {
this._parent = null; this._parent = null;
this._parentSub = null; this._parentSub = null;
this._deleted = false; this._deleted = false;
this._redone = null;
} }
/** /**
* Create a operation with the same effect (without position effect) * Copy the effect of struct
*/ */
_copy () { _copy (undeleteChildren, copyPosition) {
return new this.constructor() let struct = new this.constructor();
} if (copyPosition) {
/** struct._origin = this._left;
* Redo the effect of this operation. struct._left = this._left;
*/ struct._right = this;
_redo (y) { struct._right_origin = this;
if (this._redone !== null) { struct._parent = this._parent;
return this._redone struct._parentSub = this._parentSub;
} }
let struct = this._copy();
let left = this._left;
let right = this;
let parent = this._parent;
// make sure that parent is redone
if (parent._deleted === true && parent._redone === null) {
parent._redo(y);
}
if (parent._redone !== null) {
parent = parent._redone;
// find next cloned items
while (left !== null && left._redone === null) {
left = left._left;
}
if (left !== null) {
left = left._redone;
}
while (right !== null && right._redone === null) {
right = right._right;
}
if (right !== null) {
right = right._redone;
}
}
struct._origin = left;
struct._left = left;
struct._right = right;
struct._right_origin = right;
struct._parent = parent;
struct._parentSub = this._parentSub;
struct._integrate(y);
this._redone = struct;
return struct return struct
} }
get _lastId () { get _lastId () {
return new ID(this._id.user, this._id.clock + this._length - 1) return new ID(this._id.user, this._id.clock + this._length - 1)
} }
@@ -1758,6 +1724,40 @@ class Type extends Item {
type = type._parent; type = type._parent;
} }
} }
_copy (undeleteChildren, copyPosition) {
let copy = super._copy(undeleteChildren, copyPosition);
let map = new Map();
copy._map = map;
for (let [key, value] of this._map) {
if (undeleteChildren.has(value) || !value.deleted) {
let _item = value._copy(undeleteChildren, false);
_item._parent = copy;
_item._parentSub = key;
map.set(key, _item);
}
}
let prevUndeleted = null;
copy._start = null;
let item = this._start;
while (item !== null) {
if (undeleteChildren.has(item) || !item.deleted) {
let _item = item._copy(undeleteChildren, false);
_item._left = prevUndeleted;
_item._origin = prevUndeleted;
_item._right = null;
_item._right_origin = null;
_item._parent = copy;
if (prevUndeleted === null) {
copy._start = _item;
} else {
prevUndeleted._right = _item;
}
prevUndeleted = _item;
}
item = item._right;
}
return copy
}
_transact (f) { _transact (f) {
const y = this._y; const y = this._y;
if (y !== null) { if (y !== null) {
@@ -1821,8 +1821,8 @@ class ItemJSON extends Item {
super(); super();
this._content = null; this._content = null;
} }
_copy () { _copy (undeleteChildren, copyPosition) {
let struct = super._copy(); let struct = super._copy(undeleteChildren, copyPosition);
struct._content = this._content; struct._content = this._content;
return struct return struct
} }
@@ -1883,8 +1883,8 @@ class ItemString extends Item {
super(); super();
this._content = null; this._content = null;
} }
_copy () { _copy (undeleteChildren, copyPosition) {
let struct = super._copy(); let struct = super._copy(undeleteChildren, copyPosition);
struct._content = this._content; struct._content = this._content;
return struct return struct
} }
@@ -3137,8 +3137,8 @@ class YXmlElement extends YXmlFragment {
this._domFilter = arg2; this._domFilter = arg2;
} }
} }
_copy () { _copy (undeleteChildren, copyPosition) {
let struct = super._copy(); let struct = super._copy(undeleteChildren, copyPosition);
struct.nodeName = this.nodeName; struct.nodeName = this.nodeName;
return struct return struct
} }
@@ -3153,8 +3153,7 @@ class YXmlElement extends YXmlFragment {
let attributes = new Map(); let attributes = new Map();
for (let i = 0; i < dom.attributes.length; i++) { for (let i = 0; i < dom.attributes.length; i++) {
let attr = dom.attributes[i]; let attr = dom.attributes[i];
// get attribute via getAttribute for custom element support (some write something different in attr.value) attributes.set(attr.name, attr.value);
attributes.set(attr.name, dom.getAttribute(attr.name));
} }
attributes = this._domFilter(dom, attributes); attributes = this._domFilter(dom, attributes);
attributes.forEach((value, name) => { attributes.forEach((value, name) => {
@@ -3277,8 +3276,8 @@ class YXmlHook extends YMap {
getHook(hookName).fillType(dom, this); getHook(hookName).fillType(dom, this);
} }
} }
_copy () { _copy (undeleteChildren, copyPosition) {
const struct = super._copy(); const struct = super._copy(undeleteChildren, copyPosition);
struct.hookName = this.hookName; struct.hookName = this.hookName;
return struct return struct
} }
@@ -3676,12 +3675,11 @@ class ReverseOperation {
constructor (y, transaction) { constructor (y, transaction) {
this.created = new Date(); this.created = new Date();
const beforeState = transaction.beforeState; const beforeState = transaction.beforeState;
this.toState = new ID(y.userID, y.ss.getState(y.userID) - 1);
if (beforeState.has(y.userID)) { if (beforeState.has(y.userID)) {
this.toState = new ID(y.userID, y.ss.getState(y.userID) - 1);
this.fromState = new ID(y.userID, beforeState.get(y.userID)); this.fromState = new ID(y.userID, beforeState.get(y.userID));
} else { } else {
this.toState = null; this.fromState = this.toState;
this.fromState = null;
} }
this.deletedStructs = transaction.deletedStructs; this.deletedStructs = transaction.deletedStructs;
} }
@@ -3703,32 +3701,28 @@ function applyReverseOperation (y, scope, reverseBuffer) {
while (!performedUndo && reverseBuffer.length > 0) { while (!performedUndo && reverseBuffer.length > 0) {
let undoOp = reverseBuffer.pop(); let undoOp = reverseBuffer.pop();
// make sure that it is possible to iterate {from}-{to} // make sure that it is possible to iterate {from}-{to}
if (undoOp.fromState !== null) { y.os.getItemCleanStart(undoOp.fromState);
y.os.getItemCleanStart(undoOp.fromState); y.os.getItemCleanEnd(undoOp.toState);
y.os.getItemCleanEnd(undoOp.toState); y.os.iterate(undoOp.fromState, undoOp.toState, op => {
y.os.iterate(undoOp.fromState, undoOp.toState, op => { if (!op._deleted && isStructInScope(y, op, scope)) {
while (op._deleted && op._redone !== null) { performedUndo = true;
op = op._redone; op._delete(y);
} }
if (op._deleted === false && isStructInScope(y, op, scope)) { });
performedUndo = true;
op._delete(y);
}
});
}
for (let op of undoOp.deletedStructs) { for (let op of undoOp.deletedStructs) {
if ( if (
isStructInScope(y, op, scope) && isStructInScope(y, op, scope) &&
op._parent !== y && op._parent !== y &&
!op._parent._deleted &&
( (
op._id.user !== y.userID || op._parent._id.user !== y.userID ||
undoOp.fromState === null || op._parent._id.clock < undoOp.fromState.clock ||
op._id.clock < undoOp.fromState.clock || op._parent._id.clock > undoOp.fromState.clock
op._id.clock > undoOp.toState.clock
) )
) { ) {
performedUndo = true; performedUndo = true;
op._redo(y); op = op._copy(undoOp.deletedStructs, true);
op._integrate(y);
} }
} }
} }
@@ -3754,12 +3748,7 @@ class UndoManager {
let lastUndoOp = this._undoBuffer.length > 0 ? this._undoBuffer[this._undoBuffer.length - 1] : null; let lastUndoOp = this._undoBuffer.length > 0 ? this._undoBuffer[this._undoBuffer.length - 1] : null;
if (lastUndoOp !== null && reverseOperation.created - lastUndoOp.created <= options.captureTimeout) { if (lastUndoOp !== null && reverseOperation.created - lastUndoOp.created <= options.captureTimeout) {
lastUndoOp.created = reverseOperation.created; lastUndoOp.created = reverseOperation.created;
if (reverseOperation.toState !== null) { lastUndoOp.toState = reverseOperation.toState;
lastUndoOp.toState = reverseOperation.toState;
if (lastUndoOp.fromState === null) {
lastUndoOp.fromState = reverseOperation.fromState;
}
}
reverseOperation.deletedStructs.forEach(lastUndoOp.deletedStructs.add, lastUndoOp.deletedStructs); reverseOperation.deletedStructs.forEach(lastUndoOp.deletedStructs.add, lastUndoOp.deletedStructs);
} else { } else {
this._undoBuffer.push(reverseOperation); this._undoBuffer.push(reverseOperation);
@@ -4641,10 +4630,8 @@ class AbstractConnector {
} }
function fromBinary (y, decoder) { function fromBinary (y, decoder) {
y.transact(function () { integrateRemoteStructs(y, decoder);
integrateRemoteStructs(y, decoder); readDeleteSet(y, decoder);
readDeleteSet(y, decoder);
});
} }
function toBinary (y) { function toBinary (y) {

File diff suppressed because one or more lines are too long

19485
y.test.js Normal file

File diff suppressed because one or more lines are too long

1
y.test.js.map Normal file

File diff suppressed because one or more lines are too long