Cleaning up. No more bubbling events. All tests run fine. Following the Object.observe pattern (untested).

This commit is contained in:
DadaMonad 2014-12-17 22:50:08 +00:00
parent 584964153c
commit 21f7350c4d
35 changed files with 263 additions and 387 deletions

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"sources":["ConnectorAdapter.coffee"],"names":[],"mappings":"AAOA;AAAA,MAAA,cAAA;;AAAA,EAAA,cAAA,GAAiB,SAAC,SAAD,EAAY,MAAZ,EAAoB,EAApB,EAAwB,kBAAxB,GAAA;AACf,QAAA,uCAAA;AAAA,IAAA,KAAA,GAAQ,SAAC,CAAD,GAAA;AACN,MAAA,IAAG,CAAC,CAAC,GAAG,CAAC,OAAN,KAAiB,EAAE,CAAC,SAAH,CAAA,CAAjB,IAAoC,CAAC,MAAA,CAAA,CAAQ,CAAC,GAAG,CAAC,SAAb,KAA4B,QAA7B,CAAvC;eACE,SAAS,CAAC,SAAV,CAAoB,CAApB,EADF;OADM;IAAA,CAAR,CAAA;AAAA,IAIA,kBAAkB,CAAC,IAAnB,CAAwB,KAAxB,CAJA,CAAA;AAAA,IAKA,eAAA,GAAkB,SAAA,GAAA;aAChB,EAAE,CAAC,mBAAH,CAAA,EADgB;IAAA,CALlB,CAAA;AAAA,IAOA,MAAA,GAAS,SAAC,YAAD,GAAA;aACP,EAAE,CAAC,OAAH,CAAW,YAAX,EADO;IAAA,CAPT,CAAA;AAAA,IASA,OAAA,GAAU,SAAC,EAAD,GAAA;aACR,MAAM,CAAC,mBAAP,CAA2B,EAA3B,EADQ;IAAA,CATV,CAAA;AAAA,IAWA,SAAS,CAAC,WAAV,CAAsB,eAAtB,EAAuC,MAAvC,EAA+C,OAA/C,CAXA,CAAA;WAaA,SAAS,CAAC,aAAV,CAAwB,SAAC,MAAD,EAAS,EAAT,GAAA;AACtB,MAAA,IAAG,EAAE,CAAC,GAAG,CAAC,OAAP,KAAoB,EAAE,CAAC,SAAH,CAAA,CAAvB;eACE,MAAM,CAAC,OAAP,CAAe,EAAf,EADF;OADsB;IAAA,CAAxB,EAde;EAAA,CAAjB,CAAA;;AAAA,EAkBA,MAAM,CAAC,OAAP,GAAiB,cAlBjB,CAAA;AAAA","file":"ConnectorAdapter.js","sourceRoot":"/source/","sourcesContent":["\n\n#\n# @param {Engine} engine The transformation engine\n# @param {HistoryBuffer} HB\n# @param {Array<Function>} execution_listener You must ensure that whenever an operation is executed, every function in this Array is called.\n#\nadaptConnector = (connector, engine, HB, execution_listener)->\n send_ = (o)->\n if o.uid.creator is HB.getUserId() and (typeof o.uid.op_number isnt \"string\")\n connector.broadcast o\n \n execution_listener.push send_\n sendStateVector = ()->\n HB.getOperationCounter()\n sendHb = (state_vector)->\n HB._encode(state_vector)\n applyHb = (hb)->\n engine.applyOpsCheckDouble hb\n connector.whenSyncing sendStateVector, sendHb, applyHb\n \n connector.whenReceiving (sender, op)->\n if op.uid.creator isnt HB.getUserId()\n engine.applyOp op\n \nmodule.exports = adaptConnector"]}
{"version":3,"sources":["ConnectorAdapter.coffee"],"names":[],"mappings":"AAOA;AAAA,MAAA,cAAA;;AAAA,EAAA,cAAA,GAAiB,SAAC,SAAD,EAAY,MAAZ,EAAoB,EAApB,EAAwB,kBAAxB,GAAA;AACf,QAAA,uCAAA;AAAA,IAAA,KAAA,GAAQ,SAAC,CAAD,GAAA;AACN,MAAA,IAAG,CAAC,CAAC,GAAG,CAAC,OAAN,KAAiB,EAAE,CAAC,SAAH,CAAA,CAAjB,IAAoC,CAAC,MAAA,CAAA,CAAQ,CAAC,GAAG,CAAC,SAAb,KAA4B,QAA7B,CAAvC;eACE,SAAS,CAAC,SAAV,CAAoB,CAApB,EADF;OADM;IAAA,CAAR,CAAA;AAAA,IAIA,kBAAkB,CAAC,IAAnB,CAAwB,KAAxB,CAJA,CAAA;AAAA,IAKA,eAAA,GAAkB,SAAA,GAAA;aAChB,EAAE,CAAC,mBAAH,CAAA,EADgB;IAAA,CALlB,CAAA;AAAA,IAOA,MAAA,GAAS,SAAC,YAAD,GAAA;aACP,EAAE,CAAC,OAAH,CAAW,YAAX,EADO;IAAA,CAPT,CAAA;AAAA,IASA,OAAA,GAAU,SAAC,EAAD,GAAA;aACR,MAAM,CAAC,mBAAP,CAA2B,EAA3B,EADQ;IAAA,CATV,CAAA;AAAA,IAWA,SAAS,CAAC,WAAV,CAAsB,eAAtB,EAAuC,MAAvC,EAA+C,OAA/C,CAXA,CAAA;WAaA,SAAS,CAAC,aAAV,CAAwB,SAAC,MAAD,EAAS,EAAT,GAAA;AACtB,MAAA,IAAG,EAAE,CAAC,GAAG,CAAC,OAAP,KAAoB,EAAE,CAAC,SAAH,CAAA,CAAvB;eACE,MAAM,CAAC,OAAP,CAAe,EAAf,EADF;OADsB;IAAA,CAAxB,EAde;EAAA,CAAjB,CAAA;;AAAA,EAkBA,MAAM,CAAC,OAAP,GAAiB,cAlBjB,CAAA;AAAA","file":"ConnectorAdapter.js","sourceRoot":"/source/","sourcesContent":["\n\n#\n# @param {Engine} engine The transformation engine\n# @param {HistoryBuffer} HB\n# @param {Array<Function>} execution_listener You must ensure that whenever an operation is executed, every function in this Array is called.\n#\nadaptConnector = (connector, engine, HB, execution_listener)->\n send_ = (o)->\n if o.uid.creator is HB.getUserId() and (typeof o.uid.op_number isnt \"string\")\n connector.broadcast o\n\n execution_listener.push send_\n sendStateVector = ()->\n HB.getOperationCounter()\n sendHb = (state_vector)->\n HB._encode(state_vector)\n applyHb = (hb)->\n engine.applyOpsCheckDouble hb\n connector.whenSyncing sendStateVector, sendHb, applyHb\n\n connector.whenReceiving (sender, op)->\n if op.uid.creator isnt HB.getUserId()\n engine.applyOp op\n\nmodule.exports = adaptConnector"]}

View File

@ -1,6 +1,18 @@
(function() {
var Engine;
if (typeof window !== "undefined" && window !== null) {
window.unprocessed_counter = 0;
}
if (typeof window !== "undefined" && window !== null) {
window.unprocessed_exec_counter = 0;
}
if (typeof window !== "undefined" && window !== null) {
window.unprocessed_types = [];
}
Engine = (function() {
function Engine(HB, parser) {
this.HB = HB;
@ -66,6 +78,12 @@
} else if (!o.execute()) {
this.unprocessed_ops.push(o);
if (typeof window !== "undefined" && window !== null) {
window.unprocessed_counter++;
}
if (typeof window !== "undefined" && window !== null) {
window.unprocessed_types.push(o.type);
}
}
return this.tryUnprocessed();
};
@ -74,6 +92,9 @@
var old_length, op, unprocessed, _i, _len, _ref, _results;
_results = [];
while (true) {
if (typeof window !== "undefined" && window !== null) {
window.unprocessed_exec_counter++;
}
old_length = this.unprocessed_ops.length;
unprocessed = [];
_ref = this.unprocessed_ops;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -178,7 +178,7 @@
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -119,30 +119,6 @@ if (x.type === &quot;JsonType&quot;) {
Transform this to a Json.
</span>
</li>
<li>
<span class='signature'>
<a href='#setReplaceManager-dynamic'>
#
(void)
<b>setReplaceManager</b><span>(replace_manager)</span>
</a>
</span>
<span class='desc'>
Sets the parent of this JsonType object.
</span>
</li>
<li>
<span class='signature'>
<a href='#getParent-dynamic'>
#
(JsonType)
<b>getParent</b><span>()</span>
</a>
</span>
<span class='desc'>
Get the parent of this JsonType.
</span>
</li>
<li>
<span class='signature'>
<a href='#setMutableDefault-dynamic'>
@ -207,8 +183,9 @@ if (x.type === &quot;JsonType&quot;) {
<br>
</p>
<div class='docstring'>
<p>Transform this to a Json. If your browser supports Object.observe it will be transformed automatically when a change arrives.
Otherwise you will loose all the sharing-abilities (the new object will be a deep clone)!</p>
<p>Transform this to a Json. If your browser supports Object.observe it will be transformed automatically when a change arrives.
Otherwise you will loose all the sharing-abilities (the new object will be a deep clone)!</p><p>TODO: at the moment you don&#39;t consider changing of properties.
E.g.: let x = {a:[]}. Then x.a.push 1 wouldn&#39;t change anything</p>
</div>
<div class='tags'>
<h3>Returns:</h3>
@ -218,45 +195,6 @@ Otherwise you will loose all the sharing-abilities (the new object will be a dee
<tt>Json</tt>
</li>
</ul>
</div>
</div>
<div class='method_details'>
<p class='signature' id='setReplaceManager-dynamic'>
#
(void)
<b>setReplaceManager</b><span>(replace_manager)</span>
<br>
</p>
<div class='docstring'>
<p>Sets the parent of this JsonType object.</p>
</div>
<div class='tags'>
<h3>See also:</h3>
<ul class='see'>
<li>
<a href='WordType.setReplaceManager'>WordType.setReplaceManager</a>
</li>
</ul>
</div>
</div>
<div class='method_details'>
<p class='signature' id='getParent-dynamic'>
#
(JsonType)
<b>getParent</b><span>()</span>
<br>
</p>
<div class='docstring'>
<p>Get the parent of this JsonType.</p>
</div>
<div class='tags'>
<h3>Returns:</h3>
<ul class='return'>
<li>
<span class='type'></span>
<tt><a href='../class/JsonType.html'>JsonType</a></tt>
</li>
</ul>
</div>
</div>
<div class='method_details'>
@ -421,7 +359,7 @@ Otherwise you will loose all the sharing-abilities (the new object will be a dee
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -139,7 +139,7 @@ console.log(w.newProperty == &quot;Awesome&quot;) # true!</code></pre>
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -145,18 +145,6 @@ if (x.type === &quot;WordType&quot;) {
Deletes a part of the word.
</span>
</li>
<li>
<span class='signature'>
<a href='#replaceText-dynamic'>
#
(WordType)
<b>replaceText</b><span>(text)</span>
</a>
</span>
<span class='desc'>
Replace the content of this word with another one.
</span>
</li>
<li>
<span class='signature'>
<a href='#val-dynamic'>
@ -181,20 +169,6 @@ if (x.type === &quot;WordType&quot;) {
Same as WordType.val
</span>
</li>
<li>
<span class='signature'>
<a href='#setReplaceManager-dynamic'>
#
(void)
<b>setReplaceManager</b><span>(op)</span>
</a>
</span>
<span class='note private title'>Private</span>
<span class='desc'>
In most cases you would embed a WordType in a Replaceable, wich is handled by the ReplaceManager in order to provide replace functionality.
</span>
</li>
<li>
<span class='signature'>
<a href='#bind-dynamic'>
@ -332,31 +306,6 @@ if (x.type === &quot;WordType&quot;) {
<span class='desc'>This WordType object </span>
</li>
</ul>
</div>
</div>
<div class='method_details'>
<p class='signature' id='replaceText-dynamic'>
#
(WordType)
<b>replaceText</b><span>(text)</span>
<br>
</p>
<div class='docstring'>
<p>Replace the content of this word with another one. Concurrent replacements are not merged!
Only one of the replacements will be used.</p>
</div>
<div class='tags'>
<h3>Returns:</h3>
<ul class='return'>
<li>
<span class='type'></span>
(
<tt><a href='../class/WordType.html'>WordType</a></tt>
)
&mdash;
<span class='desc'>Returns the new WordType object. </span>
</li>
</ul>
</div>
</div>
<div class='method_details'>
@ -400,21 +349,6 @@ Only one of the replacements will be used.</p>
<a href='WordType.val'>WordType.val</a>
</li>
</ul>
</div>
</div>
<div class='method_details'>
<p class='signature' id='setReplaceManager-dynamic'>
#
(void)
<b>setReplaceManager</b><span>(op)</span>
<span class='note private'>Private</span>
<br>
</p>
<div class='docstring'>
<p>In most cases you would embed a WordType in a Replaceable, wich is handled by the ReplaceManager in order
to provide replace functionality.</p>
</div>
<div class='tags'>
</div>
</div>
<div class='method_details'>
@ -455,7 +389,7 @@ yatta.bind(textbox);</code></pre>
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -128,10 +128,10 @@ Known values that are supported:</p><ul>
</li>
<li>
<span class='signature'>
<a href='#on-dynamic'>
<a href='#observe-dynamic'>
#
(void)
<b>on</b><span>()</span>
<b>observe</b><span>()</span>
</a>
</span>
<span class='desc'>
@ -139,10 +139,10 @@ Known values that are supported:</p><ul>
</li>
<li>
<span class='signature'>
<a href='#deleteListener-dynamic'>
<a href='#unobserve-dynamic'>
#
(void)
<b>deleteListener</b><span>()</span>
<b>unobserve</b><span>()</span>
</a>
</span>
<span class='desc'>
@ -301,10 +301,10 @@ Yatta was initialized (Depending on the HistoryBuffer implementation).</p>
</div>
</div>
<div class='method_details'>
<p class='signature' id='on-dynamic'>
<p class='signature' id='observe-dynamic'>
#
(void)
<b>on</b><span>()</span>
<b>observe</b><span>()</span>
<br>
</p>
<div class='tags'>
@ -317,10 +317,10 @@ Yatta was initialized (Depending on the HistoryBuffer implementation).</p>
</div>
</div>
<div class='method_details'>
<p class='signature' id='deleteListener-dynamic'>
<p class='signature' id='unobserve-dynamic'>
#
(void)
<b>deleteListener</b><span>()</span>
<b>unobserve</b><span>()</span>
<br>
</p>
<div class='tags'>
@ -335,7 +335,7 @@ Yatta was initialized (Depending on the HistoryBuffer implementation).</p>
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -38,7 +38,7 @@
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -76,7 +76,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
</ul>
<h2 id="support">Support</h2><p>Please report <em>any</em> issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!
I would appreciate if developers gave me feedback on how <em>convenient</em> the framework is, and if it is easy to use. Particularly the XML-support may not support every DOM-methods - if you encounter a method that does not cause any change on other peers,
please state function name, and sample parameters. However, there are browser-specific features, that Yatta won&#39;t support.</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="&#x6d;&#x61;&#105;&#108;&#116;&#x6f;&#x3a;&#107;&#101;&#x76;&#x69;&#110;&#46;&#106;&#97;&#x68;&#x6e;&#115;&#64;&#x72;&#x77;&#x74;&#104;&#45;&#97;&#x61;&#99;&#x68;&#101;&#110;&#46;&#100;&#101;">&#107;&#101;&#x76;&#x69;&#110;&#46;&#106;&#97;&#x68;&#x6e;&#115;&#64;&#x72;&#x77;&#x74;&#104;&#45;&#97;&#x61;&#99;&#x68;&#101;&#110;&#46;&#100;&#101;</a>
please state function name, and sample parameters. However, there are browser-specific features, that Yatta won&#39;t support.</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="&#109;&#97;&#105;&#108;&#x74;&#111;&#58;&#107;&#101;&#118;&#x69;&#x6e;&#x2e;&#x6a;&#x61;&#104;&#x6e;&#115;&#64;&#x72;&#119;&#x74;&#104;&#45;&#x61;&#97;&#99;&#104;&#101;&#110;&#x2e;&#100;&#101;">&#107;&#101;&#118;&#x69;&#x6e;&#x2e;&#x6a;&#x61;&#104;&#x6e;&#115;&#64;&#x72;&#119;&#x74;&#104;&#45;&#x61;&#97;&#99;&#104;&#101;&#110;&#x2e;&#100;&#101;</a>
@ -85,7 +85,7 @@ please state function name, and sample parameters. However, there are browser-sp
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -106,7 +106,7 @@
</div>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -37,6 +37,30 @@
</table>
<h2>Variables Summary</h2>
<dl class='constants'>
<dt id='window.unprocessed_counter-variable'>
window.unprocessed_counter
=
</dt>
<dd>
<pre><code class='coffeescript'>0</code></pre>
</dd>
<dt id='window.unprocessed_exec_counter-variable'>
window.unprocessed_exec_counter
=
</dt>
<dd>
<pre><code class='coffeescript'>0</code></pre>
</dd>
<dt id='window.unprocessed_types-variable'>
window.unprocessed_types
=
</dt>
<dd>
<pre><code class='coffeescript'>[]</code></pre>
</dd>
<dt id='module.exports-variable'>
module.exports
=
@ -48,7 +72,7 @@
</dl>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -48,7 +48,7 @@
</dl>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -39,7 +39,7 @@
</table>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -39,7 +39,7 @@
</table>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -39,7 +39,7 @@
</table>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -39,7 +39,7 @@
</table>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -58,7 +58,7 @@
</dl>
</div>
<div id='footer'>
December 16, 14 17:57:44 by
December 17, 14 22:46:39 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo
</a>

View File

@ -1 +1 @@
window.searchData = [{"t":"JsonTypeWrapper","p":"class/JsonTypeWrapper.html"},{"t":"JsonType","p":"class/JsonType.html"},{"t":"WordType","p":"class/WordType.html"},{"t":"Yatta","p":"class/Yatta.html"},{"t":"lib/ConnectorAdapter.coffee","p":"file/lib/ConnectorAdapter.coffee.html"},{"t":"lib/Engine.coffee","p":"file/lib/Engine.coffee.html"},{"t":"lib/HistoryBuffer.coffee","p":"file/lib/HistoryBuffer.coffee.html"},{"t":"lib/Types/BasicTypes.coffee","p":"file/lib/Types/BasicTypes.coffee.html"},{"t":"lib/Types/JsonTypes.coffee","p":"file/lib/Types/JsonTypes.coffee.html"},{"t":"lib/Types/StructuredTypes.coffee","p":"file/lib/Types/StructuredTypes.coffee.html"},{"t":"lib/Types/TextTypes.coffee","p":"file/lib/Types/TextTypes.coffee.html"},{"t":"lib/Yatta.coffee","p":"file/lib/Yatta.coffee.html"},{"t":"README.md","p":"extra/README.md.html"},{"t":"LICENSE.txt","p":"extra/LICENSE.txt.html"},{"t":"JsonType#_encode","p":"class/JsonType.html#_encode-dynamic"},{"t":"WordType#_encode","p":"class/WordType.html#_encode-dynamic"},{"t":"lib/ConnectorAdapter.coffee~adaptConnector","p":"file/lib/ConnectorAdapter.coffee.html#adaptConnector-"},{"t":"JsonType#applyDelete","p":"class/JsonType.html#applyDelete-dynamic"},{"t":"WordType#applyDelete","p":"class/WordType.html#applyDelete-dynamic"},{"t":"WordType#bind","p":"class/WordType.html#bind-dynamic"},{"t":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"Yatta#deleteListener","p":"class/Yatta.html#deleteListener-dynamic"},{"t":"WordType#deleteText","p":"class/WordType.html#deleteText-dynamic"},{"t":"Yatta#getConnector","p":"class/Yatta.html#getConnector-dynamic"},{"t":"Yatta#getHistoryBuffer","p":"class/Yatta.html#getHistoryBuffer-dynamic"},{"t":"JsonType#getParent","p":"class/JsonType.html#getParent-dynamic"},{"t":"Yatta#getSharedObject","p":"class/Yatta.html#getSharedObject-dynamic"},{"t":"Yatta#getUserId","p":"class/Yatta.html#getUserId-dynamic"},{"t":"WordType#insertAfter","p":"class/WordType.html#insertAfter-dynamic"},{"t":"WordType#insertText","p":"class/WordType.html#insertText-dynamic"},{"t":"Yatta#on","p":"class/Yatta.html#on-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"WordType#replaceText","p":"class/WordType.html#replaceText-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"Yatta#setMutableDefault","p":"class/Yatta.html#setMutableDefault-dynamic"},{"t":"JsonType#setReplaceManager","p":"class/JsonType.html#setReplaceManager-dynamic"},{"t":"WordType#setReplaceManager","p":"class/WordType.html#setReplaceManager-dynamic"},{"t":"JsonType#toJson","p":"class/JsonType.html#toJson-dynamic"},{"t":"Yatta#toJson","p":"class/Yatta.html#toJson-dynamic"},{"t":"WordType#toString","p":"class/WordType.html#toString-dynamic"},{"t":"Yatta#val","p":"class/Yatta.html#val-dynamic"},{"t":"WordType#val","p":"class/WordType.html#val-dynamic"},{"t":"JsonType#val","p":"class/JsonType.html#val-dynamic"}]
window.searchData = [{"t":"JsonTypeWrapper","p":"class/JsonTypeWrapper.html"},{"t":"JsonType","p":"class/JsonType.html"},{"t":"WordType","p":"class/WordType.html"},{"t":"Yatta","p":"class/Yatta.html"},{"t":"lib/ConnectorAdapter.coffee","p":"file/lib/ConnectorAdapter.coffee.html"},{"t":"lib/Engine.coffee","p":"file/lib/Engine.coffee.html"},{"t":"lib/HistoryBuffer.coffee","p":"file/lib/HistoryBuffer.coffee.html"},{"t":"lib/Types/BasicTypes.coffee","p":"file/lib/Types/BasicTypes.coffee.html"},{"t":"lib/Types/JsonTypes.coffee","p":"file/lib/Types/JsonTypes.coffee.html"},{"t":"lib/Types/StructuredTypes.coffee","p":"file/lib/Types/StructuredTypes.coffee.html"},{"t":"lib/Types/TextTypes.coffee","p":"file/lib/Types/TextTypes.coffee.html"},{"t":"lib/Yatta.coffee","p":"file/lib/Yatta.coffee.html"},{"t":"README.md","p":"extra/README.md.html"},{"t":"LICENSE.txt","p":"extra/LICENSE.txt.html"},{"t":"JsonType#_encode","p":"class/JsonType.html#_encode-dynamic"},{"t":"WordType#_encode","p":"class/WordType.html#_encode-dynamic"},{"t":"lib/ConnectorAdapter.coffee~adaptConnector","p":"file/lib/ConnectorAdapter.coffee.html#adaptConnector-"},{"t":"WordType#applyDelete","p":"class/WordType.html#applyDelete-dynamic"},{"t":"JsonType#applyDelete","p":"class/JsonType.html#applyDelete-dynamic"},{"t":"WordType#bind","p":"class/WordType.html#bind-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#deleteText","p":"class/WordType.html#deleteText-dynamic"},{"t":"Yatta#getConnector","p":"class/Yatta.html#getConnector-dynamic"},{"t":"Yatta#getHistoryBuffer","p":"class/Yatta.html#getHistoryBuffer-dynamic"},{"t":"Yatta#getSharedObject","p":"class/Yatta.html#getSharedObject-dynamic"},{"t":"Yatta#getUserId","p":"class/Yatta.html#getUserId-dynamic"},{"t":"WordType#insertAfter","p":"class/WordType.html#insertAfter-dynamic"},{"t":"WordType#insertText","p":"class/WordType.html#insertText-dynamic"},{"t":"Yatta#observe","p":"class/Yatta.html#observe-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"Yatta#setMutableDefault","p":"class/Yatta.html#setMutableDefault-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"JsonType#toJson","p":"class/JsonType.html#toJson-dynamic"},{"t":"Yatta#toJson","p":"class/Yatta.html#toJson-dynamic"},{"t":"WordType#toString","p":"class/WordType.html#toString-dynamic"},{"t":"Yatta#unobserve","p":"class/Yatta.html#unobserve-dynamic"},{"t":"Yatta#val","p":"class/Yatta.html#val-dynamic"},{"t":"WordType#val","p":"class/WordType.html#val-dynamic"},{"t":"JsonType#val","p":"class/JsonType.html#val-dynamic"}]

View File

@ -53,14 +53,6 @@
(lib&#47;ConnectorAdapter.coffee)
</small>
</li>
<li>
<a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
#applyDelete
</a>
<small>
(JsonType)
</small>
</li>
<li>
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
#applyDelete
@ -70,16 +62,16 @@
</small>
</li>
<li>
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
#bind
<a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
#applyDelete
</a>
<small>
(WordType)
(JsonType)
</small>
</li>
<li>
<a href='class/WordType.html#cleanup-dynamic' target='main' title='cleanup'>
#cleanup
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
#bind
</a>
<small>
(WordType)
@ -93,6 +85,14 @@
(JsonType)
</small>
</li>
<li>
<a href='class/WordType.html#cleanup-dynamic' target='main' title='cleanup'>
#cleanup
</a>
<small>
(WordType)
</small>
</li>
<li>
<a href='class/Yatta.html#constructor-dynamic' target='main' title='constructor'>
#constructor
@ -101,14 +101,6 @@
(Yatta)
</small>
</li>
<li>
<a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(JsonTypeWrapper)
</small>
</li>
<li>
<a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
#constructor
@ -118,11 +110,11 @@
</small>
</li>
<li>
<a href='class/Yatta.html#deleteListener-dynamic' target='main' title='deleteListener'>
#deleteListener
<a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(Yatta)
(JsonTypeWrapper)
</small>
</li>
<li>
@ -149,14 +141,6 @@
(Yatta)
</small>
</li>
<li>
<a href='class/JsonType.html#getParent-dynamic' target='main' title='getParent'>
#getParent
</a>
<small>
(JsonType)
</small>
</li>
<li>
<a href='class/Yatta.html#getSharedObject-dynamic' target='main' title='getSharedObject'>
#getSharedObject
@ -190,8 +174,8 @@
</small>
</li>
<li>
<a href='class/Yatta.html#on-dynamic' target='main' title='on'>
#on
<a href='class/Yatta.html#observe-dynamic' target='main' title='observe'>
#observe
</a>
<small>
(Yatta)
@ -205,22 +189,6 @@
(WordType)
</small>
</li>
<li>
<a href='class/WordType.html#replaceText-dynamic' target='main' title='replaceText'>
#replaceText
</a>
<small>
(WordType)
</small>
</li>
<li>
<a href='class/JsonType.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
#setMutableDefault
</a>
<small>
(JsonType)
</small>
</li>
<li>
<a href='class/Yatta.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
#setMutableDefault
@ -230,21 +198,13 @@
</small>
</li>
<li>
<a href='class/JsonType.html#setReplaceManager-dynamic' target='main' title='setReplaceManager'>
#setReplaceManager
<a href='class/JsonType.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
#setMutableDefault
</a>
<small>
(JsonType)
</small>
</li>
<li>
<a href='class/WordType.html#setReplaceManager-dynamic' target='main' title='setReplaceManager'>
#setReplaceManager
</a>
<small>
(WordType)
</small>
</li>
<li>
<a href='class/JsonType.html#toJson-dynamic' target='main' title='toJson'>
#toJson
@ -269,6 +229,14 @@
(WordType)
</small>
</li>
<li>
<a href='class/Yatta.html#unobserve-dynamic' target='main' title='unobserve'>
#unobserve
</a>
<small>
(Yatta)
</small>
</li>
<li>
<a href='class/Yatta.html#val-dynamic' target='main' title='val'>
#val

View File

@ -0,0 +1,31 @@
## IWC + JSON Example
Here, I will give a short overview on how to use the IwcJson Framework in Role-SDK widgets.
First you have to include the following libraries in your widget file:
```
<script src="http://open-app.googlecode.com/files/openapp.js"></script>
<script src="http://dbis.rwth-aachen.de/gadgets/iwc/lib/iwc.js"></script>
<script src="http://dbis.rwth-aachen.de/~jahns/role-widgets/widgetbundles/libraries/DUIClient.js"></script>
<script src="../../build/browser/Frameworks/JsonFramework.min.js"></script>
<script src="../../build/browser/Connectors/IwcConnector.min.js"></script>
<script src="./index.js"></script>
```
A working widget implementation is [IwcJson.xml](./IwcJson.xml) and the js-file is [index.js](./index.js)
```js
function init(){
Y.createIwcConnector(function(Connector, user_id){
```
You don't have to use the proposed user_id.
```js
console.log("me is number 2")
yatta = new Y.JsonYatta(2, Connector);
})
}
window.onload = init
```

View File

@ -9,7 +9,7 @@ adaptConnector = (connector, engine, HB, execution_listener)->
send_ = (o)->
if o.uid.creator is HB.getUserId() and (typeof o.uid.op_number isnt "string")
connector.broadcast o
execution_listener.push send_
sendStateVector = ()->
HB.getOperationCounter()
@ -18,9 +18,9 @@ adaptConnector = (connector, engine, HB, execution_listener)->
applyHb = (hb)->
engine.applyOpsCheckDouble hb
connector.whenSyncing sendStateVector, sendHb, applyHb
connector.whenReceiving (sender, op)->
if op.uid.creator isnt HB.getUserId()
engine.applyOp op
module.exports = adaptConnector

View File

@ -1,4 +1,8 @@
window?.unprocessed_counter = 0 # del this
window?.unprocessed_exec_counter = 0 # TODO
window?.unprocessed_types = []
#
# @nodoc
# The Engine handles how and in which order to execute operations and add operations to the HistoryBuffer.
@ -22,7 +26,7 @@ class Engine
else
throw new Error "You forgot to specify a parser for type #{json.type}. The message is #{JSON.stringify json}."
#
# Apply a set of operations. E.g. the operations you received from another users HB._encode().
# @note You must not use this method when you already have ops in your HB!
@ -63,6 +67,8 @@ class Engine
if @HB.getOperation(o)?
else if not o.execute()
@unprocessed_ops.push o
window?.unprocessed_counter++ # TODO: del this
window?.unprocessed_types.push o.type
@tryUnprocessed()
#
@ -71,6 +77,7 @@ class Engine
#
tryUnprocessed: ()->
while true
window?.unprocessed_exec_counter++ # TODO: del this
old_length = @unprocessed_ops.length
unprocessed = []
for op in @unprocessed_ops

View File

@ -134,7 +134,7 @@ class HistoryBuffer
#
# Retrieve an operation from a unique id.
#
getOperation: (uid)->
getOperation: (uid)->
if uid.uid?
uid = uid.uid
@buffer[uid.creator]?[uid.op_number]

View File

@ -19,12 +19,13 @@ module.exports = (HB)->
class Operation
#
# @param {Object} uid A unique identifier.
# @param {Object} uid A unique identifier.
# If uid is undefined, a new uid will be created before at the end of the execution sequence
#
constructor: (uid)->
@is_deleted = false
@garbage_collected = false
@event_listeners = [] # TODO: rename to observers or sth like that
if uid?
@uid = uid
@ -32,41 +33,27 @@ module.exports = (HB)->
#
# Add an event listener. It depends on the operation which events are supported.
# @param {String} event Name of the event.
# @param {Function} f f is executed in case the event fires.
#
on: (events, f)->
@event_listeners ?= {}
if events.constructor isnt [].constructor
events = [events]
for e in events
@event_listeners[e] ?= []
@event_listeners[e].push f
observe: (f)->
@event_listeners.push f
#
# Deletes a function from an event / list of events.
# @see Operation.on
# Deletes function from the observer list
# @see Operation.observe
#
# @overload deleteListener(event, f)
# @param event {String} An event name
# @param f {Function} The function that you want to delete from these events
# @overload deleteListener(events, f)
# @param events {Array<String>} A list of event names
# @param f {Function} The function that you want to delete from these events.
deleteListener: (events, f)->
if events.constructor isnt [].constructor
events = [events]
for e in events
if @event_listeners?[e]?
@event_listeners[e] = @event_listeners[e].filter (g)->
f isnt g
#
# Deletes all subscribed event listeners.
# This should be called, e.g. after this has been replaced.
# @overload unobserve(event, f)
# @param f {Function} The function that you want to delete
unobserve: (f)->
@event_listeners.filter (g)->
f isnt g
#
# Deletes all subscribed event listeners.
# This should be called, e.g. after this has been replaced.
# (Then only one replace event should fire. )
# This is also called in the cleanup method.
deleteAllListeners: ()->
# This is also called in the cleanup method.
deleteAllObservers: ()->
@event_listeners = []
#
@ -78,11 +65,10 @@ module.exports = (HB)->
#
# Fire an event and specify in which context the listener is called (set 'this').
#
forwardEvent: (op, event, args...)->
if @event_listeners?[event]?
for f in @event_listeners[event]
f.call op, event, args...
# TODO: do you need this ?
forwardEvent: (op, args...)->
for f in @event_listeners
f.call op, args...
isDeleted: ()->
@is_deleted
@ -98,7 +84,7 @@ module.exports = (HB)->
cleanup: ()->
#console.log "cleanup: #{@type}"
HB.removeOperation @
@deleteAllListeners()
@deleteAllObservers()
#
# Set the parent of this operation.
@ -128,15 +114,15 @@ module.exports = (HB)->
#
execute: ()->
@is_executed = true
if not @uid?
# When this operation was created without a uid, then set it here.
# There is only one other place, where this can be done - before an Insertion
if not @uid?
# When this operation was created without a uid, then set it here.
# There is only one other place, where this can be done - before an Insertion
# is executed (because we need the creator_id)
@uid = HB.getNextOperationIdentifier()
@uid = HB.getNextOperationIdentifier()
HB.addOperation @
for l in execution_listener
l @_encode()
@
@
#
# @private
@ -388,7 +374,7 @@ module.exports = (HB)->
if parent? and fire_event
@setParent parent
@parent.callEvent "insert", @
@
@
#
# Compute the position of this operation.
@ -501,7 +487,7 @@ module.exports = (HB)->
delete @prev_cl.unchecked.next_cl
@prev_cl.next_cl = @
super
else if @prev_cl? or @next_cl? or true # TODO: are you sure? This can happen right?
else if @prev_cl? or @next_cl? or true # TODO: are you sure? This can happen right?
super
#else
# throw new Error "Delimiter is unsufficient defined!"

View File

@ -115,12 +115,16 @@ module.exports = (HB)->
cleanup: ()->
super()
#
# Transform this to a Json. If your browser supports Object.observe it will be transformed automatically when a change arrives.
# Transform this to a Json. If your browser supports Object.observe it will be transformed automatically when a change arrives.
# Otherwise you will loose all the sharing-abilities (the new object will be a deep clone)!
# @return {Json}
#
# TODO: at the moment you don't consider changing of properties.
# E.g.: let x = {a:[]}. Then x.a.push 1 wouldn't change anything
#
toJson: ()->
if not @bound_json? or not Object.observe? or true # TODO: currently, you are not watching mutable strings for changes, and, therefore, the @bound_json is not updated. TODO TODO wuawuawua easy
val = @val()
@ -137,14 +141,14 @@ module.exports = (HB)->
else
json[name] = o
@bound_json = json
if Object.observe?
if Object.observe?
that = @
Object.observe @bound_json, (events)->
for event in events
if not event.changed_by? and (event.type is "add" or event.type = "update")
# this event is not created by Yatta.
that.val(event.name, event.object[event.name])
that.on 'change', (event_name, property_name, op)->
that.observe (event_name, property_name, op)->
if this is that and op.uid.creator isnt HB.getUserId()
notifier = Object.getNotifier(that.bound_json)
oldVal = that.bound_json[property_name]
@ -152,17 +156,17 @@ module.exports = (HB)->
notifier.performChange 'update', ()->
that.bound_json[property_name] = that.val(property_name)
, that.bound_json
notifier.notify
notifier.notify
object: that.bound_json
type: 'update'
name: property_name
oldValue: oldVal
changed_by: op.uid.creator
else
else
notifier.performChange 'add', ()->
that.bound_json[property_name] = that.val(property_name)
, that.bound_json
notifier.notify
notifier.notify
object: that.bound_json
type: 'add'
name: property_name
@ -170,23 +174,6 @@ module.exports = (HB)->
changed_by: op.uid.creator
@bound_json
#
# @see WordType.setReplaceManager
# Sets the parent of this JsonType object.
#
setReplaceManager: (replace_manager)->
@replace_manager = replace_manager
@on ['change','addProperty'], ()->
if replace_manager.parent?
replace_manager.parent.forwardEvent this, arguments...
#
# Get the parent of this JsonType.
# @return {JsonType}
#
getParent: ()->
@replace_manager.parent
#
# Whether the default is 'mutable' (true) or 'immutable' (false)
#
@ -222,16 +209,7 @@ module.exports = (HB)->
# @return [JsonType] This object. (supports chaining)
#
val: (name, content, mutable)->
if typeof name is 'object'
# Special case. First argument is an object. Then the second arg is mutable.
# (I refer to var name and content here)
# Keep that in mind when reading the following..
jt = new JsonType()
@replace_manager.replace jt.execute()
for n,o of name
jt.val n, o, mutable
@
else if name? and arguments.length > 1
if name? and arguments.length > 1
if mutable?
if mutable is true or mutable is 'mutable'
mutable = true

View File

@ -91,10 +91,10 @@ module.exports = (HB)->
# always have the same result (ReplaceManager, and its beginning and end are the same)
#
execute: ()->
if not @validateSavedOperations()
if not @validateSavedOperations()
return false
else
# helper for cloning an object
# helper for cloning an object
clone = (o)->
p = {}
for name,value of o
@ -110,7 +110,7 @@ module.exports = (HB)->
uid_end.op_number = "#{uid_r.op_number}_end"
beg = (new types.Delimiter uid_beg, undefined, uid_end).execute()
end = (new types.Delimiter uid_end, beg, undefined).execute()
@map_manager.map[@name] = new ReplaceManager undefined, uid_r, beg, end
@map_manager.map[@name] = new ReplaceManager uid_r, beg, end
@map_manager.map[@name].setParent @map_manager, @name
(@map_manager.map[@name].add_name_ops ?= []).push @
@map_manager.map[@name].execute()
@ -224,10 +224,8 @@ module.exports = (HB)->
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
# @param {Delimiter} beginning Reference or Object.
# @param {Delimiter} end Reference or Object.
constructor: (initial_content, uid, beginning, end, prev, next, origin)->
super uid, beginning, end, prev, next, origin
if initial_content?
@replace initial_content
# constructor: (uid, beginning, end, prev, next, origin)->
# super uid, beginning, end, prev, next, origin
type: "ReplaceManager"
@ -256,24 +254,6 @@ module.exports = (HB)->
(new Replaceable content, @, replaceable_uid, o, o.next_cl).execute()
undefined
#
# Add change listeners for parent.
#
setParent: (parent, property_name)->
repl_manager = this
@on 'insert', (event, op)->
if op.next_cl instanceof types.Delimiter
repl_manager.parent.callEvent 'change', property_name, op
@on 'change', (event, op)->
if repl_manager isnt this
repl_manager.parent.callEvent 'change', property_name, op
# Call this, when the first element is inserted. Then delete the listener.
addPropertyListener = (event, op)->
repl_manager.deleteListener 'insert', addPropertyListener
repl_manager.parent.callEvent 'addProperty', property_name, op
@on 'insert', addPropertyListener
super parent
#
# Get the value of this WordType
# @return {String}
@ -304,7 +284,6 @@ module.exports = (HB)->
parser["ReplaceManager"] = (json)->
{
'content' : content
'uid' : uid
'prev': prev
'next': next
@ -312,7 +291,7 @@ module.exports = (HB)->
'beginning' : beginning
'end' : end
} = json
new ReplaceManager content, uid, beginning, end, prev, next, origin
new ReplaceManager uid, beginning, end, prev, next, origin
#
@ -342,16 +321,10 @@ module.exports = (HB)->
val: ()->
@content
#
# Replace the content of this replaceable with new content.
#
replace: (content)->
@parent.replace content
applyDelete: ()->
if @content?
if @next_cl.type isnt "Delimiter"
@content.deleteAllListeners()
@content.deleteAllObservers()
@content.applyDelete()
@content.dontSync()
@content = null
@ -361,16 +334,14 @@ module.exports = (HB)->
super
#
# If possible set the replace manager in the content.
# @see WordType.setReplaceManager
#
execute: ()->
if not @validateSavedOperations()
return false
else
@content?.setReplaceManager?(@parent)
# only fire 'insert-event' (which will result in addProperty and change events),
# when content is added. In case of Json, empty content means that this is not the last update,
# when content is added.
# In case of Json, empty content means that this is not the last update,
# since content is deleted when 'applyDelete' was exectuted.
ins_result = super(@content?) # @content? whether to fire or not
if ins_result

View File

@ -176,23 +176,6 @@ module.exports = (HB)->
delete_ops.push d._encode()
@
#
# Replace the content of this word with another one. Concurrent replacements are not merged!
# Only one of the replacements will be used.
#
# @return {WordType} Returns the new WordType object.
#
replaceText: (text)->
# Can only be used if the ReplaceManager was set!
# @see WordType.setReplaceManager
if @replace_manager?
word = (new WordType undefined).execute()
word.insertText 0, text
@replace_manager.replace(word)
word
else
throw new Error "This type is currently not maintained by a ReplaceManager!"
#
# Get the String-representation of this word.
# @return {String} The String-representation of this object.
@ -213,18 +196,6 @@ module.exports = (HB)->
@val()
#
# @private
# In most cases you would embed a WordType in a Replaceable, wich is handled by the ReplaceManager in order
# to provide replace functionality.
#
setReplaceManager: (op)->
@saveOperation 'replace_manager', op
@validateSavedOperations()
@on 'insert', (event, ins)=>
@replace_manager?.forwardEvent @, 'change', ins
@on 'delete', (event, ins, del)=>
@replace_manager?.forwardEvent @, 'change', del
#
# Bind this WordType to a textfield or input field.
#
# @example

View File

@ -135,7 +135,7 @@ module.exports = (HB)->
dont_proxy ()->
that.xml.removeChild deleted
@attributes.on ['addProperty', 'change'], (event, property_name, op)->
@attributes.on ['add', 'update'], (event, property_name, op)->
if op.creator isnt HB.getUserId() and this is that.attributes
dont_proxy ()->
newval = op.val().val()

View File

@ -9,11 +9,11 @@ adaptConnector = require "./ConnectorAdapter"
# Known values that are supported:
# * String
# * Integer
# * Array
# * Array
#
class Yatta
#
#
# @param {String} user_id Unique id of the peer.
# @param {Connector} Connector the connector class.
#
@ -25,21 +25,23 @@ class Yatta
@engine = new Engine @HB, type_manager.parser
@HB.engine = @engine # TODO: !! only for debugging
adaptConnector @connector, @engine, @HB, type_manager.execution_listener
first_word = new @types.JsonType(@HB.getReservedUniqueIdentifier()).execute()
#first_word =
@root_element = new @types.JsonType(@HB.getReservedUniqueIdentifier()).execute()
###
uid_beg = @HB.getReservedUniqueIdentifier()
uid_end = @HB.getReservedUniqueIdentifier()
beg = (new @types.Delimiter uid_beg, undefined, uid_end).execute()
end = (new @types.Delimiter uid_end, beg, undefined).execute()
@root_element = (new @types.ReplaceManager undefined, @HB.getReservedUniqueIdentifier(), beg, end).execute()
@root_element = (new @types.ReplaceManager @HB.getReservedUniqueIdentifier(), beg, end).execute()
@root_element.replace first_word, @HB.getReservedUniqueIdentifier()
###
#
# @return JsonType
#
getSharedObject: ()->
@root_element.val()
@root_element
#
# Get the initialized connector.
@ -82,14 +84,14 @@ class Yatta
#
# @see Operation.on
#
on: ()->
@getSharedObject().on arguments...
observe: ()->
@getSharedObject().observe arguments...
#
# @see Operation.deleteListener
#
deleteListener: ()->
@getSharedObject().deleteListener arguments...
unobserve: ()->
@getSharedObject().unobserve arguments...
#
# @see JsonType.value

View File

@ -73,11 +73,12 @@ describe "JsonFramework", ->
console.log "" # TODO
@yTest.run()
it "has a change listener", ()->
### TODO
it "has a update listener", ()->
addName = false
change = false
change2 = 0
@test_user.on 'addProperty', (eventname, property_name)->
@test_user.on 'add', (eventname, property_name)->
if property_name is 'x'
addName = true
@test_user.val('x',5)
@ -86,7 +87,7 @@ describe "JsonFramework", ->
change = true
@test_user.val('x', 6)
@test_user.val('ins', "text", 'mutable')
@test_user.on 'change', (eventname, property_name)->
@test_user.on 'update', (eventname, property_name)->
if property_name is 'ins'
change2++
@test_user.val('ins').insertText 4, " yay"
@ -94,6 +95,7 @@ describe "JsonFramework", ->
expect(addName).to.be.ok
expect(change).to.be.ok
expect(change2).to.equal 8
###
it "has a JsonTypeWrapper", ->
y = this.yTest.getSomeUser().getSharedObject()

File diff suppressed because one or more lines are too long