2014-12-14 17:00:02 +00:00

428 lines
79 KiB
HTML

<!DOCTYPE html> <html> <head> <title>observe-shim.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> observe-shim.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>Copyright 2012 Kap IT (http://www.kapit.fr/)</p>
<p>Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at</p>
<pre><code> http://www.apache.org/licenses/LICENSE-2.0
</code></pre>
<p>Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an 'AS IS' BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Author : François de Campredon (http://francois.de-campredon.fr/),</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <h1>Object.observe Shim</h1> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p><em>See <a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe">The harmony proposal page</a></em></p> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">global</span><span class="p">)</span> <span class="p">{</span>
<span class="s1">&#39;use strict&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <h2>Utilities</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>setImmediate shim used to deliver changes records asynchronously
use setImmediate if available</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">setImmediate</span> <span class="o">=</span> <span class="nx">global</span><span class="p">.</span><span class="nx">setImmediate</span> <span class="o">||</span> <span class="nx">global</span><span class="p">.</span><span class="nx">msSetImmediate</span><span class="p">,</span>
<span class="nx">clearImmediate</span> <span class="o">=</span> <span class="nx">global</span><span class="p">.</span><span class="nx">clearImmediate</span> <span class="o">||</span> <span class="nx">global</span><span class="p">.</span><span class="nx">msClearImmediate</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">setImmediate</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>fallback on setTimeout if not</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">setImmediate</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">clearImmediate</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">clearTimeout</span><span class="p">(</span><span class="nx">id</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h2>WeakMap</h2> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">PrivateMap</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">WeakMap</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>use weakmap if defined</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">PrivateMap</span> <span class="o">=</span> <span class="nx">WeakMap</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>else use ses like shim of WeakMap</p> </td> <td class="code"> <div class="highlight"><pre> <span class="cm">/* jshint -W016 */</span>
<span class="kd">var</span> <span class="nx">HIDDEN_PREFIX</span> <span class="o">=</span> <span class="s1">&#39;__weakmap:&#39;</span> <span class="o">+</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">1</span><span class="nx">e9</span> <span class="o">&gt;&gt;&gt;</span> <span class="mi">0</span><span class="p">),</span>
<span class="nx">counter</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">%</span> <span class="mi">1</span><span class="nx">e9</span><span class="p">,</span>
<span class="nx">mascot</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">PrivateMap</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">HIDDEN_PREFIX</span> <span class="o">+</span> <span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">1</span><span class="nx">e9</span> <span class="o">&gt;&gt;&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="nx">counter</span><span class="o">++</span> <span class="o">+</span> <span class="s1">&#39;__&#39;</span><span class="p">);</span>
<span class="p">};</span>
<span class="nx">PrivateMap</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">has</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">key</span> <span class="o">&amp;&amp;</span> <span class="nx">key</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">);</span>
<span class="p">},</span>
<span class="nx">get</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">key</span> <span class="o">&amp;&amp;</span> <span class="nx">key</span><span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">];</span>
<span class="k">return</span> <span class="nx">value</span> <span class="o">===</span> <span class="nx">mascot</span> <span class="o">?</span> <span class="kc">undefined</span> <span class="o">:</span> <span class="nx">value</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">set</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span> <span class="o">:</span> <span class="k">typeof</span> <span class="nx">value</span> <span class="o">===</span> <span class="s1">&#39;undefined&#39;</span> <span class="o">?</span> <span class="nx">mascot</span> <span class="o">:</span> <span class="nx">value</span><span class="p">,</span>
<span class="nx">enumerable</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">writable</span> <span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="p">},</span>
<span class="s1">&#39;delete&#39;</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">delete</span> <span class="nx">key</span><span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">];</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">getOwnPropertyName</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyNames</span><span class="p">;</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nb">Object</span><span class="p">,</span> <span class="s1">&#39;getOwnPropertyNames&#39;</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">fakeGetOwnPropertyNames</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">getOwnPropertyName</span><span class="p">(</span><span class="nx">obj</span><span class="p">).</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">name</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">HIDDEN_PREFIX</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">HIDDEN_PREFIX</span><span class="p">;</span>
<span class="p">});</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">enumerable</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <h2>Internal Properties</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>An ordered list used to provide a deterministic ordering in which callbacks are called.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#observercallbacks">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">observerCallbacks</span> <span class="o">=</span> <span class="p">[];</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>This object is used as the prototype of all the notifiers that are returned by Object.getNotifier(O).
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#notifierprototype">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">NotifierPrototype</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Used to store immediate uid reference</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">changeDeliveryImmediateUid</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Used to schedule a call to _deliverAllChangeRecords</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">setUpChangesDelivery</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">clearImmediate</span><span class="p">(</span><span class="nx">changeDeliveryImmediateUid</span><span class="p">);</span>
<span class="nx">changeDeliveryImmediateUid</span> <span class="o">=</span> <span class="nx">setImmediate</span><span class="p">(</span><span class="nx">_deliverAllChangeRecords</span><span class="p">);</span>
<span class="p">}</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">NotifierPrototype</span><span class="p">,</span> <span class="s1">&#39;notify&#39;</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">notify</span><span class="p">(</span><span class="nx">changeRecord</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">notifier</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">notifier</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;this must be an Object, given &#39;</span> <span class="o">+</span> <span class="nx">notifier</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">changeRecord</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">changeRecord</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;changeRecord must be an Object, given &#39;</span> <span class="o">+</span> <span class="nx">changeRecord</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">changeRecord</span><span class="p">.</span><span class="nx">type</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">type</span> <span class="o">!==</span> <span class="s1">&#39;string&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;changeRecord.type must be a string, given &#39;</span> <span class="o">+</span> <span class="nx">type</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">changeObservers</span> <span class="o">=</span> <span class="nx">changeObserversMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">changeObservers</span> <span class="o">||</span> <span class="nx">changeObservers</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">,</span>
<span class="nx">newRecord</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="p">{</span>
<span class="s1">&#39;object&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">target</span><span class="p">,</span>
<span class="nx">writable</span> <span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">enumerable</span> <span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">changeRecord</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">prop</span> <span class="o">!==</span> <span class="s1">&#39;object&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">changeRecord</span><span class="p">[</span><span class="nx">prop</span><span class="p">];</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">newRecord</span><span class="p">,</span> <span class="nx">prop</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">value</span><span class="p">,</span>
<span class="nx">writable</span> <span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">enumerable</span> <span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">preventExtensions</span><span class="p">(</span><span class="nx">newRecord</span><span class="p">);</span>
<span class="nx">_enqueueChangeRecord</span><span class="p">(</span><span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">,</span> <span class="nx">newRecord</span><span class="p">);</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">enumerable</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">configurable</span> <span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">NotifierPrototype</span><span class="p">,</span> <span class="s1">&#39;performChange&#39;</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">performChange</span><span class="p">(</span><span class="nx">changeType</span><span class="p">,</span> <span class="nx">changeFn</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">notifier</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">notifier</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;this must be an Object, given &#39;</span> <span class="o">+</span> <span class="nx">notifier</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">changeType</span> <span class="o">!==</span> <span class="s1">&#39;string&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;changeType must be a string given &#39;</span> <span class="o">+</span> <span class="nx">notifier</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">changeFn</span> <span class="o">!==</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;changeFn must be a function, given &#39;</span> <span class="o">+</span> <span class="nx">changeFn</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">_beginChange</span><span class="p">(</span><span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">,</span> <span class="nx">changeType</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">error</span><span class="p">,</span> <span class="nx">changeRecord</span><span class="p">;</span>
<span class="k">try</span> <span class="p">{</span>
<span class="nx">changeRecord</span> <span class="o">=</span> <span class="nx">changeFn</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="kc">undefined</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">error</span> <span class="o">=</span> <span class="nx">e</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">_endChange</span><span class="p">(</span><span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">,</span> <span class="nx">changeType</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">error</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">changeObservers</span> <span class="o">=</span> <span class="nx">changeObserversMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">changeObservers</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">,</span>
<span class="nx">newRecord</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="p">{</span>
<span class="s1">&#39;object&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">target</span><span class="p">,</span>
<span class="nx">writable</span> <span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">enumerable</span> <span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">},</span>
<span class="s1">&#39;type&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">changeType</span><span class="p">,</span>
<span class="nx">writable</span> <span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">enumerable</span> <span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">changeRecord</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">changeRecord</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">prop</span> <span class="o">!==</span> <span class="s1">&#39;object&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">prop</span> <span class="o">!==</span> <span class="s1">&#39;type&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">changeRecord</span><span class="p">[</span><span class="nx">prop</span><span class="p">];</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">newRecord</span><span class="p">,</span> <span class="nx">prop</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">value</span><span class="p">,</span>
<span class="nx">writable</span> <span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">enumerable</span> <span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">preventExtensions</span><span class="p">(</span><span class="nx">newRecord</span><span class="p">);</span>
<span class="nx">_enqueueChangeRecord</span><span class="p">(</span><span class="nx">notifier</span><span class="p">.</span><span class="nx">__target</span><span class="p">,</span> <span class="nx">newRecord</span><span class="p">);</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">enumerable</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nx">configurable</span> <span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Implementation of the internal algorithm 'BeginChange'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#beginchange">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_beginChange</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">changeType</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getNotifier</span><span class="p">(</span><span class="nx">object</span><span class="p">),</span>
<span class="nx">activeChanges</span> <span class="o">=</span> <span class="nx">activeChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">),</span>
<span class="nx">changeCount</span> <span class="o">=</span> <span class="nx">activeChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">)[</span><span class="nx">changeType</span><span class="p">];</span>
<span class="nx">activeChanges</span><span class="p">[</span><span class="nx">changeType</span><span class="p">]</span> <span class="o">=</span> <span class="k">typeof</span> <span class="nx">changeCount</span> <span class="o">===</span> <span class="s1">&#39;undefined&#39;</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="nx">changeCount</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Implementation of the internal algorithm 'EndChange'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#endchange">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_endChange</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">changeType</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getNotifier</span><span class="p">(</span><span class="nx">object</span><span class="p">),</span>
<span class="nx">activeChanges</span> <span class="o">=</span> <span class="nx">activeChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">),</span>
<span class="nx">changeCount</span> <span class="o">=</span> <span class="nx">activeChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">)[</span><span class="nx">changeType</span><span class="p">];</span>
<span class="nx">activeChanges</span><span class="p">[</span><span class="nx">changeType</span><span class="p">]</span> <span class="o">=</span> <span class="nx">changeCount</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="nx">changeCount</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Implementation of the internal algorithm 'ShouldDeliverToObserver'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#shoulddelivertoobserver">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_shouldDeliverToObserver</span><span class="p">(</span><span class="nx">activeChanges</span><span class="p">,</span> <span class="nx">acceptList</span><span class="p">,</span> <span class="nx">changeType</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">doesAccept</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">acceptList</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">acceptList</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">accept</span> <span class="o">=</span> <span class="nx">acceptList</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">activeChanges</span><span class="p">[</span><span class="nx">accept</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">accept</span> <span class="o">===</span> <span class="nx">changeType</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">doesAccept</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">doesAccept</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Map used to store corresponding notifier to an object</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">notifierMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrivateMap</span><span class="p">(),</span>
<span class="nx">changeObserversMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrivateMap</span><span class="p">(),</span>
<span class="nx">activeChangesMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrivateMap</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>Implementation of the internal algorithm 'GetNotifier'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#getnotifier">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_getNotifier</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">notifierMap</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">target</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">NotifierPrototype</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>we does not really need to hide this, since anyway the host object is accessible from outside of the
implementation. we just make it unwritable</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">notifier</span><span class="p">,</span> <span class="s1">&#39;__target&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">value</span> <span class="o">:</span> <span class="nx">target</span> <span class="p">});</span>
<span class="nx">changeObserversMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">notifier</span><span class="p">,</span> <span class="p">[]);</span>
<span class="nx">activeChangesMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">notifier</span><span class="p">,</span> <span class="p">{});</span>
<span class="nx">notifierMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">target</span><span class="p">,</span> <span class="nx">notifier</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">notifierMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">target</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>map used to store reference to a list of pending changeRecords
in observer callback.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">pendingChangesMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrivateMap</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Implementation of the internal algorithm 'EnqueueChangeRecord'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#enqueuechangerecord">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_enqueueChangeRecord</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">changeRecord</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getNotifier</span><span class="p">(</span><span class="nx">object</span><span class="p">),</span>
<span class="nx">changeType</span> <span class="o">=</span> <span class="nx">changeRecord</span><span class="p">.</span><span class="nx">type</span><span class="p">,</span>
<span class="nx">activeChanges</span> <span class="o">=</span> <span class="nx">activeChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">),</span>
<span class="nx">changeObservers</span> <span class="o">=</span> <span class="nx">changeObserversMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">changeObservers</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">observerRecord</span> <span class="o">=</span> <span class="nx">changeObservers</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span>
<span class="nx">acceptList</span> <span class="o">=</span> <span class="nx">observerRecord</span><span class="p">.</span><span class="nx">accept</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_shouldDeliverToObserver</span><span class="p">(</span><span class="nx">activeChanges</span><span class="p">,</span> <span class="nx">acceptList</span><span class="p">,</span> <span class="nx">changeType</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">observer</span> <span class="o">=</span> <span class="nx">observerRecord</span><span class="p">.</span><span class="nx">callback</span><span class="p">,</span>
<span class="nx">pendingChangeRecords</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">pendingChangesMap</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">observer</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">pendingChangesMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">observer</span><span class="p">,</span> <span class="nx">pendingChangeRecords</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">pendingChangeRecords</span> <span class="o">=</span> <span class="nx">pendingChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">observer</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">pendingChangeRecords</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">changeRecord</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">setUpChangesDelivery</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>map used to store a count of associated notifier to a function</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">attachedNotifierCountMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">PrivateMap</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Remove reference all reference to an observer callback,
if this one is not used anymore.
In the proposal the ObserverCallBack has a weak reference over observers,
Without this possibility we need to clean this list to avoid memory leak</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_cleanObserver</span><span class="p">(</span><span class="nx">observer</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">observer</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">pendingChangesMap</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">observer</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">observer</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">index</span> <span class="o">=</span> <span class="nx">observerCallbacks</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">observer</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">index</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">observerCallbacks</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Implementation of the internal algorithm 'DeliverChangeRecords'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#deliverchangerecords">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_deliverChangeRecords</span><span class="p">(</span><span class="nx">observer</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">pendingChangeRecords</span> <span class="o">=</span> <span class="nx">pendingChangesMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">observer</span><span class="p">);</span>
<span class="nx">pendingChangesMap</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">observer</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">pendingChangeRecords</span> <span class="o">||</span> <span class="nx">pendingChangeRecords</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">try</span> <span class="p">{</span>
<span class="nx">observer</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="kc">undefined</span><span class="p">,</span> <span class="nx">pendingChangeRecords</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
<span class="nx">_cleanObserver</span><span class="p">(</span><span class="nx">observer</span><span class="p">);</span>
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>Implementation of the internal algorithm 'DeliverAllChangeRecords'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_internals#deliverallchangerecords">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">_deliverAllChangeRecords</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">observers</span> <span class="o">=</span> <span class="nx">observerCallbacks</span><span class="p">.</span><span class="nx">slice</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">anyWorkDone</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">observers</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">observer</span> <span class="o">=</span> <span class="nx">observers</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_deliverChangeRecords</span><span class="p">(</span><span class="nx">observer</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">anyWorkDone</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">anyWorkDone</span><span class="p">;</span>
<span class="p">}</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperties</span><span class="p">(</span><span class="nb">Object</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>Implementation of the public api 'Object.observe'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_public_api#object.observe">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="s1">&#39;observe&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">observe</span><span class="p">(</span><span class="nx">target</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="nx">accept</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;target must be an Object, given &#39;</span> <span class="o">+</span> <span class="nx">target</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">callback</span> <span class="o">!==</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;observer must be a function, given &#39;</span> <span class="o">+</span> <span class="nx">callback</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">isFrozen</span><span class="p">(</span><span class="nx">callback</span><span class="p">))</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;observer cannot be frozen&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">acceptList</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">accept</span> <span class="o">===</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">acceptList</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;add&#39;</span><span class="p">,</span> <span class="s1">&#39;update&#39;</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">,</span> <span class="s1">&#39;reconfigure&#39;</span><span class="p">,</span> <span class="s1">&#39;setPrototype&#39;</span><span class="p">,</span> <span class="s1">&#39;preventExtensions&#39;</span><span class="p">];</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">accept</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">accept</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;accept must be an object, given &#39;</span> <span class="o">+</span> <span class="nx">accept</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">accept</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">len</span> <span class="o">!==</span> <span class="s1">&#39;number&#39;</span> <span class="o">||</span> <span class="nx">len</span> <span class="o">&gt;&gt;&gt;</span> <span class="mi">0</span> <span class="o">!==</span> <span class="nx">len</span> <span class="o">||</span> <span class="nx">len</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;the \&#39;length\&#39; property of accept must be a positive integer, given &#39;</span> <span class="o">+</span> <span class="nx">len</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">nextIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">acceptList</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">nextIndex</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">accept</span><span class="p">[</span><span class="nx">nextIndex</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">next</span> <span class="o">!==</span> <span class="s1">&#39;string&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;accept must contains only string, given&#39;</span> <span class="o">+</span> <span class="nx">next</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">acceptList</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">next</span><span class="p">);</span>
<span class="nx">nextIndex</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="nx">_getNotifier</span><span class="p">(</span><span class="nx">target</span><span class="p">),</span>
<span class="nx">changeObservers</span> <span class="o">=</span> <span class="nx">changeObserversMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">changeObservers</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">changeObservers</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">callback</span> <span class="o">===</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">changeObservers</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">accept</span> <span class="o">=</span> <span class="nx">acceptList</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">target</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">changeObservers</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
<span class="nx">callback</span><span class="o">:</span> <span class="nx">callback</span><span class="p">,</span>
<span class="nx">accept</span><span class="o">:</span> <span class="nx">acceptList</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">observerCallbacks</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">observerCallbacks</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">callback</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">target</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Implementation of the public api 'Object.unobseve'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_public_api#object.unobseve">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="s1">&#39;unobserve&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">unobserve</span><span class="p">(</span><span class="nx">target</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;target must be an Object, given &#39;</span> <span class="o">+</span> <span class="nx">target</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">callback</span> <span class="o">!==</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;observer must be a function, given &#39;</span> <span class="o">+</span> <span class="nx">callback</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">notifier</span> <span class="o">=</span> <span class="nx">_getNotifier</span><span class="p">(</span><span class="nx">target</span><span class="p">),</span>
<span class="nx">changeObservers</span> <span class="o">=</span> <span class="nx">changeObserversMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">notifier</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">changeObservers</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">changeObservers</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">callback</span> <span class="o">===</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">changeObservers</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">attachedNotifierCountMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">_cleanObserver</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">target</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>Implementation of the public api 'Object.deliverChangeRecords'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_public_api#object.deliverchangerecords">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="s1">&#39;deliverChangeRecords&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">deliverChangeRecords</span><span class="p">(</span><span class="nx">observer</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">observer</span> <span class="o">!==</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;callback must be a function, given &#39;</span> <span class="o">+</span> <span class="nx">observer</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">_deliverChangeRecords</span><span class="p">(</span><span class="nx">observer</span><span class="p">))</span> <span class="p">{}</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>Implementation of the public api 'Object.getNotifier'
described in the proposal.
<a href="http://wiki.ecmascript.org/doku.php?id=harmony:observe_public_api#object.getnotifier">Corresponding Section in ECMAScript wiki</a></p> </td> <td class="code"> <div class="highlight"><pre> <span class="s1">&#39;getNotifier&#39;</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="kd">function</span> <span class="nx">getNotifier</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="o">!==</span> <span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;target must be an Object, given &#39;</span> <span class="o">+</span> <span class="nx">target</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">isFrozen</span><span class="p">(</span><span class="nx">target</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">_getNotifier</span><span class="p">(</span><span class="nx">target</span><span class="p">);</span>
<span class="p">},</span>
<span class="nx">writable</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="nx">configurable</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">})(</span><span class="k">typeof</span> <span class="nx">global</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span> <span class="o">?</span> <span class="nx">global</span> <span class="o">:</span> <span class="k">this</span><span class="p">);</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>