Backbone.js 1.0

This commit is contained in:
Jeremy Ashkenas
2013-03-20 20:13:55 +08:00
parent 9414b9a7c3
commit 699fe32712
9 changed files with 5018 additions and 2727 deletions

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

@@ -1,4 +1,4 @@
// Backbone.js 0.9.10
// Backbone.js 1.0.0
// (c) 2010-2013 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license.
@@ -34,7 +34,7 @@
}
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '0.9.10';
Backbone.VERSION = '1.0.0';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
@@ -1174,7 +1174,8 @@
// If we're sending a `PATCH` request, and we're in an old Internet Explorer
// that still has ActiveX enabled by default, override jQuery to use that
// for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
if (params.type === 'PATCH' && window.ActiveXObject) {
if (params.type === 'PATCH' && window.ActiveXObject &&
!(window.external && window.external.msActiveXFilteringEnabled)) {
params.xhr = function() {
return new ActiveXObject("Microsoft.XMLHTTP");
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,458 @@
<!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 &hellip;</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">&#182;</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> &amp;&amp; define.amd) {</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</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">&#182;</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">&#182;</a>
</div>
<p>RequireJS isn&#39;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">&#182;</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">&#182;</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">&#182;</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&#39;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 &amp;&amp; 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">&#182;</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">&#182;</a>
</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>
<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">&#182;</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">&#182;</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">&#182;</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">&#182;</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">&#182;</a>
</div>
<p>fix for &quot;illegal access&quot; 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 &amp;&amp; JSON.parse(data);
}
});</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</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>
<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 &amp;&amp; $.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 &amp;&amp; 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 &amp;&amp; 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 &amp;&amp; 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">&#182;</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 &amp;&amp; options.complete) options.complete(resp);
<span class="keyword">return</span> syncDfd &amp;&amp; syncDfd.promise();
};
Backbone.ajaxSync = Backbone.sync;
Backbone.getSyncMethod = <span class="keyword">function</span>(model) {
<span class="keyword">if</span>(model.localStorage || (model.collection &amp;&amp; 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">&#182;</a>
</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>
<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>

View File

@@ -30,135 +30,93 @@
font-style: normal;
}
@font-face {
font-family: 'fleurons';
src: url('public/fonts/fleurons.eot');
src: url('public/fonts/fleurons.eot?#iefix') format('embedded-opentype'),
url('public/fonts/fleurons.woff') format('woff'),
url('public/fonts/fleurons.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
/*--------------------- Base Styles ----------------------------*/
/*--------------------- Layout ----------------------------*/
html { height: 100%; }
body {
font-family: "aller-light";
background: url(public/images/grey_@2x.png);
background-size: 322px;
margin: 0;
font-size: 14px;
line-height: 18px;
color: #30404f;
margin: 0; padding: 0;
height:100%;
}
hr {
height: 1px;
background: #ddd;
border: 0;
}
h1, h2, h3, h4, h5, h6 {
color: #112233;
font-weight: normal;
font-family: "novecento-bold";
text-transform: uppercase;
line-height: 1em;
margin-top: 50px;
}
h1 {
margin: 0;
text-align: center;
}
h2 {
font-size: 1.3em;
}
h1:after {
content: "8";
display: block;
font-family: "fleurons";
color: #999;
font-size: 80px;
padding: 10px 0 25px;
}
#container { min-height: 100%; }
a {
text-decoration: none;
color: #000;
}
a:hover {
text-decoration: underline;
}
b, strong {
font-weight: normal;
font-family: "aller-bold";
}
blockquote {
border-left: 5px solid #ccc;
margin-left: 0;
padding: 1px 0 1px 1em;
p {
margin: 15px 0 0px;
}
.page blockquote p {
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 14px; line-height: 19px;
color: #999;
margin: 10px 0;
.annotation ul, .annotation ol {
margin: 25px 0;
}
.annotation ul li, .annotation ol li {
font-size: 14px;
line-height: 18px;
margin: 10px 0;
}
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-family: Menlo, Consolas, Monaco, monospace;
font-size: 12px;
display: inline-block;
border: 1px solid #EAEAEA;
background: #f8f8f8;
color: #555;
padding: 0 5px;
line-height: 20px;
font-size: 12px; line-height: 16px;
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
.page pre {
.annotation pre {
display: block;
margin: 0;
width: 608px;
padding: 10px 15px;
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: scroll;
overflow-x: auto;
}
.page pre code {
.annotation pre code {
border: 0;
padding: 0;
background: transparent;
}
.fleur {
font-family: "fleurons";
font-size: 100px;
text-align: center;
margin: 40px 0;
color: #ccc;
}
/*--------------------- Layout ----------------------------*/
.container {
width: 760px;
margin: 0 auto;
background: #fff;
background: rgba(255,255,255, 0.4);
overflow: hidden;
blockquote {
border-left: 5px solid #ccc;
margin: 0;
padding: 1px 0 1px 1em;
}
.page {
width: 640px;
padding: 30px;
margin: 30px;
background: #fff;
font-size: 17px;
line-height: 26px;
.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;
}
.page p {
color: #30404f;
margin: 26px 0;
}
ul.sections {
list-style: none;
@@ -166,102 +124,385 @@ ul.sections {
margin:0;
}
.page li p {
margin: 12px 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 */
}
.toc {
max-height: 0;
overflow: hidden;
text-align: center;
font-size: 13px;
line-height: 20px;
-moz-transition: max-height 1s;
-webkit-transition: max-height 1s;
transition: max-height 1s;
/*---------------------- 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;
}
.header:hover .toc {
max-height: 500px;
#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;
}
.toc h3 {
margin-top: 20px;
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 30px;
}
.toc ol {
margin: 0 0 20px 0;
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;
text-align: left;
list-style-type: upper-roman;
}
.toc li {
font-family: 'novecento-bold';
}
.toc li a {
font-family: 'aller-light';
}
#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; }
body .hll { background-color: #ffffcc }
body .c { color: #408080; font-style: italic } /* Comment */
body .err { border: 1px solid #FF0000 } /* Error */
body .k { color: #954121 } /* Keyword */
body .o { color: #666666 } /* Operator */
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
body .cp { color: #BC7A00 } /* Comment.Preproc */
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
body .cs { color: #408080; font-style: italic } /* Comment.Special */
body .gd { color: #A00000 } /* Generic.Deleted */
body .ge { font-style: italic } /* Generic.Emph */
body .gr { color: #FF0000 } /* Generic.Error */
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
body .gi { color: #00A000 } /* Generic.Inserted */
body .go { color: #808080 } /* Generic.Output */
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
body .gs { font-weight: bold } /* Generic.Strong */
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
body .gt { color: #0040D0 } /* Generic.Traceback */
body .kc { color: #954121 } /* Keyword.Constant */
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
body .kp { color: #954121 } /* Keyword.Pseudo */
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
body .kt { color: #B00040 } /* Keyword.Type */
body .m { color: #666666 } /* Literal.Number */
body .s { color: #219161 } /* Literal.String */
body .na { color: #7D9029 } /* Name.Attribute */
body .nb { color: #954121 } /* Name.Builtin */
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
body .no { color: #880000 } /* Name.Constant */
body .nd { color: #AA22FF } /* Name.Decorator */
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
body .nf { color: #0000FF } /* Name.Function */
body .nl { color: #A0A000 } /* Name.Label */
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
body .nv { color: #19469D } /* Name.Variable */
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
body .w { color: #bbbbbb } /* Text.Whitespace */
body .mf { color: #666666 } /* Literal.Number.Float */
body .mh { color: #666666 } /* Literal.Number.Hex */
body .mi { color: #666666 } /* Literal.Number.Integer */
body .mo { color: #666666 } /* Literal.Number.Oct */
body .sb { color: #219161 } /* Literal.String.Backtick */
body .sc { color: #219161 } /* Literal.String.Char */
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
body .s2 { color: #219161 } /* Literal.String.Double */
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
body .sh { color: #219161 } /* Literal.String.Heredoc */
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
body .sx { color: #954121 } /* Literal.String.Other */
body .sr { color: #BB6688 } /* Literal.String.Regex */
body .s1 { color: #219161 } /* Literal.String.Single */
body .ss { color: #19469D } /* Literal.String.Symbol */
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
body .vc { color: #19469D } /* Name.Variable.Class */
body .vg { color: #19469D } /* Name.Variable.Global */
body .vi { color: #19469D } /* Name.Variable.Instance */
body .il { color: #666666 } /* Literal.Number.Integer.Long */
/*
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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -266,6 +266,7 @@
padding-bottom: 25px;
}
td.text {
line-height: 12px;
padding: 0;
position: absolute;
left: 0;
@@ -285,7 +286,7 @@
<div id="sidebar" class="interface">
<a class="toc_title" href="#">
Backbone.js <span class="version">(0.9.10)</span>
Backbone.js <span class="version">(1.0.0)</span>
</a>
<ul class="toc_section">
<li>&raquo; <a href="http://github.com/documentcloud/backbone">GitHub Repository</a></li>
@@ -310,6 +311,7 @@
<li> <a href="#Events-once">once</a></li>
<li> <a href="#Events-listenTo">listenTo</a></li>
<li> <a href="#Events-stopListening">stopListening</a></li>
<li> <a href="#Events-listenToOnce">listenToOnce</a></li>
<li>- <a href="#Events-catalog"><b>Catalog of Built-in Events</b></a></li>
</ul>
@@ -336,6 +338,7 @@
<li> <a href="#Model-fetch">fetch</a></li>
<li> <a href="#Model-save">save</a></li>
<li> <a href="#Model-destroy">destroy</a></li>
<li> <a href="#Model-Underscore-Methods"><b>Underscore Methods (6)</b></a></li>
<li> <a href="#Model-validate">validate</a></li>
<li> <a href="#Model-validationError">validationError</a></li>
<li> <a href="#Model-isValid">isValid</a></li>
@@ -364,7 +367,7 @@
<li> <a href="#Collection-add">add</a></li>
<li> <a href="#Collection-remove">remove</a></li>
<li> <a href="#Collection-reset">reset</a></li>
<li> <a href="#Collection-update">update</a></li>
<li> <a href="#Collection-set">set</a></li>
<li> <a href="#Collection-get">get</a></li>
<li> <a href="#Collection-at">at</a></li>
<li> <a href="#Collection-push">push</a></li>
@@ -377,6 +380,7 @@
<li> <a href="#Collection-sort">sort</a></li>
<li> <a href="#Collection-pluck">pluck</a></li>
<li> <a href="#Collection-where">where</a></li>
<li> <a href="#Collection-findWhere">findWhere</a></li>
<li> <a href="#Collection-url">url</a></li>
<li> <a href="#Collection-parse">parse</a></li>
<li> <a href="#Collection-clone">clone</a></li>
@@ -553,12 +557,15 @@
<table>
<tr>
<td><a class="punch" href="backbone.js">Development Version (0.9.10)</a></td>
<td class="text"><i>56kb, Full source, lots of comments</i></td>
<td><a class="punch" href="backbone.js">Development Version (1.0.0)</a></td>
<td class="text"><i>58kb, Full source, tons of comments</i></td>
</tr>
<tr>
<td><a class="punch" href="backbone-min.js">Production Version (0.9.10)</a></td>
<td class="text"><i>6.3kb, Packed and gzipped</i></td>
<td><a class="punch" href="backbone-min.js">Production Version (1.0.0)</a></td>
<td class="text" style="line-height: 16px;">
<i>7.1kb, Packed and gzipped</i><br />
<small>(<a href="backbone-min.map">Source Map</a>)</small>
</td>
</tr>
<tr>
<td><a class="punch" href="https://raw.github.com/documentcloud/backbone/master/backbone.js">Edge Version (master)</a></td>
@@ -572,9 +579,8 @@
</table>
<p>
Backbone's only hard dependency is either
<a href="http://underscorejs.org/">Underscore.js</a> <small>( >= 1.4.3)</small> or
<a href="http://lodash.com">Lo-Dash</a>.
Backbone's only hard dependency is
<a href="http://underscorejs.org/">Underscore.js</a> <small>( >= 1.4.3)</small>.
For RESTful persistence, history support via <a href="#Router">Backbone.Router</a>
and DOM manipulation with <a href="#View">Backbone.View</a>, include
<a href="https://github.com/douglascrockford/JSON-js">json2.js</a>, and either
@@ -617,60 +623,42 @@
to execute them.
</p>
<h2 id="upgrading">Upgrading to 0.9.10</h2>
<h2 id="upgrading">Upgrading to 1.0</h2>
<p>
Backbone <b>0.9.10</b> should be considered as a release candidate
for an upcoming <b>1.0</b>. If you're upgrading from a previous version,
be sure to check the
<a href="#changelog">change log</a>. In brief, a few of the larger changes
are:
Backbone <b>1.0</b> should be a fairly painless upgrade from the <b>0.9</b>
series. If you're upgrading from an older version, be sure to check out the
<a href="#changelog">change log</a>. In brief, a few of the larger breaking
changes are:
</p>
<ul>
<li>
Most importantly, Backbone events have two new methods:
If you want to smartly update the contents of a Collection,
adding new models, removing missing ones, and merging those already present,
you now call <a href="#Collection-set">set</a> (previously named "update"),
a similar operation to calling <tt>set</tt> on a Model. This is now the
default when you call <a href="#Collection-fetch">fetch</a> on a collection.
To get the old behavior, pass <tt>{reset: true}</tt>.
</li>
<li>
If you have characters in your URL segments that require URL encoding,
Backbone will now decode them for you (normalizing the behavior
cross-browser) before your route handlers receive them as arguments.
</li>
<li>
In <b>0.9.x</b>, Backbone events gained two new methods:
<a href="#Events-listenTo">listenTo</a> and
<a href="#Events-stopListening">stopListening</a>. These are an
inversion-of-control flavor of the usual <tt>on</tt> and <tt>off</tt>,
and make it a little easier to clean up <i>all</i> events
that an object is listening to on other objects. When you destroy Views
with <a href="#View-remove">view.remove()</a>, this will now be done
automatically. Note that the usual rules about programming in a garbage
collected language still apply.
</li>
<li>
HTTP <tt>PATCH</tt> support, via <tt>model.save(attrs, {patch: true})</tt>,
if you'd like to send only partial updates to the server.
</li>
<li>
An <a href="#Collection-update">update</a> method was added to Collection,
which should make it easier to perform "smart" syncing updates with the
server, where models are added or removed, and updated attributes are merged
as appropriate. If you were previously using <br />
<tt>collection.fetch({add: true})</tt>,
try <a href="#Collection-update">update</a> instead.
</li>
<li>
Backbone events now support <a href="#Events-once">once</a>.
<a href="#Events-stopListening">stopListening</a>, which make it easier
to create Views that have all of their observers unbound when you
want to <a href="#View-remove">remove</a> the view.
</li>
<li>
Model validation is now only enforced by default in
<tt>Model#save</tt> and no longer enforced by default upon
construction or in <tt>Model#set</tt>, unless the <tt>{validate:true}</tt>
option is passed.
</li>
<li>
Passing <tt>{silent:true}</tt> on change will no longer delay individual
<tt>"change:attr"</tt> events, instead they are silenced entirely.
</li>
<li>
The <tt>Model#change</tt> method has been removed, as delayed attribute
changes are no longer available.
</li>
<li>
Model validation now fires <tt>invalid</tt> event instead of
<tt>error</tt>.
<a href="#Model-save">save</a> &mdash; not in
<a href="#Model-set">set</a> unless the <tt>{validate:true}</tt>
option is passed. Model validation now fires an <tt>"invalid"</tt> event instead of
<tt>"error"</tt>.
</li>
</ul>
@@ -822,6 +810,13 @@ view.stopListening();
view.stopListening(model);
</pre>
<p id="Events-listenToOnce">
<b class="header">listenToOnce</b><code>object.listenToOnce(other, event, callback)</code>
<br />
Just like <a href="#Events-listenTo">listenTo</a>, but causes the bound
callback to only fire once before being removed.
</p>
<p id="Events-catalog">
<b class="header">Catalog of Events</b>
<br />
@@ -1292,6 +1287,29 @@ book.save("author", "F.D.R.", {error: function(){ ... }});
book.destroy({success: function(model, response) {
...
}});
</pre>
<p id="Model-Underscore-Methods">
<b class="header">Underscore Methods (6)</b>
<br />
Backbone proxies to <b>Underscore.js</b> to provide 6 object functions
on <b>Backbone.Model</b>. They aren't all documented here, but
you can take a look at the Underscore documentation for the full details&hellip;
</p>
<ul class="small">
<li><a href="http://underscorejs.org/#keys">keys</a></li>
<li><a href="http://underscorejs.org/#values">values</a></li>
<li><a href="http://underscorejs.org/#pairs">pairs</a></li>
<li><a href="http://underscorejs.org/#invert">invert</a></li>
<li><a href="http://underscorejs.org/#pick">pick</a></li>
<li><a href="http://underscorejs.org/#omit">omit</a></li>
</ul>
<pre>
user.pick('first_name', 'last_name', 'email');
chapters.keys().join(', ');
</pre>
<p id="Model-validate">
@@ -1384,7 +1402,8 @@ if (!one.isValid()) {
the server. If your models are located somewhere else, override this method
with the correct logic. Generates URLs of the form: <tt>"[collection.url]/[id]"</tt>
by default, but you may override by specifying an explicit <tt>urlRoot</tt>
if the model's collection shouldn't be taken into account.
if the model's collection shouldn't be taken into account. You can also
pass in the model's <tt>url</tt> as an option when instantiating it.
</p>
<p>
@@ -1752,10 +1771,10 @@ ships.add([
will empty the entire collection.
</p>
<p id="Collection-update">
<b class="header">update</b><code>collection.update(models, [options])</code>
<p id="Collection-set">
<b class="header">set</b><code>collection.set(models, [options])</code>
<br />
The <b>update</b> method tries to peform a "smart" update of the collection
The <b>set</b> method tries to peform a "smart" update of the collection
with the passed list of models. If a model in the list isn't yet in the
collection it will be added; if the model is already in the collection
its attributes will be merged; and if the collection contains any models that
@@ -1938,6 +1957,13 @@ var musketeers = friends.where({job: "Musketeer"});
alert(musketeers.length);
</pre>
<p id="Collection-findWhere">
<b class="header">findWhere</b><code>collection.findWhere(attributes)</code>
<br />
Just like <a href="#Collection-where">where</a>, but directly returns only
the first model in the collection that matches the passed <b>attributes</b>.
</p>
<p id="Collection-url">
<b class="header">url</b><code>collection.url or collection.url()</code>
<br />
@@ -2127,7 +2153,8 @@ var Workspace = Backbone.Router.extend({
<p id="Router-routes">
<b class="header">routes</b><code>router.routes</code>
<br />
The routes hash maps URLs with parameters to functions on your router,
The routes hash maps URLs with parameters to functions on your router
(or just direct function definitions, if you prefer),
similar to the <a href="#View">View</a>'s <a href="#View-delegateEvents">events hash</a>.
Routes can contain parameter parts, <tt>:param</tt>, which match a single URL
component between slashes; and splat parts <tt>*splat</tt>, which can match
@@ -3895,6 +3922,40 @@ ActiveRecord::Base.include_root_in_json = false
<h2 id="changelog">Change Log</h2>
<b class="header">1.0.0</b> &mdash; <small><i>March 20, 2013</i></small> &mdash; <a href="https://github.com/documentcloud/backbone/compare/0.9.10...1.0.0">Diff</a><br />
<ul style="margin-top: 5px;">
<li>
Renamed Collection's "update" to <a href="#Collection-set">set</a>, for
parallelism with the similar <tt>model.set()</tt>, and contrast with
<a href="#Collection-reset">reset</a>. It's now the default
updating mechanism after a <a href="#Collection-fetch">fetch</a>. If you'd
like to continue using "reset", pass <tt>{reset: true}</tt>.
</li>
<li>
Your route handlers will now receive their URL parameters pre-decoded.
</li>
<li>
Added <a href="#Events-listenToOnce">listenToOnce</a> as the analogue of
<a href="#Events-once">once</a>.
</li>
<li>
Added the <a href="#Collection-findWhere">findWhere</a> method to Collections,
similar to <a href="#Collection-where">where</a>.
</li>
<li>
Added the <tt>keys</tt>, <tt>values</tt>, <tt>pairs</tt>, <tt>invert</tt>,
<tt>pick</tt>, and <tt>omit</tt> Underscore.js methods to Backbone Models.
</li>
<li>
The routes in a Router's route map may now be function literals,
instead of references to methods, if you like.
</li>
<li>
<tt>url</tt> and <tt>urlRoot</tt> properties may now be passed as options
when instantiating a new Model.
</li>
</ul>
<b class="header">0.9.10</b> &mdash; <small><i>Jan. 15, 2013</i></small> &mdash; <a href="https://github.com/documentcloud/backbone/compare/0.9.9...0.9.10">Diff</a><br />
<ul style="margin-top: 5px;">
<li>

View File

@@ -16,5 +16,5 @@
"test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true && coffee test/model.coffee"
},
"main" : "backbone.js",
"version" : "0.9.10"
"version" : "1.0.0"
}