[vendor] backbone upgrade
14
vendor/backbone/.bower.json
vendored
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "backbone",
|
||||
"homepage": "https://github.com/jashkenas/backbone",
|
||||
"version": "1.1.0",
|
||||
"_release": "1.1.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.1.0",
|
||||
"commit": "0a4399e3de5cb2ab75a0338669582f18c1fae3ae"
|
||||
},
|
||||
"_source": "git://github.com/jashkenas/backbone.git",
|
||||
"_target": "~1.1.0",
|
||||
"_originalSource": "backbone"
|
||||
}
|
4
vendor/backbone/.gitignore
vendored
|
@ -1,4 +0,0 @@
|
|||
raw
|
||||
*.sw?
|
||||
.DS_Store
|
||||
node_modules
|
7
vendor/backbone/.npmignore
vendored
|
@ -1,7 +0,0 @@
|
|||
test/
|
||||
Rakefile
|
||||
docs/
|
||||
raw/
|
||||
examples/
|
||||
index.html
|
||||
.jshintrc
|
5
vendor/backbone/.travis.yml
vendored
|
@ -1,5 +0,0 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
notifications:
|
||||
email: false
|
2
vendor/backbone/CNAME
vendored
|
@ -1,2 +0,0 @@
|
|||
backbonejs.org
|
||||
|
22
vendor/backbone/CONTRIBUTING.md
vendored
|
@ -1,22 +0,0 @@
|
|||
## How to Open a Backbone.js Ticket
|
||||
|
||||
* Do not use tickets to ask for help with (debugging) your application. Ask on
|
||||
the [mailing list](https://groups.google.com/forum/#!forum/backbonejs),
|
||||
in the IRC channel (`#documentcloud` on Freenode), or if you understand your
|
||||
specific problem, on [StackOverflow](http://stackoverflow.com/questions/tagged/backbone.js).
|
||||
|
||||
* Before you open a ticket or send a pull request,
|
||||
[search](https://github.com/jashkenas/backbone/issues) for previous
|
||||
discussions about the same feature or issue. Add to the earlier ticket if you
|
||||
find one.
|
||||
|
||||
* Before sending a pull request for a feature or bug fix, be sure to have
|
||||
[tests](http://backbonejs.org/test/).
|
||||
|
||||
* Use the same coding style as the rest of the
|
||||
[codebase](https://github.com/jashkenas/backbone/blob/master/backbone.js).
|
||||
|
||||
* In your pull request, do not add documentation or rebuild the minified
|
||||
`backbone-min.js` file. We'll do that before cutting a new release.
|
||||
|
||||
* All pull requests should be made to the `master` branch.
|
22
vendor/backbone/LICENSE
vendored
|
@ -1,22 +0,0 @@
|
|||
Copyright (c) 2010-2013 Jeremy Ashkenas, DocumentCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
29
vendor/backbone/README.md
vendored
|
@ -1,29 +0,0 @@
|
|||
____ __ __
|
||||
/\ _`\ /\ \ /\ \ __
|
||||
\ \ \ \ \ __ ___\ \ \/'\\ \ \____ ___ ___ __ /\_\ ____
|
||||
\ \ _ <' /'__`\ /'___\ \ , < \ \ '__`\ / __`\ /' _ `\ /'__`\ \/\ \ /',__\
|
||||
\ \ \ \ \/\ \ \.\_/\ \__/\ \ \\`\\ \ \ \ \/\ \ \ \/\ \/\ \/\ __/ __ \ \ \/\__, `\
|
||||
\ \____/\ \__/.\_\ \____\\ \_\ \_\ \_,__/\ \____/\ \_\ \_\ \____\/\_\_\ \ \/\____/
|
||||
\/___/ \/__/\/_/\/____/ \/_/\/_/\/___/ \/___/ \/_/\/_/\/____/\/_/\ \_\ \/___/
|
||||
\ \____/
|
||||
\/___/
|
||||
(_'_______________________________________________________________________________'_)
|
||||
(_.———————————————————————————————————————————————————————————————————————————————._)
|
||||
|
||||
|
||||
Backbone supplies structure to JavaScript-heavy applications by providing models key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.
|
||||
|
||||
For Docs, License, Tests, pre-packed downloads, and everything else, really, see:
|
||||
http://backbonejs.org
|
||||
|
||||
To suggest a feature, report a bug, or general discussion:
|
||||
http://github.com/jashkenas/backbone/issues
|
||||
|
||||
Backbone is an open-sourced component of DocumentCloud:
|
||||
https://github.com/documentcloud
|
||||
|
||||
Many thanks to our contributors:
|
||||
http://github.com/jashkenas/backbone/contributors
|
||||
|
||||
Special thanks to Robert Kieffer for the original philosophy behind Backbone.
|
||||
http://github.com/broofa
|
2
vendor/backbone/backbone-min.js
vendored
1
vendor/backbone/backbone-min.map
vendored
1581
vendor/backbone/backbone.js
vendored
284
vendor/backbone/docs/backbone-localstorage.html
vendored
|
@ -1,284 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>backbone-localstorage.js</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||
<link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
|
||||
<link rel="stylesheet" media="all" href="docco.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="page">
|
||||
|
||||
<div class="header">
|
||||
|
||||
<h1>backbone-localstorage.js</h1>
|
||||
|
||||
|
||||
|
||||
<div class="toc">
|
||||
<h3>Table of Contents</h3>
|
||||
<ol>
|
||||
|
||||
|
||||
<li>
|
||||
<a class="source" href="backbone-localstorage.html">
|
||||
backbone-localstorage.js
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a class="source" href="todos.html">
|
||||
todos.js
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="cm">/**</span>
|
||||
<span class="cm"> * Backbone localStorage Adapter</span>
|
||||
<span class="cm"> * https://github.com/jeromegn/Backbone.localStorage</span>
|
||||
<span class="cm"> */</span>
|
||||
|
||||
<span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>A simple module to replace <code>Backbone.sync</code> with <em>localStorage</em>-based
|
||||
persistence. Models are given GUIDS, and saved into a JSON object. Simple
|
||||
as that.
|
||||
|
||||
</p>
|
||||
<p>Hold reference to Underscore.js and Backbone.js in the closure in order
|
||||
to make things work even if they are removed from the global namespace
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_</span><span class="p">;</span>
|
||||
<span class="kd">var</span> <span class="nx">Backbone</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">Backbone</span><span class="p">;</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Generate four random hex digits.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">S4</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="p">(((</span><span class="mi">1</span><span class="o">+</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="mh">0x10000</span><span class="p">)</span><span class="o">|</span><span class="mi">0</span><span class="p">).</span><span class="nx">toString</span><span class="p">(</span><span class="mi">16</span><span class="p">).</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
||||
<span class="p">};</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Generate a pseudo-GUID by concatenating random hexadecimal.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">guid</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">"-"</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">"-"</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">"-"</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">"-"</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="nx">S4</span><span class="p">());</span>
|
||||
<span class="p">};</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Our Store is represented by a single JS object in <em>localStorage</em>. Create it
|
||||
with a meaningful name, like the name you'd give a table.
|
||||
window.Store is deprectated, use Backbone.LocalStorage instead
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="nx">Backbone</span><span class="p">.</span><span class="nx">LocalStorage</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">Store</span> <span class="o">=</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">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
|
||||
<span class="kd">var</span> <span class="nx">store</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">().</span><span class="nx">getItem</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">this</span><span class="p">.</span><span class="nx">records</span> <span class="o">=</span> <span class="p">(</span><span class="nx">store</span> <span class="o">&&</span> <span class="nx">store</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s2">","</span><span class="p">))</span> <span class="o">||</span> <span class="p">[];</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">LocalStorage</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="p">{</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Save the current state of the <strong>Store</strong> to <em>localStorage</em>.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">save</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">localStorage</span><span class="p">().</span><span class="nx">setItem</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">this</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s2">","</span><span class="p">));</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
|
||||
have an id of it's own.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">create</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</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">model</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">model</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">guid</span><span class="p">();</span>
|
||||
<span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">idAttribute</span><span class="p">,</span> <span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">().</span><span class="nx">setItem</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="s2">"-"</span><span class="o">+</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">model</span><span class="p">));</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">save</span><span class="p">();</span>
|
||||
<span class="k">return</span> <span class="nx">model</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">();</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Update a model by replacing its copy in <code>this.data</code>.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">update</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">().</span><span class="nx">setItem</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="s2">"-"</span><span class="o">+</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">model</span><span class="p">));</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">include</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">records</span><span class="p">,</span> <span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">toString</span><span class="p">()))</span> <span class="k">this</span><span class="p">.</span><span class="nx">records</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span> <span class="k">this</span><span class="p">.</span><span class="nx">save</span><span class="p">();</span>
|
||||
<span class="k">return</span> <span class="nx">model</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">();</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Retrieve a model from <code>this.data</code> by id.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">find</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">().</span><span class="nx">getItem</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="s2">"-"</span><span class="o">+</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">));</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Return the array of all models currently in storage.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">findAll</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">_</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">records</span><span class="p">).</span><span class="nx">chain</span><span class="p">()</span>
|
||||
<span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">){</span><span class="k">return</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">().</span><span class="nx">getItem</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="s2">"-"</span><span class="o">+</span><span class="nx">id</span><span class="p">));},</span> <span class="k">this</span><span class="p">)</span>
|
||||
<span class="p">.</span><span class="nx">compact</span><span class="p">()</span>
|
||||
<span class="p">.</span><span class="nx">value</span><span class="p">();</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Delete a model from <code>this.data</code>, returning it.
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="nx">destroy</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">().</span><span class="nx">removeItem</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="s2">"-"</span><span class="o">+</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">records</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">records</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record_id</span><span class="p">){</span><span class="k">return</span> <span class="nx">record_id</span> <span class="o">==</span> <span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">toString</span><span class="p">();});</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">save</span><span class="p">();</span>
|
||||
<span class="k">return</span> <span class="nx">model</span><span class="p">;</span>
|
||||
<span class="p">},</span>
|
||||
|
||||
<span class="nx">localStorage</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">localStorage</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="p">});</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>localSync delegate to the model or collection's
|
||||
<em>localStorage</em> property, which should be an instance of <code>Store</code>.
|
||||
window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="nx">Backbone</span><span class="p">.</span><span class="nx">LocalStorage</span><span class="p">.</span><span class="nx">sync</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">Store</span><span class="p">.</span><span class="nx">sync</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">localSync</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">method</span><span class="p">,</span> <span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">,</span> <span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">store</span> <span class="o">=</span> <span class="nx">model</span><span class="p">.</span><span class="nx">localStorage</span> <span class="o">||</span> <span class="nx">model</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">;</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Backwards compatibility with Backbone <= 0.3.3
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">options</span> <span class="o">==</span> <span class="s1">'function'</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="nx">success</span><span class="o">:</span> <span class="nx">options</span><span class="p">,</span>
|
||||
<span class="nx">error</span><span class="o">:</span> <span class="nx">error</span>
|
||||
<span class="p">};</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kd">var</span> <span class="nx">resp</span><span class="p">;</span>
|
||||
|
||||
<span class="k">switch</span> <span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">case</span> <span class="s2">"read"</span><span class="o">:</span> <span class="nx">resp</span> <span class="o">=</span> <span class="nx">model</span><span class="p">.</span><span class="nx">id</span> <span class="o">!=</span> <span class="kc">undefined</span> <span class="o">?</span> <span class="nx">store</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="o">:</span> <span class="nx">store</span><span class="p">.</span><span class="nx">findAll</span><span class="p">();</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="s2">"create"</span><span class="o">:</span> <span class="nx">resp</span> <span class="o">=</span> <span class="nx">store</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">model</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="s2">"update"</span><span class="o">:</span> <span class="nx">resp</span> <span class="o">=</span> <span class="nx">store</span><span class="p">.</span><span class="nx">update</span><span class="p">(</span><span class="nx">model</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="s2">"delete"</span><span class="o">:</span> <span class="nx">resp</span> <span class="o">=</span> <span class="nx">store</span><span class="p">.</span><span class="nx">destroy</span><span class="p">(</span><span class="nx">model</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="nx">resp</span><span class="p">);</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">options</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Record not found.'</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="nx">Backbone</span><span class="p">.</span><span class="nx">ajaxSync</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">sync</span><span class="p">;</span>
|
||||
|
||||
<span class="nx">Backbone</span><span class="p">.</span><span class="nx">getSyncMethod</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span><span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">localStorage</span> <span class="o">||</span> <span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">collection</span> <span class="o">&&</span> <span class="nx">model</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">localStorage</span><span class="p">))</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">localSync</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">return</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">ajaxSync</span><span class="p">;</span>
|
||||
<span class="p">};</span></pre></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>Override 'Backbone.sync' to default to localSync,
|
||||
the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
|
||||
</p>
|
||||
|
||||
|
||||
<div class="highlight"><pre><span class="nx">Backbone</span><span class="p">.</span><span class="nx">sync</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">method</span><span class="p">,</span> <span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">,</span> <span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">getSyncMethod</span><span class="p">(</span><span class="nx">model</span><span class="p">).</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="p">[</span><span class="nx">method</span><span class="p">,</span> <span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">,</span> <span class="nx">error</span><span class="p">]);</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="p">})();</span>
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
||||
<div class="fleur">h</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
3958
vendor/backbone/docs/backbone.html
vendored
438
vendor/backbone/docs/backbone.localstorage.html
vendored
|
@ -1,438 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>backbone.localstorage.js</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||
<link rel="stylesheet" media="all" href="docco.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="background"></div>
|
||||
|
||||
<ul id="jump_to">
|
||||
<li>
|
||||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||||
<a class="small" href="javascript:void(0);">+</a>
|
||||
<div id="jump_wrapper">
|
||||
<div id="jump_page">
|
||||
|
||||
|
||||
<a class="source" href="backbone.localstorage.html">
|
||||
backbone.localstorage.js
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="todos.html">
|
||||
todos.js
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="sections">
|
||||
|
||||
<li id="title">
|
||||
<div class="annotation">
|
||||
<h1>backbone.localstorage.js</h1>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li id="section-1">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-1">¶</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="comment">/**
|
||||
* Backbone localStorage Adapter
|
||||
* Version 1.1.0
|
||||
*
|
||||
* https://github.com/jeromegn/Backbone.localStorage
|
||||
*/</span>
|
||||
(<span class="function"><span class="keyword">function</span> <span class="params">(root, factory)</span> {</span>
|
||||
<span class="keyword">if</span> (<span class="keyword">typeof</span> define === <span class="string">"function"</span> && define.amd) {</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-2">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<p>AMD. Register as an anonymous module.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> define([<span class="string">"underscore"</span>,<span class="string">"backbone"</span>], <span class="keyword">function</span>(_, Backbone) {</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-3">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Use global variables if the locals are undefined.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">return</span> factory(_ || root._, Backbone || root.Backbone);
|
||||
});
|
||||
} <span class="keyword">else</span> {</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-4">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> factory(_, Backbone);
|
||||
}
|
||||
}(<span class="keyword">this</span>, <span class="keyword">function</span>(_, Backbone) {</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-5">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>A simple module to replace <code>Backbone.sync</code> with <em>localStorage</em>-based
|
||||
persistence. Models are given GUIDS, and saved into a JSON object. Simple
|
||||
as that.</p>
|
||||
<p>Hold reference to Underscore.js and Backbone.js in the closure in order
|
||||
to make things work even if they are removed from the global namespace</p>
|
||||
<p>Generate four random hex digits.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="keyword">function</span> <span class="title">S4</span><span class="params">()</span> {</span>
|
||||
<span class="keyword">return</span> (((<span class="number">1</span>+Math.random())*<span class="number">0x10000</span>)|<span class="number">0</span>).toString(<span class="number">16</span>).substring(<span class="number">1</span>);
|
||||
};</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-6">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<p>Generate a pseudo-GUID by concatenating random hexadecimal.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre><span class="function"><span class="keyword">function</span> <span class="title">guid</span><span class="params">()</span> {</span>
|
||||
<span class="keyword">return</span> (S4()+S4()+<span class="string">"-"</span>+S4()+<span class="string">"-"</span>+S4()+<span class="string">"-"</span>+S4()+<span class="string">"-"</span>+S4()+S4()+S4());
|
||||
};</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-7">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>Our Store is represented by a single JS object in <em>localStorage</em>. Create it
|
||||
with a meaningful name, like the name you'd give a table.
|
||||
window.Store is deprectated, use Backbone.LocalStorage instead</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>Backbone.LocalStorage = window.Store = <span class="keyword">function</span>(name) {
|
||||
<span class="keyword">this</span>.name = name;
|
||||
<span class="keyword">var</span> store = <span class="keyword">this</span>.localStorage().getItem(<span class="keyword">this</span>.name);
|
||||
<span class="keyword">this</span>.records = (store && store.split(<span class="string">","</span>)) || [];
|
||||
};
|
||||
|
||||
_.extend(Backbone.LocalStorage.prototype, {</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-8">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Save the current state of the <strong>Store</strong> to <em>localStorage</em>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> save: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.localStorage().setItem(<span class="keyword">this</span>.name, <span class="keyword">this</span>.records.join(<span class="string">","</span>));
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-9">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
|
||||
have an id of it's own.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> create: <span class="keyword">function</span>(model) {
|
||||
<span class="keyword">if</span> (!model.id) {
|
||||
model.id = guid();
|
||||
model.set(model.idAttribute, model.id);
|
||||
}
|
||||
<span class="keyword">this</span>.localStorage().setItem(<span class="keyword">this</span>.name+<span class="string">"-"</span>+model.id, JSON.stringify(model));
|
||||
<span class="keyword">this</span>.records.push(model.id.toString());
|
||||
<span class="keyword">this</span>.save();
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.find(model);
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-10">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Update a model by replacing its copy in <code>this.data</code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> update: <span class="keyword">function</span>(model) {
|
||||
<span class="keyword">this</span>.localStorage().setItem(<span class="keyword">this</span>.name+<span class="string">"-"</span>+model.id, JSON.stringify(model));
|
||||
<span class="keyword">if</span> (!_.include(<span class="keyword">this</span>.records, model.id.toString()))
|
||||
<span class="keyword">this</span>.records.push(model.id.toString()); <span class="keyword">this</span>.save();
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.find(model);
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-11">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Retrieve a model from <code>this.data</code> by id.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> find: <span class="keyword">function</span>(model) {
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.jsonData(<span class="keyword">this</span>.localStorage().getItem(<span class="keyword">this</span>.name+<span class="string">"-"</span>+model.id));
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-12">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>Return the array of all models currently in storage.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> findAll: <span class="keyword">function</span>() {
|
||||
<span class="keyword">return</span> _(<span class="keyword">this</span>.records).chain()
|
||||
.map(<span class="keyword">function</span>(id){
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.jsonData(<span class="keyword">this</span>.localStorage().getItem(<span class="keyword">this</span>.name+<span class="string">"-"</span>+id));
|
||||
}, <span class="keyword">this</span>)
|
||||
.compact()
|
||||
.value();
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-13">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Delete a model from <code>this.data</code>, returning it.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> destroy: <span class="keyword">function</span>(model) {
|
||||
<span class="keyword">if</span> (model.isNew())
|
||||
<span class="keyword">return</span> <span class="literal">false</span>
|
||||
<span class="keyword">this</span>.localStorage().removeItem(<span class="keyword">this</span>.name+<span class="string">"-"</span>+model.id);
|
||||
<span class="keyword">this</span>.records = _.reject(<span class="keyword">this</span>.records, <span class="keyword">function</span>(id){
|
||||
<span class="keyword">return</span> id === model.id.toString();
|
||||
});
|
||||
<span class="keyword">this</span>.save();
|
||||
<span class="keyword">return</span> model;
|
||||
},
|
||||
|
||||
localStorage: <span class="keyword">function</span>() {
|
||||
<span class="keyword">return</span> localStorage;
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-14">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>fix for "illegal access" error on Android when JSON.parse is passed null</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> jsonData: <span class="function"><span class="keyword">function</span> <span class="params">(data)</span> {</span>
|
||||
<span class="keyword">return</span> data && JSON.parse(data);
|
||||
}
|
||||
|
||||
});</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-15">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<p>localSync delegate to the model or collection's
|
||||
<em>localStorage</em> property, which should be an instance of <code>Store</code>.
|
||||
window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = <span class="keyword">function</span>(method, model, options) {
|
||||
<span class="keyword">var</span> store = model.localStorage || model.collection.localStorage;
|
||||
|
||||
<span class="keyword">var</span> resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); <span class="comment">//If $ is having Deferred - use it.</span>
|
||||
|
||||
<span class="keyword">try</span> {
|
||||
|
||||
<span class="keyword">switch</span> (method) {
|
||||
<span class="keyword">case</span> <span class="string">"read"</span>:
|
||||
resp = model.id != <span class="literal">undefined</span> ? store.find(model) : store.findAll();
|
||||
<span class="keyword">break</span>;
|
||||
<span class="keyword">case</span> <span class="string">"create"</span>:
|
||||
resp = store.create(model);
|
||||
<span class="keyword">break</span>;
|
||||
<span class="keyword">case</span> <span class="string">"update"</span>:
|
||||
resp = store.update(model);
|
||||
<span class="keyword">break</span>;
|
||||
<span class="keyword">case</span> <span class="string">"delete"</span>:
|
||||
resp = store.destroy(model);
|
||||
<span class="keyword">break</span>;
|
||||
}
|
||||
|
||||
} <span class="keyword">catch</span>(error) {
|
||||
<span class="keyword">if</span> (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === <span class="number">0</span>)
|
||||
errorMessage = <span class="string">"Private browsing is unsupported"</span>;
|
||||
<span class="keyword">else</span>
|
||||
errorMessage = error.message;
|
||||
}
|
||||
|
||||
<span class="keyword">if</span> (resp) {
|
||||
model.trigger(<span class="string">"sync"</span>, model, resp, options);
|
||||
<span class="keyword">if</span> (options && options.success)
|
||||
options.success(resp);
|
||||
<span class="keyword">if</span> (syncDfd)
|
||||
syncDfd.resolve(resp);
|
||||
|
||||
} <span class="keyword">else</span> {
|
||||
errorMessage = errorMessage ? errorMessage
|
||||
: <span class="string">"Record Not Found"</span>;
|
||||
|
||||
<span class="keyword">if</span> (options && options.error)
|
||||
options.error(errorMessage);
|
||||
<span class="keyword">if</span> (syncDfd)
|
||||
syncDfd.reject(errorMessage);
|
||||
}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-16">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>add compatibility with $.ajax
|
||||
always execute callback for success and error</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> (options && options.complete) options.complete(resp);
|
||||
|
||||
<span class="keyword">return</span> syncDfd && syncDfd.promise();
|
||||
};
|
||||
|
||||
Backbone.ajaxSync = Backbone.sync;
|
||||
|
||||
Backbone.getSyncMethod = <span class="keyword">function</span>(model) {
|
||||
<span class="keyword">if</span>(model.localStorage || (model.collection && model.collection.localStorage)) {
|
||||
<span class="keyword">return</span> Backbone.localSync;
|
||||
}
|
||||
|
||||
<span class="keyword">return</span> Backbone.ajaxSync;
|
||||
};</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-17">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>Override 'Backbone.sync' to default to localSync,
|
||||
the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>Backbone.sync = <span class="keyword">function</span>(method, model, options) {
|
||||
<span class="keyword">return</span> Backbone.getSyncMethod(model).apply(<span class="keyword">this</span>, [method, model, options]);
|
||||
};
|
||||
|
||||
<span class="keyword">return</span> Backbone.LocalStorage;
|
||||
}));</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
500
vendor/backbone/docs/docco.css
vendored
|
@ -1,500 +0,0 @@
|
|||
/*--------------------- Typography ----------------------------*/
|
||||
|
||||
@font-face {
|
||||
font-family: 'aller-light';
|
||||
src: url('public/fonts/aller-light.eot');
|
||||
src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),
|
||||
url('public/fonts/aller-light.woff') format('woff'),
|
||||
url('public/fonts/aller-light.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'aller-bold';
|
||||
src: url('public/fonts/aller-bold.eot');
|
||||
src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('public/fonts/aller-bold.woff') format('woff'),
|
||||
url('public/fonts/aller-bold.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'novecento-bold';
|
||||
src: url('public/fonts/novecento-bold.eot');
|
||||
src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('public/fonts/novecento-bold.woff') format('woff'),
|
||||
url('public/fonts/novecento-bold.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/*--------------------- Layout ----------------------------*/
|
||||
html { height: 100%; }
|
||||
body {
|
||||
font-family: "aller-light";
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
color: #30404f;
|
||||
margin: 0; padding: 0;
|
||||
height:100%;
|
||||
}
|
||||
#container { min-height: 100%; }
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
font-weight: normal;
|
||||
font-family: "aller-bold";
|
||||
}
|
||||
|
||||
p, ul, ol {
|
||||
margin: 15px 0 0px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #112233;
|
||||
line-height: 1em;
|
||||
font-weight: normal;
|
||||
font-family: "novecento-bold";
|
||||
text-transform: uppercase;
|
||||
margin: 30px 0 15px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
background: 1px solid #ddd;
|
||||
height: 1px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
pre, tt, code {
|
||||
font-size: 12px; line-height: 16px;
|
||||
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
|
||||
margin: 0; padding: 0;
|
||||
}
|
||||
.annotation pre {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 7px 10px;
|
||||
background: #fcfcfc;
|
||||
-moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
|
||||
box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
|
||||
overflow-x: auto;
|
||||
}
|
||||
.annotation pre code {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
|
||||
blockquote {
|
||||
border-left: 5px solid #ccc;
|
||||
margin: 0;
|
||||
padding: 1px 0 1px 1em;
|
||||
}
|
||||
.sections blockquote p {
|
||||
font-family: Menlo, Consolas, Monaco, monospace;
|
||||
font-size: 12px; line-height: 16px;
|
||||
color: #999;
|
||||
margin: 10px 0 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
ul.sections {
|
||||
list-style: none;
|
||||
padding:0 0 5px 0;;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
/*
|
||||
Force border-box so that % widths fit the parent
|
||||
container without overlap because of margin/padding.
|
||||
|
||||
More Info : http://www.quirksmode.org/css/box.html
|
||||
*/
|
||||
ul.sections > li > div {
|
||||
-moz-box-sizing: border-box; /* firefox */
|
||||
-ms-box-sizing: border-box; /* ie */
|
||||
-webkit-box-sizing: border-box; /* webkit */
|
||||
-khtml-box-sizing: border-box; /* konqueror */
|
||||
box-sizing: border-box; /* css3 */
|
||||
}
|
||||
|
||||
|
||||
/*---------------------- Jump Page -----------------------------*/
|
||||
#jump_to, #jump_page {
|
||||
margin: 0;
|
||||
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: 16px Arial;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#jump_to a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#jump_to a.large {
|
||||
display: none;
|
||||
}
|
||||
#jump_to a.small {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #676767;
|
||||
}
|
||||
|
||||
#jump_to, #jump_wrapper {
|
||||
position: fixed;
|
||||
right: 0; top: 0;
|
||||
padding: 10px 15px;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#jump_wrapper {
|
||||
display: none;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
#jump_to:hover #jump_wrapper {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#jump_page {
|
||||
padding: 5px 0 3px;
|
||||
margin: 0 0 25px 25px;
|
||||
}
|
||||
|
||||
#jump_page .source {
|
||||
display: block;
|
||||
padding: 15px;
|
||||
text-decoration: none;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
#jump_page .source:hover {
|
||||
background: #f5f5ff;
|
||||
}
|
||||
|
||||
#jump_page .source:first-child {
|
||||
}
|
||||
|
||||
/*---------------------- Low resolutions (> 320px) ---------------------*/
|
||||
@media only screen and (min-width: 320px) {
|
||||
.pilwrap { display: none; }
|
||||
|
||||
ul.sections > li > div {
|
||||
display: block;
|
||||
padding:5px 10px 0 10px;
|
||||
}
|
||||
|
||||
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
ul.sections > li > div.content {
|
||||
background: #f5f5ff;
|
||||
overflow-x:auto;
|
||||
-webkit-box-shadow: inset 0 0 5px #e5e5ee;
|
||||
box-shadow: inset 0 0 5px #e5e5ee;
|
||||
border: 1px solid #dedede;
|
||||
margin:5px 10px 5px 10px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
ul.sections > li > div.annotation pre {
|
||||
margin: 7px 0 7px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
ul.sections > li > div.annotation p tt, .annotation code {
|
||||
background: #f8f8ff;
|
||||
border: 1px solid #dedede;
|
||||
font-size: 12px;
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------- (> 481px) ---------------------*/
|
||||
@media only screen and (min-width: 481px) {
|
||||
#container {
|
||||
position: relative;
|
||||
}
|
||||
body {
|
||||
background-color: #F5F5FF;
|
||||
font-size: 15px;
|
||||
line-height: 21px;
|
||||
}
|
||||
pre, tt, code {
|
||||
line-height: 18px;
|
||||
}
|
||||
p, ul, ol {
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
|
||||
|
||||
#jump_to {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#jump_wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
#jump_to, #jump_page {
|
||||
font: 10px Arial;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
#jump_page .source {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#jump_to a.large {
|
||||
display: inline-block;
|
||||
}
|
||||
#jump_to a.small {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
width: 350px;
|
||||
background: #fff;
|
||||
border-right: 1px solid #e5e5ee;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
ul.sections > li {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
ul.sections > li > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
ul.sections > li > div.annotation {
|
||||
max-width: 350px;
|
||||
min-width: 350px;
|
||||
min-height: 5px;
|
||||
padding: 13px;
|
||||
overflow-x: hidden;
|
||||
white-space: normal;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
ul.sections > li > div.annotation pre {
|
||||
margin: 15px 0 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
ul.sections > li > div.content {
|
||||
padding: 13px;
|
||||
vertical-align: top;
|
||||
background: #f5f5ff;
|
||||
border: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.pilwrap {
|
||||
position: relative;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
.for-h1 .pilcrow {
|
||||
top: 47px;
|
||||
}
|
||||
.for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
|
||||
top: 35px;
|
||||
}
|
||||
|
||||
ul.sections > li > div.annotation:hover .pilcrow {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------- (> 1025px) ---------------------*/
|
||||
@media only screen and (min-width: 1025px) {
|
||||
|
||||
body {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
#background {
|
||||
width: 525px;
|
||||
}
|
||||
ul.sections > li > div.annotation {
|
||||
max-width: 525px;
|
||||
min-width: 525px;
|
||||
padding: 10px 25px 1px 50px;
|
||||
}
|
||||
ul.sections > li > div.content {
|
||||
padding: 9px 15px 16px 25px;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------- Syntax Highlighting -----------------------------*/
|
||||
|
||||
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
|
||||
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
pre code {
|
||||
display: block; padding: 0.5em;
|
||||
color: #000;
|
||||
background: #f8f8ff
|
||||
}
|
||||
|
||||
pre .comment,
|
||||
pre .template_comment,
|
||||
pre .diff .header,
|
||||
pre .javadoc {
|
||||
color: #408080;
|
||||
font-style: italic
|
||||
}
|
||||
|
||||
pre .keyword,
|
||||
pre .assignment,
|
||||
pre .literal,
|
||||
pre .css .rule .keyword,
|
||||
pre .winutils,
|
||||
pre .javascript .title,
|
||||
pre .lisp .title,
|
||||
pre .subst {
|
||||
color: #954121;
|
||||
/*font-weight: bold*/
|
||||
}
|
||||
|
||||
pre .number,
|
||||
pre .hexcolor {
|
||||
color: #40a070
|
||||
}
|
||||
|
||||
pre .string,
|
||||
pre .tag .value,
|
||||
pre .phpdoc,
|
||||
pre .tex .formula {
|
||||
color: #219161;
|
||||
}
|
||||
|
||||
pre .title,
|
||||
pre .id {
|
||||
color: #19469D;
|
||||
}
|
||||
pre .params {
|
||||
color: #00F;
|
||||
}
|
||||
|
||||
pre .javascript .title,
|
||||
pre .lisp .title,
|
||||
pre .subst {
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
pre .class .title,
|
||||
pre .haskell .label,
|
||||
pre .tex .command {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .tag,
|
||||
pre .tag .title,
|
||||
pre .rules .property,
|
||||
pre .django .tag .keyword {
|
||||
color: #000080;
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
pre .attribute,
|
||||
pre .variable,
|
||||
pre .instancevar,
|
||||
pre .lisp .body {
|
||||
color: #008080
|
||||
}
|
||||
|
||||
pre .regexp {
|
||||
color: #B68
|
||||
}
|
||||
|
||||
pre .class {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .symbol,
|
||||
pre .ruby .symbol .string,
|
||||
pre .ruby .symbol .keyword,
|
||||
pre .ruby .symbol .keymethods,
|
||||
pre .lisp .keyword,
|
||||
pre .tex .special,
|
||||
pre .input_number {
|
||||
color: #990073
|
||||
}
|
||||
|
||||
pre .builtin,
|
||||
pre .constructor,
|
||||
pre .built_in,
|
||||
pre .lisp .title {
|
||||
color: #0086b3
|
||||
}
|
||||
|
||||
pre .preprocessor,
|
||||
pre .pi,
|
||||
pre .doctype,
|
||||
pre .shebang,
|
||||
pre .cdata {
|
||||
color: #999;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
pre .deletion {
|
||||
background: #fdd
|
||||
}
|
||||
|
||||
pre .addition {
|
||||
background: #dfd
|
||||
}
|
||||
|
||||
pre .diff .change {
|
||||
background: #0086b3
|
||||
}
|
||||
|
||||
pre .chunk {
|
||||
color: #aaa
|
||||
}
|
||||
|
||||
pre .tex .formula {
|
||||
opacity: 0.5;
|
||||
}
|
BIN
vendor/backbone/docs/images/airbnb.png
vendored
Before Width: | Height: | Size: 298 KiB |
BIN
vendor/backbone/docs/images/arrows.png
vendored
Before Width: | Height: | Size: 1.2 KiB |
BIN
vendor/backbone/docs/images/artsy.png
vendored
Before Width: | Height: | Size: 220 KiB |
BIN
vendor/backbone/docs/images/backbone-mobile.png
vendored
Before Width: | Height: | Size: 89 KiB |
BIN
vendor/backbone/docs/images/backbone.png
vendored
Before Width: | Height: | Size: 20 KiB |
BIN
vendor/backbone/docs/images/background.png
vendored
Before Width: | Height: | Size: 2.1 KiB |
BIN
vendor/backbone/docs/images/baroque.jpg
vendored
Before Width: | Height: | Size: 83 KiB |
BIN
vendor/backbone/docs/images/basecamp-calendar.jpg
vendored
Before Width: | Height: | Size: 55 KiB |
BIN
vendor/backbone/docs/images/bitbucket.png
vendored
Before Width: | Height: | Size: 71 KiB |
BIN
vendor/backbone/docs/images/blossom.png
vendored
Before Width: | Height: | Size: 81 KiB |
BIN
vendor/backbone/docs/images/cloudapp.png
vendored
Before Width: | Height: | Size: 101 KiB |
BIN
vendor/backbone/docs/images/code-school.png
vendored
Before Width: | Height: | Size: 290 KiB |
BIN
vendor/backbone/docs/images/dc-workspace.png
vendored
Before Width: | Height: | Size: 102 KiB |
BIN
vendor/backbone/docs/images/diaspora.png
vendored
Before Width: | Height: | Size: 140 KiB |
BIN
vendor/backbone/docs/images/disqus.png
vendored
Before Width: | Height: | Size: 84 KiB |
BIN
vendor/backbone/docs/images/do.png
vendored
Before Width: | Height: | Size: 100 KiB |
BIN
vendor/backbone/docs/images/easel.png
vendored
Before Width: | Height: | Size: 65 KiB |
BIN
vendor/backbone/docs/images/favicon.ico
vendored
Before Width: | Height: | Size: 8.2 KiB |
BIN
vendor/backbone/docs/images/flow.png
vendored
Before Width: | Height: | Size: 151 KiB |
BIN
vendor/backbone/docs/images/foursquare.png
vendored
Before Width: | Height: | Size: 226 KiB |
BIN
vendor/backbone/docs/images/gawker.png
vendored
Before Width: | Height: | Size: 1,010 KiB |
BIN
vendor/backbone/docs/images/gilt.jpg
vendored
Before Width: | Height: | Size: 78 KiB |
BIN
vendor/backbone/docs/images/groupon.png
vendored
Before Width: | Height: | Size: 236 KiB |
BIN
vendor/backbone/docs/images/hulu.png
vendored
Before Width: | Height: | Size: 287 KiB |
BIN
vendor/backbone/docs/images/inkling.png
vendored
Before Width: | Height: | Size: 180 KiB |
BIN
vendor/backbone/docs/images/irccloud.png
vendored
Before Width: | Height: | Size: 160 KiB |
BIN
vendor/backbone/docs/images/jolicloud.jpg
vendored
Before Width: | Height: | Size: 206 KiB |
BIN
vendor/backbone/docs/images/khan-academy.png
vendored
Before Width: | Height: | Size: 139 KiB |
BIN
vendor/backbone/docs/images/lens.png
vendored
Before Width: | Height: | Size: 466 KiB |
BIN
vendor/backbone/docs/images/menagerievet.png
vendored
Before Width: | Height: | Size: 75 KiB |
BIN
vendor/backbone/docs/images/newsblur.jpg
vendored
Before Width: | Height: | Size: 200 KiB |
BIN
vendor/backbone/docs/images/pandora.png
vendored
Before Width: | Height: | Size: 128 KiB |
BIN
vendor/backbone/docs/images/pitchfork.png
vendored
Before Width: | Height: | Size: 214 KiB |
BIN
vendor/backbone/docs/images/quartz.jpg
vendored
Before Width: | Height: | Size: 149 KiB |
BIN
vendor/backbone/docs/images/rdio.png
vendored
Before Width: | Height: | Size: 225 KiB |
BIN
vendor/backbone/docs/images/salon.png
vendored
Before Width: | Height: | Size: 254 KiB |
BIN
vendor/backbone/docs/images/seatgeek.png
vendored
Before Width: | Height: | Size: 266 KiB |
BIN
vendor/backbone/docs/images/slavery-footprint.png
vendored
Before Width: | Height: | Size: 120 KiB |
BIN
vendor/backbone/docs/images/soundcloud.png
vendored
Before Width: | Height: | Size: 129 KiB |
BIN
vendor/backbone/docs/images/spin.png
vendored
Before Width: | Height: | Size: 283 KiB |
BIN
vendor/backbone/docs/images/stripe.png
vendored
Before Width: | Height: | Size: 130 KiB |
BIN
vendor/backbone/docs/images/syllabus.jpg
vendored
Before Width: | Height: | Size: 146 KiB |
BIN
vendor/backbone/docs/images/tilemill.png
vendored
Before Width: | Height: | Size: 149 KiB |
BIN
vendor/backbone/docs/images/todos.png
vendored
Before Width: | Height: | Size: 41 KiB |
BIN
vendor/backbone/docs/images/trello.png
vendored
Before Width: | Height: | Size: 112 KiB |
BIN
vendor/backbone/docs/images/tzigla.png
vendored
Before Width: | Height: | Size: 276 KiB |
BIN
vendor/backbone/docs/images/usa-today.png
vendored
Before Width: | Height: | Size: 331 KiB |
BIN
vendor/backbone/docs/images/walmart-mobile.png
vendored
Before Width: | Height: | Size: 136 KiB |
BIN
vendor/backbone/docs/images/wpcom-notifications.png
vendored
Before Width: | Height: | Size: 79 KiB |
BIN
vendor/backbone/docs/images/zocdoc.jpg
vendored
Before Width: | Height: | Size: 156 KiB |
210
vendor/backbone/docs/js/jquery.lazyload.js
vendored
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Lazy Load - jQuery plugin for lazy loading images
|
||||
*
|
||||
* Copyright (c) 2007-2012 Mika Tuupola
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Project home:
|
||||
* http://www.appelsiini.net/projects/lazyload
|
||||
*
|
||||
* Version: 1.7.2
|
||||
*
|
||||
*/
|
||||
(function($, window) {
|
||||
|
||||
$window = $(window);
|
||||
|
||||
$.fn.lazyload = function(options) {
|
||||
var elements = this;
|
||||
var settings = {
|
||||
threshold : 0,
|
||||
failure_limit : 0,
|
||||
event : "scroll",
|
||||
effect : "show",
|
||||
container : window,
|
||||
data_attribute : "original",
|
||||
skip_invisible : true,
|
||||
appear : null,
|
||||
load : null
|
||||
};
|
||||
|
||||
function update() {
|
||||
var counter = 0;
|
||||
|
||||
elements.each(function() {
|
||||
var $this = $(this);
|
||||
if (settings.skip_invisible && !$this.is(":visible")) {
|
||||
return;
|
||||
}
|
||||
if ($.abovethetop(this, settings) ||
|
||||
$.leftofbegin(this, settings)) {
|
||||
/* Nothing. */
|
||||
} else if (!$.belowthefold(this, settings) &&
|
||||
!$.rightoffold(this, settings)) {
|
||||
$this.trigger("appear");
|
||||
} else {
|
||||
if (++counter > settings.failure_limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if(options) {
|
||||
/* Maintain BC for a couple of versions. */
|
||||
if (undefined !== options.failurelimit) {
|
||||
options.failure_limit = options.failurelimit;
|
||||
delete options.failurelimit;
|
||||
}
|
||||
if (undefined !== options.effectspeed) {
|
||||
options.effect_speed = options.effectspeed;
|
||||
delete options.effectspeed;
|
||||
}
|
||||
|
||||
$.extend(settings, options);
|
||||
}
|
||||
|
||||
/* Cache container as jQuery as object. */
|
||||
$container = (settings.container === undefined ||
|
||||
settings.container === window) ? $window : $(settings.container);
|
||||
|
||||
/* Fire one scroll event per scroll. Not one scroll event per image. */
|
||||
if (0 === settings.event.indexOf("scroll")) {
|
||||
$container.bind(settings.event, function(event) {
|
||||
return update();
|
||||
});
|
||||
}
|
||||
|
||||
this.each(function() {
|
||||
var self = this;
|
||||
var $self = $(self);
|
||||
|
||||
self.loaded = false;
|
||||
|
||||
/* When appear is triggered load original image. */
|
||||
$self.one("appear", function() {
|
||||
if (!this.loaded) {
|
||||
if (settings.appear) {
|
||||
var elements_left = elements.length;
|
||||
settings.appear.call(self, elements_left, settings);
|
||||
}
|
||||
$("<img />")
|
||||
.bind("load", function() {
|
||||
$self
|
||||
.hide()
|
||||
.attr("src", $self.data(settings.data_attribute))
|
||||
[settings.effect](settings.effect_speed);
|
||||
self.loaded = true;
|
||||
|
||||
/* Remove image from array so it is not looped next time. */
|
||||
var temp = $.grep(elements, function(element) {
|
||||
return !element.loaded;
|
||||
});
|
||||
elements = $(temp);
|
||||
|
||||
if (settings.load) {
|
||||
var elements_left = elements.length;
|
||||
settings.load.call(self, elements_left, settings);
|
||||
}
|
||||
})
|
||||
.attr("src", $self.data(settings.data_attribute));
|
||||
}
|
||||
});
|
||||
|
||||
/* When wanted event is triggered load original image */
|
||||
/* by triggering appear. */
|
||||
if (0 !== settings.event.indexOf("scroll")) {
|
||||
$self.bind(settings.event, function(event) {
|
||||
if (!self.loaded) {
|
||||
$self.trigger("appear");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/* Check if something appears when window is resized. */
|
||||
$window.bind("resize", function(event) {
|
||||
update();
|
||||
});
|
||||
|
||||
/* Force initial check if images should appear. */
|
||||
update();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/* Convenience methods in jQuery namespace. */
|
||||
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */
|
||||
|
||||
$.belowthefold = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.height() + $window.scrollTop();
|
||||
} else {
|
||||
fold = $container.offset().top + $container.height();
|
||||
}
|
||||
|
||||
return fold <= $(element).offset().top - settings.threshold;
|
||||
};
|
||||
|
||||
$.rightoffold = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.width() + $window.scrollLeft();
|
||||
} else {
|
||||
fold = $container.offset().left + $container.width();
|
||||
}
|
||||
|
||||
return fold <= $(element).offset().left - settings.threshold;
|
||||
};
|
||||
|
||||
$.abovethetop = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.scrollTop();
|
||||
} else {
|
||||
fold = $container.offset().top;
|
||||
}
|
||||
|
||||
return fold >= $(element).offset().top + settings.threshold + $(element).height();
|
||||
};
|
||||
|
||||
$.leftofbegin = function(element, settings) {
|
||||
var fold;
|
||||
|
||||
if (settings.container === undefined || settings.container === window) {
|
||||
fold = $window.scrollLeft();
|
||||
} else {
|
||||
fold = $container.offset().left;
|
||||
}
|
||||
|
||||
return fold >= $(element).offset().left + settings.threshold + $(element).width();
|
||||
};
|
||||
|
||||
$.inviewport = function(element, settings) {
|
||||
return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) &&
|
||||
!$.belowthefold(element, settings) && !$.abovethetop(element, settings);
|
||||
};
|
||||
|
||||
/* Custom selectors for your convenience. */
|
||||
/* Use as $("img:below-the-fold").something() */
|
||||
|
||||
$.extend($.expr[':'], {
|
||||
"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0, container: window}); },
|
||||
"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0, container: window}); },
|
||||
"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0, container: window}); },
|
||||
"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0, container: window}); },
|
||||
"in-viewport" : function(a) { return !$.inviewport(a, {threshold : 0, container: window}); },
|
||||
/* Maintain BC for couple of versions. */
|
||||
"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0, container: window}); },
|
||||
"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0, container: window}); },
|
||||
"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0, container: window}); }
|
||||
});
|
||||
|
||||
})(jQuery, window);
|
44
vendor/backbone/docs/jsl.conf
vendored
|
@ -1,44 +0,0 @@
|
|||
# JavaScriptLint configuration file for CoffeeScript.
|
||||
|
||||
+no_return_value # function {0} does not always return a value
|
||||
+duplicate_formal # duplicate formal argument {0}
|
||||
-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
|
||||
+var_hides_arg # variable {0} hides argument
|
||||
+redeclared_var # redeclaration of {0} {1}
|
||||
-anon_no_return_value # anonymous function does not always return a value
|
||||
+missing_semicolon # missing semicolon
|
||||
+meaningless_block # meaningless block; curly braces have no impact
|
||||
-comma_separated_stmts # multiple statements separated by commas (use semicolons?)
|
||||
+unreachable_code # unreachable code
|
||||
+missing_break # missing break statement
|
||||
+missing_break_for_last_case # missing break statement for last case in switch
|
||||
-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
|
||||
-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement
|
||||
-useless_void # use of the void type may be unnecessary (void is always undefined)
|
||||
+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
|
||||
+use_of_label # use of label
|
||||
-block_without_braces # block statement without curly braces
|
||||
+leading_decimal_point # leading decimal point may indicate a number or an object member
|
||||
+trailing_decimal_point # trailing decimal point may indicate a number or an object member
|
||||
+octal_number # leading zeros make an octal number
|
||||
+nested_comment # nested comment
|
||||
+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
|
||||
+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
|
||||
+empty_statement # empty statement or extra semicolon
|
||||
-missing_option_explicit # the "option explicit" control comment is missing
|
||||
+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
|
||||
+dup_option_explicit # duplicate "option explicit" control comment
|
||||
+useless_assign # useless assignment
|
||||
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
|
||||
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
|
||||
-missing_default_case # missing default case in switch statement
|
||||
+duplicate_case_in_switch # duplicate case in switch statements
|
||||
+default_not_at_end # the default case is not at the end of the switch statement
|
||||
+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
|
||||
+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
|
||||
+useless_comparison # useless comparison; comparing identical expressions
|
||||
+with_statement # with statement hides undeclared variables; use temporary variable instead
|
||||
+trailing_comma_in_array # extra comma is not recommended in array initializers
|
||||
+assign_to_function_call # assignment to a function call
|
||||
+parseint_missing_radix # parseInt missing radix parameter
|
||||
+lambda_assign_requires_semicolon
|
BIN
vendor/backbone/docs/public/fonts/aller-bold.eot
vendored
BIN
vendor/backbone/docs/public/fonts/aller-bold.ttf
vendored
BIN
vendor/backbone/docs/public/fonts/aller-bold.woff
vendored
BIN
vendor/backbone/docs/public/fonts/aller-light.eot
vendored
BIN
vendor/backbone/docs/public/fonts/aller-light.ttf
vendored
BIN
vendor/backbone/docs/public/fonts/aller-light.woff
vendored
BIN
vendor/backbone/docs/public/fonts/fleurons.eot
vendored
BIN
vendor/backbone/docs/public/fonts/fleurons.ttf
vendored
BIN
vendor/backbone/docs/public/fonts/fleurons.woff
vendored
BIN
vendor/backbone/docs/public/fonts/novecento-bold.eot
vendored
BIN
vendor/backbone/docs/public/fonts/novecento-bold.ttf
vendored
BIN
vendor/backbone/docs/public/images/grey_@2X.png
vendored
Before Width: | Height: | Size: 56 KiB |
|
@ -1,375 +0,0 @@
|
|||
/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
|
||||
|
||||
/* ==========================================================================
|
||||
HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Corrects `block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects `inline-block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling for `hidden` attribute not present in IE 8/9.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Base
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* 1. Sets default font family to sans-serif.
|
||||
* 2. Prevents iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Links
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses `outline` inconsistency between Chrome and other browsers.
|
||||
*/
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Typography
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
|
||||
* Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE 8/9, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Corrects font family set oddly in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability of pre-formatted text in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets consistent quote types.
|
||||
*/
|
||||
|
||||
q {
|
||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Removes border when inside `a` element in IE 8/9.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects overflow displayed oddly in IE 9.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Figures
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses margin not present in IE 8/9 and Safari 5.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Forms
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects color not being inherited in IE 8/9.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects font family not being inherited in all browsers.
|
||||
* 2. Corrects font size not being inherited in all browsers.
|
||||
* 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
button,
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Corrects inability to style clickable `input` types in iOS.
|
||||
* 3. Improves usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses box sizing set to `content-box` in IE 8/9.
|
||||
* 2. Removes excess padding in IE 8/9.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
|
||||
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and search cancel button in Safari 5 and Chrome
|
||||
* on OS X.
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and border in Firefox 4+.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Removes default vertical scrollbar in IE 8/9.
|
||||
* 2. Improves readability and alignment in all browsers.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto; /* 1 */
|
||||
vertical-align: top; /* 2 */
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Tables
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
729
vendor/backbone/docs/todos.html
vendored
|
@ -1,729 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>todos.js</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||||
<link rel="stylesheet" media="all" href="docco.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="background"></div>
|
||||
|
||||
<ul id="jump_to">
|
||||
<li>
|
||||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||||
<a class="small" href="javascript:void(0);">+</a>
|
||||
<div id="jump_wrapper">
|
||||
<div id="jump_page">
|
||||
|
||||
|
||||
<a class="source" href="backbone.localstorage.html">
|
||||
backbone.localstorage.js
|
||||
</a>
|
||||
|
||||
|
||||
<a class="source" href="todos.html">
|
||||
todos.js
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="sections">
|
||||
|
||||
<li id="title">
|
||||
<div class="annotation">
|
||||
<h1>todos.js</h1>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li id="section-1">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-1">¶</a>
|
||||
</div>
|
||||
<p>An example Backbone application contributed by
|
||||
<a href="http://jgn.me/">Jérôme Gravel-Niquet</a>. This demo uses a simple
|
||||
<a href="backbone-localstorage.html">LocalStorage adapter</a>
|
||||
to persist Backbone models within your browser.</p>
|
||||
<p>Load the application once the DOM is ready, using <code>jQuery.ready</code>:</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre>$(<span class="keyword">function</span>(){</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-2">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<a class="pilcrow" href="#section-2">¶</a>
|
||||
</div>
|
||||
<h2>Todo Model</h2>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-3">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-3">¶</a>
|
||||
</div>
|
||||
<p>Our basic <strong>Todo</strong> model has <code>title</code>, <code>order</code>, and <code>done</code> attributes.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> Todo = Backbone.Model.extend({</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-4">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-4">¶</a>
|
||||
</div>
|
||||
<p>Default attributes for the todo item.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> defaults: <span class="keyword">function</span>() {
|
||||
<span class="keyword">return</span> {
|
||||
title: <span class="string">"empty todo..."</span>,
|
||||
order: Todos.nextOrder(),
|
||||
done: <span class="literal">false</span>
|
||||
};
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-5">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</a>
|
||||
</div>
|
||||
<p>Toggle the <code>done</code> state of this todo item.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> toggle: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.save({done: !<span class="keyword">this</span>.get(<span class="string">"done"</span>)});
|
||||
}
|
||||
|
||||
});</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-6">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<a class="pilcrow" href="#section-6">¶</a>
|
||||
</div>
|
||||
<h2>Todo Collection</h2>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-7">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-7">¶</a>
|
||||
</div>
|
||||
<p>The collection of todos is backed by <em>localStorage</em> instead of a remote
|
||||
server.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> TodoList = Backbone.Collection.extend({</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-8">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-8">¶</a>
|
||||
</div>
|
||||
<p>Reference to this collection's model.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> model: Todo,</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-9">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-9">¶</a>
|
||||
</div>
|
||||
<p>Save all of the todo items under the <code>"todos-backbone"</code> namespace.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> localStorage: <span class="keyword">new</span> Backbone.LocalStorage(<span class="string">"todos-backbone"</span>),</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-10">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-10">¶</a>
|
||||
</div>
|
||||
<p>Filter down the list of all todo items that are finished.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> done: <span class="keyword">function</span>() {
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.where({done: <span class="literal">true</span>});
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-11">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-11">¶</a>
|
||||
</div>
|
||||
<p>Filter down the list to only todo items that are still not finished.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> remaining: <span class="keyword">function</span>() {
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.where({done: <span class="literal">false</span>});
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-12">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-12">¶</a>
|
||||
</div>
|
||||
<p>We keep the Todos in sequential order, despite being saved by unordered
|
||||
GUID in the database. This generates the next order number for new items.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> nextOrder: <span class="keyword">function</span>() {
|
||||
<span class="keyword">if</span> (!<span class="keyword">this</span>.length) <span class="keyword">return</span> <span class="number">1</span>;
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>.last().get(<span class="string">'order'</span>) + <span class="number">1</span>;
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-13">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-13">¶</a>
|
||||
</div>
|
||||
<p>Todos are sorted by their original insertion order.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> comparator: <span class="string">'order'</span>
|
||||
|
||||
});</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-14">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-14">¶</a>
|
||||
</div>
|
||||
<p>Create our global collection of <strong>Todos</strong>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> Todos = <span class="keyword">new</span> TodoList;</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-15">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<a class="pilcrow" href="#section-15">¶</a>
|
||||
</div>
|
||||
<h2>Todo Item View</h2>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-16">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-16">¶</a>
|
||||
</div>
|
||||
<p>The DOM element for a todo item...</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> TodoView = Backbone.View.extend({</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-17">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-17">¶</a>
|
||||
</div>
|
||||
<p>... is a list tag.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> tagName: <span class="string">"li"</span>,</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-18">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-18">¶</a>
|
||||
</div>
|
||||
<p>Cache the template function for a single item.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> template: _.template($(<span class="string">'#item-template'</span>).html()),</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-19">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-19">¶</a>
|
||||
</div>
|
||||
<p>The DOM events specific to an item.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> events: {
|
||||
<span class="string">"click .toggle"</span> : <span class="string">"toggleDone"</span>,
|
||||
<span class="string">"dblclick .view"</span> : <span class="string">"edit"</span>,
|
||||
<span class="string">"click a.destroy"</span> : <span class="string">"clear"</span>,
|
||||
<span class="string">"keypress .edit"</span> : <span class="string">"updateOnEnter"</span>,
|
||||
<span class="string">"blur .edit"</span> : <span class="string">"close"</span>
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-20">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-20">¶</a>
|
||||
</div>
|
||||
<p>The TodoView listens for changes to its model, re-rendering. Since there's
|
||||
a one-to-one correspondence between a <strong>Todo</strong> and a <strong>TodoView</strong> in this
|
||||
app, we set a direct reference on the model for convenience.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> initialize: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.listenTo(<span class="keyword">this</span>.model, <span class="string">'change'</span>, <span class="keyword">this</span>.render);
|
||||
<span class="keyword">this</span>.listenTo(<span class="keyword">this</span>.model, <span class="string">'destroy'</span>, <span class="keyword">this</span>.remove);
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-21">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-21">¶</a>
|
||||
</div>
|
||||
<p>Re-render the titles of the todo item.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> render: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.$el.html(<span class="keyword">this</span>.template(<span class="keyword">this</span>.model.toJSON()));
|
||||
<span class="keyword">this</span>.$el.toggleClass(<span class="string">'done'</span>, <span class="keyword">this</span>.model.get(<span class="string">'done'</span>));
|
||||
<span class="keyword">this</span>.input = <span class="keyword">this</span>.$(<span class="string">'.edit'</span>);
|
||||
<span class="keyword">return</span> <span class="keyword">this</span>;
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-22">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-22">¶</a>
|
||||
</div>
|
||||
<p>Toggle the <code>"done"</code> state of the model.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> toggleDone: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.model.toggle();
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-23">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-23">¶</a>
|
||||
</div>
|
||||
<p>Switch this view into <code>"editing"</code> mode, displaying the input field.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> edit: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.$el.addClass(<span class="string">"editing"</span>);
|
||||
<span class="keyword">this</span>.input.focus();
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-24">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-24">¶</a>
|
||||
</div>
|
||||
<p>Close the <code>"editing"</code> mode, saving changes to the todo.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> close: <span class="keyword">function</span>() {
|
||||
<span class="keyword">var</span> value = <span class="keyword">this</span>.input.val();
|
||||
<span class="keyword">if</span> (!value) {
|
||||
<span class="keyword">this</span>.clear();
|
||||
} <span class="keyword">else</span> {
|
||||
<span class="keyword">this</span>.model.save({title: value});
|
||||
<span class="keyword">this</span>.$el.removeClass(<span class="string">"editing"</span>);
|
||||
}
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-25">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-25">¶</a>
|
||||
</div>
|
||||
<p>If you hit <code>enter</code>, we're through editing the item.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> updateOnEnter: <span class="keyword">function</span>(e) {
|
||||
<span class="keyword">if</span> (e.keyCode == <span class="number">13</span>) <span class="keyword">this</span>.close();
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-26">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-26">¶</a>
|
||||
</div>
|
||||
<p>Remove the item, destroy the model.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> clear: <span class="keyword">function</span>() {
|
||||
<span class="keyword">this</span>.model.destroy();
|
||||
}
|
||||
|
||||
});</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-27">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap for-h2">
|
||||
<a class="pilcrow" href="#section-27">¶</a>
|
||||
</div>
|
||||
<h2>The Application</h2>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-28">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-28">¶</a>
|
||||
</div>
|
||||
<p>Our overall <strong>AppView</strong> is the top-level piece of UI.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> AppView = Backbone.View.extend({</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-29">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-29">¶</a>
|
||||
</div>
|
||||
<p>Instead of generating a new element, bind to the existing skeleton of
|
||||
the App already present in the HTML.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> el: $(<span class="string">"#todoapp"</span>),</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-30">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-30">¶</a>
|
||||
</div>
|
||||
<p>Our template for the line of statistics at the bottom of the app.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> statsTemplate: _.template($(<span class="string">'#stats-template'</span>).html()),</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-31">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-31">¶</a>
|
||||
</div>
|
||||
<p>Delegated events for creating new items, and clearing completed ones.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> events: {
|
||||
<span class="string">"keypress #new-todo"</span>: <span class="string">"createOnEnter"</span>,
|
||||
<span class="string">"click #clear-completed"</span>: <span class="string">"clearCompleted"</span>,
|
||||
<span class="string">"click #toggle-all"</span>: <span class="string">"toggleAllComplete"</span>
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-32">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-32">¶</a>
|
||||
</div>
|
||||
<p>At initialization we bind to the relevant events on the <code>Todos</code>
|
||||
collection, when items are added or changed. Kick things off by
|
||||
loading any preexisting todos that might be saved in <em>localStorage</em>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> initialize: <span class="keyword">function</span>() {
|
||||
|
||||
<span class="keyword">this</span>.input = <span class="keyword">this</span>.$(<span class="string">"#new-todo"</span>);
|
||||
<span class="keyword">this</span>.allCheckbox = <span class="keyword">this</span>.$(<span class="string">"#toggle-all"</span>)[<span class="number">0</span>];
|
||||
|
||||
<span class="keyword">this</span>.listenTo(Todos, <span class="string">'add'</span>, <span class="keyword">this</span>.addOne);
|
||||
<span class="keyword">this</span>.listenTo(Todos, <span class="string">'reset'</span>, <span class="keyword">this</span>.addAll);
|
||||
<span class="keyword">this</span>.listenTo(Todos, <span class="string">'all'</span>, <span class="keyword">this</span>.render);
|
||||
|
||||
<span class="keyword">this</span>.footer = <span class="keyword">this</span>.$(<span class="string">'footer'</span>);
|
||||
<span class="keyword">this</span>.main = $(<span class="string">'#main'</span>);
|
||||
|
||||
Todos.fetch();
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-33">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-33">¶</a>
|
||||
</div>
|
||||
<p>Re-rendering the App just means refreshing the statistics -- the rest
|
||||
of the app doesn't change.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> render: <span class="keyword">function</span>() {
|
||||
<span class="keyword">var</span> done = Todos.done().length;
|
||||
<span class="keyword">var</span> remaining = Todos.remaining().length;
|
||||
|
||||
<span class="keyword">if</span> (Todos.length) {
|
||||
<span class="keyword">this</span>.main.show();
|
||||
<span class="keyword">this</span>.footer.show();
|
||||
<span class="keyword">this</span>.footer.html(<span class="keyword">this</span>.statsTemplate({done: done, remaining: remaining}));
|
||||
} <span class="keyword">else</span> {
|
||||
<span class="keyword">this</span>.main.hide();
|
||||
<span class="keyword">this</span>.footer.hide();
|
||||
}
|
||||
|
||||
<span class="keyword">this</span>.allCheckbox.checked = !remaining;
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-34">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-34">¶</a>
|
||||
</div>
|
||||
<p>Add a single todo item to the list by creating a view for it, and
|
||||
appending its element to the <code><ul></code>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> addOne: <span class="keyword">function</span>(todo) {
|
||||
<span class="keyword">var</span> view = <span class="keyword">new</span> TodoView({model: todo});
|
||||
<span class="keyword">this</span>.$(<span class="string">"#todo-list"</span>).append(view.render().el);
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-35">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-35">¶</a>
|
||||
</div>
|
||||
<p>Add all items in the <strong>Todos</strong> collection at once.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> addAll: <span class="keyword">function</span>() {
|
||||
Todos.each(<span class="keyword">this</span>.addOne, <span class="keyword">this</span>);
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-36">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-36">¶</a>
|
||||
</div>
|
||||
<p>If you hit return in the main input field, create new <strong>Todo</strong> model,
|
||||
persisting it to <em>localStorage</em>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> createOnEnter: <span class="keyword">function</span>(e) {
|
||||
<span class="keyword">if</span> (e.keyCode != <span class="number">13</span>) <span class="keyword">return</span>;
|
||||
<span class="keyword">if</span> (!<span class="keyword">this</span>.input.val()) <span class="keyword">return</span>;
|
||||
|
||||
Todos.create({title: <span class="keyword">this</span>.input.val()});
|
||||
<span class="keyword">this</span>.input.val(<span class="string">''</span>);
|
||||
},</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-37">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-37">¶</a>
|
||||
</div>
|
||||
<p>Clear all done todo items, destroying their models.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> clearCompleted: <span class="keyword">function</span>() {
|
||||
_.invoke(Todos.done(), <span class="string">'destroy'</span>);
|
||||
<span class="keyword">return</span> <span class="literal">false</span>;
|
||||
},
|
||||
|
||||
toggleAllComplete: <span class="function"><span class="keyword">function</span> <span class="params">()</span> {</span>
|
||||
<span class="keyword">var</span> done = <span class="keyword">this</span>.allCheckbox.checked;
|
||||
Todos.each(<span class="function"><span class="keyword">function</span> <span class="params">(todo)</span> {</span> todo.save({<span class="string">'done'</span>: done}); });
|
||||
}
|
||||
|
||||
});</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-38">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-38">¶</a>
|
||||
</div>
|
||||
<p>Finally, we kick things off by creating the <strong>App</strong>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> App = <span class="keyword">new</span> AppView;
|
||||
|
||||
});</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
184
vendor/backbone/examples/backbone.localStorage.js
vendored
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
* Backbone localStorage Adapter
|
||||
* Version 1.1.0
|
||||
*
|
||||
* https://github.com/jeromegn/Backbone.localStorage
|
||||
*/
|
||||
(function (root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["underscore","backbone"], function(_, Backbone) {
|
||||
// Use global variables if the locals are undefined.
|
||||
return factory(_ || root._, Backbone || root.Backbone);
|
||||
});
|
||||
} else {
|
||||
// RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
|
||||
factory(_, Backbone);
|
||||
}
|
||||
}(this, function(_, Backbone) {
|
||||
// A simple module to replace `Backbone.sync` with *localStorage*-based
|
||||
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
|
||||
// as that.
|
||||
|
||||
// Hold reference to Underscore.js and Backbone.js in the closure in order
|
||||
// to make things work even if they are removed from the global namespace
|
||||
|
||||
// Generate four random hex digits.
|
||||
function S4() {
|
||||
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||
};
|
||||
|
||||
// Generate a pseudo-GUID by concatenating random hexadecimal.
|
||||
function guid() {
|
||||
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||
};
|
||||
|
||||
// Our Store is represented by a single JS object in *localStorage*. Create it
|
||||
// with a meaningful name, like the name you'd give a table.
|
||||
// window.Store is deprectated, use Backbone.LocalStorage instead
|
||||
Backbone.LocalStorage = window.Store = function(name) {
|
||||
this.name = name;
|
||||
var store = this.localStorage().getItem(this.name);
|
||||
this.records = (store && store.split(",")) || [];
|
||||
};
|
||||
|
||||
_.extend(Backbone.LocalStorage.prototype, {
|
||||
|
||||
// Save the current state of the **Store** to *localStorage*.
|
||||
save: function() {
|
||||
this.localStorage().setItem(this.name, this.records.join(","));
|
||||
},
|
||||
|
||||
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
|
||||
// have an id of it's own.
|
||||
create: function(model) {
|
||||
if (!model.id) {
|
||||
model.id = guid();
|
||||
model.set(model.idAttribute, model.id);
|
||||
}
|
||||
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
|
||||
this.records.push(model.id.toString());
|
||||
this.save();
|
||||
return this.find(model);
|
||||
},
|
||||
|
||||
// Update a model by replacing its copy in `this.data`.
|
||||
update: function(model) {
|
||||
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
|
||||
if (!_.include(this.records, model.id.toString()))
|
||||
this.records.push(model.id.toString()); this.save();
|
||||
return this.find(model);
|
||||
},
|
||||
|
||||
// Retrieve a model from `this.data` by id.
|
||||
find: function(model) {
|
||||
return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
|
||||
},
|
||||
|
||||
// Return the array of all models currently in storage.
|
||||
findAll: function() {
|
||||
return _(this.records).chain()
|
||||
.map(function(id){
|
||||
return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
|
||||
}, this)
|
||||
.compact()
|
||||
.value();
|
||||
},
|
||||
|
||||
// Delete a model from `this.data`, returning it.
|
||||
destroy: function(model) {
|
||||
if (model.isNew())
|
||||
return false
|
||||
this.localStorage().removeItem(this.name+"-"+model.id);
|
||||
this.records = _.reject(this.records, function(id){
|
||||
return id === model.id.toString();
|
||||
});
|
||||
this.save();
|
||||
return model;
|
||||
},
|
||||
|
||||
localStorage: function() {
|
||||
return localStorage;
|
||||
},
|
||||
|
||||
// fix for "illegal access" error on Android when JSON.parse is passed null
|
||||
jsonData: function (data) {
|
||||
return data && JSON.parse(data);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// localSync delegate to the model or collection's
|
||||
// *localStorage* property, which should be an instance of `Store`.
|
||||
// window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead
|
||||
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
|
||||
var store = model.localStorage || model.collection.localStorage;
|
||||
|
||||
var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.
|
||||
|
||||
try {
|
||||
|
||||
switch (method) {
|
||||
case "read":
|
||||
resp = model.id != undefined ? store.find(model) : store.findAll();
|
||||
break;
|
||||
case "create":
|
||||
resp = store.create(model);
|
||||
break;
|
||||
case "update":
|
||||
resp = store.update(model);
|
||||
break;
|
||||
case "delete":
|
||||
resp = store.destroy(model);
|
||||
break;
|
||||
}
|
||||
|
||||
} catch(error) {
|
||||
if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0)
|
||||
errorMessage = "Private browsing is unsupported";
|
||||
else
|
||||
errorMessage = error.message;
|
||||
}
|
||||
|
||||
if (resp) {
|
||||
model.trigger("sync", model, resp, options);
|
||||
if (options && options.success)
|
||||
options.success(resp);
|
||||
if (syncDfd)
|
||||
syncDfd.resolve(resp);
|
||||
|
||||
} else {
|
||||
errorMessage = errorMessage ? errorMessage
|
||||
: "Record Not Found";
|
||||
|
||||
if (options && options.error)
|
||||
options.error(errorMessage);
|
||||
if (syncDfd)
|
||||
syncDfd.reject(errorMessage);
|
||||
}
|
||||
|
||||
// add compatibility with $.ajax
|
||||
// always execute callback for success and error
|
||||
if (options && options.complete) options.complete(resp);
|
||||
|
||||
return syncDfd && syncDfd.promise();
|
||||
};
|
||||
|
||||
Backbone.ajaxSync = Backbone.sync;
|
||||
|
||||
Backbone.getSyncMethod = function(model) {
|
||||
if(model.localStorage || (model.collection && model.collection.localStorage)) {
|
||||
return Backbone.localSync;
|
||||
}
|
||||
|
||||
return Backbone.ajaxSync;
|
||||
};
|
||||
|
||||
// Override 'Backbone.sync' to default to localSync,
|
||||
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
|
||||
Backbone.sync = function(method, model, options) {
|
||||
return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
|
||||
};
|
||||
|
||||
return Backbone.LocalStorage;
|
||||
}));
|
BIN
vendor/backbone/examples/todos/destroy.png
vendored
Before Width: | Height: | Size: 555 B |
69
vendor/backbone/examples/todos/index.html
vendored
|
@ -1,69 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Backbone.js Todos</title>
|
||||
<link rel="stylesheet" href="todos.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="todoapp">
|
||||
|
||||
<header>
|
||||
<h1>Todos</h1>
|
||||
<input id="new-todo" type="text" placeholder="What needs to be done?">
|
||||
</header>
|
||||
|
||||
<section id="main">
|
||||
<input id="toggle-all" type="checkbox">
|
||||
<label for="toggle-all">Mark all as complete</label>
|
||||
<ul id="todo-list"></ul>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<a id="clear-completed">Clear completed</a>
|
||||
<div id="todo-count"></div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="instructions">
|
||||
Double-click to edit a todo.
|
||||
</div>
|
||||
|
||||
<div id="credits">
|
||||
Created by
|
||||
<br />
|
||||
<a href="http://jgn.me/">Jérôme Gravel-Niquet</a>.
|
||||
<br />Rewritten by: <a href="http://addyosmani.github.com/todomvc">TodoMVC</a>.
|
||||
</div>
|
||||
|
||||
<script src="../../test/vendor/json2.js"></script>
|
||||
<script src="../../test/vendor/jquery.js"></script>
|
||||
<script src="../../test/vendor/underscore.js"></script>
|
||||
<script src="../../backbone.js"></script>
|
||||
<script src="../backbone.localStorage.js"></script>
|
||||
<script src="todos.js"></script>
|
||||
|
||||
<!-- Templates -->
|
||||
|
||||
<script type="text/template" id="item-template">
|
||||
<div class="view">
|
||||
<input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
|
||||
<label><%- title %></label>
|
||||
<a class="destroy"></a>
|
||||
</div>
|
||||
<input class="edit" type="text" value="<%- title %>" />
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="stats-template">
|
||||
<% if (done) { %>
|
||||
<a id="clear-completed">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a>
|
||||
<% } %>
|
||||
<div class="todo-count"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
211
vendor/backbone/examples/todos/todos.css
vendored
|
@ -1,211 +0,0 @@
|
|||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.4em;
|
||||
background: #eeeeee;
|
||||
color: #333333;
|
||||
width: 520px;
|
||||
margin: 0 auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
#todoapp {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
margin-bottom: 40px;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-webkit-border-radius: 0 0 5px 5px;
|
||||
-moz-border-radius: 0 0 5px 5px;
|
||||
-ms-border-radius: 0 0 5px 5px;
|
||||
-o-border-radius: 0 0 5px 5px;
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
#todoapp h1 {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 0 0 10px 0;
|
||||
}
|
||||
|
||||
#todoapp input[type="text"] {
|
||||
width: 466px;
|
||||
font-size: 24px;
|
||||
font-family: inherit;
|
||||
line-height: 1.4em;
|
||||
border: 0;
|
||||
outline: none;
|
||||
padding: 6px;
|
||||
border: 1px solid #999999;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
}
|
||||
|
||||
#todoapp input::-webkit-input-placeholder {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#main {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#todo-list {
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#todo-list li {
|
||||
padding: 18px 20px 18px 0;
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
#todo-list li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#todo-list li.done label {
|
||||
color: #777777;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
#todo-list .destroy {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 20px;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(destroy.png) no-repeat;
|
||||
}
|
||||
|
||||
#todo-list li:hover .destroy {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#todo-list .destroy:hover {
|
||||
background-position: 0 -20px;
|
||||
}
|
||||
|
||||
#todo-list li.editing {
|
||||
border-bottom: none;
|
||||
margin-top: -1px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#todo-list li.editing:last-child {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
#todo-list li.editing .edit {
|
||||
display: block;
|
||||
width: 444px;
|
||||
padding: 13px 15px 14px 20px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#todo-list li.editing .view {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#todo-list li .view label {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
#todo-list li .edit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#todoapp footer {
|
||||
display: none;
|
||||
margin: 0 -20px -20px -20px;
|
||||
overflow: hidden;
|
||||
color: #555555;
|
||||
background: #f4fce8;
|
||||
border-top: 1px solid #ededed;
|
||||
padding: 0 20px;
|
||||
line-height: 37px;
|
||||
-webkit-border-radius: 0 0 5px 5px;
|
||||
-moz-border-radius: 0 0 5px 5px;
|
||||
-ms-border-radius: 0 0 5px 5px;
|
||||
-o-border-radius: 0 0 5px 5px;
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
#clear-completed {
|
||||
float: right;
|
||||
line-height: 20px;
|
||||
text-decoration: none;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
color: #555555;
|
||||
font-size: 11px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 10px 1px;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-ms-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
}
|
||||
|
||||
#clear-completed:hover {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
-ms-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
}
|
||||
|
||||
#clear-completed:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
#todo-count span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#instructions {
|
||||
margin: 10px auto;
|
||||
color: #777777;
|
||||
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#instructions a {
|
||||
color: #336699;
|
||||
}
|
||||
|
||||
#credits {
|
||||
margin: 30px auto;
|
||||
color: #999;
|
||||
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#credits a {
|
||||
color: #888;
|
||||
}
|
234
vendor/backbone/examples/todos/todos.js
vendored
|
@ -1,234 +0,0 @@
|
|||
// An example Backbone application contributed by
|
||||
// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses a simple
|
||||
// [LocalStorage adapter](backbone-localstorage.html)
|
||||
// to persist Backbone models within your browser.
|
||||
|
||||
// Load the application once the DOM is ready, using `jQuery.ready`:
|
||||
$(function(){
|
||||
|
||||
// Todo Model
|
||||
// ----------
|
||||
|
||||
// Our basic **Todo** model has `title`, `order`, and `done` attributes.
|
||||
var Todo = Backbone.Model.extend({
|
||||
|
||||
// Default attributes for the todo item.
|
||||
defaults: function() {
|
||||
return {
|
||||
title: "empty todo...",
|
||||
order: Todos.nextOrder(),
|
||||
done: false
|
||||
};
|
||||
},
|
||||
|
||||
// Toggle the `done` state of this todo item.
|
||||
toggle: function() {
|
||||
this.save({done: !this.get("done")});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Todo Collection
|
||||
// ---------------
|
||||
|
||||
// The collection of todos is backed by *localStorage* instead of a remote
|
||||
// server.
|
||||
var TodoList = Backbone.Collection.extend({
|
||||
|
||||
// Reference to this collection's model.
|
||||
model: Todo,
|
||||
|
||||
// Save all of the todo items under the `"todos-backbone"` namespace.
|
||||
localStorage: new Backbone.LocalStorage("todos-backbone"),
|
||||
|
||||
// Filter down the list of all todo items that are finished.
|
||||
done: function() {
|
||||
return this.where({done: true});
|
||||
},
|
||||
|
||||
// Filter down the list to only todo items that are still not finished.
|
||||
remaining: function() {
|
||||
return this.where({done: false});
|
||||
},
|
||||
|
||||
// We keep the Todos in sequential order, despite being saved by unordered
|
||||
// GUID in the database. This generates the next order number for new items.
|
||||
nextOrder: function() {
|
||||
if (!this.length) return 1;
|
||||
return this.last().get('order') + 1;
|
||||
},
|
||||
|
||||
// Todos are sorted by their original insertion order.
|
||||
comparator: 'order'
|
||||
|
||||
});
|
||||
|
||||
// Create our global collection of **Todos**.
|
||||
var Todos = new TodoList;
|
||||
|
||||
// Todo Item View
|
||||
// --------------
|
||||
|
||||
// The DOM element for a todo item...
|
||||
var TodoView = Backbone.View.extend({
|
||||
|
||||
//... is a list tag.
|
||||
tagName: "li",
|
||||
|
||||
// Cache the template function for a single item.
|
||||
template: _.template($('#item-template').html()),
|
||||
|
||||
// The DOM events specific to an item.
|
||||
events: {
|
||||
"click .toggle" : "toggleDone",
|
||||
"dblclick .view" : "edit",
|
||||
"click a.destroy" : "clear",
|
||||
"keypress .edit" : "updateOnEnter",
|
||||
"blur .edit" : "close"
|
||||
},
|
||||
|
||||
// The TodoView listens for changes to its model, re-rendering. Since there's
|
||||
// a one-to-one correspondence between a **Todo** and a **TodoView** in this
|
||||
// app, we set a direct reference on the model for convenience.
|
||||
initialize: function() {
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
this.listenTo(this.model, 'destroy', this.remove);
|
||||
},
|
||||
|
||||
// Re-render the titles of the todo item.
|
||||
render: function() {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
this.$el.toggleClass('done', this.model.get('done'));
|
||||
this.input = this.$('.edit');
|
||||
return this;
|
||||
},
|
||||
|
||||
// Toggle the `"done"` state of the model.
|
||||
toggleDone: function() {
|
||||
this.model.toggle();
|
||||
},
|
||||
|
||||
// Switch this view into `"editing"` mode, displaying the input field.
|
||||
edit: function() {
|
||||
this.$el.addClass("editing");
|
||||
this.input.focus();
|
||||
},
|
||||
|
||||
// Close the `"editing"` mode, saving changes to the todo.
|
||||
close: function() {
|
||||
var value = this.input.val();
|
||||
if (!value) {
|
||||
this.clear();
|
||||
} else {
|
||||
this.model.save({title: value});
|
||||
this.$el.removeClass("editing");
|
||||
}
|
||||
},
|
||||
|
||||
// If you hit `enter`, we're through editing the item.
|
||||
updateOnEnter: function(e) {
|
||||
if (e.keyCode == 13) this.close();
|
||||
},
|
||||
|
||||
// Remove the item, destroy the model.
|
||||
clear: function() {
|
||||
this.model.destroy();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// The Application
|
||||
// ---------------
|
||||
|
||||
// Our overall **AppView** is the top-level piece of UI.
|
||||
var AppView = Backbone.View.extend({
|
||||
|
||||
// Instead of generating a new element, bind to the existing skeleton of
|
||||
// the App already present in the HTML.
|
||||
el: $("#todoapp"),
|
||||
|
||||
// Our template for the line of statistics at the bottom of the app.
|
||||
statsTemplate: _.template($('#stats-template').html()),
|
||||
|
||||
// Delegated events for creating new items, and clearing completed ones.
|
||||
events: {
|
||||
"keypress #new-todo": "createOnEnter",
|
||||
"click #clear-completed": "clearCompleted",
|
||||
"click #toggle-all": "toggleAllComplete"
|
||||
},
|
||||
|
||||
// At initialization we bind to the relevant events on the `Todos`
|
||||
// collection, when items are added or changed. Kick things off by
|
||||
// loading any preexisting todos that might be saved in *localStorage*.
|
||||
initialize: function() {
|
||||
|
||||
this.input = this.$("#new-todo");
|
||||
this.allCheckbox = this.$("#toggle-all")[0];
|
||||
|
||||
this.listenTo(Todos, 'add', this.addOne);
|
||||
this.listenTo(Todos, 'reset', this.addAll);
|
||||
this.listenTo(Todos, 'all', this.render);
|
||||
|
||||
this.footer = this.$('footer');
|
||||
this.main = $('#main');
|
||||
|
||||
Todos.fetch();
|
||||
},
|
||||
|
||||
// Re-rendering the App just means refreshing the statistics -- the rest
|
||||
// of the app doesn't change.
|
||||
render: function() {
|
||||
var done = Todos.done().length;
|
||||
var remaining = Todos.remaining().length;
|
||||
|
||||
if (Todos.length) {
|
||||
this.main.show();
|
||||
this.footer.show();
|
||||
this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
|
||||
} else {
|
||||
this.main.hide();
|
||||
this.footer.hide();
|
||||
}
|
||||
|
||||
this.allCheckbox.checked = !remaining;
|
||||
},
|
||||
|
||||
// Add a single todo item to the list by creating a view for it, and
|
||||
// appending its element to the `<ul>`.
|
||||
addOne: function(todo) {
|
||||
var view = new TodoView({model: todo});
|
||||
this.$("#todo-list").append(view.render().el);
|
||||
},
|
||||
|
||||
// Add all items in the **Todos** collection at once.
|
||||
addAll: function() {
|
||||
Todos.each(this.addOne, this);
|
||||
},
|
||||
|
||||
// If you hit return in the main input field, create new **Todo** model,
|
||||
// persisting it to *localStorage*.
|
||||
createOnEnter: function(e) {
|
||||
if (e.keyCode != 13) return;
|
||||
if (!this.input.val()) return;
|
||||
|
||||
Todos.create({title: this.input.val()});
|
||||
this.input.val('');
|
||||
},
|
||||
|
||||
// Clear all done todo items, destroying their models.
|
||||
clearCompleted: function() {
|
||||
_.invoke(Todos.done(), 'destroy');
|
||||
return false;
|
||||
},
|
||||
|
||||
toggleAllComplete: function () {
|
||||
var done = this.allCheckbox.checked;
|
||||
Todos.each(function (todo) { todo.save({'done': done}); });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Finally, we kick things off by creating the **App**.
|
||||
var App = new AppView;
|
||||
|
||||
});
|
4544
vendor/backbone/index.html
vendored
1
vendor/backbone/index.js
vendored
|
@ -1 +0,0 @@
|
|||
module.exports = require('./backbone');
|
28
vendor/backbone/package.json
vendored
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name" : "backbone",
|
||||
"description" : "Give your JS App some Backbone with Models, Views, Collections, and Events.",
|
||||
"url" : "http://backbonejs.org",
|
||||
"keywords" : ["model", "view", "controller", "router", "server", "client", "browser"],
|
||||
"author" : "Jeremy Ashkenas <jeremy@documentcloud.org>",
|
||||
"dependencies" : {
|
||||
"underscore" : ">=1.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"phantomjs": "1.9.0-1",
|
||||
"docco": "0.6.1",
|
||||
"coffee-script": "1.6.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true && coffee test/model.coffee",
|
||||
"build": "uglifyjs backbone.js --mangle --source-map backbone-min.map -o backbone-min.js",
|
||||
"doc": "docco backbone.js && docco examples/todos/todos.js examples/backbone.localstorage.js",
|
||||
"lint": "jsl -nofilelisting -nologo -conf docs/jsl.conf -process backbone.js"
|
||||
},
|
||||
"main" : "backbone.js",
|
||||
"version" : "1.1.0",
|
||||
"license" : "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jashkenas/backbone.git"
|
||||
}
|
||||
}
|
1277
vendor/backbone/test/collection.js
vendored
35
vendor/backbone/test/environment.js
vendored
|
@ -1,35 +0,0 @@
|
|||
(function() {
|
||||
|
||||
var sync = Backbone.sync;
|
||||
var ajax = Backbone.ajax;
|
||||
var emulateHTTP = Backbone.emulateHTTP;
|
||||
var emulateJSON = Backbone.emulateJSON;
|
||||
|
||||
QUnit.testStart(function() {
|
||||
var env = this.config.current.testEnvironment;
|
||||
|
||||
// Capture ajax settings for comparison.
|
||||
Backbone.ajax = function(settings) {
|
||||
env.ajaxSettings = settings;
|
||||
};
|
||||
|
||||
// Capture the arguments to Backbone.sync for comparison.
|
||||
Backbone.sync = function(method, model, options) {
|
||||
env.syncArgs = {
|
||||
method: method,
|
||||
model: model,
|
||||
options: options
|
||||
};
|
||||
sync.apply(this, arguments);
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
QUnit.testDone(function() {
|
||||
Backbone.sync = sync;
|
||||
Backbone.ajax = ajax;
|
||||
Backbone.emulateHTTP = emulateHTTP;
|
||||
Backbone.emulateJSON = emulateJSON;
|
||||
});
|
||||
|
||||
})();
|
477
vendor/backbone/test/events.js
vendored
|
@ -1,477 +0,0 @@
|
|||
(function() {
|
||||
|
||||
module("Backbone.Events");
|
||||
|
||||
test("on and trigger", 2, function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
obj.on('event', function() { obj.counter += 1; });
|
||||
obj.trigger('event');
|
||||
equal(obj.counter,1,'counter should be incremented.');
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
equal(obj.counter, 5, 'counter should be incremented five times.');
|
||||
});
|
||||
|
||||
test("binding and triggering multiple events", 4, function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
obj.on('a b c', function() { obj.counter += 1; });
|
||||
|
||||
obj.trigger('a');
|
||||
equal(obj.counter, 1);
|
||||
|
||||
obj.trigger('a b');
|
||||
equal(obj.counter, 3);
|
||||
|
||||
obj.trigger('c');
|
||||
equal(obj.counter, 4);
|
||||
|
||||
obj.off('a c');
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 5);
|
||||
});
|
||||
|
||||
test("binding and triggering with event maps", function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
var increment = function() {
|
||||
this.counter += 1;
|
||||
};
|
||||
|
||||
obj.on({
|
||||
a: increment,
|
||||
b: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
|
||||
obj.trigger('a');
|
||||
equal(obj.counter, 1);
|
||||
|
||||
obj.trigger('a b');
|
||||
equal(obj.counter, 3);
|
||||
|
||||
obj.trigger('c');
|
||||
equal(obj.counter, 4);
|
||||
|
||||
obj.off({
|
||||
a: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 5);
|
||||
});
|
||||
|
||||
test("listenTo and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenTo(b, 'all', function(){ ok(true); });
|
||||
b.trigger('anything');
|
||||
a.listenTo(b, 'all', function(){ ok(false); });
|
||||
a.stopListening();
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo and stopListening with event maps", 4, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var cb = function(){ ok(true); };
|
||||
a.listenTo(b, {event: cb});
|
||||
b.trigger('event');
|
||||
a.listenTo(b, {event2: cb});
|
||||
b.on('event2', cb);
|
||||
a.stopListening(b, {event2: cb});
|
||||
b.trigger('event event2');
|
||||
a.stopListening();
|
||||
b.trigger('event event2');
|
||||
});
|
||||
|
||||
test("stopListening with omitted args", 2, function () {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var cb = function () { ok(true); };
|
||||
a.listenTo(b, 'event', cb);
|
||||
b.on('event', cb);
|
||||
a.listenTo(b, 'event2', cb);
|
||||
a.stopListening(null, {event: cb});
|
||||
b.trigger('event event2');
|
||||
b.off();
|
||||
a.listenTo(b, 'event event2', cb);
|
||||
a.stopListening(null, 'event');
|
||||
a.stopListening();
|
||||
b.trigger('event2');
|
||||
});
|
||||
|
||||
test("listenToOnce and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, 'all', function() { ok(true); });
|
||||
b.trigger('anything');
|
||||
b.trigger('anything');
|
||||
a.listenToOnce(b, 'all', function() { ok(false); });
|
||||
a.stopListening();
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo, listenToOnce and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, 'all', function() { ok(true); });
|
||||
b.trigger('anything');
|
||||
b.trigger('anything');
|
||||
a.listenTo(b, 'all', function() { ok(false); });
|
||||
a.stopListening();
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo and stopListening with event maps", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenTo(b, {change: function(){ ok(true); }});
|
||||
b.trigger('change');
|
||||
a.listenTo(b, {change: function(){ ok(false); }});
|
||||
a.stopListening();
|
||||
b.trigger('change');
|
||||
});
|
||||
|
||||
test("listenTo yourself", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", function(){ ok(true); });
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
test("listenTo yourself cleans yourself up with stopListening", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", function(){ ok(true); });
|
||||
e.trigger("foo");
|
||||
e.stopListening();
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
test("stopListening cleans up references", 4, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var fn = function() {};
|
||||
a.listenTo(b, 'all', fn).stopListening();
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
a.listenTo(b, 'all', fn).stopListening(b);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
a.listenTo(b, 'all', fn).stopListening(null, 'all');
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
a.listenTo(b, 'all', fn).stopListening(null, null, fn);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
});
|
||||
|
||||
test("listenTo and stopListening cleaning up references", 2, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenTo(b, 'all', function(){ ok(true); });
|
||||
b.trigger('anything');
|
||||
a.listenTo(b, 'other', function(){ ok(false); });
|
||||
a.stopListening(b, 'other');
|
||||
a.stopListening(b, 'all');
|
||||
equal(_.keys(a._listeningTo).length, 0);
|
||||
});
|
||||
|
||||
test("listenTo with empty callback doesn't throw an error", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", null);
|
||||
e.trigger("foo");
|
||||
ok(true);
|
||||
});
|
||||
|
||||
test("trigger all for each event", 3, function() {
|
||||
var a, b, obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
obj.on('all', function(event) {
|
||||
obj.counter++;
|
||||
if (event == 'a') a = true;
|
||||
if (event == 'b') b = true;
|
||||
})
|
||||
.trigger('a b');
|
||||
ok(a);
|
||||
ok(b);
|
||||
equal(obj.counter, 2);
|
||||
});
|
||||
|
||||
test("on, then unbind all functions", 1, function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
var callback = function() { obj.counter += 1; };
|
||||
obj.on('event', callback);
|
||||
obj.trigger('event');
|
||||
obj.off('event');
|
||||
obj.trigger('event');
|
||||
equal(obj.counter, 1, 'counter should have only been incremented once.');
|
||||
});
|
||||
|
||||
test("bind two callbacks, unbind only one", 2, function() {
|
||||
var obj = { counterA: 0, counterB: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
var callback = function() { obj.counterA += 1; };
|
||||
obj.on('event', callback);
|
||||
obj.on('event', function() { obj.counterB += 1; });
|
||||
obj.trigger('event');
|
||||
obj.off('event', callback);
|
||||
obj.trigger('event');
|
||||
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
|
||||
equal(obj.counterB, 2, 'counterB should have been incremented twice.');
|
||||
});
|
||||
|
||||
test("unbind a callback in the midst of it firing", 1, function() {
|
||||
var obj = {counter: 0};
|
||||
_.extend(obj, Backbone.Events);
|
||||
var callback = function() {
|
||||
obj.counter += 1;
|
||||
obj.off('event', callback);
|
||||
};
|
||||
obj.on('event', callback);
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
equal(obj.counter, 1, 'the callback should have been unbound.');
|
||||
});
|
||||
|
||||
test("two binds that unbind themeselves", 2, function() {
|
||||
var obj = { counterA: 0, counterB: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
|
||||
var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };
|
||||
obj.on('event', incrA);
|
||||
obj.on('event', incrB);
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
|
||||
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
|
||||
});
|
||||
|
||||
test("bind a callback with a supplied context", 1, function () {
|
||||
var TestClass = function () {
|
||||
return this;
|
||||
};
|
||||
TestClass.prototype.assertTrue = function () {
|
||||
ok(true, '`this` was bound to the callback');
|
||||
};
|
||||
|
||||
var obj = _.extend({},Backbone.Events);
|
||||
obj.on('event', function () { this.assertTrue(); }, (new TestClass));
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("nested trigger with unbind", 1, function () {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
|
||||
var incr2 = function(){ obj.counter += 1; };
|
||||
obj.on('event', incr1);
|
||||
obj.on('event', incr2);
|
||||
obj.trigger('event');
|
||||
equal(obj.counter, 3, 'counter should have been incremented three times');
|
||||
});
|
||||
|
||||
test("callback list is not altered during trigger", 2, function () {
|
||||
var counter = 0, obj = _.extend({}, Backbone.Events);
|
||||
var incr = function(){ counter++; };
|
||||
obj.on('event', function(){ obj.on('event', incr).on('all', incr); })
|
||||
.trigger('event');
|
||||
equal(counter, 0, 'bind does not alter callback list');
|
||||
obj.off()
|
||||
.on('event', function(){ obj.off('event', incr).off('all', incr); })
|
||||
.on('event', incr)
|
||||
.on('all', incr)
|
||||
.trigger('event');
|
||||
equal(counter, 2, 'unbind does not alter callback list');
|
||||
});
|
||||
|
||||
test("#1282 - 'all' callback list is retrieved after each event.", 1, function() {
|
||||
var counter = 0;
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var incr = function(){ counter++; };
|
||||
obj.on('x', function() {
|
||||
obj.on('y', incr).on('all', incr);
|
||||
})
|
||||
.trigger('x y');
|
||||
strictEqual(counter, 2);
|
||||
});
|
||||
|
||||
test("if no callback is provided, `on` is a noop", 0, function() {
|
||||
_.extend({}, Backbone.Events).on('test').trigger('test');
|
||||
});
|
||||
|
||||
test("if callback is truthy but not a function, `on` should throw an error just like jQuery", 1, function() {
|
||||
var view = _.extend({}, Backbone.Events).on('test', 'noop');
|
||||
throws(function() {
|
||||
view.trigger('test');
|
||||
});
|
||||
});
|
||||
|
||||
test("remove all events for a specific context", 4, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.on('x y all', function() { ok(true); });
|
||||
obj.on('x y all', function() { ok(false); }, obj);
|
||||
obj.off(null, null, obj);
|
||||
obj.trigger('x y');
|
||||
});
|
||||
|
||||
test("remove all events for a specific callback", 4, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var success = function() { ok(true); };
|
||||
var fail = function() { ok(false); };
|
||||
obj.on('x y all', success);
|
||||
obj.on('x y all', fail);
|
||||
obj.off(null, fail);
|
||||
obj.trigger('x y');
|
||||
});
|
||||
|
||||
test("#1310 - off does not skip consecutive events", 0, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.on('event', function() { ok(false); }, obj);
|
||||
obj.on('event', function() { ok(false); }, obj);
|
||||
obj.off(null, null, obj);
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once", 2, function() {
|
||||
// Same as the previous test, but we use once rather than having to explicitly unbind
|
||||
var obj = { counterA: 0, counterB: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
|
||||
var incrB = function(){ obj.counterB += 1; };
|
||||
obj.once('event', incrA);
|
||||
obj.once('event', incrB);
|
||||
obj.trigger('event');
|
||||
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
|
||||
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
|
||||
});
|
||||
|
||||
test("once variant one", 3, function() {
|
||||
var f = function(){ ok(true); };
|
||||
|
||||
var a = _.extend({}, Backbone.Events).once('event', f);
|
||||
var b = _.extend({}, Backbone.Events).on('event', f);
|
||||
|
||||
a.trigger('event');
|
||||
|
||||
b.trigger('event');
|
||||
b.trigger('event');
|
||||
});
|
||||
|
||||
test("once variant two", 3, function() {
|
||||
var f = function(){ ok(true); };
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
|
||||
obj
|
||||
.once('event', f)
|
||||
.on('event', f)
|
||||
.trigger('event')
|
||||
.trigger('event');
|
||||
});
|
||||
|
||||
test("once with off", 0, function() {
|
||||
var f = function(){ ok(true); };
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
|
||||
obj.once('event', f);
|
||||
obj.off('event', f);
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once with event maps", function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
var increment = function() {
|
||||
this.counter += 1;
|
||||
};
|
||||
|
||||
obj.once({
|
||||
a: increment,
|
||||
b: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
|
||||
obj.trigger('a');
|
||||
equal(obj.counter, 1);
|
||||
|
||||
obj.trigger('a b');
|
||||
equal(obj.counter, 2);
|
||||
|
||||
obj.trigger('c');
|
||||
equal(obj.counter, 3);
|
||||
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 3);
|
||||
});
|
||||
|
||||
test("once with off only by context", 0, function() {
|
||||
var context = {};
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.once('event', function(){ ok(false); }, context);
|
||||
obj.off(null, null, context);
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("Backbone object inherits Events", function() {
|
||||
ok(Backbone.on === Backbone.Events.on);
|
||||
});
|
||||
|
||||
asyncTest("once with asynchronous events", 1, function() {
|
||||
var func = _.debounce(function() { ok(true); start(); }, 50);
|
||||
var obj = _.extend({}, Backbone.Events).once('async', func);
|
||||
|
||||
obj.trigger('async');
|
||||
obj.trigger('async');
|
||||
});
|
||||
|
||||
test("once with multiple events.", 2, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.once('x y', function() { ok(true); });
|
||||
obj.trigger('x y');
|
||||
});
|
||||
|
||||
test("Off during iteration with once.", 2, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var f = function(){ this.off('event', f); };
|
||||
obj.on('event', f);
|
||||
obj.once('event', function(){});
|
||||
obj.on('event', function(){ ok(true); });
|
||||
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("`once` on `all` should work as expected", 1, function() {
|
||||
Backbone.once('all', function() {
|
||||
ok(true);
|
||||
Backbone.trigger('all');
|
||||
});
|
||||
Backbone.trigger('all');
|
||||
});
|
||||
|
||||
test("once without a callback is a noop", 0, function() {
|
||||
_.extend({}, Backbone.Events).once('event').trigger('event');
|
||||
});
|
||||
|
||||
test("event functions are chainable", function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var obj2 = _.extend({}, Backbone.Events);
|
||||
var fn = function() {};
|
||||
equal(obj, obj.trigger('noeventssetyet'));
|
||||
equal(obj, obj.off('noeventssetyet'));
|
||||
equal(obj, obj.stopListening('noeventssetyet'));
|
||||
equal(obj, obj.on('a', fn));
|
||||
equal(obj, obj.once('c', fn));
|
||||
equal(obj, obj.trigger('a'));
|
||||
equal(obj, obj.listenTo(obj2, 'a', fn));
|
||||
equal(obj, obj.listenToOnce(obj2, 'b', fn));
|
||||
equal(obj, obj.off('a c'));
|
||||
equal(obj, obj.stopListening(obj2, 'a'));
|
||||
equal(obj, obj.stopListening());
|
||||
});
|
||||
|
||||
})();
|
30
vendor/backbone/test/index.html
vendored
|
@ -1,30 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf8'>
|
||||
<title>Backbone Test Suite</title>
|
||||
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen">
|
||||
<link rel="icon" href="../docs/images/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture">
|
||||
<div id='testElement'>
|
||||
<h1>Test</h1>
|
||||
</div>
|
||||
</div>
|
||||
<script src="vendor/json2.js"></script>
|
||||
<script src="vendor/jquery.js"></script>
|
||||
<script src="vendor/qunit.js"></script>
|
||||
<script src="vendor/underscore.js"></script>
|
||||
<script src="../backbone.js"></script>
|
||||
<script src="environment.js"></script>
|
||||
<script src="noconflict.js"></script>
|
||||
<script src="events.js"></script>
|
||||
<script src="model.js"></script>
|
||||
<script src="collection.js"></script>
|
||||
<script src="router.js"></script>
|
||||
<script src="view.js"></script>
|
||||
<script src="sync.js"></script>
|
||||
</body>
|
||||
</html>
|
43
vendor/backbone/test/model.coffee
vendored
|
@ -1,43 +0,0 @@
|
|||
# Quick Backbone/CoffeeScript tests to make sure that inheritance
|
||||
# works correctly.
|
||||
|
||||
{ok, equal, deepEqual} = require 'assert'
|
||||
{Model, Collection, Events} = require '../backbone'
|
||||
|
||||
|
||||
# Patch `ok` to store a count of passed tests...
|
||||
count = 0
|
||||
oldOk = ok
|
||||
ok = ->
|
||||
oldOk arguments...
|
||||
count++
|
||||
|
||||
|
||||
class Document extends Model
|
||||
|
||||
fullName: ->
|
||||
@get('name') + ' ' + @get('surname')
|
||||
|
||||
tempest = new Document
|
||||
id : '1-the-tempest',
|
||||
title : "The Tempest",
|
||||
name : "William"
|
||||
surname : "Shakespeare"
|
||||
length : 123
|
||||
|
||||
ok tempest.fullName() is "William Shakespeare"
|
||||
ok tempest.get('length') is 123
|
||||
|
||||
|
||||
class ProperDocument extends Document
|
||||
|
||||
fullName: ->
|
||||
"Mr. " + super
|
||||
|
||||
properTempest = new ProperDocument tempest.attributes
|
||||
|
||||
ok properTempest.fullName() is "Mr. William Shakespeare"
|
||||
ok properTempest.get('length') is 123
|
||||
|
||||
|
||||
console.log "passed #{count} tests"
|
1110
vendor/backbone/test/model.js
vendored
12
vendor/backbone/test/noconflict.js
vendored
|
@ -1,12 +0,0 @@
|
|||
(function() {
|
||||
|
||||
module("Backbone.noConflict");
|
||||
|
||||
test('noConflict', 2, function() {
|
||||
var noconflictBackbone = Backbone.noConflict();
|
||||
equal(window.Backbone, undefined, 'Returned window.Backbone');
|
||||
window.Backbone = noconflictBackbone;
|
||||
equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
|
||||
});
|
||||
|
||||
})();
|
729
vendor/backbone/test/router.js
vendored
|
@ -1,729 +0,0 @@
|
|||
(function() {
|
||||
|
||||
var router = null;
|
||||
var location = null;
|
||||
var lastRoute = null;
|
||||
var lastArgs = [];
|
||||
|
||||
function onRoute(router, route, args) {
|
||||
lastRoute = route;
|
||||
lastArgs = args;
|
||||
}
|
||||
|
||||
var Location = function(href) {
|
||||
this.replace(href);
|
||||
};
|
||||
|
||||
_.extend(Location.prototype, {
|
||||
|
||||
replace: function(href) {
|
||||
_.extend(this, _.pick($('<a></a>', {href: href})[0],
|
||||
'href',
|
||||
'hash',
|
||||
'host',
|
||||
'search',
|
||||
'fragment',
|
||||
'pathname',
|
||||
'protocol'
|
||||
));
|
||||
// In IE, anchor.pathname does not contain a leading slash though
|
||||
// window.location.pathname does.
|
||||
if (!/^\//.test(this.pathname)) this.pathname = '/' + this.pathname;
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return this.href;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module("Backbone.Router", {
|
||||
|
||||
setup: function() {
|
||||
location = new Location('http://example.com');
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
router = new Router({testing: 101});
|
||||
Backbone.history.interval = 9;
|
||||
Backbone.history.start({pushState: false});
|
||||
lastRoute = null;
|
||||
lastArgs = [];
|
||||
Backbone.history.on('route', onRoute);
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history.off('route', onRoute);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var ExternalObject = {
|
||||
value: 'unset',
|
||||
|
||||
routingFunction: function(value) {
|
||||
this.value = value;
|
||||
}
|
||||
};
|
||||
_.bindAll(ExternalObject);
|
||||
|
||||
var Router = Backbone.Router.extend({
|
||||
|
||||
count: 0,
|
||||
|
||||
routes: {
|
||||
"noCallback": "noCallback",
|
||||
"counter": "counter",
|
||||
"search/:query": "search",
|
||||
"search/:query/p:page": "search",
|
||||
"charñ": "charUTF",
|
||||
"char%C3%B1": "charEscaped",
|
||||
"contacts": "contacts",
|
||||
"contacts/new": "newContact",
|
||||
"contacts/:id": "loadContact",
|
||||
"route-event/:arg": "routeEvent",
|
||||
"optional(/:item)": "optionalItem",
|
||||
"named/optional/(y:z)": "namedOptional",
|
||||
"splat/*args/end": "splat",
|
||||
":repo/compare/*from...*to": "github",
|
||||
"decode/:named/*splat": "decode",
|
||||
"*first/complex-*part/*rest": "complex",
|
||||
":entity?*args": "query",
|
||||
"function/:value": ExternalObject.routingFunction,
|
||||
"*anything": "anything"
|
||||
},
|
||||
|
||||
initialize : function(options) {
|
||||
this.testing = options.testing;
|
||||
this.route('implicit', 'implicit');
|
||||
},
|
||||
|
||||
counter: function() {
|
||||
this.count++;
|
||||
},
|
||||
|
||||
implicit: function() {
|
||||
this.count++;
|
||||
},
|
||||
|
||||
search: function(query, page) {
|
||||
this.query = query;
|
||||
this.page = page;
|
||||
},
|
||||
|
||||
charUTF: function() {
|
||||
this.charType = 'UTF';
|
||||
},
|
||||
|
||||
charEscaped: function() {
|
||||
this.charType = 'escaped';
|
||||
},
|
||||
|
||||
contacts: function(){
|
||||
this.contact = 'index';
|
||||
},
|
||||
|
||||
newContact: function(){
|
||||
this.contact = 'new';
|
||||
},
|
||||
|
||||
loadContact: function(){
|
||||
this.contact = 'load';
|
||||
},
|
||||
|
||||
optionalItem: function(arg){
|
||||
this.arg = arg != void 0 ? arg : null;
|
||||
},
|
||||
|
||||
splat: function(args) {
|
||||
this.args = args;
|
||||
},
|
||||
|
||||
github: function(repo, from, to) {
|
||||
this.repo = repo;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
},
|
||||
|
||||
complex: function(first, part, rest) {
|
||||
this.first = first;
|
||||
this.part = part;
|
||||
this.rest = rest;
|
||||
},
|
||||
|
||||
query: function(entity, args) {
|
||||
this.entity = entity;
|
||||
this.queryArgs = args;
|
||||
},
|
||||
|
||||
anything: function(whatever) {
|
||||
this.anything = whatever;
|
||||
},
|
||||
|
||||
namedOptional: function(z) {
|
||||
this.z = z;
|
||||
},
|
||||
|
||||
decode: function(named, path) {
|
||||
this.named = named;
|
||||
this.path = path;
|
||||
},
|
||||
|
||||
routeEvent: function(arg) {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
test("initialize", 1, function() {
|
||||
equal(router.testing, 101);
|
||||
});
|
||||
|
||||
test("routes (simple)", 4, function() {
|
||||
location.replace('http://example.com#search/news');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'news');
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
equal(lastArgs[0], 'news');
|
||||
});
|
||||
|
||||
test("routes (simple, but unicode)", 4, function() {
|
||||
location.replace('http://example.com#search/тест');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, "тест");
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
equal(lastArgs[0], "тест");
|
||||
});
|
||||
|
||||
test("routes (two part)", 2, function() {
|
||||
location.replace('http://example.com#search/nyc/p10');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'nyc');
|
||||
equal(router.page, '10');
|
||||
});
|
||||
|
||||
test("routes via navigate", 2, function() {
|
||||
Backbone.history.navigate('search/manhattan/p20', {trigger: true});
|
||||
equal(router.query, 'manhattan');
|
||||
equal(router.page, '20');
|
||||
});
|
||||
|
||||
test("routes via navigate for backwards-compatibility", 2, function() {
|
||||
Backbone.history.navigate('search/manhattan/p20', true);
|
||||
equal(router.query, 'manhattan');
|
||||
equal(router.page, '20');
|
||||
});
|
||||
|
||||
test("reports matched route via nagivate", 1, function() {
|
||||
ok(Backbone.history.navigate('search/manhattan/p20', true));
|
||||
});
|
||||
|
||||
test("route precedence via navigate", 6, function(){
|
||||
// check both 0.9.x and backwards-compatibility options
|
||||
_.each([ { trigger: true }, true ], function( options ){
|
||||
Backbone.history.navigate('contacts', options);
|
||||
equal(router.contact, 'index');
|
||||
Backbone.history.navigate('contacts/new', options);
|
||||
equal(router.contact, 'new');
|
||||
Backbone.history.navigate('contacts/foo', options);
|
||||
equal(router.contact, 'load');
|
||||
});
|
||||
});
|
||||
|
||||
test("loadUrl is not called for identical routes.", 0, function() {
|
||||
Backbone.history.loadUrl = function(){ ok(false); };
|
||||
location.replace('http://example.com#route');
|
||||
Backbone.history.navigate('route');
|
||||
Backbone.history.navigate('/route');
|
||||
Backbone.history.navigate('/route');
|
||||
});
|
||||
|
||||
test("use implicit callback if none provided", 1, function() {
|
||||
router.count = 0;
|
||||
router.navigate('implicit', {trigger: true});
|
||||
equal(router.count, 1);
|
||||
});
|
||||
|
||||
test("routes via navigate with {replace: true}", 1, function() {
|
||||
location.replace('http://example.com#start_here');
|
||||
Backbone.history.checkUrl();
|
||||
location.replace = function(href) {
|
||||
strictEqual(href, new Location('http://example.com#end_here').href);
|
||||
};
|
||||
Backbone.history.navigate('end_here', {replace: true});
|
||||
});
|
||||
|
||||
test("routes (splats)", 1, function() {
|
||||
location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.args, 'long-list/of/splatted_99args');
|
||||
});
|
||||
|
||||
test("routes (github)", 3, function() {
|
||||
location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.repo, 'backbone');
|
||||
equal(router.from, '1.0');
|
||||
equal(router.to, 'braddunbar:with/slash');
|
||||
});
|
||||
|
||||
test("routes (optional)", 2, function() {
|
||||
location.replace('http://example.com#optional');
|
||||
Backbone.history.checkUrl();
|
||||
ok(!router.arg);
|
||||
location.replace('http://example.com#optional/thing');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.arg, 'thing');
|
||||
});
|
||||
|
||||
test("routes (complex)", 3, function() {
|
||||
location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.first, 'one/two/three');
|
||||
equal(router.part, 'part');
|
||||
equal(router.rest, 'four/five/six/seven');
|
||||
});
|
||||
|
||||
test("routes (query)", 5, function() {
|
||||
location.replace('http://example.com#mandel?a=b&c=d');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.entity, 'mandel');
|
||||
equal(router.queryArgs, 'a=b&c=d');
|
||||
equal(lastRoute, 'query');
|
||||
equal(lastArgs[0], 'mandel');
|
||||
equal(lastArgs[1], 'a=b&c=d');
|
||||
});
|
||||
|
||||
test("routes (anything)", 1, function() {
|
||||
location.replace('http://example.com#doesnt-match-a-route');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.anything, 'doesnt-match-a-route');
|
||||
});
|
||||
|
||||
test("routes (function)", 3, function() {
|
||||
router.on('route', function(name) {
|
||||
ok(name === '');
|
||||
});
|
||||
equal(ExternalObject.value, 'unset');
|
||||
location.replace('http://example.com#function/set');
|
||||
Backbone.history.checkUrl();
|
||||
equal(ExternalObject.value, 'set');
|
||||
});
|
||||
|
||||
test("Decode named parameters, not splats.", 2, function() {
|
||||
location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.named, 'a/b');
|
||||
strictEqual(router.path, 'c/d/e');
|
||||
});
|
||||
|
||||
test("fires event when router doesn't have callback on it", 1, function() {
|
||||
router.on("route:noCallback", function(){ ok(true); });
|
||||
location.replace('http://example.com#noCallback');
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
test("#933, #908 - leading slash", 2, function() {
|
||||
location.replace('http://example.com/root/foo');
|
||||
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
Backbone.history.start({root: '/root', hashChange: false, silent: true});
|
||||
strictEqual(Backbone.history.getFragment(), 'foo');
|
||||
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
Backbone.history.start({root: '/root/', hashChange: false, silent: true});
|
||||
strictEqual(Backbone.history.getFragment(), 'foo');
|
||||
});
|
||||
|
||||
test("#1003 - History is started before navigate is called", 1, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history.navigate = function(){ ok(Backbone.History.started); };
|
||||
Backbone.history.start();
|
||||
// If this is not an old IE navigate will not be called.
|
||||
if (!Backbone.history.iframe) ok(true);
|
||||
});
|
||||
|
||||
test("#967 - Route callback gets passed encoded values.", 3, function() {
|
||||
var route = 'has%2Fslash/complex-has%23hash/has%20space';
|
||||
Backbone.history.navigate(route, {trigger: true});
|
||||
strictEqual(router.first, 'has/slash');
|
||||
strictEqual(router.part, 'has#hash');
|
||||
strictEqual(router.rest, 'has space');
|
||||
});
|
||||
|
||||
test("correctly handles URLs with % (#868)", 3, function() {
|
||||
location.replace('http://example.com#search/fat%3A1.5%25');
|
||||
Backbone.history.checkUrl();
|
||||
location.replace('http://example.com#search/fat');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'fat');
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
});
|
||||
|
||||
test("#2666 - Hashes with UTF8 in them.", 2, function() {
|
||||
Backbone.history.navigate('charñ', {trigger: true});
|
||||
equal(router.charType, 'UTF');
|
||||
Backbone.history.navigate('char%C3%B1', {trigger: true});
|
||||
equal(router.charType, 'escaped');
|
||||
});
|
||||
|
||||
test("#1185 - Use pathname when hashChange is not wanted.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/path/name#hash');
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
Backbone.history.start({hashChange: false});
|
||||
var fragment = Backbone.history.getFragment();
|
||||
strictEqual(fragment, location.pathname.replace(/^\//, ''));
|
||||
});
|
||||
|
||||
test("#1206 - Strip leading slash before location.assign.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root/');
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
Backbone.history.start({hashChange: false, root: '/root/'});
|
||||
location.assign = function(pathname) {
|
||||
strictEqual(pathname, '/root/fragment');
|
||||
};
|
||||
Backbone.history.navigate('/fragment');
|
||||
});
|
||||
|
||||
test("#1387 - Root fragment without trailing slash.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root');
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
Backbone.history.start({hashChange: false, root: '/root/', silent: true});
|
||||
strictEqual(Backbone.history.getFragment(), '');
|
||||
});
|
||||
|
||||
test("#1366 - History does not prepend root to fragment.", 2, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root/');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {
|
||||
strictEqual(url, '/root/x');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
root: '/root/',
|
||||
pushState: true,
|
||||
hashChange: false
|
||||
});
|
||||
Backbone.history.navigate('x');
|
||||
strictEqual(Backbone.history.fragment, 'x');
|
||||
});
|
||||
|
||||
test("Normalize root.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {
|
||||
strictEqual(url, '/root/fragment');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '/root',
|
||||
hashChange: false
|
||||
});
|
||||
Backbone.history.navigate('fragment');
|
||||
});
|
||||
|
||||
test("Normalize root.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root#fragment');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {},
|
||||
replaceState: function(state, title, url) {
|
||||
strictEqual(url, '/root/fragment');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '/root'
|
||||
});
|
||||
});
|
||||
|
||||
test("Normalize root.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root');
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
Backbone.history.loadUrl = function() { ok(true); };
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '/root'
|
||||
});
|
||||
});
|
||||
|
||||
test("Normalize root - leading slash.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){},
|
||||
replaceState: function(){}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({root: 'root'});
|
||||
strictEqual(Backbone.history.root, '/root/');
|
||||
});
|
||||
|
||||
test("Transition from hashChange to pushState.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root#x/y');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){},
|
||||
replaceState: function(state, title, url){
|
||||
strictEqual(url, '/root/x/y');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
root: 'root',
|
||||
pushState: true
|
||||
});
|
||||
});
|
||||
|
||||
test("#1619: Router: Normalize empty root", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){},
|
||||
replaceState: function(){}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({root: ''});
|
||||
strictEqual(Backbone.history.root, '/');
|
||||
});
|
||||
|
||||
test("#1619: Router: nagivate with empty root", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {
|
||||
strictEqual(url, '/fragment');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
root: '',
|
||||
hashChange: false
|
||||
});
|
||||
Backbone.history.navigate('fragment');
|
||||
});
|
||||
|
||||
test("Transition from pushState to hashChange.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root/x/y?a=b');
|
||||
location.replace = function(url) {
|
||||
strictEqual(url, '/root/?a=b#x/y');
|
||||
};
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: null,
|
||||
replaceState: null
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
root: 'root',
|
||||
pushState: true
|
||||
});
|
||||
});
|
||||
|
||||
test("#1695 - hashChange to pushState with search.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root?a=b#x/y');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){},
|
||||
replaceState: function(state, title, url){
|
||||
strictEqual(url, '/root/x/y?a=b');
|
||||
}
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
root: 'root',
|
||||
pushState: true
|
||||
});
|
||||
});
|
||||
|
||||
test("#1746 - Router allows empty route.", 1, function() {
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {'': 'empty'},
|
||||
empty: function(){},
|
||||
route: function(route){
|
||||
strictEqual(route, '');
|
||||
}
|
||||
});
|
||||
new Router;
|
||||
});
|
||||
|
||||
test("#1794 - Trailing space in fragments.", 1, function() {
|
||||
var history = new Backbone.History;
|
||||
strictEqual(history.getFragment('fragment '), 'fragment');
|
||||
});
|
||||
|
||||
test("#1820 - Leading slash and trailing space.", 1, function() {
|
||||
var history = new Backbone.History;
|
||||
strictEqual(history.getFragment('/fragment '), 'fragment');
|
||||
});
|
||||
|
||||
test("#1980 - Optional parameters.", 2, function() {
|
||||
location.replace('http://example.com#named/optional/y');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.z, undefined);
|
||||
location.replace('http://example.com#named/optional/y123');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.z, '123');
|
||||
});
|
||||
|
||||
test("#2062 - Trigger 'route' event on router instance.", 2, function() {
|
||||
router.on('route', function(name, args) {
|
||||
strictEqual(name, 'routeEvent');
|
||||
deepEqual(args, ['x']);
|
||||
});
|
||||
location.replace('http://example.com#route-event/x');
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
test("#2255 - Extend routes by making routes a function.", 1, function() {
|
||||
var RouterBase = Backbone.Router.extend({
|
||||
routes: function() {
|
||||
return {
|
||||
home: "root",
|
||||
index: "index.html"
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
var RouterExtended = RouterBase.extend({
|
||||
routes: function() {
|
||||
var _super = RouterExtended.__super__.routes;
|
||||
return _.extend(_super(),
|
||||
{ show: "show",
|
||||
search: "search" });
|
||||
}
|
||||
});
|
||||
|
||||
var router = new RouterExtended();
|
||||
deepEqual({home: "root", index: "index.html", show: "show", search: "search"}, router.routes);
|
||||
});
|
||||
|
||||
test("#2538 - hashChange to pushState only if both requested.", 0, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root?a=b#x/y');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){},
|
||||
replaceState: function(){ ok(false); }
|
||||
}
|
||||
});
|
||||
Backbone.history.start({
|
||||
root: 'root',
|
||||
pushState: true,
|
||||
hashChange: false
|
||||
});
|
||||
});
|
||||
|
||||
test('No hash fallback.', 0, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){},
|
||||
replaceState: function(){}
|
||||
}
|
||||
});
|
||||
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {
|
||||
hash: function() { ok(false); }
|
||||
}
|
||||
});
|
||||
var router = new Router;
|
||||
|
||||
location.replace('http://example.com/');
|
||||
Backbone.history.start({
|
||||
pushState: true,
|
||||
hashChange: false
|
||||
});
|
||||
location.replace('http://example.com/nomatch#hash');
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
test('#2656 - No trailing slash on root.', 1, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url){
|
||||
strictEqual(url, '/root');
|
||||
}
|
||||
}
|
||||
});
|
||||
location.replace('http://example.com/root/path');
|
||||
Backbone.history.start({pushState: true, root: 'root'});
|
||||
Backbone.history.navigate('');
|
||||
});
|
||||
|
||||
test('#2656 - No trailing slash on root.', 1, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {
|
||||
strictEqual(url, '/');
|
||||
}
|
||||
}
|
||||
});
|
||||
location.replace('http://example.com/path');
|
||||
Backbone.history.start({pushState: true});
|
||||
Backbone.history.navigate('');
|
||||
});
|
||||
|
||||
test('#2765 - Fragment matching sans query/hash.', 2, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url) {
|
||||
strictEqual(url, '/path?query#hash');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {
|
||||
path: function() { ok(true); }
|
||||
}
|
||||
});
|
||||
var router = new Router;
|
||||
|
||||
location.replace('http://example.com/');
|
||||
Backbone.history.start({pushState: true});
|
||||
Backbone.history.navigate('path?query#hash', true);
|
||||
});
|
||||
|
||||
})();
|
210
vendor/backbone/test/sync.js
vendored
|
@ -1,210 +0,0 @@
|
|||
(function() {
|
||||
|
||||
var Library = Backbone.Collection.extend({
|
||||
url : function() { return '/library'; }
|
||||
});
|
||||
var library;
|
||||
|
||||
var attrs = {
|
||||
title : "The Tempest",
|
||||
author : "Bill Shakespeare",
|
||||
length : 123
|
||||
};
|
||||
|
||||
module("Backbone.sync", {
|
||||
|
||||
setup : function() {
|
||||
library = new Library;
|
||||
library.create(attrs, {wait: false});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
Backbone.emulateHTTP = false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
test("read", 4, function() {
|
||||
library.fetch();
|
||||
equal(this.ajaxSettings.url, '/library');
|
||||
equal(this.ajaxSettings.type, 'GET');
|
||||
equal(this.ajaxSettings.dataType, 'json');
|
||||
ok(_.isEmpty(this.ajaxSettings.data));
|
||||
});
|
||||
|
||||
test("passing data", 3, function() {
|
||||
library.fetch({data: {a: 'a', one: 1}});
|
||||
equal(this.ajaxSettings.url, '/library');
|
||||
equal(this.ajaxSettings.data.a, 'a');
|
||||
equal(this.ajaxSettings.data.one, 1);
|
||||
});
|
||||
|
||||
test("create", 6, function() {
|
||||
equal(this.ajaxSettings.url, '/library');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(this.ajaxSettings.dataType, 'json');
|
||||
var data = JSON.parse(this.ajaxSettings.data);
|
||||
equal(data.title, 'The Tempest');
|
||||
equal(data.author, 'Bill Shakespeare');
|
||||
equal(data.length, 123);
|
||||
});
|
||||
|
||||
test("update", 7, function() {
|
||||
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
|
||||
equal(this.ajaxSettings.url, '/library/1-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'PUT');
|
||||
equal(this.ajaxSettings.dataType, 'json');
|
||||
var data = JSON.parse(this.ajaxSettings.data);
|
||||
equal(data.id, '1-the-tempest');
|
||||
equal(data.title, 'The Tempest');
|
||||
equal(data.author, 'William Shakespeare');
|
||||
equal(data.length, 123);
|
||||
});
|
||||
|
||||
test("update with emulateHTTP and emulateJSON", 7, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||
emulateHTTP: true,
|
||||
emulateJSON: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(this.ajaxSettings.dataType, 'json');
|
||||
equal(this.ajaxSettings.data._method, 'PUT');
|
||||
var data = JSON.parse(this.ajaxSettings.data.model);
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
});
|
||||
|
||||
test("update with just emulateHTTP", 6, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||
emulateHTTP: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(this.ajaxSettings.contentType, 'application/json');
|
||||
var data = JSON.parse(this.ajaxSettings.data);
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
});
|
||||
|
||||
test("update with just emulateJSON", 6, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||
emulateJSON: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'PUT');
|
||||
equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
|
||||
var data = JSON.parse(this.ajaxSettings.data.model);
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
});
|
||||
|
||||
test("read model", 3, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
library.first().fetch();
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'GET');
|
||||
ok(_.isEmpty(this.ajaxSettings.data));
|
||||
});
|
||||
|
||||
test("destroy", 3, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
library.first().destroy({wait: true});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'DELETE');
|
||||
equal(this.ajaxSettings.data, null);
|
||||
});
|
||||
|
||||
test("destroy with emulateHTTP", 3, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
library.first().destroy({
|
||||
emulateHTTP: true,
|
||||
emulateJSON: true
|
||||
});
|
||||
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||
equal(this.ajaxSettings.type, 'POST');
|
||||
equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
|
||||
});
|
||||
|
||||
test("urlError", 2, function() {
|
||||
var model = new Backbone.Model();
|
||||
raises(function() {
|
||||
model.fetch();
|
||||
});
|
||||
model.fetch({url: '/one/two'});
|
||||
equal(this.ajaxSettings.url, '/one/two');
|
||||
});
|
||||
|
||||
test("#1052 - `options` is optional.", 0, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.url = '/test';
|
||||
Backbone.sync('create', model);
|
||||
});
|
||||
|
||||
test("Backbone.ajax", 1, function() {
|
||||
Backbone.ajax = function(settings){
|
||||
strictEqual(settings.url, '/test');
|
||||
};
|
||||
var model = new Backbone.Model();
|
||||
model.url = '/test';
|
||||
Backbone.sync('create', model);
|
||||
});
|
||||
|
||||
test("Call provided error callback on error.", 1, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
Backbone.sync('read', model, {
|
||||
error: function() { ok(true); }
|
||||
});
|
||||
this.ajaxSettings.error();
|
||||
});
|
||||
|
||||
test('Use Backbone.emulateHTTP as default.', 2, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
|
||||
Backbone.emulateHTTP = true;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateHTTP, true);
|
||||
|
||||
Backbone.emulateHTTP = false;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateHTTP, false);
|
||||
});
|
||||
|
||||
test('Use Backbone.emulateJSON as default.', 2, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
|
||||
Backbone.emulateJSON = true;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateJSON, true);
|
||||
|
||||
Backbone.emulateJSON = false;
|
||||
model.sync('create', model);
|
||||
strictEqual(this.ajaxSettings.emulateJSON, false);
|
||||
});
|
||||
|
||||
test("#1756 - Call user provided beforeSend function.", 4, function() {
|
||||
Backbone.emulateHTTP = true;
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
var xhr = {
|
||||
setRequestHeader: function(header, value) {
|
||||
strictEqual(header, 'X-HTTP-Method-Override');
|
||||
strictEqual(value, 'DELETE');
|
||||
}
|
||||
};
|
||||
model.sync('delete', model, {
|
||||
beforeSend: function(_xhr) {
|
||||
ok(_xhr === xhr);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
|
||||
});
|
||||
|
||||
})();
|