Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
todomvc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eugene Shen
todomvc
Commits
f57e0b77
Commit
f57e0b77
authored
Feb 17, 2014
by
Bo-Yi Wu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
upgrade backbone to 1.1.1 and underscore to 1.6.0
Signed-off-by:
Bo-Yi Wu
<
appleboy.tw@gmail.com
>
parent
55c44717
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
247 additions
and
152 deletions
+247
-152
architecture-examples/backbone/bower.json
architecture-examples/backbone/bower.json
+2
-2
architecture-examples/backbone/bower_components/backbone/backbone.js
...e-examples/backbone/bower_components/backbone/backbone.js
+95
-67
architecture-examples/backbone/bower_components/underscore/underscore.js
...amples/backbone/bower_components/underscore/underscore.js
+150
-83
No files found.
architecture-examples/backbone/bower.json
View file @
f57e0b77
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
"name"
:
"todomvc-backbone"
,
"name"
:
"todomvc-backbone"
,
"version"
:
"0.0.0"
,
"version"
:
"0.0.0"
,
"dependencies"
:
{
"dependencies"
:
{
"backbone"
:
"~1.1.
0
"
,
"backbone"
:
"~1.1.
1
"
,
"underscore"
:
"~1.
5
.0"
,
"underscore"
:
"~1.
6
.0"
,
"jquery"
:
"~2.0.0"
,
"jquery"
:
"~2.0.0"
,
"todomvc-common"
:
"~0.1.4"
,
"todomvc-common"
:
"~0.1.4"
,
"backbone.localStorage"
:
"~1.1.0"
"backbone.localStorage"
:
"~1.1.0"
...
...
architecture-examples/backbone/bower_components/backbone/backbone.js
View file @
f57e0b77
// Backbone.js 1.1.
0
// Backbone.js 1.1.
1
// (c) 2010-2011 Jeremy Ashkenas, DocumentCloud Inc.
// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Backbone may be freely distributed under the MIT license.
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// For all details and documentation:
// http://backbonejs.org
// http://backbonejs.org
(
function
(){
(
function
(
root
,
factory
)
{
// Set up Backbone appropriately for the environment. Start with AMD.
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
define
([
'
underscore
'
,
'
jquery
'
,
'
exports
'
],
function
(
_
,
$
,
exports
)
{
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backbone.
root
.
Backbone
=
factory
(
root
,
exports
,
_
,
$
);
});
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
}
else
if
(
typeof
exports
!==
'
undefined
'
)
{
var
_
=
require
(
'
underscore
'
),
$
;
try
{
$
=
require
(
'
jquery
'
);
}
catch
(
e
)
{}
factory
(
root
,
exports
,
_
,
$
);
// Finally, as a browser global.
}
else
{
root
.
Backbone
=
factory
(
root
,
{},
root
.
_
,
(
root
.
jQuery
||
root
.
Zepto
||
root
.
ender
||
root
.
$
));
}
}(
this
,
function
(
root
,
Backbone
,
_
,
$
)
{
// Initial Setup
// Initial Setup
// -------------
// -------------
// Save a reference to the global object (`window` in the browser, `exports`
// on the server).
var
root
=
this
;
// Save the previous value of the `Backbone` variable, so that it can be
// Save the previous value of the `Backbone` variable, so that it can be
// restored later on, if `noConflict` is used.
// restored later on, if `noConflict` is used.
var
previousBackbone
=
root
.
Backbone
;
var
previousBackbone
=
root
.
Backbone
;
...
@@ -25,25 +41,12 @@
...
@@ -25,25 +41,12 @@
var
slice
=
array
.
slice
;
var
slice
=
array
.
slice
;
var
splice
=
array
.
splice
;
var
splice
=
array
.
splice
;
// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both the browser and the server.
var
Backbone
;
if
(
typeof
exports
!==
'
undefined
'
)
{
Backbone
=
exports
;
}
else
{
Backbone
=
root
.
Backbone
=
{};
}
// Current version of the library. Keep in sync with `package.json`.
// Current version of the library. Keep in sync with `package.json`.
Backbone
.
VERSION
=
'
1.1.0
'
;
Backbone
.
VERSION
=
'
1.1.1
'
;
// Require Underscore, if we're on the server, and it's not already present.
var
_
=
root
.
_
;
if
(
!
_
&&
(
typeof
require
!==
'
undefined
'
))
_
=
require
(
'
underscore
'
);
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// the `$` variable.
// the `$` variable.
Backbone
.
$
=
root
.
jQuery
||
root
.
Zepto
||
root
.
ender
||
root
.
$
;
Backbone
.
$
=
$
;
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
// to its previous owner. Returns a reference to this Backbone object.
...
@@ -109,7 +112,7 @@
...
@@ -109,7 +112,7 @@
var
retain
,
ev
,
events
,
names
,
i
,
l
,
j
,
k
;
var
retain
,
ev
,
events
,
names
,
i
,
l
,
j
,
k
;
if
(
!
this
.
_events
||
!
eventsApi
(
this
,
'
off
'
,
name
,
[
callback
,
context
]))
return
this
;
if
(
!
this
.
_events
||
!
eventsApi
(
this
,
'
off
'
,
name
,
[
callback
,
context
]))
return
this
;
if
(
!
name
&&
!
callback
&&
!
context
)
{
if
(
!
name
&&
!
callback
&&
!
context
)
{
this
.
_events
=
{}
;
this
.
_events
=
void
0
;
return
this
;
return
this
;
}
}
names
=
name
?
[
name
]
:
_
.
keys
(
this
.
_events
);
names
=
name
?
[
name
]
:
_
.
keys
(
this
.
_events
);
...
@@ -205,7 +208,7 @@
...
@@ -205,7 +208,7 @@
case
1
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
call
(
ev
.
ctx
,
a1
);
return
;
case
1
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
call
(
ev
.
ctx
,
a1
);
return
;
case
2
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
call
(
ev
.
ctx
,
a1
,
a2
);
return
;
case
2
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
call
(
ev
.
ctx
,
a1
,
a2
);
return
;
case
3
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
call
(
ev
.
ctx
,
a1
,
a2
,
a3
);
return
;
case
3
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
call
(
ev
.
ctx
,
a1
,
a2
,
a3
);
return
;
default
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
apply
(
ev
.
ctx
,
args
);
default
:
while
(
++
i
<
l
)
(
ev
=
events
[
i
]).
callback
.
apply
(
ev
.
ctx
,
args
);
return
;
}
}
};
};
...
@@ -350,7 +353,7 @@
...
@@ -350,7 +353,7 @@
// Trigger all relevant attribute changes.
// Trigger all relevant attribute changes.
if
(
!
silent
)
{
if
(
!
silent
)
{
if
(
changes
.
length
)
this
.
_pending
=
true
;
if
(
changes
.
length
)
this
.
_pending
=
options
;
for
(
var
i
=
0
,
l
=
changes
.
length
;
i
<
l
;
i
++
)
{
for
(
var
i
=
0
,
l
=
changes
.
length
;
i
<
l
;
i
++
)
{
this
.
trigger
(
'
change:
'
+
changes
[
i
],
this
,
current
[
changes
[
i
]],
options
);
this
.
trigger
(
'
change:
'
+
changes
[
i
],
this
,
current
[
changes
[
i
]],
options
);
}
}
...
@@ -361,6 +364,7 @@
...
@@ -361,6 +364,7 @@
if
(
changing
)
return
this
;
if
(
changing
)
return
this
;
if
(
!
silent
)
{
if
(
!
silent
)
{
while
(
this
.
_pending
)
{
while
(
this
.
_pending
)
{
options
=
this
.
_pending
;
this
.
_pending
=
false
;
this
.
_pending
=
false
;
this
.
trigger
(
'
change
'
,
this
,
options
);
this
.
trigger
(
'
change
'
,
this
,
options
);
}
}
...
@@ -528,9 +532,12 @@
...
@@ -528,9 +532,12 @@
// using Backbone's restful methods, override this to change the endpoint
// using Backbone's restful methods, override this to change the endpoint
// that will be called.
// that will be called.
url
:
function
()
{
url
:
function
()
{
var
base
=
_
.
result
(
this
,
'
urlRoot
'
)
||
_
.
result
(
this
.
collection
,
'
url
'
)
||
urlError
();
var
base
=
_
.
result
(
this
,
'
urlRoot
'
)
||
_
.
result
(
this
.
collection
,
'
url
'
)
||
urlError
();
if
(
this
.
isNew
())
return
base
;
if
(
this
.
isNew
())
return
base
;
return
base
+
(
base
.
charAt
(
base
.
length
-
1
)
===
'
/
'
?
''
:
'
/
'
)
+
encodeURIComponent
(
this
.
id
);
return
base
.
replace
(
/
([^\/])
$/
,
'
$1
/
'
)
+
encodeURIComponent
(
this
.
id
);
},
},
// **parse** converts a response into the hash of attributes to be `set` on
// **parse** converts a response into the hash of attributes to be `set` on
...
@@ -546,7 +553,7 @@
...
@@ -546,7 +553,7 @@
// A model is new if it has never been saved to the server, and lacks an id.
// A model is new if it has never been saved to the server, and lacks an id.
isNew
:
function
()
{
isNew
:
function
()
{
return
this
.
id
==
null
;
return
!
this
.
has
(
this
.
idAttribute
)
;
},
},
// Check if the model is currently in a valid state.
// Check if the model is currently in a valid state.
...
@@ -650,7 +657,7 @@
...
@@ -650,7 +657,7 @@
options
.
index
=
index
;
options
.
index
=
index
;
model
.
trigger
(
'
remove
'
,
model
,
this
,
options
);
model
.
trigger
(
'
remove
'
,
model
,
this
,
options
);
}
}
this
.
_removeReference
(
model
);
this
.
_removeReference
(
model
,
options
);
}
}
return
singular
?
models
[
0
]
:
models
;
return
singular
?
models
[
0
]
:
models
;
},
},
...
@@ -676,11 +683,11 @@
...
@@ -676,11 +683,11 @@
// Turn bare objects into model references, and prevent invalid models
// Turn bare objects into model references, and prevent invalid models
// from being added.
// from being added.
for
(
i
=
0
,
l
=
models
.
length
;
i
<
l
;
i
++
)
{
for
(
i
=
0
,
l
=
models
.
length
;
i
<
l
;
i
++
)
{
attrs
=
models
[
i
];
attrs
=
models
[
i
]
||
{}
;
if
(
attrs
instanceof
Model
)
{
if
(
attrs
instanceof
Model
)
{
id
=
model
=
attrs
;
id
=
model
=
attrs
;
}
else
{
}
else
{
id
=
attrs
[
targetModel
.
prototype
.
idAttribute
];
id
=
attrs
[
targetModel
.
prototype
.
idAttribute
||
'
id
'
];
}
}
// If a duplicate is found, prevent it from being added and
// If a duplicate is found, prevent it from being added and
...
@@ -700,14 +707,13 @@
...
@@ -700,14 +707,13 @@
model
=
models
[
i
]
=
this
.
_prepareModel
(
attrs
,
options
);
model
=
models
[
i
]
=
this
.
_prepareModel
(
attrs
,
options
);
if
(
!
model
)
continue
;
if
(
!
model
)
continue
;
toAdd
.
push
(
model
);
toAdd
.
push
(
model
);
this
.
_addReference
(
model
,
options
);
// Listen to added models' events, and index models for lookup by
// `id` and by `cid`.
model
.
on
(
'
all
'
,
this
.
_onModelEvent
,
this
);
this
.
_byId
[
model
.
cid
]
=
model
;
if
(
model
.
id
!=
null
)
this
.
_byId
[
model
.
id
]
=
model
;
}
}
if
(
order
)
order
.
push
(
existing
||
model
);
// Do not add multiple models with the same `id`.
model
=
existing
||
model
;
if
(
order
&&
(
model
.
isNew
()
||
!
modelMap
[
model
.
id
]))
order
.
push
(
model
);
modelMap
[
model
.
id
]
=
true
;
}
}
// Remove nonexistent models if appropriate.
// Remove nonexistent models if appropriate.
...
@@ -757,7 +763,7 @@
...
@@ -757,7 +763,7 @@
reset
:
function
(
models
,
options
)
{
reset
:
function
(
models
,
options
)
{
options
||
(
options
=
{});
options
||
(
options
=
{});
for
(
var
i
=
0
,
l
=
this
.
models
.
length
;
i
<
l
;
i
++
)
{
for
(
var
i
=
0
,
l
=
this
.
models
.
length
;
i
<
l
;
i
++
)
{
this
.
_removeReference
(
this
.
models
[
i
]);
this
.
_removeReference
(
this
.
models
[
i
]
,
options
);
}
}
options
.
previousModels
=
this
.
models
;
options
.
previousModels
=
this
.
models
;
this
.
_reset
();
this
.
_reset
();
...
@@ -798,7 +804,7 @@
...
@@ -798,7 +804,7 @@
// Get a model from the set by id.
// Get a model from the set by id.
get
:
function
(
obj
)
{
get
:
function
(
obj
)
{
if
(
obj
==
null
)
return
void
0
;
if
(
obj
==
null
)
return
void
0
;
return
this
.
_byId
[
obj
.
id
]
||
this
.
_byId
[
obj
.
cid
]
||
this
.
_byId
[
obj
];
return
this
.
_byId
[
obj
]
||
this
.
_byId
[
obj
.
id
]
||
this
.
_byId
[
obj
.
cid
];
},
},
// Get the model at the given index.
// Get the model at the given index.
...
@@ -874,7 +880,7 @@
...
@@ -874,7 +880,7 @@
if
(
!
options
.
wait
)
this
.
add
(
model
,
options
);
if
(
!
options
.
wait
)
this
.
add
(
model
,
options
);
var
collection
=
this
;
var
collection
=
this
;
var
success
=
options
.
success
;
var
success
=
options
.
success
;
options
.
success
=
function
(
model
,
resp
,
options
)
{
options
.
success
=
function
(
model
,
resp
)
{
if
(
options
.
wait
)
collection
.
add
(
model
,
options
);
if
(
options
.
wait
)
collection
.
add
(
model
,
options
);
if
(
success
)
success
(
model
,
resp
,
options
);
if
(
success
)
success
(
model
,
resp
,
options
);
};
};
...
@@ -904,10 +910,7 @@
...
@@ -904,10 +910,7 @@
// Prepare a hash of attributes (or other model) to be added to this
// Prepare a hash of attributes (or other model) to be added to this
// collection.
// collection.
_prepareModel
:
function
(
attrs
,
options
)
{
_prepareModel
:
function
(
attrs
,
options
)
{
if
(
attrs
instanceof
Model
)
{
if
(
attrs
instanceof
Model
)
return
attrs
;
if
(
!
attrs
.
collection
)
attrs
.
collection
=
this
;
return
attrs
;
}
options
=
options
?
_
.
clone
(
options
)
:
{};
options
=
options
?
_
.
clone
(
options
)
:
{};
options
.
collection
=
this
;
options
.
collection
=
this
;
var
model
=
new
this
.
model
(
attrs
,
options
);
var
model
=
new
this
.
model
(
attrs
,
options
);
...
@@ -916,8 +919,16 @@
...
@@ -916,8 +919,16 @@
return
false
;
return
false
;
},
},
// Internal method to create a model's ties to a collection.
_addReference
:
function
(
model
,
options
)
{
this
.
_byId
[
model
.
cid
]
=
model
;
if
(
model
.
id
!=
null
)
this
.
_byId
[
model
.
id
]
=
model
;
if
(
!
model
.
collection
)
model
.
collection
=
this
;
model
.
on
(
'
all
'
,
this
.
_onModelEvent
,
this
);
},
// Internal method to sever a model's ties to a collection.
// Internal method to sever a model's ties to a collection.
_removeReference
:
function
(
model
)
{
_removeReference
:
function
(
model
,
options
)
{
if
(
this
===
model
.
collection
)
delete
model
.
collection
;
if
(
this
===
model
.
collection
)
delete
model
.
collection
;
model
.
off
(
'
all
'
,
this
.
_onModelEvent
,
this
);
model
.
off
(
'
all
'
,
this
.
_onModelEvent
,
this
);
},
},
...
@@ -946,7 +957,7 @@
...
@@ -946,7 +957,7 @@
'
reject
'
,
'
every
'
,
'
all
'
,
'
some
'
,
'
any
'
,
'
include
'
,
'
contains
'
,
'
invoke
'
,
'
reject
'
,
'
every
'
,
'
all
'
,
'
some
'
,
'
any
'
,
'
include
'
,
'
contains
'
,
'
invoke
'
,
'
max
'
,
'
min
'
,
'
toArray
'
,
'
size
'
,
'
first
'
,
'
head
'
,
'
take
'
,
'
initial
'
,
'
rest
'
,
'
max
'
,
'
min
'
,
'
toArray
'
,
'
size
'
,
'
first
'
,
'
head
'
,
'
take
'
,
'
initial
'
,
'
rest
'
,
'
tail
'
,
'
drop
'
,
'
last
'
,
'
without
'
,
'
difference
'
,
'
indexOf
'
,
'
shuffle
'
,
'
tail
'
,
'
drop
'
,
'
last
'
,
'
without
'
,
'
difference
'
,
'
indexOf
'
,
'
shuffle
'
,
'
lastIndexOf
'
,
'
isEmpty
'
,
'
chain
'
];
'
lastIndexOf
'
,
'
isEmpty
'
,
'
chain
'
,
'
sample
'
];
// Mix in each Underscore method as a proxy to `Collection#models`.
// Mix in each Underscore method as a proxy to `Collection#models`.
_
.
each
(
methods
,
function
(
method
)
{
_
.
each
(
methods
,
function
(
method
)
{
...
@@ -958,7 +969,7 @@
...
@@ -958,7 +969,7 @@
});
});
// Underscore methods that take a property name as an argument.
// Underscore methods that take a property name as an argument.
var
attributeMethods
=
[
'
groupBy
'
,
'
countBy
'
,
'
sortBy
'
];
var
attributeMethods
=
[
'
groupBy
'
,
'
countBy
'
,
'
sortBy
'
,
'
indexBy
'
];
// Use attributes instead of properties.
// Use attributes instead of properties.
_
.
each
(
attributeMethods
,
function
(
method
)
{
_
.
each
(
attributeMethods
,
function
(
method
)
{
...
@@ -1180,7 +1191,9 @@
...
@@ -1180,7 +1191,9 @@
return
xhr
;
return
xhr
;
};
};
var
noXhrPatch
=
typeof
window
!==
'
undefined
'
&&
!!
window
.
ActiveXObject
&&
!
(
window
.
XMLHttpRequest
&&
(
new
XMLHttpRequest
).
dispatchEvent
);
var
noXhrPatch
=
typeof
window
!==
'
undefined
'
&&
!!
window
.
ActiveXObject
&&
!
(
window
.
XMLHttpRequest
&&
(
new
XMLHttpRequest
).
dispatchEvent
);
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var
methodMap
=
{
var
methodMap
=
{
...
@@ -1239,7 +1252,7 @@
...
@@ -1239,7 +1252,7 @@
var
router
=
this
;
var
router
=
this
;
Backbone
.
history
.
route
(
route
,
function
(
fragment
)
{
Backbone
.
history
.
route
(
route
,
function
(
fragment
)
{
var
args
=
router
.
_extractParameters
(
route
,
fragment
);
var
args
=
router
.
_extractParameters
(
route
,
fragment
);
callback
&&
callback
.
apply
(
router
,
args
);
router
.
execute
(
callback
,
args
);
router
.
trigger
.
apply
(
router
,
[
'
route:
'
+
name
].
concat
(
args
));
router
.
trigger
.
apply
(
router
,
[
'
route:
'
+
name
].
concat
(
args
));
router
.
trigger
(
'
route
'
,
name
,
args
);
router
.
trigger
(
'
route
'
,
name
,
args
);
Backbone
.
history
.
trigger
(
'
route
'
,
router
,
name
,
args
);
Backbone
.
history
.
trigger
(
'
route
'
,
router
,
name
,
args
);
...
@@ -1247,6 +1260,12 @@
...
@@ -1247,6 +1260,12 @@
return
this
;
return
this
;
},
},
// Execute a route handler with the provided parameters. This is an
// excellent place to do pre-route setup or post-route cleanup.
execute
:
function
(
callback
,
args
)
{
if
(
callback
)
callback
.
apply
(
this
,
args
);
},
// Simple proxy to `Backbone.history` to save a fragment into the history.
// Simple proxy to `Backbone.history` to save a fragment into the history.
navigate
:
function
(
fragment
,
options
)
{
navigate
:
function
(
fragment
,
options
)
{
Backbone
.
history
.
navigate
(
fragment
,
options
);
Backbone
.
history
.
navigate
(
fragment
,
options
);
...
@@ -1271,10 +1290,10 @@
...
@@ -1271,10 +1290,10 @@
route
=
route
.
replace
(
escapeRegExp
,
'
\\
$&
'
)
route
=
route
.
replace
(
escapeRegExp
,
'
\\
$&
'
)
.
replace
(
optionalParam
,
'
(?:$1)?
'
)
.
replace
(
optionalParam
,
'
(?:$1)?
'
)
.
replace
(
namedParam
,
function
(
match
,
optional
)
{
.
replace
(
namedParam
,
function
(
match
,
optional
)
{
return
optional
?
match
:
'
([^
\
/
]+)
'
;
return
optional
?
match
:
'
([^
/?
]+)
'
;
})
})
.
replace
(
splatParam
,
'
(
.
*?)
'
);
.
replace
(
splatParam
,
'
(
[^?]
*?)
'
);
return
new
RegExp
(
'
^
'
+
route
+
'
$
'
);
return
new
RegExp
(
'
^
'
+
route
+
'
(?:
\\
?(.*))?
$
'
);
},
},
// Given a route, and a URL fragment that it matches, return the array of
// Given a route, and a URL fragment that it matches, return the array of
...
@@ -1282,7 +1301,9 @@
...
@@ -1282,7 +1301,9 @@
// treated as `null` to normalize cross-browser behavior.
// treated as `null` to normalize cross-browser behavior.
_extractParameters
:
function
(
route
,
fragment
)
{
_extractParameters
:
function
(
route
,
fragment
)
{
var
params
=
route
.
exec
(
fragment
).
slice
(
1
);
var
params
=
route
.
exec
(
fragment
).
slice
(
1
);
return
_
.
map
(
params
,
function
(
param
)
{
return
_
.
map
(
params
,
function
(
param
,
i
)
{
// Don't decode the search params.
if
(
i
===
params
.
length
-
1
)
return
param
||
null
;
return
param
?
decodeURIComponent
(
param
)
:
null
;
return
param
?
decodeURIComponent
(
param
)
:
null
;
});
});
}
}
...
@@ -1320,8 +1341,8 @@
...
@@ -1320,8 +1341,8 @@
// Cached regex for removing a trailing slash.
// Cached regex for removing a trailing slash.
var
trailingSlash
=
/
\/
$/
;
var
trailingSlash
=
/
\/
$/
;
// Cached regex for stripping urls of hash
and query
.
// Cached regex for stripping urls of hash.
var
pathStripper
=
/
[
?#
]
.*$/
;
var
pathStripper
=
/
#
.*$/
;
// Has the history handling already been started?
// Has the history handling already been started?
History
.
started
=
false
;
History
.
started
=
false
;
...
@@ -1333,6 +1354,11 @@
...
@@ -1333,6 +1354,11 @@
// twenty times a second.
// twenty times a second.
interval
:
50
,
interval
:
50
,
// Are we at the app root?
atRoot
:
function
()
{
return
this
.
location
.
pathname
.
replace
(
/
[^\/]
$/
,
'
$&/
'
)
===
this
.
root
;
},
// Gets the true hash value. Cannot use location.hash directly due to bug
// Gets the true hash value. Cannot use location.hash directly due to bug
// in Firefox where location.hash will always be decoded.
// in Firefox where location.hash will always be decoded.
getHash
:
function
(
window
)
{
getHash
:
function
(
window
)
{
...
@@ -1345,7 +1371,7 @@
...
@@ -1345,7 +1371,7 @@
getFragment
:
function
(
fragment
,
forcePushState
)
{
getFragment
:
function
(
fragment
,
forcePushState
)
{
if
(
fragment
==
null
)
{
if
(
fragment
==
null
)
{
if
(
this
.
_hasPushState
||
!
this
.
_wantsHashChange
||
forcePushState
)
{
if
(
this
.
_hasPushState
||
!
this
.
_wantsHashChange
||
forcePushState
)
{
fragment
=
this
.
location
.
pathname
;
fragment
=
decodeURI
(
this
.
location
.
pathname
+
this
.
location
.
search
)
;
var
root
=
this
.
root
.
replace
(
trailingSlash
,
''
);
var
root
=
this
.
root
.
replace
(
trailingSlash
,
''
);
if
(
!
fragment
.
indexOf
(
root
))
fragment
=
fragment
.
slice
(
root
.
length
);
if
(
!
fragment
.
indexOf
(
root
))
fragment
=
fragment
.
slice
(
root
.
length
);
}
else
{
}
else
{
...
@@ -1376,7 +1402,8 @@
...
@@ -1376,7 +1402,8 @@
this
.
root
=
(
'
/
'
+
this
.
root
+
'
/
'
).
replace
(
rootStripper
,
'
/
'
);
this
.
root
=
(
'
/
'
+
this
.
root
+
'
/
'
).
replace
(
rootStripper
,
'
/
'
);
if
(
oldIE
&&
this
.
_wantsHashChange
)
{
if
(
oldIE
&&
this
.
_wantsHashChange
)
{
this
.
iframe
=
Backbone
.
$
(
'
<iframe src="javascript:0" tabindex="-1" />
'
).
hide
().
appendTo
(
'
body
'
)[
0
].
contentWindow
;
var
frame
=
Backbone
.
$
(
'
<iframe src="javascript:0" tabindex="-1">
'
);
this
.
iframe
=
frame
.
hide
().
appendTo
(
'
body
'
)[
0
].
contentWindow
;
this
.
navigate
(
fragment
);
this
.
navigate
(
fragment
);
}
}
...
@@ -1394,7 +1421,6 @@
...
@@ -1394,7 +1421,6 @@
// opened by a non-pushState browser.
// opened by a non-pushState browser.
this
.
fragment
=
fragment
;
this
.
fragment
=
fragment
;
var
loc
=
this
.
location
;
var
loc
=
this
.
location
;
var
atRoot
=
loc
.
pathname
.
replace
(
/
[^\/]
$/
,
'
$&/
'
)
===
this
.
root
;
// Transition from hashChange to pushState or vice versa if both are
// Transition from hashChange to pushState or vice versa if both are
// requested.
// requested.
...
@@ -1402,17 +1428,17 @@
...
@@ -1402,17 +1428,17 @@
// If we've started off with a route from a `pushState`-enabled
// If we've started off with a route from a `pushState`-enabled
// browser, but we're currently in a browser that doesn't support it...
// browser, but we're currently in a browser that doesn't support it...
if
(
!
this
.
_hasPushState
&&
!
atRoot
)
{
if
(
!
this
.
_hasPushState
&&
!
this
.
atRoot
()
)
{
this
.
fragment
=
this
.
getFragment
(
null
,
true
);
this
.
fragment
=
this
.
getFragment
(
null
,
true
);
this
.
location
.
replace
(
this
.
root
+
this
.
location
.
search
+
'
#
'
+
this
.
fragment
);
this
.
location
.
replace
(
this
.
root
+
'
#
'
+
this
.
fragment
);
// Return immediately as browser will do redirect to new url
// Return immediately as browser will do redirect to new url
return
true
;
return
true
;
// Or if we've started out with a hash-based route, but we're currently
// Or if we've started out with a hash-based route, but we're currently
// in a browser where it could be `pushState`-based instead...
// in a browser where it could be `pushState`-based instead...
}
else
if
(
this
.
_hasPushState
&&
atRoot
&&
loc
.
hash
)
{
}
else
if
(
this
.
_hasPushState
&&
this
.
atRoot
()
&&
loc
.
hash
)
{
this
.
fragment
=
this
.
getHash
().
replace
(
routeStripper
,
''
);
this
.
fragment
=
this
.
getHash
().
replace
(
routeStripper
,
''
);
this
.
history
.
replaceState
({},
document
.
title
,
this
.
root
+
this
.
fragment
+
loc
.
search
);
this
.
history
.
replaceState
({},
document
.
title
,
this
.
root
+
this
.
fragment
);
}
}
}
}
...
@@ -1472,7 +1498,7 @@
...
@@ -1472,7 +1498,7 @@
var
url
=
this
.
root
+
(
fragment
=
this
.
getFragment
(
fragment
||
''
));
var
url
=
this
.
root
+
(
fragment
=
this
.
getFragment
(
fragment
||
''
));
// Strip the
fragment of the query and
hash for matching.
// Strip the hash for matching.
fragment
=
fragment
.
replace
(
pathStripper
,
''
);
fragment
=
fragment
.
replace
(
pathStripper
,
''
);
if
(
this
.
fragment
===
fragment
)
return
;
if
(
this
.
fragment
===
fragment
)
return
;
...
@@ -1578,4 +1604,6 @@
...
@@ -1578,4 +1604,6 @@
};
};
};
};
}).
call
(
this
);
return
Backbone
;
}));
architecture-examples/backbone/bower_components/underscore/underscore.js
View file @
f57e0b77
// Underscore.js 1.
5.2
// Underscore.js 1.
6.0
// http://underscorejs.org
// http://underscorejs.org
// (c) 2009-201
3
Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2009-201
4
Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
// Underscore may be freely distributed under the MIT license.
(
function
()
{
(
function
()
{
...
@@ -65,7 +65,7 @@
...
@@ -65,7 +65,7 @@
}
}
// Current version.
// Current version.
_
.
VERSION
=
'
1.
5.2
'
;
_
.
VERSION
=
'
1.
6.0
'
;
// Collection Functions
// Collection Functions
// --------------------
// --------------------
...
@@ -74,7 +74,7 @@
...
@@ -74,7 +74,7 @@
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var
each
=
_
.
each
=
_
.
forEach
=
function
(
obj
,
iterator
,
context
)
{
var
each
=
_
.
each
=
_
.
forEach
=
function
(
obj
,
iterator
,
context
)
{
if
(
obj
==
null
)
return
;
if
(
obj
==
null
)
return
obj
;
if
(
nativeForEach
&&
obj
.
forEach
===
nativeForEach
)
{
if
(
nativeForEach
&&
obj
.
forEach
===
nativeForEach
)
{
obj
.
forEach
(
iterator
,
context
);
obj
.
forEach
(
iterator
,
context
);
}
else
if
(
obj
.
length
===
+
obj
.
length
)
{
}
else
if
(
obj
.
length
===
+
obj
.
length
)
{
...
@@ -87,6 +87,7 @@
...
@@ -87,6 +87,7 @@
if
(
iterator
.
call
(
context
,
obj
[
keys
[
i
]],
keys
[
i
],
obj
)
===
breaker
)
return
;
if
(
iterator
.
call
(
context
,
obj
[
keys
[
i
]],
keys
[
i
],
obj
)
===
breaker
)
return
;
}
}
}
}
return
obj
;
};
};
// Return the results of applying the iterator to each element.
// Return the results of applying the iterator to each element.
...
@@ -152,10 +153,10 @@
...
@@ -152,10 +153,10 @@
};
};
// Return the first value which passes a truth test. Aliased as `detect`.
// Return the first value which passes a truth test. Aliased as `detect`.
_
.
find
=
_
.
detect
=
function
(
obj
,
iterator
,
context
)
{
_
.
find
=
_
.
detect
=
function
(
obj
,
predicate
,
context
)
{
var
result
;
var
result
;
any
(
obj
,
function
(
value
,
index
,
list
)
{
any
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
iterator
.
call
(
context
,
value
,
index
,
list
))
{
if
(
predicate
.
call
(
context
,
value
,
index
,
list
))
{
result
=
value
;
result
=
value
;
return
true
;
return
true
;
}
}
...
@@ -166,33 +167,33 @@
...
@@ -166,33 +167,33 @@
// Return all the elements that pass a truth test.
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
// Aliased as `select`.
_
.
filter
=
_
.
select
=
function
(
obj
,
iterator
,
context
)
{
_
.
filter
=
_
.
select
=
function
(
obj
,
predicate
,
context
)
{
var
results
=
[];
var
results
=
[];
if
(
obj
==
null
)
return
results
;
if
(
obj
==
null
)
return
results
;
if
(
nativeFilter
&&
obj
.
filter
===
nativeFilter
)
return
obj
.
filter
(
iterator
,
context
);
if
(
nativeFilter
&&
obj
.
filter
===
nativeFilter
)
return
obj
.
filter
(
predicate
,
context
);
each
(
obj
,
function
(
value
,
index
,
list
)
{
each
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
iterator
.
call
(
context
,
value
,
index
,
list
))
results
.
push
(
value
);
if
(
predicate
.
call
(
context
,
value
,
index
,
list
))
results
.
push
(
value
);
});
});
return
results
;
return
results
;
};
};
// Return all the elements for which a truth test fails.
// Return all the elements for which a truth test fails.
_
.
reject
=
function
(
obj
,
iterator
,
context
)
{
_
.
reject
=
function
(
obj
,
predicate
,
context
)
{
return
_
.
filter
(
obj
,
function
(
value
,
index
,
list
)
{
return
_
.
filter
(
obj
,
function
(
value
,
index
,
list
)
{
return
!
iterator
.
call
(
context
,
value
,
index
,
list
);
return
!
predicate
.
call
(
context
,
value
,
index
,
list
);
},
context
);
},
context
);
};
};
// Determine whether all of the elements match a truth test.
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
// Aliased as `all`.
_
.
every
=
_
.
all
=
function
(
obj
,
iterator
,
context
)
{
_
.
every
=
_
.
all
=
function
(
obj
,
predicate
,
context
)
{
iterator
||
(
iterator
=
_
.
identity
);
predicate
||
(
predicate
=
_
.
identity
);
var
result
=
true
;
var
result
=
true
;
if
(
obj
==
null
)
return
result
;
if
(
obj
==
null
)
return
result
;
if
(
nativeEvery
&&
obj
.
every
===
nativeEvery
)
return
obj
.
every
(
iterator
,
context
);
if
(
nativeEvery
&&
obj
.
every
===
nativeEvery
)
return
obj
.
every
(
predicate
,
context
);
each
(
obj
,
function
(
value
,
index
,
list
)
{
each
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
!
(
result
=
result
&&
iterator
.
call
(
context
,
value
,
index
,
list
)))
return
breaker
;
if
(
!
(
result
=
result
&&
predicate
.
call
(
context
,
value
,
index
,
list
)))
return
breaker
;
});
});
return
!!
result
;
return
!!
result
;
};
};
...
@@ -200,13 +201,13 @@
...
@@ -200,13 +201,13 @@
// Determine if at least one element in the object matches a truth test.
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
// Aliased as `any`.
var
any
=
_
.
some
=
_
.
any
=
function
(
obj
,
iterator
,
context
)
{
var
any
=
_
.
some
=
_
.
any
=
function
(
obj
,
predicate
,
context
)
{
iterator
||
(
iterator
=
_
.
identity
);
predicate
||
(
predicate
=
_
.
identity
);
var
result
=
false
;
var
result
=
false
;
if
(
obj
==
null
)
return
result
;
if
(
obj
==
null
)
return
result
;
if
(
nativeSome
&&
obj
.
some
===
nativeSome
)
return
obj
.
some
(
iterator
,
context
);
if
(
nativeSome
&&
obj
.
some
===
nativeSome
)
return
obj
.
some
(
predicate
,
context
);
each
(
obj
,
function
(
value
,
index
,
list
)
{
each
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
result
||
(
result
=
iterator
.
call
(
context
,
value
,
index
,
list
)))
return
breaker
;
if
(
result
||
(
result
=
predicate
.
call
(
context
,
value
,
index
,
list
)))
return
breaker
;
});
});
return
!!
result
;
return
!!
result
;
};
};
...
@@ -232,25 +233,19 @@
...
@@ -232,25 +233,19 @@
// Convenience version of a common use case of `map`: fetching a property.
// Convenience version of a common use case of `map`: fetching a property.
_
.
pluck
=
function
(
obj
,
key
)
{
_
.
pluck
=
function
(
obj
,
key
)
{
return
_
.
map
(
obj
,
function
(
value
){
return
value
[
key
];
}
);
return
_
.
map
(
obj
,
_
.
property
(
key
)
);
};
};
// Convenience version of a common use case of `filter`: selecting only objects
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
// containing specific `key:value` pairs.
_
.
where
=
function
(
obj
,
attrs
,
first
)
{
_
.
where
=
function
(
obj
,
attrs
)
{
if
(
_
.
isEmpty
(
attrs
))
return
first
?
void
0
:
[];
return
_
.
filter
(
obj
,
_
.
matches
(
attrs
));
return
_
[
first
?
'
find
'
:
'
filter
'
](
obj
,
function
(
value
)
{
for
(
var
key
in
attrs
)
{
if
(
attrs
[
key
]
!==
value
[
key
])
return
false
;
}
return
true
;
});
};
};
// Convenience version of a common use case of `find`: getting the first object
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
// containing specific `key:value` pairs.
_
.
findWhere
=
function
(
obj
,
attrs
)
{
_
.
findWhere
=
function
(
obj
,
attrs
)
{
return
_
.
where
(
obj
,
attrs
,
true
);
return
_
.
find
(
obj
,
_
.
matches
(
attrs
)
);
};
};
// Return the maximum element or (element-based computation).
// Return the maximum element or (element-based computation).
...
@@ -260,13 +255,15 @@
...
@@ -260,13 +255,15 @@
if
(
!
iterator
&&
_
.
isArray
(
obj
)
&&
obj
[
0
]
===
+
obj
[
0
]
&&
obj
.
length
<
65535
)
{
if
(
!
iterator
&&
_
.
isArray
(
obj
)
&&
obj
[
0
]
===
+
obj
[
0
]
&&
obj
.
length
<
65535
)
{
return
Math
.
max
.
apply
(
Math
,
obj
);
return
Math
.
max
.
apply
(
Math
,
obj
);
}
}
if
(
!
iterator
&&
_
.
isEmpty
(
obj
))
return
-
Infinity
;
var
result
=
-
Infinity
,
lastComputed
=
-
Infinity
;
var
result
=
{
computed
:
-
Infinity
,
value
:
-
Infinity
};
each
(
obj
,
function
(
value
,
index
,
list
)
{
each
(
obj
,
function
(
value
,
index
,
list
)
{
var
computed
=
iterator
?
iterator
.
call
(
context
,
value
,
index
,
list
)
:
value
;
var
computed
=
iterator
?
iterator
.
call
(
context
,
value
,
index
,
list
)
:
value
;
computed
>
result
.
computed
&&
(
result
=
{
value
:
value
,
computed
:
computed
});
if
(
computed
>
lastComputed
)
{
result
=
value
;
lastComputed
=
computed
;
}
});
});
return
result
.
value
;
return
result
;
};
};
// Return the minimum element (or element-based computation).
// Return the minimum element (or element-based computation).
...
@@ -274,13 +271,15 @@
...
@@ -274,13 +271,15 @@
if
(
!
iterator
&&
_
.
isArray
(
obj
)
&&
obj
[
0
]
===
+
obj
[
0
]
&&
obj
.
length
<
65535
)
{
if
(
!
iterator
&&
_
.
isArray
(
obj
)
&&
obj
[
0
]
===
+
obj
[
0
]
&&
obj
.
length
<
65535
)
{
return
Math
.
min
.
apply
(
Math
,
obj
);
return
Math
.
min
.
apply
(
Math
,
obj
);
}
}
if
(
!
iterator
&&
_
.
isEmpty
(
obj
))
return
Infinity
;
var
result
=
Infinity
,
lastComputed
=
Infinity
;
var
result
=
{
computed
:
Infinity
,
value
:
Infinity
};
each
(
obj
,
function
(
value
,
index
,
list
)
{
each
(
obj
,
function
(
value
,
index
,
list
)
{
var
computed
=
iterator
?
iterator
.
call
(
context
,
value
,
index
,
list
)
:
value
;
var
computed
=
iterator
?
iterator
.
call
(
context
,
value
,
index
,
list
)
:
value
;
computed
<
result
.
computed
&&
(
result
=
{
value
:
value
,
computed
:
computed
});
if
(
computed
<
lastComputed
)
{
result
=
value
;
lastComputed
=
computed
;
}
});
});
return
result
.
value
;
return
result
;
};
};
// Shuffle an array, using the modern version of the
// Shuffle an array, using the modern version of the
...
@@ -297,11 +296,12 @@
...
@@ -297,11 +296,12 @@
return
shuffled
;
return
shuffled
;
};
};
// Sample **n** random values from a
n array
.
// Sample **n** random values from a
collection
.
// If **n** is not specified, returns a single random element
from the array
.
// If **n** is not specified, returns a single random element.
// The internal `guard` argument allows it to work with `map`.
// The internal `guard` argument allows it to work with `map`.
_
.
sample
=
function
(
obj
,
n
,
guard
)
{
_
.
sample
=
function
(
obj
,
n
,
guard
)
{
if
(
arguments
.
length
<
2
||
guard
)
{
if
(
n
==
null
||
guard
)
{
if
(
obj
.
length
!==
+
obj
.
length
)
obj
=
_
.
values
(
obj
);
return
obj
[
_
.
random
(
obj
.
length
-
1
)];
return
obj
[
_
.
random
(
obj
.
length
-
1
)];
}
}
return
_
.
shuffle
(
obj
).
slice
(
0
,
Math
.
max
(
0
,
n
));
return
_
.
shuffle
(
obj
).
slice
(
0
,
Math
.
max
(
0
,
n
));
...
@@ -309,12 +309,14 @@
...
@@ -309,12 +309,14 @@
// An internal function to generate lookup iterators.
// An internal function to generate lookup iterators.
var
lookupIterator
=
function
(
value
)
{
var
lookupIterator
=
function
(
value
)
{
return
_
.
isFunction
(
value
)
?
value
:
function
(
obj
){
return
obj
[
value
];
};
if
(
value
==
null
)
return
_
.
identity
;
if
(
_
.
isFunction
(
value
))
return
value
;
return
_
.
property
(
value
);
};
};
// Sort the object's values by a criterion produced by an iterator.
// Sort the object's values by a criterion produced by an iterator.
_
.
sortBy
=
function
(
obj
,
value
,
context
)
{
_
.
sortBy
=
function
(
obj
,
iterator
,
context
)
{
var
iterator
=
lookupIterator
(
value
);
iterator
=
lookupIterator
(
iterator
);
return
_
.
pluck
(
_
.
map
(
obj
,
function
(
value
,
index
,
list
)
{
return
_
.
pluck
(
_
.
map
(
obj
,
function
(
value
,
index
,
list
)
{
return
{
return
{
value
:
value
,
value
:
value
,
...
@@ -334,9 +336,9 @@
...
@@ -334,9 +336,9 @@
// An internal function used for aggregate "group by" operations.
// An internal function used for aggregate "group by" operations.
var
group
=
function
(
behavior
)
{
var
group
=
function
(
behavior
)
{
return
function
(
obj
,
value
,
context
)
{
return
function
(
obj
,
iterator
,
context
)
{
var
result
=
{};
var
result
=
{};
var
iterator
=
value
==
null
?
_
.
identity
:
lookupIterator
(
value
);
iterator
=
lookupIterator
(
iterator
);
each
(
obj
,
function
(
value
,
index
)
{
each
(
obj
,
function
(
value
,
index
)
{
var
key
=
iterator
.
call
(
context
,
value
,
index
,
obj
);
var
key
=
iterator
.
call
(
context
,
value
,
index
,
obj
);
behavior
(
result
,
key
,
value
);
behavior
(
result
,
key
,
value
);
...
@@ -348,7 +350,7 @@
...
@@ -348,7 +350,7 @@
// Groups the object's values by a criterion. Pass either a string attribute
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
// to group by, or a function that returns the criterion.
_
.
groupBy
=
group
(
function
(
result
,
key
,
value
)
{
_
.
groupBy
=
group
(
function
(
result
,
key
,
value
)
{
(
_
.
has
(
result
,
key
)
?
result
[
key
]
:
(
result
[
key
]
=
[])).
push
(
value
)
;
_
.
has
(
result
,
key
)
?
result
[
key
].
push
(
value
)
:
result
[
key
]
=
[
value
]
;
});
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// Indexes the object's values by a criterion, similar to `groupBy`, but for
...
@@ -367,7 +369,7 @@
...
@@ -367,7 +369,7 @@
// Use a comparator function to figure out the smallest index at which
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
// an object should be inserted so as to maintain order. Uses binary search.
_
.
sortedIndex
=
function
(
array
,
obj
,
iterator
,
context
)
{
_
.
sortedIndex
=
function
(
array
,
obj
,
iterator
,
context
)
{
iterator
=
iterator
==
null
?
_
.
identity
:
lookupIterator
(
iterator
);
iterator
=
lookupIterator
(
iterator
);
var
value
=
iterator
.
call
(
context
,
obj
);
var
value
=
iterator
.
call
(
context
,
obj
);
var
low
=
0
,
high
=
array
.
length
;
var
low
=
0
,
high
=
array
.
length
;
while
(
low
<
high
)
{
while
(
low
<
high
)
{
...
@@ -399,7 +401,9 @@
...
@@ -399,7 +401,9 @@
// allows it to work with `_.map`.
// allows it to work with `_.map`.
_
.
first
=
_
.
head
=
_
.
take
=
function
(
array
,
n
,
guard
)
{
_
.
first
=
_
.
head
=
_
.
take
=
function
(
array
,
n
,
guard
)
{
if
(
array
==
null
)
return
void
0
;
if
(
array
==
null
)
return
void
0
;
return
(
n
==
null
)
||
guard
?
array
[
0
]
:
slice
.
call
(
array
,
0
,
n
);
if
((
n
==
null
)
||
guard
)
return
array
[
0
];
if
(
n
<
0
)
return
[];
return
slice
.
call
(
array
,
0
,
n
);
};
};
// Returns everything but the last entry of the array. Especially useful on
// Returns everything but the last entry of the array. Especially useful on
...
@@ -414,11 +418,8 @@
...
@@ -414,11 +418,8 @@
// values in the array. The **guard** check allows it to work with `_.map`.
// values in the array. The **guard** check allows it to work with `_.map`.
_
.
last
=
function
(
array
,
n
,
guard
)
{
_
.
last
=
function
(
array
,
n
,
guard
)
{
if
(
array
==
null
)
return
void
0
;
if
(
array
==
null
)
return
void
0
;
if
((
n
==
null
)
||
guard
)
{
if
((
n
==
null
)
||
guard
)
return
array
[
array
.
length
-
1
];
return
array
[
array
.
length
-
1
];
}
else
{
return
slice
.
call
(
array
,
Math
.
max
(
array
.
length
-
n
,
0
));
return
slice
.
call
(
array
,
Math
.
max
(
array
.
length
-
n
,
0
));
}
};
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
...
@@ -459,6 +460,16 @@
...
@@ -459,6 +460,16 @@
return
_
.
difference
(
array
,
slice
.
call
(
arguments
,
1
));
return
_
.
difference
(
array
,
slice
.
call
(
arguments
,
1
));
};
};
// Split an array into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_
.
partition
=
function
(
array
,
predicate
)
{
var
pass
=
[],
fail
=
[];
each
(
array
,
function
(
elem
)
{
(
predicate
(
elem
)
?
pass
:
fail
).
push
(
elem
);
});
return
[
pass
,
fail
];
};
// Produce a duplicate-free version of the array. If the array has already
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
// Aliased as `unique`.
...
@@ -492,7 +503,7 @@
...
@@ -492,7 +503,7 @@
var
rest
=
slice
.
call
(
arguments
,
1
);
var
rest
=
slice
.
call
(
arguments
,
1
);
return
_
.
filter
(
_
.
uniq
(
array
),
function
(
item
)
{
return
_
.
filter
(
_
.
uniq
(
array
),
function
(
item
)
{
return
_
.
every
(
rest
,
function
(
other
)
{
return
_
.
every
(
rest
,
function
(
other
)
{
return
_
.
indexOf
(
other
,
item
)
>=
0
;
return
_
.
contains
(
other
,
item
)
;
});
});
});
});
};
};
...
@@ -507,7 +518,7 @@
...
@@ -507,7 +518,7 @@
// Zip together multiple lists into a single array -- elements that share
// Zip together multiple lists into a single array -- elements that share
// an index go together.
// an index go together.
_
.
zip
=
function
()
{
_
.
zip
=
function
()
{
var
length
=
_
.
max
(
_
.
pluck
(
arguments
,
"
length
"
).
concat
(
0
));
var
length
=
_
.
max
(
_
.
pluck
(
arguments
,
'
length
'
).
concat
(
0
));
var
results
=
new
Array
(
length
);
var
results
=
new
Array
(
length
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
results
[
i
]
=
_
.
pluck
(
arguments
,
''
+
i
);
results
[
i
]
=
_
.
pluck
(
arguments
,
''
+
i
);
...
@@ -613,19 +624,27 @@
...
@@ -613,19 +624,27 @@
};
};
// Partially apply a function by creating a version that has had some of its
// Partially apply a function by creating a version that has had some of its
// arguments pre-filled, without changing its dynamic `this` context.
// arguments pre-filled, without changing its dynamic `this` context. _ acts
// as a placeholder, allowing any combination of arguments to be pre-filled.
_
.
partial
=
function
(
func
)
{
_
.
partial
=
function
(
func
)
{
var
a
rgs
=
slice
.
call
(
arguments
,
1
);
var
boundA
rgs
=
slice
.
call
(
arguments
,
1
);
return
function
()
{
return
function
()
{
return
func
.
apply
(
this
,
args
.
concat
(
slice
.
call
(
arguments
)));
var
position
=
0
;
var
args
=
boundArgs
.
slice
();
for
(
var
i
=
0
,
length
=
args
.
length
;
i
<
length
;
i
++
)
{
if
(
args
[
i
]
===
_
)
args
[
i
]
=
arguments
[
position
++
];
}
while
(
position
<
arguments
.
length
)
args
.
push
(
arguments
[
position
++
]);
return
func
.
apply
(
this
,
args
);
};
};
};
};
// Bind all of an object's methods to that object. Useful for ensuring that
// Bind a number of an object's methods to that object. Remaining arguments
// all callbacks defined on an object belong to it.
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_
.
bindAll
=
function
(
obj
)
{
_
.
bindAll
=
function
(
obj
)
{
var
funcs
=
slice
.
call
(
arguments
,
1
);
var
funcs
=
slice
.
call
(
arguments
,
1
);
if
(
funcs
.
length
===
0
)
throw
new
Error
(
"
bindAll must be passed function names
"
);
if
(
funcs
.
length
===
0
)
throw
new
Error
(
'
bindAll must be passed function names
'
);
each
(
funcs
,
function
(
f
)
{
obj
[
f
]
=
_
.
bind
(
obj
[
f
],
obj
);
});
each
(
funcs
,
function
(
f
)
{
obj
[
f
]
=
_
.
bind
(
obj
[
f
],
obj
);
});
return
obj
;
return
obj
;
};
};
...
@@ -664,12 +683,13 @@
...
@@ -664,12 +683,13 @@
var
previous
=
0
;
var
previous
=
0
;
options
||
(
options
=
{});
options
||
(
options
=
{});
var
later
=
function
()
{
var
later
=
function
()
{
previous
=
options
.
leading
===
false
?
0
:
new
Date
;
previous
=
options
.
leading
===
false
?
0
:
_
.
now
()
;
timeout
=
null
;
timeout
=
null
;
result
=
func
.
apply
(
context
,
args
);
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
};
};
return
function
()
{
return
function
()
{
var
now
=
new
Date
;
var
now
=
_
.
now
()
;
if
(
!
previous
&&
options
.
leading
===
false
)
previous
=
now
;
if
(
!
previous
&&
options
.
leading
===
false
)
previous
=
now
;
var
remaining
=
wait
-
(
now
-
previous
);
var
remaining
=
wait
-
(
now
-
previous
);
context
=
this
;
context
=
this
;
...
@@ -679,6 +699,7 @@
...
@@ -679,6 +699,7 @@
timeout
=
null
;
timeout
=
null
;
previous
=
now
;
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
timeout
=
setTimeout
(
later
,
remaining
);
}
}
...
@@ -692,24 +713,33 @@
...
@@ -692,24 +713,33 @@
// leading edge, instead of the trailing.
// leading edge, instead of the trailing.
_
.
debounce
=
function
(
func
,
wait
,
immediate
)
{
_
.
debounce
=
function
(
func
,
wait
,
immediate
)
{
var
timeout
,
args
,
context
,
timestamp
,
result
;
var
timeout
,
args
,
context
,
timestamp
,
result
;
return
function
()
{
context
=
this
;
args
=
arguments
;
timestamp
=
new
Date
();
var
later
=
function
()
{
var
later
=
function
()
{
var
last
=
(
new
Date
()
)
-
timestamp
;
var
last
=
_
.
now
(
)
-
timestamp
;
if
(
last
<
wait
)
{
if
(
last
<
wait
)
{
timeout
=
setTimeout
(
later
,
wait
-
last
);
timeout
=
setTimeout
(
later
,
wait
-
last
);
}
else
{
}
else
{
timeout
=
null
;
timeout
=
null
;
if
(
!
immediate
)
result
=
func
.
apply
(
context
,
args
);
if
(
!
immediate
)
{
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
}
}
};
};
return
function
()
{
context
=
this
;
args
=
arguments
;
timestamp
=
_
.
now
();
var
callNow
=
immediate
&&
!
timeout
;
var
callNow
=
immediate
&&
!
timeout
;
if
(
!
timeout
)
{
if
(
!
timeout
)
{
timeout
=
setTimeout
(
later
,
wait
);
timeout
=
setTimeout
(
later
,
wait
);
}
}
if
(
callNow
)
result
=
func
.
apply
(
context
,
args
);
if
(
callNow
)
{
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
return
result
;
return
result
;
};
};
};
};
...
@@ -731,11 +761,7 @@
...
@@ -731,11 +761,7 @@
// allowing you to adjust arguments, run code before and after, and
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
// conditionally execute the original function.
_
.
wrap
=
function
(
func
,
wrapper
)
{
_
.
wrap
=
function
(
func
,
wrapper
)
{
return
function
()
{
return
_
.
partial
(
wrapper
,
func
);
var
args
=
[
func
];
push
.
apply
(
args
,
arguments
);
return
wrapper
.
apply
(
this
,
args
);
};
};
};
// Returns a function that is the composition of a list of functions, each
// Returns a function that is the composition of a list of functions, each
...
@@ -765,8 +791,9 @@
...
@@ -765,8 +791,9 @@
// Retrieve the names of an object's properties.
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
// Delegates to **ECMAScript 5**'s native `Object.keys`
_
.
keys
=
nativeKeys
||
function
(
obj
)
{
_
.
keys
=
function
(
obj
)
{
if
(
obj
!==
Object
(
obj
))
throw
new
TypeError
(
'
Invalid object
'
);
if
(
!
_
.
isObject
(
obj
))
return
[];
if
(
nativeKeys
)
return
nativeKeys
(
obj
);
var
keys
=
[];
var
keys
=
[];
for
(
var
key
in
obj
)
if
(
_
.
has
(
obj
,
key
))
keys
.
push
(
key
);
for
(
var
key
in
obj
)
if
(
_
.
has
(
obj
,
key
))
keys
.
push
(
key
);
return
keys
;
return
keys
;
...
@@ -921,7 +948,8 @@
...
@@ -921,7 +948,8 @@
// from different frames are.
// from different frames are.
var
aCtor
=
a
.
constructor
,
bCtor
=
b
.
constructor
;
var
aCtor
=
a
.
constructor
,
bCtor
=
b
.
constructor
;
if
(
aCtor
!==
bCtor
&&
!
(
_
.
isFunction
(
aCtor
)
&&
(
aCtor
instanceof
aCtor
)
&&
if
(
aCtor
!==
bCtor
&&
!
(
_
.
isFunction
(
aCtor
)
&&
(
aCtor
instanceof
aCtor
)
&&
_
.
isFunction
(
bCtor
)
&&
(
bCtor
instanceof
bCtor
)))
{
_
.
isFunction
(
bCtor
)
&&
(
bCtor
instanceof
bCtor
))
&&
(
'
constructor
'
in
a
&&
'
constructor
'
in
b
))
{
return
false
;
return
false
;
}
}
// Add the first object to the stack of traversed objects.
// Add the first object to the stack of traversed objects.
...
@@ -1061,6 +1089,30 @@
...
@@ -1061,6 +1089,30 @@
return
value
;
return
value
;
};
};
_
.
constant
=
function
(
value
)
{
return
function
()
{
return
value
;
};
};
_
.
property
=
function
(
key
)
{
return
function
(
obj
)
{
return
obj
[
key
];
};
};
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
_
.
matches
=
function
(
attrs
)
{
return
function
(
obj
)
{
if
(
obj
===
attrs
)
return
true
;
//avoid comparing an object to itself.
for
(
var
key
in
attrs
)
{
if
(
attrs
[
key
]
!==
obj
[
key
])
return
false
;
}
return
true
;
}
};
// Run a function **n** times.
// Run a function **n** times.
_
.
times
=
function
(
n
,
iterator
,
context
)
{
_
.
times
=
function
(
n
,
iterator
,
context
)
{
var
accum
=
Array
(
Math
.
max
(
0
,
n
));
var
accum
=
Array
(
Math
.
max
(
0
,
n
));
...
@@ -1077,6 +1129,9 @@
...
@@ -1077,6 +1129,9 @@
return
min
+
Math
.
floor
(
Math
.
random
()
*
(
max
-
min
+
1
));
return
min
+
Math
.
floor
(
Math
.
random
()
*
(
max
-
min
+
1
));
};
};
// A (possibly faster) way to get the current timestamp as an integer.
_
.
now
=
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
};
// List of HTML entities for escaping.
// List of HTML entities for escaping.
var
entityMap
=
{
var
entityMap
=
{
escape
:
{
escape
:
{
...
@@ -1273,4 +1328,16 @@
...
@@ -1273,4 +1328,16 @@
});
});
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
define
(
'
underscore
'
,
[],
function
()
{
return
_
;
});
}
}).
call
(
this
);
}).
call
(
this
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment