merge in master branch

This commit is contained in:
Adam Krebs
2015-05-13 11:10:03 -04:00
13 changed files with 272 additions and 442 deletions

View File

@@ -10,7 +10,7 @@ before_script:
- sh -e /etc/init.d/xvfb start
script:
- npm test
# Karma sauce is limited to running about 5-7 browsers (or it will tiemout) at a time so we just run vendor by vendor here
# Karma sauce is limited to running about 5-7 browsers (or it will timeout) at a time so we just run vendor by vendor here
- karma start karma.conf-sauce.js --browsers FIREFOX_V4,FIREFOX_V11,FIREFOX_V21,FIREFOX_V30,FIREFOX_V35,CHROME_V26,CHROME_V31,CHROME_V39,CHROME_V40,ANDROID_V4.0,ANDROID_V4.3
- karma start karma.conf-sauce.js --browsers IE_V7,IE_V8,IE_V9,IE_V10,IE_V11
- karma start karma.conf-sauce.js --browsers SAFARI_V5,SAFARI_V6,SAFARI_V7,SAFARI_V8.0,OPERA_V11,OPERA_V12

2
backbone-min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -17,8 +17,9 @@
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore');
factory(root, exports, _);
var _ = require('underscore'), $;
try { $ = require('jquery'); } catch(e) {}
factory(root, exports, _, $);
// Finally, as a browser global.
} else {
@@ -242,7 +243,10 @@
};
// Bind an event to only be triggered a single time. After the first time
// the callback is invoked, it will be removed.
// the callback is invoked, it will be removed. When multiple events are
// passed in using the space-separated syntax, the event will fire once for every
// event you passed in, not once for a combination of all events
Events.once = function(name, callback, context) {
// Map the event into a `{event: once}` object.
var events = onceMap(name, callback, _.bind(this.off, this));
@@ -277,7 +281,7 @@
// receive the true name of the event as the first argument).
Events.trigger = function(name) {
if (!this._events) return this;
var length = Math.max(0, arguments.length - 1);
var args = Array(length);
for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
@@ -1523,6 +1527,13 @@
return path === this.root && !this.getSearch();
},
// Does the pathname match the root?
matchRoot: function() {
var path = this.decodeFragment(this.location.pathname);
var root = path.slice(0, this.root.length - 1) + '/';
return root === this.root;
},
// Unicode characters in `location.pathname` are percent encoded so they're
// decoded for comparison. `%25` should not be decoded since it may be part
// of an encoded parameter.
@@ -1548,9 +1559,7 @@
getPath: function() {
var path = this.decodeFragment(
this.location.pathname + this.getSearch()
);
var root = this.root.slice(0, -1);
if (!path.indexOf(root)) path = path.slice(root.length);
).slice(this.root.length - 1);
return path.charAt(0) === '/' ? path.slice(1) : path;
},
@@ -1692,6 +1701,8 @@
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl: function(fragment) {
// If the root doesn't match, no routes can match either.
if (!this.matchRoot()) return false;
fragment = this.fragment = this.getFragment(fragment);
return _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
@@ -1772,7 +1783,7 @@
// Helpers
// -------
// Helper function to correctly set up the prototype chain, for subclasses.
// Helper function to correctly set up the prototype chain for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var extend = function(protoProps, staticProps) {
@@ -1781,7 +1792,7 @@
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent's constructor.
// by us to simply call the parent constructor.
if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
} else {
@@ -1792,7 +1803,7 @@
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
// `parent` constructor function.
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;

View File

@@ -5,5 +5,5 @@
"dependencies" : {
"underscore" : ">=1.7.0"
},
"ignore" : ["docs", "examples", "test", "*.yml", "*.html", "*.ico", "*.md", "CNAME"]
"ignore" : ["docs", "examples", "test", "*.yml", "*.html", "*.ico", "*.md", "CNAME", ".*", "karma.*", "component.json", "package.json"]
}

View File

@@ -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">&quot;-&quot;</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">&quot;-&quot;</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">&quot;-&quot;</span><span class="o">+</span><span class="nx">S4</span><span class="p">()</span><span class="o">+</span><span class="s2">&quot;-&quot;</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&#39;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">&amp;&amp;</span> <span class="nx">store</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s2">&quot;,&quot;</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">&quot;,&quot;</span><span class="p">));</span>
<span class="p">},</span></pre></div>
<p>Add a model, giving it a (hopefully)-unique GUID, if it doesn&#39;t already
have an id of it&#39;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">&quot;-&quot;</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">&quot;-&quot;</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">&quot;-&quot;</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">&quot;-&quot;</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">&quot;-&quot;</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&#39;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 &lt;= 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">&#39;function&#39;</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">&quot;read&quot;</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">&quot;create&quot;</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">&quot;update&quot;</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">&quot;delete&quot;</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">&#39;Record not found.&#39;</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">&amp;&amp;</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 &#39;Backbone.sync&#39; to default to localSync,
the original &#39;Backbone.sync&#39; is still available in &#39;Backbone.ajaxSync&#39;
</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>

View File

@@ -97,8 +97,9 @@ others that may still expect a global Backbone.</p>
</div>
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> exports !== <span class="hljs-string">'undefined'</span>) {
<span class="hljs-keyword">var</span> _ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'underscore'</span>);
factory(root, exports, _);</pre></div></div>
<span class="hljs-keyword">var</span> _ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'underscore'</span>), $;
<span class="hljs-keyword">try</span> { $ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'jquery'</span>); } <span class="hljs-keyword">catch</span>(e) {}
factory(root, exports, _, $);</pre></div></div>
</li>
@@ -750,11 +751,14 @@ are removed. If so, stop delete the listening.</p>
<a class="pilcrow" href="#section-41">&#182;</a>
</div>
<p>Bind an event to only be triggered a single time. After the first time
the callback is invoked, it will be removed.</p>
the callback is invoked, it will be removed. When multiple events are
passed in using the space-separated syntax, the event will fire once for every
event you passed in, not once for a combination of all events</p>
</div>
<div class="content"><div class='highlight'><pre> Events.once = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(name, callback, context)</span> </span>{</pre></div></div>
<div class="content"><div class='highlight'><pre>
Events.once = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(name, callback, context)</span> </span>{</pre></div></div>
</li>
@@ -850,7 +854,7 @@ receive the true name of the event as the first argument).</p>
<div class="content"><div class='highlight'><pre> Events.trigger = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(name)</span> </span>{
<span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>._events) <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> length = <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">0</span>, <span class="hljs-built_in">arguments</span>.length - <span class="hljs-number">1</span>);
<span class="hljs-keyword">var</span> args = <span class="hljs-built_in">Array</span>(length);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; length; i++) args[i] = <span class="hljs-built_in">arguments</span>[i + <span class="hljs-number">1</span>];
@@ -4043,6 +4047,25 @@ twenty times a second.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-210">&#182;</a>
</div>
<p>Does the pathname match the root?</p>
</div>
<div class="content"><div class='highlight'><pre> matchRoot: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> path = <span class="hljs-keyword">this</span>.decodeFragment(<span class="hljs-keyword">this</span>.location.pathname);
<span class="hljs-keyword">var</span> root = path.slice(<span class="hljs-number">0</span>, <span class="hljs-keyword">this</span>.root.length - <span class="hljs-number">1</span>) + <span class="hljs-string">'/'</span>;
<span class="hljs-keyword">return</span> root === <span class="hljs-keyword">this</span>.root;
},</pre></div></div>
</li>
<li id="section-211">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-211">&#182;</a>
</div>
<p>Unicode characters in <code>location.pathname</code> are percent encoded so theyre
decoded for comparison. <code>%25</code> should not be decoded since it may be part
of an encoded parameter.</p>
@@ -4056,11 +4079,11 @@ of an encoded parameter.</p>
</li>
<li id="section-211">
<li id="section-212">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-211">&#182;</a>
<a class="pilcrow" href="#section-212">&#182;</a>
</div>
<p>In IE6, the hash fragment and search params are incorrect if the
fragment contains <code>?</code>.</p>
@@ -4075,11 +4098,11 @@ fragment contains <code>?</code>.</p>
</li>
<li id="section-212">
<li id="section-213">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-212">&#182;</a>
<a class="pilcrow" href="#section-213">&#182;</a>
</div>
<p>Gets the true hash value. Cannot use location.hash directly due to bug
in Firefox where location.hash will always be decoded.</p>
@@ -4094,11 +4117,11 @@ in Firefox where location.hash will always be decoded.</p>
</li>
<li id="section-213">
<li id="section-214">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-213">&#182;</a>
<a class="pilcrow" href="#section-214">&#182;</a>
</div>
<p>Get the pathname and search params, without the root.</p>
@@ -4107,20 +4130,18 @@ in Firefox where location.hash will always be decoded.</p>
<div class="content"><div class='highlight'><pre> getPath: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">var</span> path = <span class="hljs-keyword">this</span>.decodeFragment(
<span class="hljs-keyword">this</span>.location.pathname + <span class="hljs-keyword">this</span>.getSearch()
);
<span class="hljs-keyword">var</span> root = <span class="hljs-keyword">this</span>.root.slice(<span class="hljs-number">0</span>, -<span class="hljs-number">1</span>);
<span class="hljs-keyword">if</span> (!path.indexOf(root)) path = path.slice(root.length);
).slice(<span class="hljs-keyword">this</span>.root.length - <span class="hljs-number">1</span>);
<span class="hljs-keyword">return</span> path.charAt(<span class="hljs-number">0</span>) === <span class="hljs-string">'/'</span> ? path.slice(<span class="hljs-number">1</span>) : path;
},</pre></div></div>
</li>
<li id="section-214">
<li id="section-215">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-214">&#182;</a>
<a class="pilcrow" href="#section-215">&#182;</a>
</div>
<p>Get the cross-browser normalized URL fragment from the path or hash.</p>
@@ -4140,11 +4161,11 @@ in Firefox where location.hash will always be decoded.</p>
</li>
<li id="section-215">
<li id="section-216">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-215">&#182;</a>
<a class="pilcrow" href="#section-216">&#182;</a>
</div>
<p>Start the hash change handling, returning <code>true</code> if the current URL matches
an existing route, and <code>false</code> otherwise.</p>
@@ -4158,11 +4179,11 @@ an existing route, and <code>false</code> otherwise.</p>
</li>
<li id="section-216">
<li id="section-217">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-216">&#182;</a>
<a class="pilcrow" href="#section-217">&#182;</a>
</div>
<p>Figure out the initial configuration. Do we need an iframe?
Is pushState desired … is it available?</p>
@@ -4182,11 +4203,11 @@ Is pushState desired … is it available?</p>
</li>
<li id="section-217">
<li id="section-218">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-217">&#182;</a>
<a class="pilcrow" href="#section-218">&#182;</a>
</div>
<p>Normalize root to always include a leading and trailing slash.</p>
@@ -4197,11 +4218,11 @@ Is pushState desired … is it available?</p>
</li>
<li id="section-218">
<li id="section-219">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-218">&#182;</a>
<a class="pilcrow" href="#section-219">&#182;</a>
</div>
<p>Transition from hashChange to pushState or vice versa if both are
requested.</p>
@@ -4213,11 +4234,11 @@ requested.</p>
</li>
<li id="section-219">
<li id="section-220">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-219">&#182;</a>
<a class="pilcrow" href="#section-220">&#182;</a>
</div>
<p>If weve started off with a route from a <code>pushState</code>-enabled
browser, but were currently in a browser that doesnt support it…</p>
@@ -4231,11 +4252,11 @@ browser, but were currently in a browser that doesnt support it…</p>
</li>
<li id="section-220">
<li id="section-221">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-220">&#182;</a>
<a class="pilcrow" href="#section-221">&#182;</a>
</div>
<p>Return immediately as browser will do redirect to new url</p>
@@ -4246,11 +4267,11 @@ browser, but were currently in a browser that doesnt support it…</p>
</li>
<li id="section-221">
<li id="section-222">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-221">&#182;</a>
<a class="pilcrow" href="#section-222">&#182;</a>
</div>
<p>Or if weve started out with a hash-based route, but were currently
in a browser where it could be <code>pushState</code>-based instead…</p>
@@ -4266,11 +4287,11 @@ in a browser where it could be <code>pushState</code>-based instead…</p>
</li>
<li id="section-222">
<li id="section-223">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-222">&#182;</a>
<a class="pilcrow" href="#section-223">&#182;</a>
</div>
<p>Proxy an iframe to handle location events if the browser doesnt
support the <code>hashchange</code> event, HTML5 history, or the user wants
@@ -4288,11 +4309,11 @@ support the <code>hashchange</code> event, HTML5 history, or the user wants
</li>
<li id="section-223">
<li id="section-224">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-223">&#182;</a>
<a class="pilcrow" href="#section-224">&#182;</a>
</div>
<p>Using <code>appendChild</code> will throw on IE &lt; 9 if the document is not ready.</p>
@@ -4306,11 +4327,11 @@ support the <code>hashchange</code> event, HTML5 history, or the user wants
</li>
<li id="section-224">
<li id="section-225">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-224">&#182;</a>
<a class="pilcrow" href="#section-225">&#182;</a>
</div>
<p>Add a cross-platform <code>addEventListener</code> shim for older browsers.</p>
@@ -4323,11 +4344,11 @@ support the <code>hashchange</code> event, HTML5 history, or the user wants
</li>
<li id="section-225">
<li id="section-226">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-225">&#182;</a>
<a class="pilcrow" href="#section-226">&#182;</a>
</div>
<p>Depending on whether were using pushState or hashes, and whether
onhashchange is supported, determine how we check the URL state.</p>
@@ -4348,11 +4369,11 @@ support the <code>hashchange</code> event, HTML5 history, or the user wants
</li>
<li id="section-226">
<li id="section-227">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-226">&#182;</a>
<a class="pilcrow" href="#section-227">&#182;</a>
</div>
<p>Disable Backbone.history, perhaps temporarily. Not useful in a real app,
but possibly useful for unit testing Routers.</p>
@@ -4364,11 +4385,11 @@ but possibly useful for unit testing Routers.</p>
</li>
<li id="section-227">
<li id="section-228">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-227">&#182;</a>
<a class="pilcrow" href="#section-228">&#182;</a>
</div>
<p>Add a cross-platform <code>removeEventListener</code> shim for older browsers.</p>
@@ -4381,11 +4402,11 @@ but possibly useful for unit testing Routers.</p>
</li>
<li id="section-228">
<li id="section-229">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-228">&#182;</a>
<a class="pilcrow" href="#section-229">&#182;</a>
</div>
<p>Remove window listeners.</p>
@@ -4400,11 +4421,11 @@ but possibly useful for unit testing Routers.</p>
</li>
<li id="section-229">
<li id="section-230">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-229">&#182;</a>
<a class="pilcrow" href="#section-230">&#182;</a>
</div>
<p>Clean up the iframe if necessary.</p>
@@ -4418,11 +4439,11 @@ but possibly useful for unit testing Routers.</p>
</li>
<li id="section-230">
<li id="section-231">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-230">&#182;</a>
<a class="pilcrow" href="#section-231">&#182;</a>
</div>
<p>Some environments will throw when clearing an undefined interval.</p>
@@ -4435,11 +4456,11 @@ but possibly useful for unit testing Routers.</p>
</li>
<li id="section-231">
<li id="section-232">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-231">&#182;</a>
<a class="pilcrow" href="#section-232">&#182;</a>
</div>
<p>Add a route to be tested when the fragment changes. Routes added later
may override previous routes.</p>
@@ -4453,11 +4474,11 @@ may override previous routes.</p>
</li>
<li id="section-232">
<li id="section-233">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-232">&#182;</a>
<a class="pilcrow" href="#section-233">&#182;</a>
</div>
<p>Checks the current URL to see if it has changed, and if it has,
calls <code>loadUrl</code>, normalizing across the hidden iframe.</p>
@@ -4470,11 +4491,11 @@ calls <code>loadUrl</code>, normalizing across the hidden iframe.</p>
</li>
<li id="section-233">
<li id="section-234">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-233">&#182;</a>
<a class="pilcrow" href="#section-234">&#182;</a>
</div>
<p>If the user pressed the back button, the iframes hash will have
changed and we should use that for comparison.</p>
@@ -4493,11 +4514,11 @@ changed and we should use that for comparison.</p>
</li>
<li id="section-234">
<li id="section-235">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-234">&#182;</a>
<a class="pilcrow" href="#section-235">&#182;</a>
</div>
<p>Attempt to load the current URL fragment. If a route succeeds with a
match, returns <code>true</code>. If no defined routes matches the fragment,
@@ -4505,7 +4526,22 @@ returns <code>false</code>.</p>
</div>
<div class="content"><div class='highlight'><pre> loadUrl: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(fragment)</span> </span>{
<div class="content"><div class='highlight'><pre> loadUrl: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(fragment)</span> </span>{</pre></div></div>
</li>
<li id="section-236">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-236">&#182;</a>
</div>
<p>If the root doesnt match, no routes can match either.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.matchRoot()) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
fragment = <span class="hljs-keyword">this</span>.fragment = <span class="hljs-keyword">this</span>.getFragment(fragment);
<span class="hljs-keyword">return</span> _.any(<span class="hljs-keyword">this</span>.handlers, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(handler)</span> </span>{
<span class="hljs-keyword">if</span> (handler.route.test(fragment)) {
@@ -4518,11 +4554,11 @@ returns <code>false</code>.</p>
</li>
<li id="section-235">
<li id="section-237">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-235">&#182;</a>
<a class="pilcrow" href="#section-237">&#182;</a>
</div>
<p>Save a fragment into the hash history, or replace the URL state if the
replace option is passed. You are responsible for properly URL-encoding
@@ -4540,11 +4576,11 @@ you wish to modify the current URL without adding an entry to the history.</p>
</li>
<li id="section-236">
<li id="section-238">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-236">&#182;</a>
<a class="pilcrow" href="#section-238">&#182;</a>
</div>
<p>Normalize the fragment.</p>
@@ -4555,11 +4591,11 @@ you wish to modify the current URL without adding an entry to the history.</p>
</li>
<li id="section-237">
<li id="section-239">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-237">&#182;</a>
<a class="pilcrow" href="#section-239">&#182;</a>
</div>
<p>Dont include a trailing slash on the root.</p>
@@ -4574,11 +4610,11 @@ you wish to modify the current URL without adding an entry to the history.</p>
</li>
<li id="section-238">
<li id="section-240">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-238">&#182;</a>
<a class="pilcrow" href="#section-240">&#182;</a>
</div>
<p>Strip the hash and decode for matching.</p>
@@ -4592,11 +4628,11 @@ you wish to modify the current URL without adding an entry to the history.</p>
</li>
<li id="section-239">
<li id="section-241">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-239">&#182;</a>
<a class="pilcrow" href="#section-241">&#182;</a>
</div>
<p>If pushState is available, we use it to set the fragment as a real URL.</p>
@@ -4608,11 +4644,11 @@ you wish to modify the current URL without adding an entry to the history.</p>
</li>
<li id="section-240">
<li id="section-242">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-240">&#182;</a>
<a class="pilcrow" href="#section-242">&#182;</a>
</div>
<p>If hash changes havent been explicitly disabled, update the hash
fragment to store history.</p>
@@ -4626,11 +4662,11 @@ fragment to store history.</p>
</li>
<li id="section-241">
<li id="section-243">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-241">&#182;</a>
<a class="pilcrow" href="#section-243">&#182;</a>
</div>
<p>Opening and closing the iframe tricks IE7 and earlier to push a
history entry on hash-tag change. When replace is true, we dont
@@ -4645,11 +4681,11 @@ want this.</p>
</li>
<li id="section-242">
<li id="section-244">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-242">&#182;</a>
<a class="pilcrow" href="#section-244">&#182;</a>
</div>
<p>If youve told us that you explicitly dont want fallback hashchange-
based history, then <code>navigate</code> becomes a page refresh.</p>
@@ -4665,11 +4701,11 @@ based history, then <code>navigate</code> becomes a page refresh.</p>
</li>
<li id="section-243">
<li id="section-245">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-243">&#182;</a>
<a class="pilcrow" href="#section-245">&#182;</a>
</div>
<p>Update the hash location, either replacing the current entry, or adding
a new one to the browser history.</p>
@@ -4685,11 +4721,11 @@ a new one to the browser history.</p>
</li>
<li id="section-244">
<li id="section-246">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-244">&#182;</a>
<a class="pilcrow" href="#section-246">&#182;</a>
</div>
<p>Some browsers require that <code>hash</code> contains a leading #.</p>
@@ -4704,11 +4740,11 @@ a new one to the browser history.</p>
</li>
<li id="section-245">
<li id="section-247">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-245">&#182;</a>
<a class="pilcrow" href="#section-247">&#182;</a>
</div>
<p>Create the default Backbone.history.</p>
@@ -4719,11 +4755,11 @@ a new one to the browser history.</p>
</li>
<li id="section-246">
<li id="section-248">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-246">&#182;</a>
<a class="pilcrow" href="#section-248">&#182;</a>
</div>
<h2 id="helpers">Helpers</h2>
@@ -4732,11 +4768,11 @@ a new one to the browser history.</p>
</li>
<li id="section-247">
<li id="section-249">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-247">&#182;</a>
<a class="pilcrow" href="#section-249">&#182;</a>
</div>
</div>
@@ -4744,13 +4780,13 @@ a new one to the browser history.</p>
</li>
<li id="section-248">
<li id="section-250">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-248">&#182;</a>
<a class="pilcrow" href="#section-250">&#182;</a>
</div>
<p>Helper function to correctly set up the prototype chain, for subclasses.
<p>Helper function to correctly set up the prototype chain for subclasses.
Similar to <code>goog.inherits</code>, but uses a hash of prototype properties and
class properties to be extended.</p>
@@ -4763,15 +4799,15 @@ class properties to be extended.</p>
</li>
<li id="section-249">
<li id="section-251">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-249">&#182;</a>
<a class="pilcrow" href="#section-251">&#182;</a>
</div>
<p>The constructor function for the new subclass is either defined by you
(the “constructor” property in your <code>extend</code> definition), or defaulted
by us to simply call the parents constructor.</p>
by us to simply call the parent constructor.</p>
</div>
@@ -4784,11 +4820,11 @@ by us to simply call the parents constructor.</p>
</li>
<li id="section-250">
<li id="section-252">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-250">&#182;</a>
<a class="pilcrow" href="#section-252">&#182;</a>
</div>
<p>Add static properties to the constructor function, if supplied.</p>
@@ -4799,14 +4835,14 @@ by us to simply call the parents constructor.</p>
</li>
<li id="section-251">
<li id="section-253">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-251">&#182;</a>
<a class="pilcrow" href="#section-253">&#182;</a>
</div>
<p>Set the prototype chain to inherit from <code>parent</code>, without calling
<code>parent</code>s constructor function.</p>
<code>parent</code> constructor function.</p>
</div>
@@ -4817,11 +4853,11 @@ by us to simply call the parents constructor.</p>
</li>
<li id="section-252">
<li id="section-254">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-252">&#182;</a>
<a class="pilcrow" href="#section-254">&#182;</a>
</div>
<p>Add prototype properties (instance properties) to the subclass,
if supplied.</p>
@@ -4833,11 +4869,11 @@ if supplied.</p>
</li>
<li id="section-253">
<li id="section-255">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-253">&#182;</a>
<a class="pilcrow" href="#section-255">&#182;</a>
</div>
<p>Set a convenience property in case the parents prototype is needed
later.</p>
@@ -4852,11 +4888,11 @@ later.</p>
</li>
<li id="section-254">
<li id="section-256">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-254">&#182;</a>
<a class="pilcrow" href="#section-256">&#182;</a>
</div>
<p>Set up inheritance for the model, collection, router, view and history.</p>
@@ -4867,11 +4903,11 @@ later.</p>
</li>
<li id="section-255">
<li id="section-257">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-255">&#182;</a>
<a class="pilcrow" href="#section-257">&#182;</a>
</div>
<p>Throw an error when a URL is needed, and none is supplied.</p>
@@ -4884,11 +4920,11 @@ later.</p>
</li>
<li id="section-256">
<li id="section-258">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-256">&#182;</a>
<a class="pilcrow" href="#section-258">&#182;</a>
</div>
<p>Wrap an optional error callback with a fallback error event.</p>

View File

@@ -50,7 +50,7 @@
</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>
<a href="backbone.localstorage.html">LocalStorage adapter</a>
to persist Backbone models within your browser.</p>
</div>

View File

@@ -1,6 +1,6 @@
// An example Backbone application contributed by
// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses a simple
// [LocalStorage adapter](backbone-localstorage.html)
// [LocalStorage adapter](backbone.localstorage.html)
// to persist Backbone models within your browser.
// Load the application once the DOM is ready, using `jQuery.ready`:

View File

@@ -653,7 +653,7 @@
<p>
Many of the code examples in this documentation are runnable, because
Backbone is included on this page.
Backbone is included on this page.
Click the <i>play</i> button to execute them.
</p>
@@ -663,7 +663,7 @@
<p>
The single most important thing that Backbone can help you with is keeping
your business logic separate from your user interface. When the two are
your business logic separate from your user interface. When the two are
entangled, change is hard; when logic doesn't depend on UI, your
interface becomes easier to work with.
</p>
@@ -688,9 +688,9 @@
</div>
<p>
A <b>Model</b> manages an internal table of data attributes, and
triggers <tt>"change"</tt> events when any of its data is modified.
Models handle syncing data with a persistence layer — usually a REST API
A <b>Model</b> manages an internal table of data attributes, and
triggers <tt>"change"</tt> events when any of its data is modified.
Models handle syncing data with a persistence layer — usually a REST API
with a backing database. Design your models as the atomic reusable objects
containing all of the helpful functions for manipulating their particular
bit of data. Models should be able to be passed around throughout your app,
@@ -700,9 +700,9 @@
<p>
A <b>View</b> is an atomic chunk of user interface. It often renders the
data from a specific model, or number of models &mdash; but views can
also be data-less chunks of UI that stand alone.
also be data-less chunks of UI that stand alone.
Models should be generally unaware of views. Instead, views listen to
the model <tt>"change"</tt> events, and react or re-render themselves
the model <tt>"change"</tt> events, and react or re-render themselves
appropriately.
</p>
@@ -722,7 +722,7 @@
<h2 id="API-integration">API Integration</h2>
<p>
Backbone is pre-configured to sync with a RESTful API. Simply create a
Backbone is pre-configured to sync with a RESTful API. Simply create a
new Collection with the <tt>url</tt> of your resource endpoint:
</p>
@@ -733,7 +733,7 @@ var Books = Backbone.Collection.extend({
</pre>
<p>
The <b>Collection</b> and <b>Model</b> components together form a direct
The <b>Collection</b> and <b>Model</b> components together form a direct
mapping of REST resources using the following methods:
</p>
@@ -744,11 +744,11 @@ GET /books/1 ... model.fetch();
PUT /books/1 ... model.save();
DEL /books/1 ... model.destroy();
</pre>
<p>
When fetching raw JSON data from an API, a <b>Collection</b> will
automatically populate itself with data formatted as an array, while
a <b>Model</b> will automatically populate itself with data formatted
When fetching raw JSON data from an API, a <b>Collection</b> will
automatically populate itself with data formatted as an array, while
a <b>Model</b> will automatically populate itself with data formatted
as an object:
</p>
@@ -758,9 +758,9 @@ DEL /books/1 ... model.destroy();
</pre>
<p>
However, it's fairly common to encounter APIs that return data in a
different format than what Backbone expects. For example, consider
fetching a <b>Collection</b> from an API that returns the real data
However, it's fairly common to encounter APIs that return data in a
different format than what Backbone expects. For example, consider
fetching a <b>Collection</b> from an API that returns the real data
array wrapped in metadata:
</p>
@@ -772,14 +772,14 @@ DEL /books/1 ... model.destroy();
"books": [
{"id": 1, "title": "Pride and Prejudice"},
{"id": 4, "title": "The Great Gatsby"}
]
]
}
</pre>
<p>
In the above example data, a <b>Collection</b> should populate using the
<tt>"books"</tt> array rather than the root object structure. This
difference is easily reconciled using a <tt>parse</tt> method that
In the above example data, a <b>Collection</b> should populate using the
<tt>"books"</tt> array rather than the root object structure. This
difference is easily reconciled using a <tt>parse</tt> method that
returns (or transforms) the desired portion of API data:
</p>
@@ -797,20 +797,20 @@ var Books = Backbone.Collection.extend({
<img class="figure" src="docs/images/intro-views.svg" alt="View rendering.">
<p>
Each <b>View</b> manages the rendering and user interaction within its own
DOM element. If you're strict about not allowing views to reach outside
of themselves, it helps keep your interface flexible &mdash; allowing
Each <b>View</b> manages the rendering and user interaction within its own
DOM element. If you're strict about not allowing views to reach outside
of themselves, it helps keep your interface flexible &mdash; allowing
views to be rendered in isolation in any place where they might be needed.
</p>
<p>
Backbone remains unopinionated about the process used to render <b>View</b>
objects and their subviews into UI: you define how your models get translated
into HTML (or SVG, or Canvas, or something even more exotic).
It could be as prosaic as a simple
Backbone remains unopinionated about the process used to render <b>View</b>
objects and their subviews into UI: you define how your models get translated
into HTML (or SVG, or Canvas, or something even more exotic).
It could be as prosaic as a simple
<a href="http://underscorejs.org/#template">Underscore template</a>, or as fancy as the
<a href="http://facebook.github.io/react/docs/tutorial.html">React virtual DOM</a>.
Some basic approaches to rendering views can be found
Some basic approaches to rendering views can be found
in the <a href="https://github.com/jashkenas/backbone/wiki/Backbone%2C-The-Primer">Backbone primer</a>.
</p>
@@ -819,12 +819,12 @@ var Books = Backbone.Collection.extend({
<img class="figure" src="docs/images/intro-routing.svg" alt="Routing">
<p>
In rich web applications, we still want to provide linkable,
bookmarkable, and shareable URLs to meaningful locations within an app.
In rich web applications, we still want to provide linkable,
bookmarkable, and shareable URLs to meaningful locations within an app.
Use the <b>Router</b> to update the browser URL whenever the user
reaches a new "place" in your app that they might want to bookmark or share.
Conversely, the <b>Router</b> detects changes to the URL &mdash; say,
pressing the "Back" button &mdash; and can tell your application exactly where you
Conversely, the <b>Router</b> detects changes to the URL &mdash; say,
pressing the "Back" button &mdash; and can tell your application exactly where you
are now.
</p>
@@ -945,6 +945,8 @@ object.off();
<br />
Just like <a href="#Events-on">on</a>, but causes the bound callback to fire
only once before being removed. Handy for saying "the next time that X happens, do this".
When multiple events are passed in using the space separated syntax, the event will fire once
for every event you passed in, not once for a combination of all events
</p>
<p id="Events-listenTo">
@@ -1294,7 +1296,7 @@ alert("Cake id: " + cake.id);
<b class="header">changed</b><code>model.changed</code>
<br />
The <b>changed</b> property is the internal hash containing all the attributes
that have changed since the last <a href="#Model-set">set</a>.
that have changed since its last <a href="#Model-set">set</a>.
Please do not update <b>changed</b> directly since its state is internally maintained
by <a href="#Model-set">set</a>. A copy of <b>changed</b> can be acquired from
<a href="#Model-changedAttributes">changedAttributes</a>.
@@ -1652,7 +1654,7 @@ ActiveRecord::Base.include_root_in_json = false
<p id="Model-hasChanged">
<b class="header">hasChanged</b><code>model.hasChanged([attribute])</code>
<br />
Has the model changed since the last <a href="#Model-set">set</a>? If an <b>attribute</b>
Has the model changed since its last <a href="#Model-set">set</a>? If an <b>attribute</b>
is passed, returns <tt>true</tt> if that specific attribute has changed.
</p>
@@ -2303,7 +2305,7 @@ var othello = nypl.create({
<p>
During page load, after your application has finished creating all of its routers,
be sure to call <tt>Backbone.history.start()</tt>, or
be sure to call <tt>Backbone.history.start()</tt> or
<tt>Backbone.history.start({pushState: true})</tt> to route the initial URL.
</p>
@@ -2992,7 +2994,7 @@ var model = localBackbone.Model.extend(...);
</p>
<pre>
var Backbone.$ = require('jquery');
Backbone.$ = require('jquery');
</pre>
<h2 id="faq">F.A.Q.</h2>

View File

@@ -9,10 +9,11 @@
},
"devDependencies": {
"coffee-script": "1.7.1",
"docco": "0.6.3",
"docco": "0.7.0",
"karma": "^0.12.31",
"karma-phantomjs-launcher": "^0.1.4",
"karma-qunit": "^0.1.4"
"karma-qunit": "^0.1.4",
"uglify-js": "^2.4.17"
},
"main": "backbone.js",
"scripts": {
@@ -32,3 +33,4 @@
"backbone.js", "backbone-min.js", "backbone-min.map", "LICENSE"
]
}

View File

@@ -932,4 +932,67 @@
Backbone.history.start({root: '/root', pushState: true});
});
test("Paths that don't match the root should not match no root", 0, function() {
location.replace('http://example.com/foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({
routes: {
foo: function(){
ok(false, 'should not match unless root matches');
}
}
});
var router = new Router;
Backbone.history.start({root: 'root', pushState: true});
});
test("Paths that don't match the root should not match roots of the same length", 0, function() {
location.replace('http://example.com/xxxx/foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({
routes: {
foo: function(){
ok(false, 'should not match unless root matches');
}
}
});
var router = new Router;
Backbone.history.start({root: 'root', pushState: true});
});
test("roots with regex characters", 1, function() {
location.replace('http://example.com/x+y.z/foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({
routes: {foo: function(){ ok(true); }}
});
var router = new Router;
Backbone.history.start({root: 'x+y.z', pushState: true});
});
test("roots with unicode characters", 1, function() {
location.replace('http://example.com/®ooτ/foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({
routes: {foo: function(){ ok(true); }}
});
var router = new Router;
Backbone.history.start({root: '®ooτ', pushState: true});
});
test("roots without slash", 1, function() {
location.replace('http://example.com/®ooτ');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({
routes: {'': function(){ ok(true); }}
});
var router = new Router;
Backbone.history.start({root: '®ooτ', pushState: true});
});
})();