Skip to content
Browse files

chassis block reloading

  • Loading branch information...
1 parent 930c121 commit 042c3cef45b8bd53a536e23f1feb89aaec6d8962 @collin committed Dec 12, 2012
View
0 examples/todo/.monitor
No changes.
View
0 examples/todo/.nodemonignore
No changes.
View
4 examples/todo/.stitchignore
@@ -1,4 +0,0 @@
-/share/src/server
-coffee-script
-/bin/
-/socket.io-client/lib/vendor/
View
186 examples/todo/docs/docco.css
@@ -1,186 +0,0 @@
-/*--------------------- Layout and Typography ----------------------------*/
-body {
- font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
- font-size: 15px;
- line-height: 22px;
- color: #252519;
- margin: 0; padding: 0;
-}
-a {
- color: #261a3b;
-}
- a:visited {
- color: #261a3b;
- }
-p {
- margin: 0 0 15px 0;
-}
-h1, h2, h3, h4, h5, h6 {
- margin: 0px 0 15px 0;
-}
- h1 {
- margin-top: 40px;
- }
-#container {
- position: relative;
-}
-#background {
- position: fixed;
- top: 0; left: 525px; right: 0; bottom: 0;
- background: #f5f5ff;
- border-left: 1px solid #e5e5ee;
- z-index: -1;
-}
-#jump_to, #jump_page {
- background: white;
- -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
- -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
- font: 10px Arial;
- text-transform: uppercase;
- cursor: pointer;
- text-align: right;
-}
-#jump_to, #jump_wrapper {
- position: fixed;
- right: 0; top: 0;
- padding: 5px 10px;
-}
- #jump_wrapper {
- padding: 0;
- display: none;
- }
- #jump_to:hover #jump_wrapper {
- display: block;
- }
- #jump_page {
- padding: 5px 0 3px;
- margin: 0 0 25px 25px;
- }
- #jump_page .source {
- display: block;
- padding: 5px 10px;
- text-decoration: none;
- border-top: 1px solid #eee;
- }
- #jump_page .source:hover {
- background: #f5f5ff;
- }
- #jump_page .source:first-child {
- }
-table td {
- border: 0;
- outline: 0;
-}
- td.docs, th.docs {
- max-width: 450px;
- min-width: 450px;
- min-height: 5px;
- padding: 10px 25px 1px 50px;
- overflow-x: hidden;
- vertical-align: top;
- text-align: left;
- }
- .docs pre {
- margin: 15px 0 15px;
- padding-left: 15px;
- }
- .docs p tt, .docs p code {
- background: #f8f8ff;
- border: 1px solid #dedede;
- font-size: 12px;
- padding: 0 0.2em;
- }
- .pilwrap {
- position: relative;
- }
- .pilcrow {
- font: 12px Arial;
- text-decoration: none;
- color: #454545;
- position: absolute;
- top: 3px; left: -20px;
- padding: 1px 2px;
- opacity: 0;
- -webkit-transition: opacity 0.2s linear;
- }
- td.docs:hover .pilcrow {
- opacity: 1;
- }
- td.code, th.code {
- padding: 14px 15px 16px 25px;
- width: 100%;
- vertical-align: top;
- background: #f5f5ff;
- border-left: 1px solid #e5e5ee;
- }
- pre, tt, code {
- font-size: 12px; line-height: 18px;
- font-family: Monaco, Consolas, "Lucida Console", monospace;
- margin: 0; padding: 0;
- }
-
-
-/*---------------------- Syntax Highlighting -----------------------------*/
-td.linenos { background-color: #f0f0f0; padding-right: 10px; }
-span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
-body .hll { background-color: #ffffcc }
-body .c { color: #408080; font-style: italic } /* Comment */
-body .err { border: 1px solid #FF0000 } /* Error */
-body .k { color: #954121 } /* Keyword */
-body .o { color: #666666 } /* Operator */
-body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
-body .cp { color: #BC7A00 } /* Comment.Preproc */
-body .c1 { color: #408080; font-style: italic } /* Comment.Single */
-body .cs { color: #408080; font-style: italic } /* Comment.Special */
-body .gd { color: #A00000 } /* Generic.Deleted */
-body .ge { font-style: italic } /* Generic.Emph */
-body .gr { color: #FF0000 } /* Generic.Error */
-body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-body .gi { color: #00A000 } /* Generic.Inserted */
-body .go { color: #808080 } /* Generic.Output */
-body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
-body .gs { font-weight: bold } /* Generic.Strong */
-body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-body .gt { color: #0040D0 } /* Generic.Traceback */
-body .kc { color: #954121 } /* Keyword.Constant */
-body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
-body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
-body .kp { color: #954121 } /* Keyword.Pseudo */
-body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
-body .kt { color: #B00040 } /* Keyword.Type */
-body .m { color: #666666 } /* Literal.Number */
-body .s { color: #219161 } /* Literal.String */
-body .na { color: #7D9029 } /* Name.Attribute */
-body .nb { color: #954121 } /* Name.Builtin */
-body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
-body .no { color: #880000 } /* Name.Constant */
-body .nd { color: #AA22FF } /* Name.Decorator */
-body .ni { color: #999999; font-weight: bold } /* Name.Entity */
-body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
-body .nf { color: #0000FF } /* Name.Function */
-body .nl { color: #A0A000 } /* Name.Label */
-body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
-body .nt { color: #954121; font-weight: bold } /* Name.Tag */
-body .nv { color: #19469D } /* Name.Variable */
-body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
-body .w { color: #bbbbbb } /* Text.Whitespace */
-body .mf { color: #666666 } /* Literal.Number.Float */
-body .mh { color: #666666 } /* Literal.Number.Hex */
-body .mi { color: #666666 } /* Literal.Number.Integer */
-body .mo { color: #666666 } /* Literal.Number.Oct */
-body .sb { color: #219161 } /* Literal.String.Backtick */
-body .sc { color: #219161 } /* Literal.String.Char */
-body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
-body .s2 { color: #219161 } /* Literal.String.Double */
-body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
-body .sh { color: #219161 } /* Literal.String.Heredoc */
-body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
-body .sx { color: #954121 } /* Literal.String.Other */
-body .sr { color: #BB6688 } /* Literal.String.Regex */
-body .s1 { color: #219161 } /* Literal.String.Single */
-body .ss { color: #19469D } /* Literal.String.Symbol */
-body .bp { color: #954121 } /* Name.Builtin.Pseudo */
-body .vc { color: #19469D } /* Name.Variable.Class */
-body .vg { color: #19469D } /* Name.Variable.Global */
-body .vi { color: #19469D } /* Name.Variable.Instance */
-body .il { color: #666666 } /* Literal.Number.Integer.Long */
View
141 examples/todo/docs/todo.html
@@ -1,141 +0,0 @@
-<!DOCTYPE html> <html> <head> <title>todo.coffee</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> todo.coffee </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> <h4>Alpha Simprini Todo example application.</h4>
-
-<p>The first step is to load Alpha Simprini and the AS <code>client</code> module.
-The client module includes the AS.View class and is used to generate
-guis.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">AS = </span><span class="nx">require</span><span class="p">(</span><span class="s2">&quot;alpha_simprini&quot;</span><span class="p">)</span>
-<span class="nx">AS</span><span class="p">.</span><span class="nx">require</span><span class="p">(</span><span class="s2">&quot;client&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>This module contains Modules and Views.
-More complicated modules might include a Collections object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Todo = module.exports =</span>
- <span class="nv">Models: </span><span class="k">new</span> <span class="nb">Object</span>
- <span class="nv">Views: </span><span class="k">new</span> <span class="nb">Object</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h3>Todo.Models.List</h3> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">List</span> <span class="k">extends</span> <span class="nx">AS</span><span class="p">.</span><span class="nx">Model</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>The AS.Model.Share mixin adds features from the ShareJS library.
-The ShareJS integration neccessitates a string path which is used
-to inflate objects passed in through the ShareJS transport.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">AS</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">Share</span><span class="p">.</span><span class="k">extends</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s2">&quot;Todo.Models.List&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <h4>Fields</h4>
-
-<p>The name field is a simple string property with a default value.
-It's a suitable default name for a list of things to do.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@field</span> <span class="s2">&quot;name&quot;</span><span class="p">,</span> <span class="nv">default: </span><span class="s2">&quot;A list of things to do...&quot;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <h4>Relationships</h4>
-
-<p>When we embed_many items, we're creating a 1-n relationship between
-Lists and Items. In coordination with AS.Model.Share, @embeds_many
-stores all the embedded models within the same ShareJS document as
-the list object. If we had used @has_many, they would be stored in
-seperate documents with something like a foreign key relation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@embeds_many</span> <span class="s2">&quot;items&quot;</span><span class="p">,</span> <span class="nv">model: </span><span class="o">-&gt;</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">Item</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h4>Virtual Properties</h4>
-
-<p>These virtual properties are similar to computed properties in Ember.js.
-These particular properties only hinge on one real property, but they
-could be connected to any number of properties (including other virtual
-properties.)</p>
-
-<p>When the 'items' collection changes, these functions are ran and the reluts
-are compared to previous values. If the value is different a change event is
-triggered.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@virtualProperties</span> <span class="s2">&quot;items&quot;</span><span class="p">,</span>
- <span class="nv">items_length: </span><span class="o">-&gt;</span>
- <span class="nx">@items</span><span class="p">().</span><span class="nx">length</span>
-
- <span class="nv">remaining_items_length: </span><span class="o">-&gt;</span>
- <span class="nx">@items</span><span class="p">().</span><span class="nx">filter</span><span class="p">(</span><span class="nf">(item) -&gt;</span> <span class="o">!</span><span class="nx">item</span><span class="p">.</span><span class="nx">done</span><span class="p">()).</span><span class="nx">value</span><span class="p">().</span><span class="nx">length</span>
-
- <span class="nv">all_done: </span><span class="o">-&gt;</span>
- <span class="nx">@remaining_items_length</span><span class="p">()</span> <span class="o">is</span> <span class="mi">0</span>
-
- <span class="nv">done_items_length: </span><span class="o">-&gt;</span>
- <span class="nx">@items</span><span class="p">().</span><span class="nx">filter</span><span class="p">(</span><span class="nf">(item) -&gt;</span> <span class="nx">item</span><span class="p">.</span><span class="nx">done</span><span class="p">()).</span><span class="nx">value</span><span class="p">().</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <h3>Todo.Models.Item</h3>
-
-<p>These items are embedded within a Todo.Views.List</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">Item</span> <span class="k">extends</span> <span class="nx">AS</span><span class="p">.</span><span class="nx">Model</span>
- <span class="nx">AS</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">Share</span><span class="p">.</span><span class="k">extends</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s2">&quot;Todo.Models.Item&quot;</span><span class="p">)</span>
-
- <span class="nx">@field</span> <span class="s2">&quot;task&quot;</span><span class="p">,</span> <span class="nv">default: </span><span class="s2">&quot;Something to do...&quot;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <h4>Field types.</h4>
-
-<p>A field may have a type. This field is a boolean field.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@field</span> <span class="s2">&quot;done&quot;</span><span class="p">,</span> <span class="nv">type: </span><span class="nb">Boolean</span><span class="p">,</span> <span class="nv">default: </span><span class="kc">false</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <h3>Todo.Views.List</h3> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Views</span><span class="p">.</span><span class="nx">List</span> <span class="k">extends</span> <span class="nx">AS</span><span class="p">.</span><span class="nx">View</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <h4>View Events</h4>
-
-<p>Similar to Backbone.js View events these events are 'live' bound
-to the container element for this view.
-In this case, the jQuery for these events might look like this:</p>
-
-<pre><code>this.el.find(".add_item").live("click", this.add_item)
-this.el.find(".remove_item").live("click", this.remove_item)
-this.el.find(".clear_items").live("click", this.clear_items)
-</code></pre> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">events:</span>
- <span class="s2">&quot;click .add_item&quot;</span><span class="o">:</span> <span class="s2">&quot;add_item&quot;</span>
- <span class="s2">&quot;click .remove_item&quot;</span><span class="o">:</span> <span class="s2">&quot;remove_item&quot;</span>
- <span class="s2">&quot;click .clear_items&quot;</span><span class="o">:</span> <span class="s2">&quot;clear_items&quot;</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <h4>DOM Generation</h4>
-
-<p>AlphaSimprini uses pure script to generate DOM.
-All DOM is appended to a top-level @el. Which defaults to a <div>
-The tagname may be spetified as:</p>
-
-<pre><code>tag_name: "ul"
-</code></pre> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">initialize: </span><span class="o">-&gt;</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <h4>editline</h4>
-
-<p>A special content binding for use in conjuction with
-AS.Model.Share. It provides a [contenteditable] <span> which is linked
-"as-you-type" to other active sessions via ShareJS.</p>
-
-<p>(We will see later, in the Application initializer, that this view has been
- constructed with a Todo.Models.List object. )</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@h1</span> <span class="o">-&gt;</span> <span class="nx">@list</span><span class="p">.</span><span class="nx">editline</span> <span class="s2">&quot;name&quot;</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>This button is bound to the add_item method through the
-events: specified at the top of the class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@button</span> <span class="k">class</span><span class="o">:</span> <span class="s2">&quot;add_item&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="s2">&quot;Add Item&quot;</span>
-
- <span class="nx">@label</span> <span class="o">-&gt;</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <h4>Field/Property/Relation Binding</h4>
-
-<p>Calling binding with field, virtual_property, or relation name creates
-the appropriate databinding in the DOM. Here a function is used to specify
-the content in the binding. As 'all_done' is a virtual property the contents
-of this binding will be redrawn whenever the value of the property changes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@list</span><span class="p">.</span><span class="nx">binding</span> <span class="s2">&quot;all_done&quot;</span><span class="p">,</span> <span class="o">-&gt;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <h4>Checkbox Binding</h4>
-
-<p>Binds the value of 'all_done' to a checkbox. This binding is two-way. Changing
-the value of the checkbox changes the value on the model.
-(TODO: At this moment the implementation of setting virtual properties is non-existent.
-clicking this checkbox will not effect the underlying data.)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@list</span><span class="p">.</span><span class="nx">checkbox</span><span class="p">(</span><span class="s2">&quot;all_done&quot;</span><span class="p">)</span>
- <span class="k">if</span> <span class="nx">@list</span><span class="p">.</span><span class="nx">all_done</span><span class="p">()</span>
- <span class="nx">@text</span> <span class="s2">&quot;Mark all as incomplete&quot;</span>
- <span class="k">else</span>
- <span class="nx">@text</span> <span class="s2">&quot;Mark all as complete&quot;</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>The listing method encapsulates and makes reusable the code to display a list
-Items in the List.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@listing</span> <span class="s2">&quot;Things to do:&quot;</span><span class="p">,</span> <span class="nv">done: </span><span class="kc">false</span>
- <span class="nx">@listing</span> <span class="s2">&quot;Things I&#39;ve done:&quot;</span><span class="p">,</span> <span class="nv">done: </span><span class="kc">true</span>
-
- <span class="nx">@footer</span> <span class="o">-&gt;</span>
- <span class="nx">@span</span> <span class="o">-&gt;</span>
- <span class="nx">@list</span><span class="p">.</span><span class="nx">binding</span> <span class="s2">&quot;remaining_items_length&quot;</span><span class="p">,</span> <span class="o">=&gt;</span>
- <span class="nv">count = </span><span class="nx">@list</span><span class="p">.</span><span class="nx">remaining_items_length</span><span class="p">()</span>
- <span class="nx">@span</span> <span class="s2">&quot;#{count} more #{@pluralize(&quot;</span><span class="nx">thing</span><span class="s2">&quot;, count)} to do!&quot;</span>
-
- <span class="nx">@span</span> <span class="o">-&gt;</span>
- <span class="nx">@list</span><span class="p">.</span><span class="nx">binding</span> <span class="s2">&quot;done_items_length&quot;</span><span class="p">,</span> <span class="o">=&gt;</span>
- <span class="nv">count = </span><span class="nx">@list</span><span class="p">.</span><span class="nx">done_items_length</span><span class="p">()</span>
- <span class="k">return</span> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="nx">count</span> <span class="o">is</span> <span class="mi">0</span>
- <span class="nx">@button</span> <span class="k">class</span><span class="o">:</span> <span class="s2">&quot;clear_items&quot;</span><span class="p">,</span> <span class="o">-&gt;</span>
- <span class="s2">&quot;Clear #{count} completed #{@pluralize(&#39;item&#39;, count)}.&quot;</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>The listing "partial"</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">listing: </span><span class="nf">(label, filter) -&gt;</span>
- <span class="nx">@h2</span> <span class="nx">label</span>
- <span class="nx">@ul</span> <span class="o">-&gt;</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <h4>Filtering Relation bindings.</h4>
-
-<p>When binding to a collection (@has_many or @embeds_many), you may
-provide a filter. In this case the filter will be on the 'done' property.
-Items matching the filter will be excluded from the view. As an item's fields
-and properties change it will be refiltered and possibly displayed in this binding.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@list</span><span class="p">.</span><span class="nx">binding</span> <span class="s2">&quot;items&quot;</span><span class="p">,</span> <span class="nv">filter: </span><span class="nx">filter</span><span class="p">,</span> <span class="nf">(item) -&gt;</span>
- <span class="nx">@li</span> <span class="o">-&gt;</span>
- <span class="nx">item</span><span class="p">.</span><span class="nx">checkbox</span><span class="p">(</span><span class="s2">&quot;done&quot;</span><span class="p">)</span>
- <span class="nx">@p</span> <span class="o">-&gt;</span> <span class="nx">item</span><span class="p">.</span><span class="nx">editline</span><span class="p">(</span><span class="s2">&quot;task&quot;</span><span class="p">)</span>
- <span class="nv">button = </span><span class="nx">@button</span> <span class="k">class</span><span class="o">:</span> <span class="s2">&quot;remove_item&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="s2">&quot;x&quot;</span>
- <span class="nx">@$</span><span class="p">(</span><span class="nx">button</span><span class="p">).</span><span class="nx">data</span><span class="p">().</span><span class="nv">item = </span><span class="nx">item</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <h3>View Methods</h3>
-
-<p>These are the methods bound in the events property at the top of the class.
-While application state changes the View will be redrawn as warranted.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">add_item: </span><span class="nf">(item) -&gt;</span>
- <span class="nx">@list</span><span class="p">.</span><span class="nx">items</span><span class="p">().</span><span class="nx">add</span> <span class="k">new</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">Item</span>
-
- <span class="nv">remove_item: </span><span class="nf">(event) -&gt;</span>
- <span class="nx">@list</span><span class="p">.</span><span class="nx">items</span><span class="p">().</span><span class="nx">remove</span> <span class="nx">@$</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">currentTarget</span><span class="p">).</span><span class="nx">data</span><span class="p">().</span><span class="nx">item</span>
-
- <span class="nv">clear_items: </span><span class="nf">(event) -&gt;</span>
- <span class="nv">items = </span><span class="nx">@list</span><span class="p">.</span><span class="nx">items</span><span class="p">()</span>
- <span class="nx">items</span><span class="p">.</span><span class="nx">each</span> <span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">items</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="k">if</span> <span class="nx">item</span><span class="p">.</span><span class="nx">done</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> <h3>Todo.Application</h3> </td> <td class="code"> <div class="highlight"><pre><span class="k">class</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Application</span> <span class="k">extends</span> <span class="nx">AS</span><span class="p">.</span><span class="nx">Application</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>Because we are using ShareJS, we must "open" our List object and bind to the "ready"
-event. The @params are set on the Todo namespace and passed onto the @params field
-at application initialization time.</p>
-
-<pre><code>Todo.params = {list_id: "some list"};
-Todo.app = new Todo.Application()
-</code></pre> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">initialize: </span><span class="o">-&gt;</span>
- <span class="vi">@list = </span><span class="nx">Todo</span><span class="p">.</span><span class="nx">Models</span><span class="p">.</span><span class="nx">List</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">@params</span><span class="p">.</span><span class="nx">list_id</span><span class="p">)</span>
- <span class="nx">@list</span><span class="p">.</span><span class="nx">bind</span> <span class="s2">&quot;ready&quot;</span><span class="p">,</span> <span class="nx">@listready</span><span class="p">,</span> <span class="k">this</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>When the list is ready we create the view and pass in the list.
-Then the list view is appended to the application and we're good to go.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">listready: </span><span class="o">-&gt;</span>
- <span class="vi">@list_view = </span><span class="nx">@view</span> <span class="nx">Todo</span><span class="p">.</span><span class="nx">Views</span><span class="p">.</span><span class="nx">List</span><span class="p">,</span> <span class="nv">list: </span><span class="nx">@list</span>
- <span class="nx">@append</span> <span class="nx">@list_view</span>
-
-</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
View
36 examples/todo/package.json
@@ -1,36 +0,0 @@
-{
- "author": "Collin Miller <collintmiller@gmail.com>",
- "name": "todo",
- "description": "A sample AlphaSimprini app.",
- "version": "0.0.0",
- "engines": {
- "node": "~0.6.6"
- },
- "dependencies": {
- "alpha_simprini": "latest",
- "module_loader": "latest",
- "underscore": ">= 1.2",
- "underscore.string": ">= 2.0.0",
- "jquery": ">= 1.6",
- "jwerty": ">= 0.3",
- "express": "2.5.2",
- "connect": "1.8.3",
- "cookie-sessions": "0.0.2",
- "socket.io-client": "https://github.com/collin/socket.io-client/tarball/master",
- "share": "https://github.com/collin/ShareJS/tarball/pg",
- "minimatch": "https://github.com/isaacs/minimatch/tarball/master",
- "pg": "0.6.8",
- "rangy-core": "0.2.2",
- "coffee-script": "1.2.0",
- "b64": "1.0.1",
- "orm": "0.1.8",
- "knead": "~> 0.2",
- "module_loader": "~> 0.2",
- "jsdom": "latest",
- "coffeekup": "0.3.0",
- "fleck": "0.5.1"
-
- },
- "devDependencies": {},
- "main": "todo"
-}
View
30 examples/todo/server.coffee
@@ -1,30 +0,0 @@
-AS = require "alpha_simprini"
-ModuleLoader = require "module_loader"
-share = require("share").server
-express = require "express"
-connect = require "connect"
-pathname = require "path"
-
-app = express.createServer(connect.logger())
-
-app.set 'view engine', 'coffee'
-app.register '.coffee', require('coffeekup').adapters.express
-
-share.attach app, db: type: "none"
-
-new ModuleLoader
- server: app
- env: "production"
- module_root: pathname.resolve("./node_modules")
- ignorefile: pathname.resolve("./.stitchignore")
- packages: "jquery underscore underscore.string jwerty socket.io-client share rangy-core pathology taxialpha_simprini fleck todo".split(" ")
-
-
-app.get "/list/:id", (req, res) ->
- res.render "list", id: req.params.id, layout: false
-
-app.listen 3210 || process.env.PORT
-console.log """
- AlphaSimprini Todo example running...
- http://#{app.address().address}:#{app.address().port}/list/one
-"""
View
100 examples/todo/todo.coffee
@@ -2,36 +2,31 @@
# The first step is to load Alpha Simprini and the AS `client` module.
# The client module includes the AS.View class and is used to generate
# guis.
-AS = require("alpha_simprini")
+require("alpha_simprini")
+# Alpha Simprini provides it's own mechanism to require
+# it's modules.
AS.require("client")
+AS.require("keyboard")
# This module contains Modules and Views.
-# More complicated modules might include a Collections object.
-Todo = module.exports =
- Models: new Object
- Views: new Object
-
+# More complicated apps might include
+# Collections or other modules
+module Todo
+module Todo.Models
+module Todo.Views
# ### Todo.Models.List
-class Todo.Models.List extends AS.Model
- # The AS.Model.Share mixin adds features from the ShareJS library.
- # The ShareJS integration neccessitates a string path which is used
- # to inflate objects passed in through the ShareJS transport.
- AS.Model.Share.extends(this, "Todo.Models.List")
-
+class Todo.Models.List < AS.Model
# #### Fields
# The name field is a simple string property with a default value.
# It's a suitable default name for a list of things to do.
@field "name", default: "A list of things to do..."
# #### Relationships
- # When we embed\_many items, we're creating a 1-n relationship between
- # Lists and Items. In coordination with AS.Model.Share, @embeds\_many
- # stores all the embedded models within the same ShareJS document as
- # the list object. If we had used @has\_many, they would be stored in
- # seperate documents with something like a foreign key relation.
- @embeds_many "items", model: -> Todo.Models.Item
+ # When we `hasMany items`, we're creating a 1-n relationship between
+ # Lists and Items.
+ @hasMany "items", model: -> Todo.Models.Item
# #### Virtual Properties
@@ -44,30 +39,28 @@ class Todo.Models.List extends AS.Model
# are compared to previous values. If the value is different a change event is
# triggered.
@virtualProperties "items",
- items_length: ->
- @items().length
+ itemsLength: ->
+ @items.count()
- remaining_items_length: ->
- @items().filter((item) -> !item.done()).value().length
+ remainingItemsLength: ->
+ @items.filter((item) -> !item.done()).value().length
- all_done: ->
- @remaining_items_length() is 0
+ allDone: ->
+ @remainingItemsLength() is 0
- done_items_length: ->
- @items().filter((item) -> item.done()).value().length
+ doneItemsLength: ->
+ @items.filter((item) -> item.done()).value().length
# ### Todo.Models.Item
# These items are embedded within a Todo.Views.List
-class Todo.Models.Item extends AS.Model
- AS.Model.Share.extends(this, "Todo.Models.Item")
-
+class Todo.Models.Item < AS.Model
@field "task", default: "Something to do..."
# #### Field types.
# A field may have a type. This field is a boolean field.
@field "done", type: AS.Model.Boolean, default: false
# ### Todo.Views.List
-class Todo.Views.List extends AS.View
+class Todo.Views.List < AS.View
# #### View Events
# Similar to Backbone.js View events these events are 'live' bound
# to the container element for this view.
@@ -85,41 +78,43 @@ class Todo.Views.List extends AS.View
# #### DOM Generation
# AlphaSimprini uses pure script to generate DOM.
# All DOM is appended to a top-level @el. Which defaults to a <div>
- # The tagname may be spetified as:
+ # The tagname may be specified as:
#
# tag_name: "ul"
#
initialize: ->
- # #### editline
- # A special content binding for use in conjuction with
- # AS.Model.Share. It provides a [contenteditable] <span> which is linked
- # "as-you-type" to other active sessions via ShareJS.
- #
- # (We will see later, in the Application initializer, that this view has been
- # constructed with a Todo.Models.List object. )
- #
- @h1 -> @list.editline "name"
+ # # #### editline
+ # # A special content binding for use in conjuction with
+ # # AS.Model.Share. It provides a [contenteditable] <span> which is linked
+ # # "as-you-type" to other active sessions via ShareJS.
+ # #
+ # # (We will see later, in the Application initializer, that this view has been
+ # # constructed with a Todo.Models.List object. )
+ # #
+ # @h1 -> @list.editline "name"
+ @h1 -> @list.input("name")
# This button is bound to the add\_item method through the
# events: specified at the top of the class.
- @button class: "add_item", -> "Add Item"
+ @button class: "add-item", -> "Add Item"
@label ->
# #### Field/Property/Relation Binding
# Calling binding with field, virtual\_property, or relation name creates
# the appropriate databinding in the DOM. Here a function is used to specify
# the content in the binding. As 'all\_done' is a virtual property the contents
# of this binding will be redrawn whenever the value of the property changes.
- @list.binding "all_done", ->
- # #### Checkbox Binding
- # Binds the value of 'all\_done' to a checkbox. This binding is two-way. Changing
- # the value of the checkbox changes the value on the model.
- # (TODO: At this moment the implementation of setting virtual properties is non-existent.
- # clicking this checkbox will not effect the underlying data.)
- @list.checkbox("all_done")
- if @list.all_done()
+
+ # #### Checkbox Binding
+ # Binds the value of 'allDone' to a checkbox. This binding is two-way. Changing
+ # the value of the checkbox changes the value on the model.
+ # (TODO: At this moment the implementation of setting virtual properties is non-existent.
+ # clicking this checkbox will not effect the underlying data.)
+ @list.checkbox("allDone")
+ @list.if "allDone",
+ then: ->
@text "Mark all as incomplete"
- else
+ else: ->
@text "Mark all as complete"
# The listing method encapsulates and makes reusable the code to display a list
@@ -129,8 +124,7 @@ class Todo.Views.List extends AS.View
@footer ->
@span ->
- @list.binding "remaining_items_length", =>
- count = @list.remaining_items_length()
+ @list.binding "remainingItemsLength", (count) =>
@span "#{count} more #{@pluralize("thing", count)} to do!"
@span ->
@@ -170,7 +164,7 @@ class Todo.Views.List extends AS.View
items.each (item) => items.remove(item) if item.done()
# ### Todo.Application
-class Todo.Application extends AS.Application
+class Todo.Application < AS.Application
# Because we are using ShareJS, we must "open" our List object and bind to the "ready"
# event. The @params are set on the Todo namespace and passed onto the @params field
# at application initialization time.
View
19 examples/todo/views/list.coffee
@@ -1,19 +0,0 @@
-text "<!DOCTYPE html>"
-html ->
- head ->
- title "AlphaSimprini Todo"
- script src: "/node_modules.js"
- script """
- require("alpha_simprini").params = {list_id: "#{@id}"};
- """
-
- coffeescript ->
- _ = require("underscore")
- io = require("socket.io-client")
- io.transports = _(io.transports).chain().without("websocket").uniq().value()
-
- Todo = require "todo"
- require("jquery") ->
- Todo.app = new Todo.Application
-
- body ->
View
1 sharejs.js
@@ -1 +0,0 @@
-minispade.register('sharejs', "(function() {(function() {\n var BCSocket, Connection, Doc, MicroEvent, SockJS, append, bootstrapTransform, checkValidComponent, checkValidOp, exports, hasBCSocket, hasSockJS, invertComponent, nextTick, strInject, text, transformComponent, transformPosition, types, useSockJS,\n __slice = Array.prototype.slice,\n __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },\n __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\n\n window.sharejs = exports = {\n 'version': '0.5.0-pre'\n };\n\n if (typeof WEB === 'undefined') window.WEB = true;\n\n nextTick = typeof WEB !== \"undefined\" && WEB !== null ? function(fn) {\n return setTimeout(fn, 0);\n } : process['nextTick'];\n\n MicroEvent = (function() {\n\n function MicroEvent() {}\n\n MicroEvent.prototype.on = function(event, fct) {\n var _base;\n this._events || (this._events = {});\n (_base = this._events)[event] || (_base[event] = []);\n this._events[event].push(fct);\n return this;\n };\n\n MicroEvent.prototype.removeListener = function(event, fct) {\n var i, listeners, _base,\n _this = this;\n this._events || (this._events = {});\n listeners = ((_base = this._events)[event] || (_base[event] = []));\n i = 0;\n while (i < listeners.length) {\n if (listeners[i] === fct) listeners[i] = void 0;\n i++;\n }\n nextTick(function() {\n var x;\n return _this._events[event] = (function() {\n var _i, _len, _ref, _results;\n _ref = this._events[event];\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n x = _ref[_i];\n if (x) _results.push(x);\n }\n return _results;\n }).call(_this);\n });\n return this;\n };\n\n MicroEvent.prototype.emit = function() {\n var args, event, fn, _i, _len, _ref, _ref2;\n event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n if (!((_ref = this._events) != null ? _ref[event] : void 0)) return this;\n _ref2 = this._events[event];\n for (_i = 0, _len = _ref2.length; _i < _len; _i++) {\n fn = _ref2[_i];\n if (fn) fn.apply(this, args);\n }\n return this;\n };\n\n return MicroEvent;\n\n })();\n\n MicroEvent.mixin = function(obj) {\n var proto;\n proto = obj.prototype || obj;\n proto.on = MicroEvent.prototype.on;\n proto.removeListener = MicroEvent.prototype.removeListener;\n proto.emit = MicroEvent.prototype.emit;\n return obj;\n };\n\n if (typeof WEB === \"undefined\" || WEB === null) module.exports = MicroEvent;\n\n exports['_bt'] = bootstrapTransform = function(type, transformComponent, checkValidOp, append) {\n var transformComponentX, transformX;\n transformComponentX = function(left, right, destLeft, destRight) {\n transformComponent(destLeft, left, right, 'left');\n return transformComponent(destRight, right, left, 'right');\n };\n type.transformX = type['transformX'] = transformX = function(leftOp, rightOp) {\n var k, l, l_, newLeftOp, newRightOp, nextC, r, r_, rightComponent, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2;\n checkValidOp(leftOp);\n checkValidOp(rightOp);\n newRightOp = [];\n for (_i = 0, _len = rightOp.length; _i < _len; _i++) {\n rightComponent = rightOp[_i];\n newLeftOp = [];\n k = 0;\n while (k < leftOp.length) {\n nextC = [];\n transformComponentX(leftOp[k], rightComponent, newLeftOp, nextC);\n k++;\n if (nextC.length === 1) {\n rightComponent = nextC[0];\n } else if (nextC.length === 0) {\n _ref = leftOp.slice(k);\n for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {\n l = _ref[_j];\n append(newLeftOp, l);\n }\n rightComponent = null;\n break;\n } else {\n _ref2 = transformX(leftOp.slice(k), nextC), l_ = _ref2[0], r_ = _ref2[1];\n for (_k = 0, _len3 = l_.length; _k < _len3; _k++) {\n l = l_[_k];\n append(newLeftOp, l);\n }\n for (_l = 0, _len4 = r_.length; _l < _len4; _l++) {\n r = r_[_l];\n append(newRightOp, r);\n }\n rightComponent = null;\n break;\n }\n }\n if (rightComponent != null) append(newRightOp, rightComponent);\n leftOp = newLeftOp;\n }\n return [leftOp, newRightOp];\n };\n return type.transform = type['transform'] = function(op, otherOp, type) {\n var left, right, _, _ref, _ref2;\n if (!(type === 'left' || type === 'right')) {\n throw new Error(\"type must be 'left' or 'right'\");\n }\n if (otherOp.length === 0) return op;\n if (op.length === 1 && otherOp.length === 1) {\n return transformComponent([], op[0], otherOp[0], type);\n }\n if (type === 'left') {\n _ref = transformX(op, otherOp), left = _ref[0], _ = _ref[1];\n return left;\n } else {\n _ref2 = transformX(otherOp, op), _ = _ref2[0], right = _ref2[1];\n return right;\n }\n };\n };\n\n if (typeof WEB === 'undefined') exports.bootstrapTransform = bootstrapTransform;\n\n text = {};\n\n text.name = 'text';\n\n text.create = function() {\n return '';\n };\n\n strInject = function(s1, pos, s2) {\n return s1.slice(0, pos) + s2 + s1.slice(pos);\n };\n\n checkValidComponent = function(c) {\n var d_type, i_type;\n if (typeof c.p !== 'number') {\n throw new Error('component missing position field');\n }\n i_type = typeof c.i;\n d_type = typeof c.d;\n if (!((i_type === 'string') ^ (d_type === 'string'))) {\n throw new Error('component needs an i or d field');\n }\n if (!(c.p >= 0)) throw new Error('position cannot be negative');\n };\n\n checkValidOp = function(op) {\n var c, _i, _len;\n for (_i = 0, _len = op.length; _i < _len; _i++) {\n c = op[_i];\n checkValidComponent(c);\n }\n return true;\n };\n\n text.apply = function(snapshot, op) {\n var component, deleted, _i, _len;\n checkValidOp(op);\n for (_i = 0, _len = op.length; _i < _len; _i++) {\n component = op[_i];\n if (component.i != null) {\n snapshot = strInject(snapshot, component.p, component.i);\n } else {\n deleted = snapshot.slice(component.p, (component.p + component.d.length));\n if (component.d !== deleted) {\n throw new Error(\"Delete component '\" + component.d + \"' does not match deleted text '\" + deleted + \"'\");\n }\n snapshot = snapshot.slice(0, component.p) + snapshot.slice(component.p + component.d.length);\n }\n }\n return snapshot;\n };\n\n text._append = append = function(newOp, c) {\n var last, _ref, _ref2;\n if (c.i === '' || c.d === '') return;\n if (newOp.length === 0) {\n return newOp.push(c);\n } else {\n last = newOp[newOp.length - 1];\n if ((last.i != null) && (c.i != null) && (last.p <= (_ref = c.p) && _ref <= (last.p + last.i.length))) {\n return newOp[newOp.length - 1] = {\n i: strInject(last.i, c.p - last.p, c.i),\n p: last.p\n };\n } else if ((last.d != null) && (c.d != null) && (c.p <= (_ref2 = last.p) && _ref2 <= (c.p + c.d.length))) {\n return newOp[newOp.length - 1] = {\n d: strInject(c.d, last.p - c.p, last.d),\n p: c.p\n };\n } else {\n return newOp.push(c);\n }\n }\n };\n\n text.compose = function(op1, op2) {\n var c, newOp, _i, _len;\n checkValidOp(op1);\n checkValidOp(op2);\n newOp = op1.slice();\n for (_i = 0, _len = op2.length; _i < _len; _i++) {\n c = op2[_i];\n append(newOp, c);\n }\n return newOp;\n };\n\n text.compress = function(op) {\n return text.compose([], op);\n };\n\n text.normalize = function(op) {\n var c, newOp, _i, _len;\n newOp = [];\n if ((op.i != null) || (op.p != null)) op = [op];\n for (_i = 0, _len = op.length; _i < _len; _i++) {\n c = op[_i];\n if (c.p == null) c.p = 0;\n append(newOp, c);\n }\n return newOp;\n };\n\n transformPosition = function(pos, c, insertAfter) {\n if (c.i != null) {\n if (c.p < pos || (c.p === pos && insertAfter)) {\n return pos + c.i.length;\n } else {\n return pos;\n }\n } else {\n if (pos <= c.p) {\n return pos;\n } else if (pos <= c.p + c.d.length) {\n return c.p;\n } else {\n return pos - c.d.length;\n }\n }\n };\n\n text.transformCursor = function(position, op, insertAfter) {\n var c, _i, _len;\n for (_i = 0, _len = op.length; _i < _len; _i++) {\n c = op[_i];\n position = transformPosition(position, c, insertAfter);\n }\n return position;\n };\n\n text._tc = transformComponent = function(dest, c, otherC, type) {\n var cIntersect, intersectEnd, intersectStart, newC, otherIntersect, s;\n checkValidOp([c]);\n checkValidOp([otherC]);\n if (c.i != null) {\n append(dest, {\n i: c.i,\n p: transformPosition(c.p, otherC, type === 'right')\n });\n } else {\n if (otherC.i != null) {\n s = c.d;\n if (c.p < otherC.p) {\n append(dest, {\n d: s.slice(0, (otherC.p - c.p)),\n p: c.p\n });\n s = s.slice(otherC.p - c.p);\n }\n if (s !== '') {\n append(dest, {\n d: s,\n p: c.p + otherC.i.length\n });\n }\n } else {\n if (c.p >= otherC.p + otherC.d.length) {\n append(dest, {\n d: c.d,\n p: c.p - otherC.d.length\n });\n } else if (c.p + c.d.length <= otherC.p) {\n append(dest, c);\n } else {\n newC = {\n d: '',\n p: c.p\n };\n if (c.p < otherC.p) newC.d = c.d.slice(0, (otherC.p - c.p));\n if (c.p + c.d.length > otherC.p + otherC.d.length) {\n newC.d += c.d.slice(otherC.p + otherC.d.length - c.p);\n }\n intersectStart = Math.max(c.p, otherC.p);\n intersectEnd = Math.min(c.p + c.d.length, otherC.p + otherC.d.length);\n cIntersect = c.d.slice(intersectStart - c.p, (intersectEnd - c.p));\n otherIntersect = otherC.d.slice(intersectStart - otherC.p, (intersectEnd - otherC.p));\n if (cIntersect !== otherIntersect) {\n throw new Error('Delete ops delete different text in the same region of the document');\n }\n if (newC.d !== '') {\n newC.p = transformPosition(newC.p, otherC);\n append(dest, newC);\n }\n }\n }\n }\n return dest;\n };\n\n invertComponent = function(c) {\n if (c.i != null) {\n return {\n d: c.i,\n p: c.p\n };\n } else {\n return {\n i: c.d,\n p: c.p\n };\n }\n };\n\n text.invert = function(op) {\n var c, _i, _len, _ref, _results;\n _ref = op.slice().reverse();\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n c = _ref[_i];\n _results.push(invertComponent(c));\n }\n return _results;\n };\n\n if (typeof WEB !== \"undefined\" && WEB !== null) {\n exports.types || (exports.types = {});\n bootstrapTransform(text, transformComponent, checkValidOp, append);\n exports.types.text = text;\n } else {\n module.exports = text;\nminispade.require('./helpers').bootstrapTransform(text, transformComponent, checkValidOp, append);\n }\n\n if (typeof WEB === 'undefined') text = require('./text');\n\n text.api = {\n provides: {\n text: true\n },\n getLength: function() {\n return this.snapshot.length;\n },\n getText: function() {\n return this.snapshot;\n },\n insert: function(pos, text, callback) {\n var op;\n op = [\n {\n p: pos,\n i: text\n }\n ];\n this.submitOp(op, callback);\n return op;\n },\n del: function(pos, length, callback) {\n var op;\n op = [\n {\n p: pos,\n d: this.snapshot.slice(pos, (pos + length))\n }\n ];\n this.submitOp(op, callback);\n return op;\n },\n _register: function() {\n return this.on('remoteop', function(op) {\n var component, _i, _len, _results;\n _results = [];\n for (_i = 0, _len = op.length; _i < _len; _i++) {\n component = op[_i];\n if (component.i !== void 0) {\n _results.push(this.emit('insert', component.p, component.i));\n } else {\n _results.push(this.emit('delete', component.p, component.d));\n }\n }\n return _results;\n });\n }\n };\n\n if (typeof WEB === \"undefined\" || WEB === null) types = require('../types');\n\n if (typeof WEB !== \"undefined\" && WEB !== null) {\n exports.extendDoc = function(name, fn) {\n return Doc.prototype[name] = fn;\n };\n }\n\n Doc = (function() {\n\n function Doc(connection, name, openData) {\n this.connection = connection;\n this.name = name;\n this.shout = __bind(this.shout, this);\n this.flush = __bind(this.flush, this);\n openData || (openData = {});\n this.version = openData.v;\n this.snapshot = openData.snaphot;\n if (openData.type) this._setType(openData.type);\n this.state = 'closed';\n this.autoOpen = false;\n this._create = openData.create;\n this.inflightOp = null;\n this.inflightCallbacks = [];\n this.inflightSubmittedIds = [];\n this.pendingOp = null;\n this.pendingCallbacks = [];\n this.serverOps = {};\n }\n\n Doc.prototype._xf = function(client, server) {\n var client_, server_;\n if (this.type.transformX) {\n return this.type.transformX(client, server);\n } else {\n client_ = this.type.transform(client, server, 'left');\n server_ = this.type.transform(server, client, 'right');\n return [client_, server_];\n }\n };\n\n Doc.prototype._otApply = function(docOp, isRemote) {\n var oldSnapshot;\n oldSnapshot = this.snapshot;\n this.snapshot = this.type.apply(this.snapshot, docOp);\n this.emit('change', docOp, oldSnapshot);\n if (isRemote) return this.emit('remoteop', docOp, oldSnapshot);\n };\n\n Doc.prototype._connectionStateChanged = function(state, data) {\n switch (state) {\n case 'disconnected':\n this.state = 'closed';\n if (this.inflightOp) this.inflightSubmittedIds.push(this.connection.id);\n this.emit('closed');\n break;\n case 'ok':\n if (this.autoOpen) this.open();\n break;\n case 'stopped':\n if (typeof this._openCallback === \"function\") this._openCallback(data);\n }\n return this.emit(state, data);\n };\n\n Doc.prototype._setType = function(type) {\n var k, v, _ref;\n if (typeof type === 'string') type = types[type];\n if (!(type && type.compose)) {\n throw new Error('Support for types without compose() is not implemented');\n }\n this.type = type;\n if (type.api) {\n _ref = type.api;\n for (k in _ref) {\n v = _ref[k];\n this[k] = v;\n }\n return typeof this._register === \"function\" ? this._register() : void 0;\n } else {\n return this.provides = {};\n }\n };\n\n Doc.prototype._onMessage = function(msg) {\n var callback, docOp, error, oldInflightOp, op, path, response, undo, value, _i, _j, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;\n if (msg.open === true) {\n this.state = 'open';\n this._create = false;\n if (this.created == null) this.created = !!msg.create;\n if (msg.type) this._setType(msg.type);\n if (msg.create) {\n this.created = true;\n this.snapshot = this.type.create();\n } else {\n if (this.created !== true) this.created = false;\n if (msg.snapshot !== void 0) this.snapshot = msg.snapshot;\n }\n if (msg.v != null) this.version = msg.v;\n if (this.inflightOp) {\n response = {\n doc: this.name,\n op: this.inflightOp,\n v: this.version\n };\n if (this.inflightSubmittedIds.length) {\n response.dupIfSource = this.inflightSubmittedIds;\n }\n this.connection.send(response);\n } else {\n this.flush();\n }\n this.emit('open');\n return typeof this._openCallback === \"function\" ? this._openCallback(null) : void 0;\n } else if (msg.open === false) {\n if (msg.error) {\n if (typeof console !== \"undefined\" && console !== null) {\n console.error(\"Could not open document: \" + msg.error);\n }\n this.emit('error', msg.error);\n if (typeof this._openCallback === \"function\") {\n this._openCallback(msg.error);\n }\n }\n this.state = 'closed';\n this.emit('closed');\n if (typeof this._closeCallback === \"function\") this._closeCallback();\n return this._closeCallback = null;\n } else if (msg.op === null && error === 'Op already submitted') {} else if ((msg.op === void 0 && msg.v !== void 0) || (msg.op && (_ref = msg.meta.source, __indexOf.call(this.inflightSubmittedIds, _ref) >= 0))) {\n oldInflightOp = this.inflightOp;\n this.inflightOp = null;\n this.inflightSubmittedIds.length = 0;\n error = msg.error;\n if (error) {\n if (this.type.invert) {\n undo = this.type.invert(oldInflightOp);\n if (this.pendingOp) {\n _ref2 = this._xf(this.pendingOp, undo), this.pendingOp = _ref2[0], undo = _ref2[1];\n }\n this._otApply(undo, true);\n } else {\n this.emit('error', \"Op apply failed (\" + error + \") and the op could not be reverted\");\n }\n _ref3 = this.inflightCallbacks;\n for (_i = 0, _len = _ref3.length; _i < _len; _i++) {\n callback = _ref3[_i];\n callback(error);\n }\n } else {\n if (msg.v !== this.version) {\n throw new Error('Invalid version from server');\n }\n this.serverOps[this.version] = oldInflightOp;\n this.version++;\n _ref4 = this.inflightCallbacks;\n for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {\n callback = _ref4[_j];\n callback(null, oldInflightOp);\n }\n }\n return this.flush();\n } else if (msg.op) {\n if (msg.v < this.version) return;\n if (msg.doc !== this.name) {\n return this.emit('error', \"Expected docName '\" + this.name + \"' but got \" + msg.doc);\n }\n if (msg.v !== this.version) {\n return this.emit('error', \"Expected version \" + this.version + \" but got \" + msg.v);\n }\n op = msg.op;\n this.serverOps[this.version] = op;\n docOp = op;\n if (this.inflightOp !== null) {\n _ref5 = this._xf(this.inflightOp, docOp), this.inflightOp = _ref5[0], docOp = _ref5[1];\n }\n if (this.pendingOp !== null) {\n _ref6 = this._xf(this.pendingOp, docOp), this.pendingOp = _ref6[0], docOp = _ref6[1];\n }\n this.version++;\n return this._otApply(docOp, true);\n } else if (msg.meta) {\n _ref7 = msg.meta, path = _ref7.path, value = _ref7.value;\n switch (path != null ? path[0] : void 0) {\n case 'shout':\n return this.emit('shout', value);\n default:\n return typeof console !== \"undefined\" && console !== null ? console.warn('Unhandled meta op:', msg) : void 0;\n }\n } else {\n return typeof console !== \"undefined\" && console !== null ? console.warn('Unhandled document message:', msg) : void 0;\n }\n };\n\n Doc.prototype.flush = function() {\n if (!(this.connection.state === 'ok' && this.inflightOp === null && this.pendingOp !== null)) {\n return;\n }\n this.inflightOp = this.pendingOp;\n this.inflightCallbacks = this.pendingCallbacks;\n this.pendingOp = null;\n this.pendingCallbacks = [];\n return this.connection.send({\n doc: this.name,\n op: this.inflightOp,\n v: this.version\n });\n };\n\n Doc.prototype.submitOp = function(op, callback) {\n if (this.type.normalize != null) op = this.type.normalize(op);\n this.snapshot = this.type.apply(this.snapshot, op);\n if (this.pendingOp !== null) {\n this.pendingOp = this.type.compose(this.pendingOp, op);\n } else {\n this.pendingOp = op;\n }\n if (callback) this.pendingCallbacks.push(callback);\n this.emit('change', op);\n return setTimeout(this.flush, 0);\n };\n\n Doc.prototype.shout = function(msg) {\n return this.connection.send({\n doc: this.name,\n meta: {\n path: ['shout'],\n value: msg\n }\n });\n };\n\n Doc.prototype.open = function(callback) {\n var message,\n _this = this;\n this.autoOpen = true;\n if (this.state !== 'closed') return;\n message = {\n doc: this.name,\n open: true\n };\n if (this.snapshot === void 0) message.snapshot = null;\n if (this.type) message.type = this.type.name;\n if (this.version != null) message.v = this.version;\n if (this._create) message.create = true;\n this.connection.send(message);\n this.state = 'opening';\n return this._openCallback = function(error) {\n _this._openCallback = null;\n return typeof callback === \"function\" ? callback(error) : void 0;\n };\n };\n\n Doc.prototype.close = function(callback) {\n this.autoOpen = false;\n if (this.state === 'closed') {\n return typeof callback === \"function\" ? callback() : void 0;\n }\n this.connection.send({\n doc: this.name,\n open: false\n });\n this.state = 'closed';\n this.emit('closing');\n return this._closeCallback = callback;\n };\n\n return Doc;\n\n })();\n\n if (typeof WEB === \"undefined\" || WEB === null) {\n MicroEvent = require('./microevent');\n }\n\n MicroEvent.mixin(Doc);\n\n exports.Doc = Doc;\n\n if (typeof WEB !== \"undefined\" && WEB !== null) {\n types = exports.types;\n BCSocket = window.BCSocket, SockJS = window.SockJS;\n } else {\n types = require('../types');\n BCSocket = require('browserchannel').BCSocket;\n Doc = require('./doc').Doc;\n }\n\n Connection = (function() {\n\n function Connection(host) {\n var _this = this;\n this.docs = {};\n this.state = 'connecting';\n this.socket = typeof useSockJS !== \"undefined\" && useSockJS !== null ? new SockJS(host) : new BCSocket(host, {\n reconnect: true\n });\n this.socket.onmessage = function(msg) {\n var docName;\n if (typeof useSockJS !== \"undefined\" && useSockJS !== null) {\n msg = JSON.parse(msg.data);\n }\n if (msg.auth === null) {\n _this.lastError = msg.error;\n _this.disconnect();\n return _this.emit('connect failed', msg.error);\n } else if (msg.auth) {\n _this.id = msg.auth;\n _this.setState('ok');\n return;\n }\n docName = msg.doc;\n if (docName !== void 0) {\n _this.lastReceivedDoc = docName;\n } else {\n msg.doc = docName = _this.lastReceivedDoc;\n }\n if (_this.docs[docName]) {\n return _this.docs[docName]._onMessage(msg);\n } else {\n return typeof console !== \"undefined\" && console !== null ? console.error('Unhandled message', msg) : void 0;\n }\n };\n this.connected = false;\n this.socket.onclose = function(reason) {\n _this.setState('disconnected', reason);\n if (reason === 'Closed' || reason === 'Stopped by server') {\n return _this.setState('stopped', _this.lastError || reason);\n }\n };\n this.socket.onerror = function(e) {\n return _this.emit('error', e);\n };\n this.socket.onopen = function() {\n _this.lastError = _this.lastReceivedDoc = _this.lastSentDoc = null;\n return _this.setState('handshaking');\n };\n this.socket.onconnecting = function() {\n return _this.setState('connecting');\n };\n }\n\n Connection.prototype.setState = function(state, data) {\n var doc, docName, _ref, _results;\n if (this.state === state) return;\n this.state = state;\n if (state === 'disconnected') delete this.id;\n this.emit(state, data);\n _ref = this.docs;\n _results = [];\n for (docName in _ref) {\n doc = _ref[docName];\n _results.push(doc._connectionStateChanged(state, data));\n }\n return _results;\n };\n\n Connection.prototype.send = function(data) {\n var docName;\n docName = data.doc;\n if (docName === this.lastSentDoc) {\n delete data.doc;\n } else {\n this.lastSentDoc = docName;\n }\n if (typeof useSockJS !== \"undefined\" && useSockJS !== null) {\n data = JSON.stringify(data);\n }\n return this.socket.send(data);\n };\n\n Connection.prototype.disconnect = function() {\n return this.socket.close();\n };\n\n Connection.prototype.makeDoc = function(name, data, callback) {\n var doc,\n _this = this;\n if (this.docs[name]) throw new Error(\"Doc \" + name + \" already open\");\n doc = new Doc(this, name, data);\n this.docs[name] = doc;\n return doc.open(function(error) {\n if (error) delete _this.docs[name];\n return callback(error, (!error ? doc : void 0));\n });\n };\n\n Connection.prototype.openExisting = function(docName, callback) {\n var doc;\n if (this.state === 'stopped') return callback('connection closed');\n if (this.docs[docName]) return callback(null, this.docs[docName]);\n return doc = this.makeDoc(docName, {}, callback);\n };\n\n Connection.prototype.open = function(docName, type, callback) {\n var doc;\n if (this.state === 'stopped') return callback('connection closed');\n if (this.state === 'connecting') {\n this.on('handshaking', function() {\n return this.open(docName, type, callback);\n });\n return;\n }\n if (typeof type === 'function') {\n callback = type;\n type = 'text';\n }\n callback || (callback = function() {});\n if (typeof type === 'string') type = types[type];\n if (!type) throw new Error(\"OT code for document type missing\");\n if (docName == null) {\n throw new Error('Server-generated random doc names are not currently supported');\n }\n if (this.docs[docName]) {\n doc = this.docs[docName];\n if (doc.type === type) {\n callback(null, doc);\n } else {\n callback('Type mismatch', doc);\n }\n return;\n }\n return this.makeDoc(docName, {\n create: true,\n type: type.name\n }, callback);\n };\n\n return Connection;\n\n })();\n\n if (typeof WEB === \"undefined\" || WEB === null) {\n MicroEvent = require('./microevent');\n }\n\n MicroEvent.mixin(Connection);\n\n exports.Connection = Connection;\n\n if (typeof WEB !== \"undefined\" && WEB !== null) {\n hasBCSocket = window.BCSocket !== void 0;\n hasSockJS = window.SockJS !== void 0;\n if (!(hasBCSocket || hasSockJS)) {\n throw new Error('Must load socks or browserchannel before this library');\n }\n useSockJS = hasSockJS && !hasBCSocket;\n } else {\n Connection = require('./connection').Connection;\n }\n\n exports.open = (function() {\n var connections, getConnection, maybeClose;\n connections = {};\n getConnection = function(origin) {\n var c, del, location, path;\n if (typeof WEB !== \"undefined\" && WEB !== null) {\n location = window.location;\n path = useSockJS ? 'sockjs' : 'channel';\n if (origin == null) {\n origin = \"\" + location.protocol + \"//\" + location.host + \"/\" + path;\n }\n }\n if (!connections[origin]) {\n c = new Connection(origin);\n del = function() {\n return delete connections[origin];\n };\n c.on('disconnecting', del);\n c.on('connect failed', del);\n connections[origin] = c;\n }\n return connections[origin];\n };\n maybeClose = function(c) {\n var doc, name, numDocs, _ref;\n numDocs = 0;\n _ref = c.docs;\n for (name in _ref) {\n doc = _ref[name];\n if (doc.state !== 'closed' || doc.autoOpen) numDocs++;\n }\n if (numDocs === 0) return c.disconnect();\n };\n return function(docName, type, origin, callback) {\n var c;\n if (typeof origin === 'function') {\n callback = origin;\n origin = null;\n }\n c = getConnection(origin);\n c.numDocs++;\n c.open(docName, type, function(error, doc) {\n if (error) {\n callback(error);\n return maybeClose(c);\n } else {\n doc.on('closed', function() {\n return maybeClose(c);\n });\n return callback(null, doc);\n }\n });\n c.on('connect failed');\n return c;\n };\n })();\n\n if (typeof WEB === \"undefined\" || WEB === null) {\n exports.Doc = require('./doc').Doc;\n exports.Connection = require('./connection').Connection;\n }\n\n}).call(this);\n\n})();\n//@ sourceURL=sharejs");
View
6 src/alpha_simprini/client.coffee
@@ -7,14 +7,16 @@ Client.require """
binding
binding/container
- binding/model binding/field binding/if binding/input binding/select
- binding/file binding/check_box binding/edit_line binding/one binding/many
+ binding/model binding/field binding/if binding/input binding/select
+ binding/file binding/check_box binding/edit_line binding/one binding/many
views/panel views/region views/dialog
models/targets
application key_router
+
+ chassis chassis/frame chassis/block
"""
AS.require("keyboard")
View
20 src/alpha_simprini/client/application.coffee
@@ -71,9 +71,9 @@ class AS.Application
def prepareModel: (id, _model) ->
path = _model.constructor.path()
- constructor = AS.loadPath(path)
- model = constructor.prepare(id: id, application: this)
- console.log "[preparedModel] #{model.toString()}, #{model.id}"
+ _constructor = AS.loadPath(path)
+ model = _constructor.prepare(id: id, application: this)
+ # console.log "[preparedModel] #{model.toString()}, #{model.id}"
# @::prepareModel.doc =
# params: [
# ["id", [String], true]
@@ -102,7 +102,7 @@ class AS.Application
def takeOverState: (application) ->
for key, value of application.stateObjects
- console.log "[takeOverState] #{key} => #{value.toString()}", value.id
+ # console.log "[takeOverState] #{key} => #{value.toString()}", value.id
@stateObjects[key] = @[key] = AS.Model.find(value.id)
# @::takeOverState.doc =
# params: [
@@ -112,23 +112,23 @@ class AS.Application
# Take aver the state objects of another application. Used when cutting over.
# """
- def state: (name, constructor, options...) ->
+ def state: (name, _constructor, options...) ->
return if @[name]?
- stateObject = if constructor.new
- constructor.new.apply(constructor, options)
+ stateObject = if _constructor.new
+ _constructor.new.apply(_constructor, options)
else
- constructor
+ _constructor
@[name] = @stateObjects[name] = stateObject
# @::state.doc =
# desc: """
# Creates a state object in the application.
# """
- def view: (constructor, options={}) ->
+ def view: (_constructor, options={}) ->
options.application = this
- constructor.new options
+ _constructor.new options
# @::view.doc =
# desc: """
# Creates a view in the application.
View
2 src/alpha_simprini/client/binding/if.coffee
@@ -1,6 +1,4 @@
class AS.Binding.If < AS.Binding.Field
-
-
def setContent: ->
@content.empty()
@bindingGroup.unbind()
View
70 src/alpha_simprini/client/binding/model.coffee
@@ -11,33 +11,25 @@ class AS.Binding.Model < AS.Binding
# """
def css: (properties) ->
- for property, path of properties
- do (property, path) =>
- @styles[property] = => @model.readPath(path)
- painter = =>
- value = @styles[property]()
- @content.css property, value
+ # for property, options of properties
+ # do (property, options) =>
+ # if _.isArray(options)
+ # options = {
+ # path: options
+ # fn: =>
+ # value = @styles[property]()
+ # @content.css property, value
+ # }
- @context.binds @model, path, painter, this
+ # @styles[property] = => options.fn(@model)
+ # painter = => _.defer => @content.css property, @styles[property]()
- _.defer => @paint()
+ # {path} = options
+ # @context.binds @model, options.path, painter, this
- # for property, options of properties
- # do (property, options) =>
- # if _.isArray(options)
- # @styles[property] = => @model.readPath(options)
- # painter = => _.defer =>
- # value = @styles[property]()
- # @content.css property, value
+ _.defer => @paint()
- # @context.binds @model, options, painter, this
- # else
- # @styles[property] = =>
- # console.log "PAINTER"
- # options.fn(@model)
- # painter = => _.defer => @content.css property, @styles[property]()
- # @context.binds @model, options.field, painter, this
# @::css.doc =
# params: [
# []
@@ -58,40 +50,6 @@ class AS.Binding.Model < AS.Binding
_.defer => @paint()
- # for property, options of attrs
- # do (property, options) =>
- # if _.isArray(options)
- # @attrs[property] = =>
- # value = @model.readPath(options)
- # if value
- # "yes"
- # else if value in [false, null, undefined]
- # "no"
- # else
- # value
-
- # painter = => _.defer =>
- # @content.attr property, @attrs[property]()
-
- # bindingPath = options
- # @context.binds @model, bindingPath, painter, this
- # else
- # @attrs[property] = =>
- # if options.fn
- # options.fn(@model)
- # else
- # value = @model[options.field].get()
- # if value
- # "yes"
- # else if value in [false, null, undefined]
- # "no"
- # else
- # value
-
- # painter = => _.defer =>
- # @content.attr property, @attrs[property]()
-
- # @context.binds @model, options.field, painter, this
# @::attr.doc =
# params: [
# []
View
1 src/alpha_simprini/client/chassis.coffee
@@ -0,0 +1 @@
+module AS.Chassis
View
65 src/alpha_simprini/client/chassis/block.coffee
@@ -0,0 +1,65 @@
+# how to use
+# chassis = Chassis.Block.new("http://pasteup-lite.dev/editor.js", "editor")
+# FIXME: publish chassis-only alpha_simprini package
+# DevChannel: reload
+class AS.Chassis.Block
+
+ def initialize: (@application) ->
+ @appname = "app"
+ # window.addEventListener "message", bind(@forwardMessage, this), false
+ $ =>
+ @viewport = $(document.createElement("section"))
+ @viewport.addClass("Viewport")
+ @viewport.appendTo(document.body)
+ $(document).bind "devchannel:script", (=> @loadFrame())
+ @loadFrame()
+
+ # def forwardMessage: (event) ->
+ # console.log "forwardMessage", event.data
+ # if event.source is @currentFrame.dom
+ # console.log "to opener"
+ # window.opener?.postMessage(event.data, "*")
+ # else if event.source is window.opener
+ # console.log "to currentFrame"
+ # @currentFrame.dom.postMessage(event.data, "*")
+
+ def log: (args...) ->
+ console.log "[Chassis.Block]", args...
+
+ def loadFrame: ->
+ @lastFrame = @currentFrame
+ @currentFrame = AS.Chassis.Frame.new()
+ # @currentFrame.bind 'update', (=> @loadFrame())
+ @currentFrame.bind 'load', (=> @cutOver())
+
+ def cutOver: ->
+ console.profile()
+ @log "cutOver"
+ @currentFrame.dom.AS.DOM.def _document: document
+ @currentFrame.boot()
+
+ currentApp = @currentFrame.get("Pasteup."+@appname)
+
+ if @lastFrame?
+ lastApp = @lastFrame.get("Pasteup."+@appname)
+
+ # first pass instantiates
+ for id, object of @lastFrame.get("AS.All.byId")
+ # console.log "[prepare] #{object.toString()} #{id}"
+ currentApp.prepareModel(id, object)
+
+ # second pass does the takeover
+ for id, object of @lastFrame.get("AS.All.byId")
+ # console.log "[takeOverModel] #{object.toString()} #{id}"
+ currentApp.takeOverModel(id, object)
+
+ # console.log "TAKE OVER STATE"
+ currentApp.takeOverState(lastApp)
+ lastApp.keyRouter.reroute(null)
+
+ @lastFrame?.close()
+ @viewport.empty()
+ currentApp.applyTo(@viewport)
+ currentApp.keyRouter.reroute(document.body)
+ window.Pasteup = @currentFrame.dom.Pasteup
+ console.profileEnd()
View
54 src/alpha_simprini/client/chassis/frame.coffee
@@ -0,0 +1,54 @@
+# DevChannel: reload
+{defer} = _
+class AS.Chassis.Frame
+ include Taxi.Mixin
+
+ def initialize: (X, @loadCallback) ->
+ console.log "INITIALIZED"
+ @frame = document.createElement('iframe')
+ # @frame.src = "data:text/html;charset=utf-8," # BLANK DOCUMENT :D
+ defer =>
+ @dom = @frame.contentWindow
+ @handleload()
+ # @dom.applicationCache.addEventListener 'updateready', bind(@handleupdateready, this), false
+
+ $ =>
+ $(@frame).css(width:0, height:0, border: 'none').appendTo(document.body)
+
+ def boot: ->
+ @dom.boot()
+
+ def close: ->
+ console.log "CLOSE FRAME"
+ @dom.unbindGoverner?()
+ @frame.src = "about:blank"
+ $(@frame).remove()
+
+ def handleEvent: (event) ->
+ @["handle#{event.type}"](event)
+
+ def handlemessage: (event) ->
+ return unless event.source is @dom
+
+ def handleload: (event) ->
+ # @dom.applicationCache.update()
+ Taxi.Governer.exit() if Taxi.Governer.currentLoop
+ minispade.global = @dom
+ @dom.minispade = minispade
+ minispade.loaded = {}
+ minispade.require("pasteup/pasteup")
+ @dom.AS.params = AS.params
+ @trigger 'load'
+ Taxi.Governer.exit()
+
+ def handleupdateready: (event) ->
+ @dom.applicationCache.swapCache()
+ @trigger 'update'
+
+ def get: (path) ->
+ value = @dom
+ for item in path.split(".")
+ continue if value is undefined
+ value = value[item]
+
+ value
View
10 src/alpha_simprini/core/model.coffee
@@ -57,10 +57,10 @@ class AS.Model
def takeOver: (model) ->
for property in model.properties()
- continue unless property.rawValue?
+ continue unless property.rawValue? and rawValue = property.rawValue()
name = property.options.name
- console.log "takeOver #{name} #{property.rawValue()}"
- @[name].set property.rawValue()
+ # console.log "takeOver #{name} rawValue #{property.rawValue()}"
+ @[name].set property.rawValue()
@runCallbacks 'afterInitialize'
# @::takeOver.doc =
# params: [
@@ -120,8 +120,8 @@ class AS.Model
def setId: (id) ->
if @id
- delete AS.All.byId[@id]
- delete AS.All.byIdRef["#{@id}-#{@constructor.path()}"]
+ AS.All.byId[@id] = undefined
+ AS.All.byIdRef["#{@id}-#{@constructor.path()}"] = undefined
@id = id
@idRef = makeIdRef(@id, @constructor)
View
2 src/alpha_simprini/core/models/multiple_selection_model.coffee
@@ -1,5 +1,5 @@
class AS.Models.MultipleSelectionModel < AS.Model
- @hasMany "items"
+ @hasMany "items", remote:false
def initialize: (options={}) ->
@property = options.property
View
2 src/alpha_simprini/core/models/radio_selection_model.coffee
@@ -1,5 +1,5 @@
class AS.Models.RadioSelectionModel < AS.Model
- @property 'selected'
+ @belongsTo 'selected', remote:false
def initialize: (options={}) ->
@property = options.property
View
2 src/alpha_simprini/css/views/dialogs/color.coffee
@@ -6,7 +6,7 @@ JPICKER_SETTINGS =
alphaSupport:true
alphaPrecision:2
-class AS.Views.Dialogs.Color
+class AS.Views.Dialogs.Color < AS.Views.Dialog
def events:
"dblclick .Map": "triggerCommit"
View
37 src/dev-channel.coffee
@@ -1,37 +0,0 @@
-{bind} = _
-class DevChannel
- def initialize: (@host, @port, Socket=WebSocket) ->
- @connect()
-
- def connect: ->
- @socket?.close()
- @socket = Socket.new("ws://#{@host}:#{port}")
- @socket.onmessage = bind(@onmessage, this)
- @socket.onclose = bind(@onclose, this)
- @socket.onerror = bind(@onclose, this)
-
- def onmessage: ({data}) ->
- @trampoline = undefined
- if data.protocol
- @[data.protocol].apply(this, data.arguments)
-
- def onclose: (event) ->
- @trampoline ||= 1
- if @trampoline
- console.log "Attempting reconnect #{@trampoline}/3"
- @trampoline++
-
- if @trampoline < 3
- @connect()
- else
- console.error "Unexpectedly Closed DevChannel", event
- console.info "Reason Unknown"
- console.log "reload page to reconnect"
-
- def loadStylesheet: (path, source) ->
-
- def loadScript: (path, source) ->
- console.log "loadScript", path, source
- minispade.modules[path] = source
- minispade.flushCache()
-
View
93 src/dev-channel.rb
@@ -1,93 +0,0 @@
-require 'rubygems'
-require 'listen'
-require 'bundler/setup'
-require 'reel'
-require 'rake-pipeline'
-
-module Pathology
-end
-
-class Pathology::Engine < Rails::Engine
- def self.add_project(assetfile)
- Celluloid::Actor[:asset_change_server].add_project(assetfile)
- end
-
- initializer "pathology.asset_change_server" do
- Pathology::AssetChangeServer.supervise_as :asset_change_server
- end
-end
-
-class Pathology::AssetChangeServer
- include Celluloid
- include Celluloid::Notifications
- include Celluloid::Logger
-
- def add_project(assetfile)
- project = Rake::Pipeline::Project.new(assetfile)
- project.pipelines.map(&:inputs).each do |map|
- next unless map.key?("src")
- path = "./src/#{map["src"].gsub!('*', '')}"
- path.gsub! "//", "/"
- end
-
- listener = Listen.to().change do |modified, added, removed|
- modified.each do |path|
- changed(path)
- end
- end
- listener.start(false)
- end
-
- def changed(path)
- publish 'file_change', path
- end
-end
-
-class Pathology::DevChannel
- include Celluloid
- include Celluloid::Notifications
- include Celluloid::Logger
-
- include Celluloid::Instrumentation
-
- def initialize(socket)
- info "Streaming DevChannel updates to client #{socket}"
- @socket = socket
- subscribe('file_change', :notify_file_change)
- end
-
- def notify_file_change(topic, path)
- instrument :FileChange
- new_path = "tmp/outfile.js"
- project = Rake::Pipeline::Project.build do
- tmpdir "tmp"
- output "tmp"
-
- input File.dirname(path) do
- match File.basename(path) do
- concat new_path
- end
- end
- end
-
- # client_path = new_path.gsub /.*lib\//, ''
-
- # @socket << JSON.dump({protocol: "loadScript", args: [client_path, File.read(new_path)]})
- end_instrument :FileChange
- rescue Reel::SocketError
- info "AssetChangeServer client disconnected"
- terminate
- end
-
- def instrument(id)
- @active ||= {}
- @active[id] = Time.new
- end
-
- def end_instrument(id)
- started_at = @active.delete(id)
- total = ((Time.new - started_at) * 1000.0).to_s
- info "[#{id}] #{total}ms"
- end
-end
-

0 comments on commit 042c3ce

Please sign in to comment.
Something went wrong with that request. Please try again.