updated xml example with commands

This commit is contained in:
Kevin Jahns 2016-03-23 19:53:52 +01:00
parent 658081566b
commit 3156c7b19f
7 changed files with 5927 additions and 152 deletions

View File

@ -1,8 +1,39 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<body> </head>
<script src="../bower_components/yjs/y.es6"></script> <script src="../bower_components/yjs/y.es6"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script> <script src="../bower_components/jquery/dist/jquery.min.js"></script>
<script src="./index.js"></script> <script src="./index.js"></script>
</head>
<body>
<h1> Shared DOM Example </h1>
<p> Use native DOM function or jQuery to manipulate the shared DOM (window.sharedDom). </p>
<div class="command">
<button type="button">Execute</button>
<input type="text" value='$(sharedDom).append("<h3>Appended headline</h3>")' size="40"/>
</div>
<div class="command">
<button type="button">Execute</button>
<input type="text" value='$(sharedDom).attr("align","right")' size="40"/>
</div>
<div class="command">
<button type="button">Execute</button>
<input type="text" value='$(sharedDom).attr("style","color:blue;")' size="40"/>
</div>
<script>
var commands = document.querySelectorAll(".command");
Array.prototype.forEach.call(document.querySelectorAll('.command'), function (command) {
var execute = function(){
eval(command.querySelector("input").value);
}
command.querySelector("button").onclick = execute
$(command.querySelector("input")).keyup(function (e) {
if (e.keyCode == 13) {
execute()
}
})
})
</script>
</body> </body>
</html> </html>

View File

@ -18,8 +18,10 @@
"y-websockets-client": "latest", "y-websockets-client": "latest",
"y-text": "latest", "y-text": "latest",
"y-indexeddb": "latest", "y-indexeddb": "latest",
"y-xml": "latest",
"quill": "~0.20.1", "quill": "~0.20.1",
"ace": "~1.2.3", "ace": "~1.2.3",
"ace-builds": "~1.2.3" "ace-builds": "~1.2.3",
"jquery": "~2.2.2"
} }
} }

View File

@ -177,16 +177,8 @@ If you want to see an issue fixed, please subscribe to the thread (or remind me
## Changelog ## Changelog
### 10.0.0
* Support for more complex types (a type can be a composition of several types)
* Fixes several memory leaks
### 9.0.0 ### 9.0.0
There were several rolling updates from 0.6 to 0.8. We consider Yjs stable since a long time, There were several rolling updates from 0.6 to 0.8. We'll now follow the semver versioning scheme. This is all what this jump from 0.8 to 9.0 is about.
and intend to continue stable releases. From this release forward y-* modules will implement peer-dependencies for npm, and dependencies for bower.
Furthermore, incompatible yjs instances will now throw errors when syncing - this feature was influenced by #48. The versioning jump was influenced by react (see [here](https://facebook.github.io/react/blog/2016/02/19/new-versioning-scheme.html))
### 0.6.0 ### 0.6.0
This is a complete rewrite of the 0.5 version of Yjs. Since Yjs 0.6.0 it is possible to work asynchronously on a persistent database, which enables offline support. This is a complete rewrite of the 0.5 version of Yjs. Since Yjs 0.6.0 it is possible to work asynchronously on a persistent database, which enables offline support.

147
y.es6
View File

@ -20,8 +20,6 @@ module.exports = function (Y/* :any */) {
userId: UserId; userId: UserId;
send: Function; send: Function;
broadcast: Function; broadcast: Function;
broadcastOpBuffer: Array<Operation>;
protocolVersion: number;
*/ */
/* /*
opts contains the following information: opts contains the following information:
@ -54,7 +52,7 @@ module.exports = function (Y/* :any */) {
this.broadcastedHB = false this.broadcastedHB = false
this.syncStep2 = Promise.resolve() this.syncStep2 = Promise.resolve()
this.broadcastOpBuffer = [] this.broadcastOpBuffer = []
this.protocolVersion = 10 this.protocolVersion = 8
} }
reconnect () { reconnect () {
} }
@ -153,8 +151,7 @@ module.exports = function (Y/* :any */) {
conn.send(syncUser, { conn.send(syncUser, {
type: 'sync step 1', type: 'sync step 1',
stateSet: stateSet, stateSet: stateSet,
deleteSet: deleteSet, deleteSet: deleteSet
protocolVersion: conn.protocolVersion
}) })
}) })
} else { } else {
@ -238,8 +235,7 @@ module.exports = function (Y/* :any */) {
type: 'sync step 2', type: 'sync step 2',
os: ops, os: ops,
stateSet: currentStateSet, stateSet: currentStateSet,
deleteSet: ds, deleteSet: ds
protocolVersion: this.protocolVersion
}) })
if (this.forwardToSyncingClients) { if (this.forwardToSyncingClients) {
conn.syncingClients.push(sender) conn.syncingClients.push(sender)
@ -669,18 +665,6 @@ module.exports = function (Y /* :any */) {
garbageCollect() garbageCollect()
} }
} }
emptyGarbageCollector () {
return new Promise(resolve => {
var check = () => {
if (this.gc1.length > 0 || this.gc2.length > 0) {
this.garbageCollect().then(check)
} else {
resolve()
}
}
setTimeout(check, 0)
})
}
addToDebug () { addToDebug () {
if (typeof YConcurrency_TestingMode !== 'undefined') { if (typeof YConcurrency_TestingMode !== 'undefined') {
var command /* :string */ = Array.prototype.map.call(arguments, function (s) { var command /* :string */ = Array.prototype.map.call(arguments, function (s) {
@ -910,7 +894,15 @@ module.exports = function (Y /* :any */) {
} }
} else { } else {
// increase SS // increase SS
yield* transaction.updateState(op.id[0]) var o = op
var state = yield* transaction.getState(op.id[0])
while (o != null && o.id[1] === state.clock && op.id[0] === o.id[0]) {
// either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS
state.clock++
yield* transaction.checkDeleteStoreForState(state)
o = yield* transaction.os.findNext(o.id)
}
yield* transaction.setState(state)
// notify whenOperation listeners (by id) // notify whenOperation listeners (by id)
var sid = JSON.stringify(op.id) var sid = JSON.stringify(op.id)
@ -927,15 +919,6 @@ module.exports = function (Y /* :any */) {
} }
var t = this.initializedTypes[JSON.stringify(op.parent)] var t = this.initializedTypes[JSON.stringify(op.parent)]
// if parent is deleted, mark as gc'd and return
if (op.parent != null) {
var parentIsDeleted = yield* transaction.isDeleted(op.parent)
if (parentIsDeleted) {
yield* transaction.deleteList(op.id)
return
}
}
// Delete if DS says this is actually deleted // Delete if DS says this is actually deleted
var opIsDeleted = yield* transaction.isDeleted(op.id) var opIsDeleted = yield* transaction.isDeleted(op.id)
if (!op.deleted && opIsDeleted) { if (!op.deleted && opIsDeleted) {
@ -947,13 +930,8 @@ module.exports = function (Y /* :any */) {
} }
// notify parent, if it was instanciated as a custom type // notify parent, if it was instanciated as a custom type
if (t != null) { if (t != null && !opIsDeleted) {
let o = Y.utils.copyObject(op) yield* t._changed(transaction, Y.utils.copyObject(op))
if (opIsDeleted && !o.deleted) {
// op did not reflect the created delete op (happens when not using y-memory)
o.deleted = true
}
yield* t._changed(transaction, o)
} }
} }
} }
@ -1555,22 +1533,18 @@ module.exports = function (Y/* :any */) {
} }
* deleteList (start) { * deleteList (start) {
while (start != null) {
start = yield* this.getOperation(start)
if (!start.gc) {
start.gc = true
start.deleted = true
yield* this.setOperation(start)
yield* this.markDeleted(start.id, 1)
if (start.opContent != null) {
yield* this.deleteOperation(start.opContent)
}
if (this.store.y.connector.isSynced) { if (this.store.y.connector.isSynced) {
while (start != null && this.store.y.connector.isSynced) {
start = yield* this.getOperation(start)
start.gc = true
yield* this.setOperation(start)
// TODO: will always reset the parent..
this.store.gc1.push(start.id) this.store.gc1.push(start.id)
}
}
start = start.right start = start.right
} }
} else {
// TODO: when not possible??? do later in (gcWhenSynced)
}
} }
/* /*
@ -1604,24 +1578,19 @@ module.exports = function (Y/* :any */) {
if (target.start != null) { if (target.start != null) {
// TODO: don't do it like this .. -.- // TODO: don't do it like this .. -.-
yield* this.deleteList(target.start) yield* this.deleteList(target.start)
// yield* this.deleteList(target.id) -- do not gc itself because this may still get referenced yield* this.deleteList(target.id)
} }
if (target.map != null) { if (target.map != null) {
for (var name in target.map) { for (var name in target.map) {
yield* this.deleteList(target.map[name]) yield* this.deleteList(target.map[name])
} }
// TODO: here to.. (see above) // TODO: here to.. (see above)
// yield* this.deleteList(target.id) -- see above yield* this.deleteList(target.id)
} }
if (target.opContent != null) { if (target.opContent != null) {
yield* this.deleteOperation(target.opContent) yield* this.deleteOperation(target.opContent)
// target.opContent = null // target.opContent = null
} }
if (target.requires != null) {
for (var i = 0; i < target.requires.length; i++) {
yield* this.deleteOperation(target.requires[i])
}
}
} }
var left var left
if (target.left != null) { if (target.left != null) {
@ -1787,41 +1756,10 @@ module.exports = function (Y/* :any */) {
*/ */
* garbageCollectAfterSync () { * garbageCollectAfterSync () {
yield* this.os.iterate(this, null, null, function * (op) { yield* this.os.iterate(this, null, null, function * (op) {
if (op.gc) {
this.store.gc1.push(op.id)
} else {
if (op.parent != null) {
var parentDeleted = yield* this.isDeleted(op.parent)
if (parentDeleted) {
op.gc = true
if (!op.deleted) {
yield* this.markDeleted(op.id, 1)
op.deleted = true
if (op.opContent != null) {
yield* this.deleteOperation(op.opContent)
/*
var opContent = yield* this.getOperation(op.opContent)
opContent.gc = true
yield* this.setOperation(opContent)
this.store.gc1.push(opContent.id)
*/
}
if (op.requires != null) {
for (var i = 0; i < op.requires.length; i++) {
yield* this.deleteOperation(op.requires[i])
}
}
}
yield* this.setOperation(op)
this.store.gc1.push(op.id)
return
}
}
if (op.deleted && op.left != null) { if (op.deleted && op.left != null) {
var left = yield* this.getOperation(op.left) var left = yield* this.getOperation(op.left)
this.store.addToGarbageCollector(op, left) this.store.addToGarbageCollector(op, left)
} }
}
}) })
} }
/* /*
@ -1846,29 +1784,6 @@ module.exports = function (Y/* :any */) {
} }
*/ */
var deps = []
if (o.opContent != null) {
deps.push(o.opContent)
}
if (o.requires != null) {
deps = deps.concat(o.requires)
}
for (var i = 0; i < deps.length; i++) {
var dep = yield* this.getOperation(deps[i])
if (dep != null) {
if (!dep.deleted) {
yield* this.deleteOperation(dep.id)
dep = yield* this.getOperation(dep.id)
}
dep.gc = true
yield* this.setOperation(dep)
this.store.gc1.push(dep.id)
} else {
yield* this.markGarbageCollected(deps[i], 1)
yield* this.updateState(deps[i][0]) // TODO: unneccessary?
}
}
// remove gc'd op from the left op, if it exists // remove gc'd op from the left op, if it exists
if (o.left != null) { if (o.left != null) {
var left = yield* this.getOperation(o.left) var left = yield* this.getOperation(o.left)
@ -1951,7 +1866,6 @@ module.exports = function (Y/* :any */) {
// so we have to set right here // so we have to set right here
yield* this.setOperation(right) yield* this.setOperation(right)
} }
}
// o may originate in another operation. // o may originate in another operation.
// Since o is deleted, we have to reset o.origin's `originOf` property // Since o is deleted, we have to reset o.origin's `originOf` property
if (o.origin != null) { if (o.origin != null) {
@ -1961,6 +1875,7 @@ module.exports = function (Y/* :any */) {
}) })
yield* this.setOperation(origin) yield* this.setOperation(origin)
} }
}
var parent var parent
if (o.parent != null){ if (o.parent != null){
parent = yield* this.getOperation(o.parent) parent = yield* this.getOperation(o.parent)
@ -1999,18 +1914,6 @@ module.exports = function (Y/* :any */) {
state.clock = Math.max(state.clock, n.id[1] + n.len) state.clock = Math.max(state.clock, n.id[1] + n.len)
} }
} }
* updateState (user) {
var state = yield* this.getState(user)
yield* this.checkDeleteStoreForState(state)
var o = yield* this.getOperation([user, state.clock])
while (o != null && o.id[1] === state.clock && user === o.id[0]) {
// either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS
state.clock++
yield* this.checkDeleteStoreForState(state)
o = yield* this.os.findNext(o.id)
}
yield* this.setState(state)
}
/* /*
apply a delete set in order to get apply a delete set in order to get
the state of the supplied ds the state of the supplied ds

File diff suppressed because one or more lines are too long

5853
y.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long