# TodoMVC demo in Polymer + PuppetJS

In this demo, we will enhance Polymer TodoMVC. We will replace client side logic and using `localStorage` as database
with Starcounter. After our changes, client will only contain the presentation and all the business logic and storage
will be handled by server, updating the client using JSON Patch (RFC 6902).

# Changes in master.html

Remove the line that imports `td-model` custom element.

Remove the line that inserts `<td-model>` instance to the DOM.

Change `<td-model modelId="model">` to `<td-todos storageId="storage">`. By removing model we
removed one line of concern to the application design. Now the presentation binds directly to the data model
that comes from server.

Load scripts `/puppet.js` and it's dependency, `/json-patch-duplex.js`.

Place a `/` before all resource URLs (scripts, styles and HTML imports) to make the paths absolute. Our app
will use a multi-level URL scheme to access the task lists and their filters, so relative URLs would no longer work.

# Changes in lib-elements/polymer-localstorage.html

Actually this file should be placed under a new name, but for the sake of presentation
we apply the changes in the existing file.

In JS controller, add `value: {}` property. This will be the object, in which PuppetJs
inserts data model obtained from the server on page load.

In `load` method, replace the contents with `new Puppet(null, null, this.value);`. This 
creates an instance of PuppetJs that binds the server data model with the `value` object 
and sets up observation of the changes.

Remove the contents of the `save` method. Local changes in the data model are 
automatically observed and there is no need to imperatively call the save method.

# Changes in elements/td-todos.html

Remove the line that imports `flatiron-director` custom element (client side routing). Instead,
routing is be done by switching the window location using HTML5 History API. We intercept 
HTML5 history changes and send them as JSON Patches to the server, which decides whether 
new data and template should be sent to the client.

Change observable attribute `modelId` to `storageId`.

Remove the line that inserts `<flatiron-director>` instance to the DOM.

Remove value binding `checked="{{model.allCompleted}}"` from the "Complete All" input field. This field
now becomes just a trigger (implemented in method `toggleAllCompletedAction` below).

Change the line that iterates over `model.filtered` to `model.items`. Server exposes only a
single array of items to the client, that is already a result of an SQL query. If the
query returns only filtered items, this is what the client receives as the items array.

Change the conditional attribute value `model.items.length === 0` to `model.activeCount + model.completedCount === 0`.
This is because the `items` array no longer contains all items from the database, but only the part that the server
decided to return for the current filter.

Change filter selector attribute `selected="{{route || 'all'}}"` to `selected="{{model.filterOption}}"`, because we
no longer use client side routing. Now the server decides which link is highlighted by setting the `filterOption`
property to the appropriate value.

Change filter links from `../#/` to `{{model.taskListUrl}}`, `../#active` to `{{model.taskListUrl}}/active`,
`.../#completed` to `{{model.taskListUrl}}/completed`. We switch from fake URLs that use the hash character,
to clean, easily bookmarkable URLs that point to a task list with a certain filter.

These links are required to expose the `click` event outside of the Shadow DOM by using
`on-click="fireAction"` attribute. This enables PuppetJs to intercept the click event, and replace it with a
HTML5 History API entry and a JSON Patch that is sent to server. Server responds with
only the partial data for what has changed on screen. A partial template can be also returned from server but this is
not in scope of this demo.

In JS controller replace `modelIdChanged` method name to `storageIdChanged`. Inside that method,
bind model property directly to the storage value: 
`this.model = document.querySelector('#' + this.storageId).value;`

In the `addTodoAction` method, replace `this.model.newItem(this.$['new-todo'].value);` 
with simpler assignment to the object property: `this.model.newItemTitle$ = this.$['new-todo'].value;`

After that add a line that triggers the `blur` event outside of Shadow DOM, so that PuppetJS
can observe the change (it listens for the `click` and `blur` events).

Replace contents of in `destroyItemAction` with a trigger `detail.remove$ = null`. This trigger
will be sent in JSON Patch and handled by the server.

Replace contents of in `toggleAllCompletedAction` with a trigger `this.model.allCompleted$ = null`. This trigger
will be sent in JSON Patch and handled by the server.

Replace contents of in `clearCompletedAction` with a trigger `this.model.clearCompleted$ = null`. This trigger
will be sent in JSON Patch and handled by the server.

Remove the contents of `itemChangedAction`. Those actions are handled by server now.

At the end, add a handler for `fireAction` that triggers the `click` event outside of the 
Shadow DOM.

# Changes in elements/td-item.html

Replace all the references to `item.completed` with `item.completed$` (2 changes). 

The `$` character is a Starcounter convention to describe all the JSON properties that 
are writable. The properties that do not have the `$` character in their name, are 
regarded as read-only.

Replace all the references to `item.title` with `item.title$` (4 changes) for the same reason.

# Delete files

File `elements/td-model.html` can be removed, because client side logic is no longer used.

File `lib-elements/flatiron-director.html` can be removed, because client side routing is no longer used.
