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
3c4b899e
Commit
3c4b899e
authored
Feb 10, 2015
by
André Ruffert
Committed by
Sindre Sorhus
Feb 10, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Close #1151 PR: Update `backbone_require` to new app UI. Fixes #1110
parent
d24fcd67
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
6945 additions
and
5750 deletions
+6945
-5750
examples/backbone_require/.gitignore
examples/backbone_require/.gitignore
+28
-0
examples/backbone_require/bower.json
examples/backbone_require/bower.json
+0
-13
examples/backbone_require/bower_components/todomvc-common/bg.png
...s/backbone_require/bower_components/todomvc-common/bg.png
+0
-0
examples/backbone_require/index.html
examples/backbone_require/index.html
+4
-3
examples/backbone_require/js/main.js
examples/backbone_require/js/main.js
+5
-5
examples/backbone_require/node_modules/backbone.localstorage/backbone.localStorage.js
...de_modules/backbone.localstorage/backbone.localStorage.js
+88
-52
examples/backbone_require/node_modules/backbone/backbone.js
examples/backbone_require/node_modules/backbone/backbone.js
+94
-67
examples/backbone_require/node_modules/jquery/dist/jquery.js
examples/backbone_require/node_modules/jquery/dist/jquery.js
+5412
-5036
examples/backbone_require/node_modules/requirejs-text/text.js
...ples/backbone_require/node_modules/requirejs-text/text.js
+12
-8
examples/backbone_require/node_modules/requirejs/require.js
examples/backbone_require/node_modules/requirejs/require.js
+145
-123
examples/backbone_require/node_modules/todomvc-app-css/index.css
...s/backbone_require/node_modules/todomvc-app-css/index.css
+394
-0
examples/backbone_require/node_modules/todomvc-common/base.css
...les/backbone_require/node_modules/todomvc-common/base.css
+141
-0
examples/backbone_require/node_modules/todomvc-common/base.js
...ples/backbone_require/node_modules/todomvc-common/base.js
+27
-0
examples/backbone_require/node_modules/underscore/underscore.js
...es/backbone_require/node_modules/underscore/underscore.js
+582
-443
examples/backbone_require/package.json
examples/backbone_require/package.json
+13
-0
No files found.
examples/backbone_require/.gitignore
0 → 100644
View file @
3c4b899e
node_modules/*
node_modules/backbone/*
!node_modules/backbone/backbone.js
node_modules/backbone.localstorage/*
!node_modules/backbone.localstorage/backbone.localStorage.js
node_modules/jquery/*
!node_modules/jquery/dist
node_modules/jquery/dist/*
!node_modules/jquery/dist/jquery.js
node_modules/requirejs/*
!node_modules/requirejs/require.js
node_modules/requirejs-text/*
!node_modules/requirejs-text/text.js
node_modules/todomvc-app-css/*
!node_modules/todomvc-app-css/index.css
node_modules/todomvc-common/*
!node_modules/todomvc-common/base.css
!node_modules/todomvc-common/base.js
node_modules/underscore/*
!node_modules/underscore/underscore.js
examples/backbone_require/bower.json
deleted
100644 → 0
View file @
d24fcd67
{
"name"
:
"todomvc-backbone-requirejs"
,
"version"
:
"0.0.0"
,
"dependencies"
:
{
"backbone"
:
"~1.1.0"
,
"underscore"
:
"~1.5.0"
,
"jquery"
:
"~2.0.0"
,
"todomvc-common"
:
"~0.3.0"
,
"backbone.localStorage"
:
"~1.1.0"
,
"requirejs"
:
"~2.1.5"
,
"requirejs-text"
:
"~2.0.5"
}
}
examples/backbone_require/bower_components/todomvc-common/bg.png
deleted
100644 → 0
View file @
d24fcd67
2.08 KB
examples/backbone_require/index.html
View file @
3c4b899e
...
@@ -3,8 +3,8 @@
...
@@ -3,8 +3,8 @@
<head>
<head>
<meta
charset=
"utf-8"
>
<meta
charset=
"utf-8"
>
<title>
Backbone.js + RequireJS • TodoMVC
</title>
<title>
Backbone.js + RequireJS • TodoMVC
</title>
<link
rel=
"stylesheet"
href=
"
bower_component
s/todomvc-common/base.css"
>
<link
rel=
"stylesheet"
href=
"
node_module
s/todomvc-common/base.css"
>
<
script
src=
"bower_components/todomvc-common/base.js"
></script
>
<
link
rel=
"stylesheet"
href=
"node_modules/todomvc-app-css/index.css"
>
</head>
</head>
<body>
<body>
<section
id=
"todoapp"
>
<section
id=
"todoapp"
>
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
<p>
Written by
<a
href=
"http://addyosmani.github.com/todomvc/"
>
Addy Osmani
</a></p>
<p>
Written by
<a
href=
"http://addyosmani.github.com/todomvc/"
>
Addy Osmani
</a></p>
<p>
Part of
<a
href=
"http://todomvc.com"
>
TodoMVC
</a></p>
<p>
Part of
<a
href=
"http://todomvc.com"
>
TodoMVC
</a></p>
</footer>
</footer>
<script
data-main=
"js/main"
src=
"bower_components/requirejs/require.js"
></script>
<script
src=
"node_modules/todomvc-common/base.js"
></script>
<script
data-main=
"js/main"
src=
"node_modules/requirejs/require.js"
></script>
</body>
</body>
</html>
</html>
examples/backbone_require/js/main.js
View file @
3c4b899e
...
@@ -22,11 +22,11 @@ require.config({
...
@@ -22,11 +22,11 @@ require.config({
}
}
},
},
paths
:
{
paths
:
{
jquery
:
'
../
bower_components/jquery
/jquery
'
,
jquery
:
'
../
node_modules/jquery/dist
/jquery
'
,
underscore
:
'
../
bower_component
s/underscore/underscore
'
,
underscore
:
'
../
node_module
s/underscore/underscore
'
,
backbone
:
'
../
bower_component
s/backbone/backbone
'
,
backbone
:
'
../
node_module
s/backbone/backbone
'
,
backboneLocalstorage
:
'
../
bower_component
s/backbone.localStorage/backbone.localStorage
'
,
backboneLocalstorage
:
'
../
node_module
s/backbone.localStorage/backbone.localStorage
'
,
text
:
'
../
bower_component
s/requirejs-text/text
'
text
:
'
../
node_module
s/requirejs-text/text
'
}
}
});
});
...
...
examples/backbone_require/
bower_components/backbone.localS
torage/backbone.localStorage.js
→
examples/backbone_require/
node_modules/backbone.locals
torage/backbone.localStorage.js
View file @
3c4b899e
/**
/**
* Backbone localStorage Adapter
* Backbone localStorage Adapter
* Version 1.1.
7
* Version 1.1.
16
*
*
* https://github.com/jeromegn/Backbone.localStorage
* https://github.com/jeromegn/Backbone.localStorage
*/
*/
(
function
(
root
,
factory
)
{
(
function
(
root
,
factory
)
{
if
(
typeof
exports
===
'
object
'
&&
typeof
require
===
'
function
'
)
{
if
(
typeof
exports
===
'
object
'
&&
typeof
require
===
'
function
'
)
{
module
.
exports
=
factory
(
require
(
"
underscore
"
),
require
(
"
backbone
"
));
module
.
exports
=
factory
(
require
(
"
backbone
"
));
}
else
if
(
typeof
define
===
"
function
"
&&
define
.
amd
)
{
}
else
if
(
typeof
define
===
"
function
"
&&
define
.
amd
)
{
// AMD. Register as an anonymous module.
// AMD. Register as an anonymous module.
define
([
"
underscore
"
,
"
backbone
"
],
function
(
_
,
Backbone
)
{
define
([
"
backbone
"
],
function
(
Backbone
)
{
// Use global variables if the locals are undefined.
// Use global variables if the locals are undefined.
return
factory
(
_
||
root
.
_
,
Backbone
||
root
.
Backbone
);
return
factory
(
Backbone
||
root
.
Backbone
);
});
});
}
else
{
}
else
{
// RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
factory
(
Backbone
);
factory
(
_
,
Backbone
);
}
}
}(
this
,
function
(
_
,
Backbone
)
{
}(
this
,
function
(
Backbone
)
{
// A simple module to replace `Backbone.sync` with *localStorage*-based
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.
// as that.
// Hold reference to Underscore.js and Backbone.js in the closure in order
// to make things work even if they are removed from the global namespace
// Generate four random hex digits.
// Generate four random hex digits.
function
S4
()
{
function
S4
()
{
return
(((
1
+
Math
.
random
())
*
0x10000
)
|
0
).
toString
(
16
).
substring
(
1
);
return
(((
1
+
Math
.
random
())
*
0x10000
)
|
0
).
toString
(
16
).
substring
(
1
);
...
@@ -35,19 +31,49 @@ function guid() {
...
@@ -35,19 +31,49 @@ function guid() {
return
(
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
());
return
(
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
());
};
};
function
isObject
(
item
)
{
return
item
===
Object
(
item
);
}
function
contains
(
array
,
item
)
{
var
i
=
array
.
length
;
while
(
i
--
)
if
(
array
[
i
]
===
item
)
return
true
;
return
false
;
}
function
extend
(
obj
,
props
)
{
for
(
var
key
in
props
)
obj
[
key
]
=
props
[
key
]
return
obj
;
}
function
result
(
object
,
property
)
{
if
(
object
==
null
)
return
void
0
;
var
value
=
object
[
property
];
return
(
typeof
value
===
'
function
'
)
?
object
[
property
]()
:
value
;
}
// Our Store is represented by a single JS object in *localStorage*. Create it
// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
// with a meaningful name, like the name you'd give a table.
// window.Store is deprectated, use Backbone.LocalStorage instead
// window.Store is deprectated, use Backbone.LocalStorage instead
Backbone
.
LocalStorage
=
window
.
Store
=
function
(
name
)
{
Backbone
.
LocalStorage
=
window
.
Store
=
function
(
name
,
serializer
)
{
if
(
!
this
.
localStorage
)
{
if
(
!
this
.
localStorage
)
{
throw
"
Backbone.localStorage: Environment does not support localStorage.
"
throw
"
Backbone.localStorage: Environment does not support localStorage.
"
}
}
this
.
name
=
name
;
this
.
name
=
name
;
this
.
serializer
=
serializer
||
{
serialize
:
function
(
item
)
{
return
isObject
(
item
)
?
JSON
.
stringify
(
item
)
:
item
;
},
// fix for "illegal access" error on Android when JSON.parse is passed null
deserialize
:
function
(
data
)
{
return
data
&&
JSON
.
parse
(
data
);
}
};
var
store
=
this
.
localStorage
().
getItem
(
this
.
name
);
var
store
=
this
.
localStorage
().
getItem
(
this
.
name
);
this
.
records
=
(
store
&&
store
.
split
(
"
,
"
))
||
[];
this
.
records
=
(
store
&&
store
.
split
(
"
,
"
))
||
[];
};
};
_
.
extend
(
Backbone
.
LocalStorage
.
prototype
,
{
extend
(
Backbone
.
LocalStorage
.
prototype
,
{
// Save the current state of the **Store** to *localStorage*.
// Save the current state of the **Store** to *localStorage*.
save
:
function
()
{
save
:
function
()
{
...
@@ -57,11 +83,11 @@ _.extend(Backbone.LocalStorage.prototype, {
...
@@ -57,11 +83,11 @@ _.extend(Backbone.LocalStorage.prototype, {
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
// have an id of it's own.
// have an id of it's own.
create
:
function
(
model
)
{
create
:
function
(
model
)
{
if
(
!
model
.
id
)
{
if
(
!
model
.
id
&&
model
.
id
!==
0
)
{
model
.
id
=
guid
();
model
.
id
=
guid
();
model
.
set
(
model
.
idAttribute
,
model
.
id
);
model
.
set
(
model
.
idAttribute
,
model
.
id
);
}
}
this
.
localStorage
().
setItem
(
this
.
name
+
"
-
"
+
model
.
id
,
JSON
.
stringify
(
model
));
this
.
localStorage
().
setItem
(
this
.
_itemName
(
model
.
id
),
this
.
serializer
.
serialize
(
model
));
this
.
records
.
push
(
model
.
id
.
toString
());
this
.
records
.
push
(
model
.
id
.
toString
());
this
.
save
();
this
.
save
();
return
this
.
find
(
model
);
return
this
.
find
(
model
);
...
@@ -69,36 +95,40 @@ _.extend(Backbone.LocalStorage.prototype, {
...
@@ -69,36 +95,40 @@ _.extend(Backbone.LocalStorage.prototype, {
// Update a model by replacing its copy in `this.data`.
// Update a model by replacing its copy in `this.data`.
update
:
function
(
model
)
{
update
:
function
(
model
)
{
this
.
localStorage
().
setItem
(
this
.
name
+
"
-
"
+
model
.
id
,
JSON
.
stringify
(
model
));
this
.
localStorage
().
setItem
(
this
.
_itemName
(
model
.
id
),
this
.
serializer
.
serialize
(
model
));
if
(
!
_
.
include
(
this
.
records
,
model
.
id
.
toString
()))
var
modelId
=
model
.
id
.
toString
();
this
.
records
.
push
(
model
.
id
.
toString
());
this
.
save
();
if
(
!
contains
(
this
.
records
,
modelId
))
{
this
.
records
.
push
(
modelId
);
this
.
save
();
}
return
this
.
find
(
model
);
return
this
.
find
(
model
);
},
},
// Retrieve a model from `this.data` by id.
// Retrieve a model from `this.data` by id.
find
:
function
(
model
)
{
find
:
function
(
model
)
{
return
this
.
jsonData
(
this
.
localStorage
().
getItem
(
this
.
name
+
"
-
"
+
model
.
id
));
return
this
.
serializer
.
deserialize
(
this
.
localStorage
().
getItem
(
this
.
_itemName
(
model
.
id
)
));
},
},
// Return the array of all models currently in storage.
// Return the array of all models currently in storage.
findAll
:
function
()
{
findAll
:
function
()
{
// Lodash removed _#chain in v1.0.0-rc.1
var
result
=
[];
return
(
_
.
chain
||
_
)(
this
.
records
)
for
(
var
i
=
0
,
id
,
data
;
i
<
this
.
records
.
length
;
i
++
)
{
.
map
(
function
(
id
){
id
=
this
.
records
[
i
];
return
this
.
jsonData
(
this
.
localStorage
().
getItem
(
this
.
name
+
"
-
"
+
id
));
data
=
this
.
serializer
.
deserialize
(
this
.
localStorage
().
getItem
(
this
.
_itemName
(
id
)
));
},
this
)
if
(
data
!=
null
)
result
.
push
(
data
);
.
compact
()
}
.
value
()
;
return
result
;
},
},
// Delete a model from `this.data`, returning it.
// Delete a model from `this.data`, returning it.
destroy
:
function
(
model
)
{
destroy
:
function
(
model
)
{
if
(
model
.
isNew
())
this
.
localStorage
().
removeItem
(
this
.
_itemName
(
model
.
id
));
return
false
var
modelId
=
model
.
id
.
toString
();
this
.
localStorage
().
removeItem
(
this
.
name
+
"
-
"
+
model
.
id
);
for
(
var
i
=
0
,
id
;
i
<
this
.
records
.
length
;
i
++
)
{
this
.
records
=
_
.
reject
(
this
.
records
,
function
(
id
){
if
(
this
.
records
[
i
]
===
modelId
)
{
return
id
===
model
.
id
.
toString
();
this
.
records
.
splice
(
i
,
1
);
});
}
}
this
.
save
();
this
.
save
();
return
model
;
return
model
;
},
},
...
@@ -107,11 +137,6 @@ _.extend(Backbone.LocalStorage.prototype, {
...
@@ -107,11 +137,6 @@ _.extend(Backbone.LocalStorage.prototype, {
return
localStorage
;
return
localStorage
;
},
},
// fix for "illegal access" error on Android when JSON.parse is passed null
jsonData
:
function
(
data
)
{
return
data
&&
JSON
.
parse
(
data
);
},
// Clear localStorage for specific collection.
// Clear localStorage for specific collection.
_clear
:
function
()
{
_clear
:
function
()
{
var
local
=
this
.
localStorage
(),
var
local
=
this
.
localStorage
(),
...
@@ -120,11 +145,12 @@ _.extend(Backbone.LocalStorage.prototype, {
...
@@ -120,11 +145,12 @@ _.extend(Backbone.LocalStorage.prototype, {
// Remove id-tracking item (e.g., "foo").
// Remove id-tracking item (e.g., "foo").
local
.
removeItem
(
this
.
name
);
local
.
removeItem
(
this
.
name
);
// Lodash removed _#chain in v1.0.0-rc.1
// Match all data items (e.g., "foo-ID") and remove.
// Match all data items (e.g., "foo-ID") and remove.
(
_
.
chain
||
_
)(
local
).
keys
()
for
(
var
k
in
local
)
{
.
filter
(
function
(
k
)
{
return
itemRe
.
test
(
k
);
})
if
(
itemRe
.
test
(
k
))
{
.
each
(
function
(
k
)
{
local
.
removeItem
(
k
);
});
local
.
removeItem
(
k
);
}
}
this
.
records
.
length
=
0
;
this
.
records
.
length
=
0
;
},
},
...
@@ -132,6 +158,10 @@ _.extend(Backbone.LocalStorage.prototype, {
...
@@ -132,6 +158,10 @@ _.extend(Backbone.LocalStorage.prototype, {
// Size of localStorage.
// Size of localStorage.
_storageSize
:
function
()
{
_storageSize
:
function
()
{
return
this
.
localStorage
().
length
;
return
this
.
localStorage
().
length
;
},
_itemName
:
function
(
id
)
{
return
this
.
name
+
"
-
"
+
id
;
}
}
});
});
...
@@ -140,9 +170,13 @@ _.extend(Backbone.LocalStorage.prototype, {
...
@@ -140,9 +170,13 @@ _.extend(Backbone.LocalStorage.prototype, {
// *localStorage* property, which should be an instance of `Store`.
// *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead
// window.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead
Backbone
.
LocalStorage
.
sync
=
window
.
Store
.
sync
=
Backbone
.
localSync
=
function
(
method
,
model
,
options
)
{
Backbone
.
LocalStorage
.
sync
=
window
.
Store
.
sync
=
Backbone
.
localSync
=
function
(
method
,
model
,
options
)
{
var
store
=
model
.
localStorage
||
model
.
collection
.
localStorage
;
var
store
=
result
(
model
,
'
localStorage
'
)
||
result
(
model
.
collection
,
'
localStorage
'
)
;
var
resp
,
errorMessage
,
syncDfd
=
Backbone
.
$
.
Deferred
&&
Backbone
.
$
.
Deferred
();
//If $ is having Deferred - use it.
var
resp
,
errorMessage
;
//If $ is having Deferred - use it.
var
syncDfd
=
Backbone
.
$
?
(
Backbone
.
$
.
Deferred
&&
Backbone
.
$
.
Deferred
())
:
(
Backbone
.
Deferred
&&
Backbone
.
Deferred
());
try
{
try
{
...
@@ -204,8 +238,10 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m
...
@@ -204,8 +238,10 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m
Backbone
.
ajaxSync
=
Backbone
.
sync
;
Backbone
.
ajaxSync
=
Backbone
.
sync
;
Backbone
.
getSyncMethod
=
function
(
model
)
{
Backbone
.
getSyncMethod
=
function
(
model
,
options
)
{
if
(
model
.
localStorage
||
(
model
.
collection
&&
model
.
collection
.
localStorage
))
{
var
forceAjaxSync
=
options
&&
options
.
ajaxSync
;
if
(
!
forceAjaxSync
&&
(
result
(
model
,
'
localStorage
'
)
||
result
(
model
.
collection
,
'
localStorage
'
)))
{
return
Backbone
.
localSync
;
return
Backbone
.
localSync
;
}
}
...
@@ -215,7 +251,7 @@ Backbone.getSyncMethod = function(model) {
...
@@ -215,7 +251,7 @@ Backbone.getSyncMethod = function(model) {
// Override 'Backbone.sync' to default to localSync,
// Override 'Backbone.sync' to default to localSync,
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
Backbone
.
sync
=
function
(
method
,
model
,
options
)
{
Backbone
.
sync
=
function
(
method
,
model
,
options
)
{
return
Backbone
.
getSyncMethod
(
model
).
apply
(
this
,
[
method
,
model
,
options
]);
return
Backbone
.
getSyncMethod
(
model
,
options
).
apply
(
this
,
[
method
,
model
,
options
]);
};
};
return
Backbone
.
LocalStorage
;
return
Backbone
.
LocalStorage
;
...
...
examples/backbone_require/
bower_component
s/backbone/backbone.js
→
examples/backbone_require/
node_module
s/backbone/backbone.js
View file @
3c4b899e
// Backbone.js 1.1.
0
// Backbone.js 1.1.
2
// (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
'
);
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 +40,12 @@
...
@@ -25,25 +40,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.2
'
;
// 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 +111,7 @@
...
@@ -109,7 +111,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 +207,7 @@
...
@@ -205,7 +207,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 +352,7 @@
...
@@ -350,7 +352,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 +363,7 @@
...
@@ -361,6 +363,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 +531,12 @@
...
@@ -528,9 +531,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 +552,7 @@
...
@@ -546,7 +552,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 +656,7 @@
...
@@ -650,7 +656,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 +682,11 @@
...
@@ -676,11 +682,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 +706,13 @@
...
@@ -700,14 +706,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 +762,7 @@
...
@@ -757,7 +762,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 +803,7 @@
...
@@ -798,7 +803,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 +879,7 @@
...
@@ -874,7 +879,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 +909,7 @@
...
@@ -904,10 +909,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 +918,16 @@
...
@@ -916,8 +918,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 +956,7 @@
...
@@ -946,7 +956,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 +968,7 @@
...
@@ -958,7 +968,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 +1190,9 @@
...
@@ -1180,7 +1190,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 +1251,7 @@
...
@@ -1239,7 +1251,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 +1259,12 @@
...
@@ -1247,6 +1259,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 +1289,10 @@
...
@@ -1271,10 +1289,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
+
'
(?:
\\
?([
\\
s
\\
S]*))?
$
'
);
},
},
// 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 +1300,9 @@
...
@@ -1282,7 +1300,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 +1340,8 @@
...
@@ -1320,8 +1340,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 +1353,11 @@
...
@@ -1333,6 +1353,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 +1370,7 @@
...
@@ -1345,7 +1370,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 +1401,8 @@
...
@@ -1376,7 +1401,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 +1420,6 @@
...
@@ -1394,7 +1420,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 +1427,17 @@
...
@@ -1402,17 +1427,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
);
}
}
}
}
...
@@ -1424,7 +1449,7 @@
...
@@ -1424,7 +1449,7 @@
// but possibly useful for unit testing Routers.
// but possibly useful for unit testing Routers.
stop
:
function
()
{
stop
:
function
()
{
Backbone
.
$
(
window
).
off
(
'
popstate
'
,
this
.
checkUrl
).
off
(
'
hashchange
'
,
this
.
checkUrl
);
Backbone
.
$
(
window
).
off
(
'
popstate
'
,
this
.
checkUrl
).
off
(
'
hashchange
'
,
this
.
checkUrl
);
clearInterval
(
this
.
_checkUrlInterval
);
if
(
this
.
_checkUrlInterval
)
clearInterval
(
this
.
_checkUrlInterval
);
History
.
started
=
false
;
History
.
started
=
false
;
},
},
...
@@ -1472,7 +1497,7 @@
...
@@ -1472,7 +1497,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 +1603,6 @@
...
@@ -1578,4 +1603,6 @@
};
};
};
};
}).
call
(
this
);
return
Backbone
;
}));
examples/backbone_require/
bower_components/jquery
/jquery.js
→
examples/backbone_require/
node_modules/jquery/dist
/jquery.js
View file @
3c4b899e
This source diff could not be displayed because it is too large. You can
view the blob
instead.
examples/backbone_require/
bower_component
s/requirejs-text/text.js
→
examples/backbone_require/
node_module
s/requirejs-text/text.js
View file @
3c4b899e
/**
/**
* @license RequireJS text 2.0.1
0 Copyright (c) 2010-2012
, The Dojo Foundation All Rights Reserved.
* @license RequireJS text 2.0.1
2 Copyright (c) 2010-2014
, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* Available via the MIT or new BSD license.
* see: http://github.com/requirejs/text for details
* see: http://github.com/requirejs/text for details
*/
*/
...
@@ -23,7 +23,7 @@ define(['module'], function (module) {
...
@@ -23,7 +23,7 @@ define(['module'], function (module) {
masterConfig
=
(
module
.
config
&&
module
.
config
())
||
{};
masterConfig
=
(
module
.
config
&&
module
.
config
())
||
{};
text
=
{
text
=
{
version
:
'
2.0.1
0
'
,
version
:
'
2.0.1
2
'
,
strip
:
function
(
content
)
{
strip
:
function
(
content
)
{
//Strips <?xml ...?> declarations so that external SVG and XML
//Strips <?xml ...?> declarations so that external SVG and XML
...
@@ -162,12 +162,12 @@ define(['module'], function (module) {
...
@@ -162,12 +162,12 @@ define(['module'], function (module) {
// Do not bother with the work if a build and text will
// Do not bother with the work if a build and text will
// not be inlined.
// not be inlined.
if
(
config
.
isBuild
&&
!
config
.
inlineText
)
{
if
(
config
&&
config
.
isBuild
&&
!
config
.
inlineText
)
{
onLoad
();
onLoad
();
return
;
return
;
}
}
masterConfig
.
isBuild
=
config
.
isBuild
;
masterConfig
.
isBuild
=
config
&&
config
.
isBuild
;
var
parsed
=
text
.
parseName
(
name
),
var
parsed
=
text
.
parseName
(
name
),
nonStripName
=
parsed
.
moduleName
+
nonStripName
=
parsed
.
moduleName
+
...
@@ -257,8 +257,10 @@ define(['module'], function (module) {
...
@@ -257,8 +257,10 @@ define(['module'], function (module) {
}
}
callback
(
file
);
callback
(
file
);
}
catch
(
e
)
{
}
catch
(
e
)
{
if
(
errback
)
{
errback
(
e
);
errback
(
e
);
}
}
}
};
};
}
else
if
(
masterConfig
.
env
===
'
xhr
'
||
(
!
masterConfig
.
env
&&
}
else
if
(
masterConfig
.
env
===
'
xhr
'
||
(
!
masterConfig
.
env
&&
text
.
createXhr
()))
{
text
.
createXhr
()))
{
...
@@ -285,12 +287,14 @@ define(['module'], function (module) {
...
@@ -285,12 +287,14 @@ define(['module'], function (module) {
//Do not explicitly handle errors, those should be
//Do not explicitly handle errors, those should be
//visible via console output in the browser.
//visible via console output in the browser.
if
(
xhr
.
readyState
===
4
)
{
if
(
xhr
.
readyState
===
4
)
{
status
=
xhr
.
status
;
status
=
xhr
.
status
||
0
;
if
(
status
>
399
&&
status
<
600
)
{
if
(
status
>
399
&&
status
<
600
)
{
//An http 4xx or 5xx error. Signal an error.
//An http 4xx or 5xx error. Signal an error.
err
=
new
Error
(
url
+
'
HTTP status:
'
+
status
);
err
=
new
Error
(
url
+
'
HTTP status:
'
+
status
);
err
.
xhr
=
xhr
;
err
.
xhr
=
xhr
;
if
(
errback
)
{
errback
(
err
);
errback
(
err
);
}
}
else
{
}
else
{
callback
(
xhr
.
responseText
);
callback
(
xhr
.
responseText
);
}
}
...
@@ -347,7 +351,7 @@ define(['module'], function (module) {
...
@@ -347,7 +351,7 @@ define(['module'], function (module) {
typeof
Components
!==
'
undefined
'
&&
Components
.
classes
&&
typeof
Components
!==
'
undefined
'
&&
Components
.
classes
&&
Components
.
interfaces
))
{
Components
.
interfaces
))
{
//Avert your gaze!
//Avert your gaze!
Cc
=
Components
.
classes
,
Cc
=
Components
.
classes
;
Ci
=
Components
.
interfaces
;
Ci
=
Components
.
interfaces
;
Components
.
utils
[
'
import
'
](
'
resource://gre/modules/FileUtils.jsm
'
);
Components
.
utils
[
'
import
'
](
'
resource://gre/modules/FileUtils.jsm
'
);
xpcIsWindows
=
(
'
@mozilla.org/windows-registry-key;1
'
in
Cc
);
xpcIsWindows
=
(
'
@mozilla.org/windows-registry-key;1
'
in
Cc
);
...
...
examples/backbone_require/
bower_component
s/requirejs/require.js
→
examples/backbone_require/
node_module
s/requirejs/require.js
View file @
3c4b899e
/** vim: et:ts=4:sw=4:sts=4
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.
9 Copyright (c) 2010-2012
, The Dojo Foundation All Rights Reserved.
* @license RequireJS 2.1.
15 Copyright (c) 2010-2014
, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
* see: http://github.com/jrburke/requirejs for details
*/
*/
...
@@ -12,7 +12,7 @@ var requirejs, require, define;
...
@@ -12,7 +12,7 @@ var requirejs, require, define;
(
function
(
global
)
{
(
function
(
global
)
{
var
req
,
s
,
head
,
baseElement
,
dataMain
,
src
,
var
req
,
s
,
head
,
baseElement
,
dataMain
,
src
,
interactiveScript
,
currentlyAddingScript
,
mainScript
,
subPath
,
interactiveScript
,
currentlyAddingScript
,
mainScript
,
subPath
,
version
=
'
2.1.
9
'
,
version
=
'
2.1.
15
'
,
commentRegExp
=
/
(\/\*([\s\S]
*
?)\*\/
|
([^
:
]
|^
)\/\/(
.*
)
$
)
/mg
,
commentRegExp
=
/
(\/\*([\s\S]
*
?)\*\/
|
([^
:
]
|^
)\/\/(
.*
)
$
)
/mg
,
cjsRequireRegExp
=
/
[^
.
]\s
*require
\s
*
\(\s
*
[
"'
]([^
'"
\s]
+
)[
"'
]\s
*
\)
/g
,
cjsRequireRegExp
=
/
[^
.
]\s
*require
\s
*
\(\s
*
[
"'
]([^
'"
\s]
+
)[
"'
]\s
*
\)
/g
,
jsSuffixRegExp
=
/
\.
js$/
,
jsSuffixRegExp
=
/
\.
js$/
,
...
@@ -108,7 +108,10 @@ var requirejs, require, define;
...
@@ -108,7 +108,10 @@ var requirejs, require, define;
if
(
source
)
{
if
(
source
)
{
eachProp
(
source
,
function
(
value
,
prop
)
{
eachProp
(
source
,
function
(
value
,
prop
)
{
if
(
force
||
!
hasProp
(
target
,
prop
))
{
if
(
force
||
!
hasProp
(
target
,
prop
))
{
if
(
deepStringMixin
&&
typeof
value
!==
'
string
'
)
{
if
(
deepStringMixin
&&
typeof
value
===
'
object
'
&&
value
&&
!
isArray
(
value
)
&&
!
isFunction
(
value
)
&&
!
(
value
instanceof
RegExp
))
{
if
(
!
target
[
prop
])
{
if
(
!
target
[
prop
])
{
target
[
prop
]
=
{};
target
[
prop
]
=
{};
}
}
...
@@ -138,7 +141,7 @@ var requirejs, require, define;
...
@@ -138,7 +141,7 @@ var requirejs, require, define;
throw
err
;
throw
err
;
}
}
//Allow getting a global that expressed in
//Allow getting a global that
is
expressed in
//dot notation, like 'a.b.c'.
//dot notation, like 'a.b.c'.
function
getGlobal
(
value
)
{
function
getGlobal
(
value
)
{
if
(
!
value
)
{
if
(
!
value
)
{
...
@@ -177,7 +180,7 @@ var requirejs, require, define;
...
@@ -177,7 +180,7 @@ var requirejs, require, define;
if
(
typeof
requirejs
!==
'
undefined
'
)
{
if
(
typeof
requirejs
!==
'
undefined
'
)
{
if
(
isFunction
(
requirejs
))
{
if
(
isFunction
(
requirejs
))
{
//Do not overwrite an
d
existing requirejs instance.
//Do not overwrite an existing requirejs instance.
return
;
return
;
}
}
cfg
=
requirejs
;
cfg
=
requirejs
;
...
@@ -201,6 +204,7 @@ var requirejs, require, define;
...
@@ -201,6 +204,7 @@ var requirejs, require, define;
waitSeconds
:
7
,
waitSeconds
:
7
,
baseUrl
:
'
./
'
,
baseUrl
:
'
./
'
,
paths
:
{},
paths
:
{},
bundles
:
{},
pkgs
:
{},
pkgs
:
{},
shim
:
{},
shim
:
{},
config
:
{}
config
:
{}
...
@@ -214,6 +218,7 @@ var requirejs, require, define;
...
@@ -214,6 +218,7 @@ var requirejs, require, define;
defQueue
=
[],
defQueue
=
[],
defined
=
{},
defined
=
{},
urlFetched
=
{},
urlFetched
=
{},
bundlesMap
=
{},
requireCounter
=
1
,
requireCounter
=
1
,
unnormalizedCounter
=
1
;
unnormalizedCounter
=
1
;
...
@@ -228,20 +233,19 @@ var requirejs, require, define;
...
@@ -228,20 +233,19 @@ var requirejs, require, define;
*/
*/
function
trimDots
(
ary
)
{
function
trimDots
(
ary
)
{
var
i
,
part
;
var
i
,
part
;
for
(
i
=
0
;
ary
[
i
];
i
+=
1
)
{
for
(
i
=
0
;
i
<
ary
.
length
;
i
++
)
{
part
=
ary
[
i
];
part
=
ary
[
i
];
if
(
part
===
'
.
'
)
{
if
(
part
===
'
.
'
)
{
ary
.
splice
(
i
,
1
);
ary
.
splice
(
i
,
1
);
i
-=
1
;
i
-=
1
;
}
else
if
(
part
===
'
..
'
)
{
}
else
if
(
part
===
'
..
'
)
{
if
(
i
===
1
&&
(
ary
[
2
]
===
'
..
'
||
ary
[
0
]
===
'
..
'
))
{
// If at the start, or previous value is still ..,
//End of the line. Keep at least one non-dot
// keep them so that when converted to a path it may
//path segment at the front so it can be mapped
// still work when converted to a path, even though
//correctly to disk. Otherwise, there is likely
// as an ID it is less than ideal. In larger point
//no path mapping for a path starting with '..'.
// releases, may be better to just kick out an error.
//This can still fail, but catches the most reasonable
if
(
i
===
0
||
(
i
==
1
&&
ary
[
2
]
===
'
..
'
)
||
ary
[
i
-
1
]
===
'
..
'
)
{
//uses of ..
continue
;
break
;
}
else
if
(
i
>
0
)
{
}
else
if
(
i
>
0
)
{
ary
.
splice
(
i
-
1
,
2
);
ary
.
splice
(
i
-
1
,
2
);
i
-=
2
;
i
-=
2
;
...
@@ -261,54 +265,45 @@ var requirejs, require, define;
...
@@ -261,54 +265,45 @@ var requirejs, require, define;
* @returns {String} normalized name
* @returns {String} normalized name
*/
*/
function
normalize
(
name
,
baseName
,
applyMap
)
{
function
normalize
(
name
,
baseName
,
applyMap
)
{
var
pkgName
,
pkgConfig
,
mapValue
,
nameParts
,
i
,
j
,
nameSegment
,
var
pkgMain
,
mapValue
,
nameParts
,
i
,
j
,
nameSegment
,
lastIndex
,
foundMap
,
foundI
,
foundStarMap
,
starI
,
foundMap
,
foundI
,
foundStarMap
,
starI
,
normalizedBaseParts
,
baseParts
=
baseName
&&
baseName
.
split
(
'
/
'
),
baseParts
=
(
baseName
&&
baseName
.
split
(
'
/
'
)),
normalizedBaseParts
=
baseParts
,
map
=
config
.
map
,
map
=
config
.
map
,
starMap
=
map
&&
map
[
'
*
'
];
starMap
=
map
&&
map
[
'
*
'
];
//Adjust any relative paths.
//Adjust any relative paths.
if
(
name
&&
name
.
charAt
(
0
)
===
'
.
'
)
{
if
(
name
)
{
//If have a base name, try to normalize against it,
name
=
name
.
split
(
'
/
'
);
//otherwise, assume it is a top-level require that will
lastIndex
=
name
.
length
-
1
;
//be relative to baseUrl in the end.
if
(
baseName
)
{
// If wanting node ID compatibility, strip .js from end
if
(
getOwn
(
config
.
pkgs
,
baseName
))
{
// of IDs. Have to do this here, and not in nameToUrl
//If the baseName is a package name, then just treat it as one
// because node allows either .js or non .js to map
//name to concat the name with.
// to same file.
normalizedBaseParts
=
baseParts
=
[
baseName
];
if
(
config
.
nodeIdCompat
&&
jsSuffixRegExp
.
test
(
name
[
lastIndex
]))
{
}
else
{
name
[
lastIndex
]
=
name
[
lastIndex
].
replace
(
jsSuffixRegExp
,
''
);
}
// Starts with a '.' so need the baseName
if
(
name
[
0
].
charAt
(
0
)
===
'
.
'
&&
baseParts
)
{
//Convert baseName to array, and lop off the last part,
//Convert baseName to array, and lop off the last part,
//so that . matches that 'directory' and not name of the baseName's
//so that . matches that 'directory' and not name of the baseName's
//module. For instance, baseName of 'one/two/three', maps to
//module. For instance, baseName of 'one/two/three', maps to
//'one/two/three.js', but we want the directory, 'one/two' for
//'one/two/three.js', but we want the directory, 'one/two' for
//this normalization.
//this normalization.
normalizedBaseParts
=
baseParts
.
slice
(
0
,
baseParts
.
length
-
1
);
normalizedBaseParts
=
baseParts
.
slice
(
0
,
baseParts
.
length
-
1
);
name
=
normalizedBaseParts
.
concat
(
name
);
}
}
name
=
normalizedBaseParts
.
concat
(
name
.
split
(
'
/
'
));
trimDots
(
name
);
trimDots
(
name
);
//Some use of packages may use a . path to reference the
//'main' module name, so normalize for that.
pkgConfig
=
getOwn
(
config
.
pkgs
,
(
pkgName
=
name
[
0
]));
name
=
name
.
join
(
'
/
'
);
name
=
name
.
join
(
'
/
'
);
if
(
pkgConfig
&&
name
===
pkgName
+
'
/
'
+
pkgConfig
.
main
)
{
name
=
pkgName
;
}
}
else
if
(
name
.
indexOf
(
'
./
'
)
===
0
)
{
// No baseName, so this is ID is resolved relative
// to baseUrl, pull off the leading dot.
name
=
name
.
substring
(
2
);
}
}
}
//Apply map config if available.
//Apply map config if available.
if
(
applyMap
&&
map
&&
(
baseParts
||
starMap
))
{
if
(
applyMap
&&
map
&&
(
baseParts
||
starMap
))
{
nameParts
=
name
.
split
(
'
/
'
);
nameParts
=
name
.
split
(
'
/
'
);
for
(
i
=
nameParts
.
length
;
i
>
0
;
i
-=
1
)
{
outerLoop
:
for
(
i
=
nameParts
.
length
;
i
>
0
;
i
-=
1
)
{
nameSegment
=
nameParts
.
slice
(
0
,
i
).
join
(
'
/
'
);
nameSegment
=
nameParts
.
slice
(
0
,
i
).
join
(
'
/
'
);
if
(
baseParts
)
{
if
(
baseParts
)
{
...
@@ -325,16 +320,12 @@ var requirejs, require, define;
...
@@ -325,16 +320,12 @@ var requirejs, require, define;
//Match, update name to the new value.
//Match, update name to the new value.
foundMap
=
mapValue
;
foundMap
=
mapValue
;
foundI
=
i
;
foundI
=
i
;
break
;
break
outerLoop
;
}
}
}
}
}
}
}
}
if
(
foundMap
)
{
break
;
}
//Check for a star map match, but just hold on to it,
//Check for a star map match, but just hold on to it,
//if there is a shorter segment match later in a matching
//if there is a shorter segment match later in a matching
//config, then favor over this star map.
//config, then favor over this star map.
...
@@ -355,7 +346,11 @@ var requirejs, require, define;
...
@@ -355,7 +346,11 @@ var requirejs, require, define;
}
}
}
}
return
name
;
// If the name points to a package's name, use
// the package main instead.
pkgMain
=
getOwn
(
config
.
pkgs
,
name
);
return
pkgMain
?
pkgMain
:
name
;
}
}
function
removeScript
(
name
)
{
function
removeScript
(
name
)
{
...
@@ -377,7 +372,13 @@ var requirejs, require, define;
...
@@ -377,7 +372,13 @@ var requirejs, require, define;
//retry
//retry
pathConfig
.
shift
();
pathConfig
.
shift
();
context
.
require
.
undef
(
id
);
context
.
require
.
undef
(
id
);
context
.
require
([
id
]);
//Custom require that does not do map translation, since
//ID is "absolute", already mapped/resolved.
context
.
makeRequire
(
null
,
{
skipMap
:
true
})([
id
]);
return
true
;
return
true
;
}
}
}
}
...
@@ -443,7 +444,16 @@ var requirejs, require, define;
...
@@ -443,7 +444,16 @@ var requirejs, require, define;
return
normalize
(
name
,
parentName
,
applyMap
);
return
normalize
(
name
,
parentName
,
applyMap
);
});
});
}
else
{
}
else
{
normalizedName
=
normalize
(
name
,
parentName
,
applyMap
);
// If nested plugin references, then do not try to
// normalize, as it will not normalize correctly. This
// places a restriction on resourceIds, and the longer
// term solution is not to normalize until plugins are
// loaded and all normalizations to allow for async
// loading of a loader plugin. But for now, fixes the
// common uses. Details in #1131
normalizedName
=
name
.
indexOf
(
'
!
'
)
===
-
1
?
normalize
(
name
,
parentName
,
applyMap
)
:
name
;
}
}
}
else
{
}
else
{
//A regular module.
//A regular module.
...
@@ -548,7 +558,7 @@ var requirejs, require, define;
...
@@ -548,7 +558,7 @@ var requirejs, require, define;
//local var ref to defQueue, so cannot just reassign the one
//local var ref to defQueue, so cannot just reassign the one
//on context.
//on context.
apsp
.
apply
(
defQueue
,
apsp
.
apply
(
defQueue
,
[
defQueue
.
length
-
1
,
0
].
concat
(
globalDefQueue
));
[
defQueue
.
length
,
0
].
concat
(
globalDefQueue
));
globalDefQueue
=
[];
globalDefQueue
=
[];
}
}
}
}
...
@@ -565,7 +575,7 @@ var requirejs, require, define;
...
@@ -565,7 +575,7 @@ var requirejs, require, define;
mod
.
usingExports
=
true
;
mod
.
usingExports
=
true
;
if
(
mod
.
map
.
isDefine
)
{
if
(
mod
.
map
.
isDefine
)
{
if
(
mod
.
exports
)
{
if
(
mod
.
exports
)
{
return
mod
.
exports
;
return
(
defined
[
mod
.
map
.
id
]
=
mod
.
exports
)
;
}
else
{
}
else
{
return
(
mod
.
exports
=
defined
[
mod
.
map
.
id
]
=
{});
return
(
mod
.
exports
=
defined
[
mod
.
map
.
id
]
=
{});
}
}
...
@@ -579,15 +589,9 @@ var requirejs, require, define;
...
@@ -579,15 +589,9 @@ var requirejs, require, define;
id
:
mod
.
map
.
id
,
id
:
mod
.
map
.
id
,
uri
:
mod
.
map
.
url
,
uri
:
mod
.
map
.
url
,
config
:
function
()
{
config
:
function
()
{
var
c
,
return
getOwn
(
config
.
config
,
mod
.
map
.
id
)
||
{};
pkg
=
getOwn
(
config
.
pkgs
,
mod
.
map
.
id
);
// For packages, only support config targeted
// at the main module.
c
=
pkg
?
getOwn
(
config
.
config
,
mod
.
map
.
id
+
'
/
'
+
pkg
.
main
)
:
getOwn
(
config
.
config
,
mod
.
map
.
id
);
return
c
||
{};
},
},
exports
:
defined
[
mod
.
map
.
id
]
exports
:
mod
.
exports
||
(
mod
.
exports
=
{})
});
});
}
}
}
}
...
@@ -628,7 +632,7 @@ var requirejs, require, define;
...
@@ -628,7 +632,7 @@ var requirejs, require, define;
}
}
function
checkLoaded
()
{
function
checkLoaded
()
{
var
map
,
modId
,
err
,
usingPathFallback
,
var
err
,
usingPathFallback
,
waitInterval
=
config
.
waitSeconds
*
1000
,
waitInterval
=
config
.
waitSeconds
*
1000
,
//It is possible to disable the wait interval by using waitSeconds of 0.
//It is possible to disable the wait interval by using waitSeconds of 0.
expired
=
waitInterval
&&
(
context
.
startTime
+
waitInterval
)
<
new
Date
().
getTime
(),
expired
=
waitInterval
&&
(
context
.
startTime
+
waitInterval
)
<
new
Date
().
getTime
(),
...
@@ -646,7 +650,7 @@ var requirejs, require, define;
...
@@ -646,7 +650,7 @@ var requirejs, require, define;
//Figure out the state of all the modules.
//Figure out the state of all the modules.
eachProp
(
enabledRegistry
,
function
(
mod
)
{
eachProp
(
enabledRegistry
,
function
(
mod
)
{
map
=
mod
.
map
;
var
map
=
mod
.
map
,
modId
=
map
.
id
;
modId
=
map
.
id
;
//Skip things that are not enabled or in error state.
//Skip things that are not enabled or in error state.
...
@@ -870,17 +874,14 @@ var requirejs, require, define;
...
@@ -870,17 +874,14 @@ var requirejs, require, define;
exports
=
context
.
execCb
(
id
,
factory
,
depExports
,
exports
);
exports
=
context
.
execCb
(
id
,
factory
,
depExports
,
exports
);
}
}
if
(
this
.
map
.
isDefine
)
{
// Favor return value over exports. If node/cjs in play,
//If setting exports via 'module' is in play,
// then will not have a return value anyway. Favor
//favor that over return value and exports. After that,
// module.exports assignment over exports object.
//favor a non-undefined return value over exports use.
if
(
this
.
map
.
isDefine
&&
exports
===
undefined
)
{
cjsModule
=
this
.
module
;
cjsModule
=
this
.
module
;
if
(
cjsModule
&&
if
(
cjsModule
)
{
cjsModule
.
exports
!==
undefined
&&
//Make sure it is not already the exports value
cjsModule
.
exports
!==
this
.
exports
)
{
exports
=
cjsModule
.
exports
;
exports
=
cjsModule
.
exports
;
}
else
if
(
exports
===
undefined
&&
this
.
usingExports
)
{
}
else
if
(
this
.
usingExports
)
{
//exports already set the defined value.
//exports already set the defined value.
exports
=
this
.
exports
;
exports
=
this
.
exports
;
}
}
...
@@ -940,6 +941,7 @@ var requirejs, require, define;
...
@@ -940,6 +941,7 @@ var requirejs, require, define;
on
(
pluginMap
,
'
defined
'
,
bind
(
this
,
function
(
plugin
)
{
on
(
pluginMap
,
'
defined
'
,
bind
(
this
,
function
(
plugin
)
{
var
load
,
normalizedMap
,
normalizedMod
,
var
load
,
normalizedMap
,
normalizedMod
,
bundleId
=
getOwn
(
bundlesMap
,
this
.
map
.
id
),
name
=
this
.
map
.
name
,
name
=
this
.
map
.
name
,
parentName
=
this
.
map
.
parentMap
?
this
.
map
.
parentMap
.
name
:
null
,
parentName
=
this
.
map
.
parentMap
?
this
.
map
.
parentMap
.
name
:
null
,
localRequire
=
context
.
makeRequire
(
map
.
parentMap
,
{
localRequire
=
context
.
makeRequire
(
map
.
parentMap
,
{
...
@@ -985,6 +987,14 @@ var requirejs, require, define;
...
@@ -985,6 +987,14 @@ var requirejs, require, define;
return
;
return
;
}
}
//If a paths config, then just load that file instead to
//resolve the plugin, as it is built into that paths layer.
if
(
bundleId
)
{
this
.
map
.
url
=
context
.
nameToUrl
(
bundleId
);
this
.
load
();
return
;
}
load
=
bind
(
this
,
function
(
value
)
{
load
=
bind
(
this
,
function
(
value
)
{
this
.
init
([],
function
()
{
return
value
;
},
null
,
{
this
.
init
([],
function
()
{
return
value
;
},
null
,
{
enabled
:
true
enabled
:
true
...
@@ -1249,31 +1259,38 @@ var requirejs, require, define;
...
@@ -1249,31 +1259,38 @@ var requirejs, require, define;
}
}
}
}
//Save off the paths
and packages
since they require special processing,
//Save off the paths since they require special processing,
//they are additive.
//they are additive.
var
pkgs
=
config
.
pkgs
,
var
shim
=
config
.
shim
,
shim
=
config
.
shim
,
objs
=
{
objs
=
{
paths
:
true
,
paths
:
true
,
bundles
:
true
,
config
:
true
,
config
:
true
,
map
:
true
map
:
true
};
};
eachProp
(
cfg
,
function
(
value
,
prop
)
{
eachProp
(
cfg
,
function
(
value
,
prop
)
{
if
(
objs
[
prop
])
{
if
(
objs
[
prop
])
{
if
(
prop
===
'
map
'
)
{
if
(
!
config
[
prop
])
{
if
(
!
config
.
map
)
{
config
[
prop
]
=
{};
config
.
map
=
{};
}
}
mixin
(
config
[
prop
],
value
,
true
,
true
);
mixin
(
config
[
prop
],
value
,
true
,
true
);
}
else
{
mixin
(
config
[
prop
],
value
,
true
);
}
}
else
{
}
else
{
config
[
prop
]
=
value
;
config
[
prop
]
=
value
;
}
}
});
});
//Reverse map the bundles
if
(
cfg
.
bundles
)
{
eachProp
(
cfg
.
bundles
,
function
(
value
,
prop
)
{
each
(
value
,
function
(
v
)
{
if
(
v
!==
prop
)
{
bundlesMap
[
v
]
=
prop
;
}
});
});
}
//Merge shim
//Merge shim
if
(
cfg
.
shim
)
{
if
(
cfg
.
shim
)
{
eachProp
(
cfg
.
shim
,
function
(
value
,
id
)
{
eachProp
(
cfg
.
shim
,
function
(
value
,
id
)
{
...
@@ -1294,29 +1311,25 @@ var requirejs, require, define;
...
@@ -1294,29 +1311,25 @@ var requirejs, require, define;
//Adjust packages if necessary.
//Adjust packages if necessary.
if
(
cfg
.
packages
)
{
if
(
cfg
.
packages
)
{
each
(
cfg
.
packages
,
function
(
pkgObj
)
{
each
(
cfg
.
packages
,
function
(
pkgObj
)
{
var
location
;
var
location
,
name
;
pkgObj
=
typeof
pkgObj
===
'
string
'
?
{
name
:
pkgObj
}
:
pkgObj
;
pkgObj
=
typeof
pkgObj
===
'
string
'
?
{
name
:
pkgObj
}
:
pkgObj
;
name
=
pkgObj
.
name
;
location
=
pkgObj
.
location
;
location
=
pkgObj
.
location
;
if
(
location
)
{
config
.
paths
[
name
]
=
pkgObj
.
location
;
}
//Create a brand new object on pkgs, since currentPackages can
//Save pointer to main module ID for pkg name.
//be passed in again, and config.pkgs is the internal transformed
//state for all package configs.
pkgs
[
pkgObj
.
name
]
=
{
name
:
pkgObj
.
name
,
location
:
location
||
pkgObj
.
name
,
//Remove leading dot in main, so main paths are normalized,
//Remove leading dot in main, so main paths are normalized,
//and remove any trailing .js, since different package
//and remove any trailing .js, since different package
//envs have different conventions: some use a module name,
//envs have different conventions: some use a module name,
//some use a file name.
//some use a file name.
main
:
(
pkgObj
.
main
||
'
main
'
)
config
.
pkgs
[
name
]
=
pkgObj
.
name
+
'
/
'
+
(
pkgObj
.
main
||
'
main
'
)
.
replace
(
currDirRegExp
,
''
)
.
replace
(
currDirRegExp
,
''
)
.
replace
(
jsSuffixRegExp
,
''
)
.
replace
(
jsSuffixRegExp
,
''
);
};
});
});
//Done with modifications, assing packages back to context config
config
.
pkgs
=
pkgs
;
}
}
//If there are any "waiting to execute" modules in the registry,
//If there are any "waiting to execute" modules in the registry,
...
@@ -1469,6 +1482,15 @@ var requirejs, require, define;
...
@@ -1469,6 +1482,15 @@ var requirejs, require, define;
delete
urlFetched
[
map
.
url
];
delete
urlFetched
[
map
.
url
];
delete
undefEvents
[
id
];
delete
undefEvents
[
id
];
//Clean queued defines too. Go backwards
//in array so that the splices do not
//mess up the iteration.
eachReverse
(
defQueue
,
function
(
args
,
i
)
{
if
(
args
[
0
]
===
id
)
{
defQueue
.
splice
(
i
,
1
);
}
});
if
(
mod
)
{
if
(
mod
)
{
//Hold on to listeners in case the
//Hold on to listeners in case the
//module will be attempted to be reloaded
//module will be attempted to be reloaded
...
@@ -1488,7 +1510,7 @@ var requirejs, require, define;
...
@@ -1488,7 +1510,7 @@ var requirejs, require, define;
/**
/**
* Called to enable a module if it is still in the registry
* Called to enable a module if it is still in the registry
* awaiting enablement. A second arg, parent, the parent module,
* awaiting enablement. A second arg, parent, the parent module,
* is passed in for context, when this method is overriden by
* is passed in for context, when this method is overrid
d
en by
* the optimizer. Not shown here to keep code compact.
* the optimizer. Not shown here to keep code compact.
*/
*/
enable
:
function
(
depMap
)
{
enable
:
function
(
depMap
)
{
...
@@ -1562,8 +1584,19 @@ var requirejs, require, define;
...
@@ -1562,8 +1584,19 @@ var requirejs, require, define;
* internal API, not a public one. Use toUrl for the public API.
* internal API, not a public one. Use toUrl for the public API.
*/
*/
nameToUrl
:
function
(
moduleName
,
ext
,
skipExt
)
{
nameToUrl
:
function
(
moduleName
,
ext
,
skipExt
)
{
var
paths
,
pkgs
,
pkg
,
pkgPath
,
syms
,
i
,
parentModule
,
url
,
var
paths
,
syms
,
i
,
parentModule
,
url
,
parentPath
;
parentPath
,
bundleId
,
pkgMain
=
getOwn
(
config
.
pkgs
,
moduleName
);
if
(
pkgMain
)
{
moduleName
=
pkgMain
;
}
bundleId
=
getOwn
(
bundlesMap
,
moduleName
);
if
(
bundleId
)
{
return
context
.
nameToUrl
(
bundleId
,
ext
,
skipExt
);
}
//If a colon is in the URL, it indicates a protocol is used and it is just
//If a colon is in the URL, it indicates a protocol is used and it is just
//an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
//an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
...
@@ -1577,7 +1610,6 @@ var requirejs, require, define;
...
@@ -1577,7 +1610,6 @@ var requirejs, require, define;
}
else
{
}
else
{
//A module that needs to be converted to a path.
//A module that needs to be converted to a path.
paths
=
config
.
paths
;
paths
=
config
.
paths
;
pkgs
=
config
.
pkgs
;
syms
=
moduleName
.
split
(
'
/
'
);
syms
=
moduleName
.
split
(
'
/
'
);
//For each module name segment, see if there is a path
//For each module name segment, see if there is a path
...
@@ -1585,7 +1617,7 @@ var requirejs, require, define;
...
@@ -1585,7 +1617,7 @@ var requirejs, require, define;
//and work up from it.
//and work up from it.
for
(
i
=
syms
.
length
;
i
>
0
;
i
-=
1
)
{
for
(
i
=
syms
.
length
;
i
>
0
;
i
-=
1
)
{
parentModule
=
syms
.
slice
(
0
,
i
).
join
(
'
/
'
);
parentModule
=
syms
.
slice
(
0
,
i
).
join
(
'
/
'
);
pkg
=
getOwn
(
pkgs
,
parentModule
);
parentPath
=
getOwn
(
paths
,
parentModule
);
parentPath
=
getOwn
(
paths
,
parentModule
);
if
(
parentPath
)
{
if
(
parentPath
)
{
//If an array, it means there are a few choices,
//If an array, it means there are a few choices,
...
@@ -1595,16 +1627,6 @@ var requirejs, require, define;
...
@@ -1595,16 +1627,6 @@ var requirejs, require, define;
}
}
syms
.
splice
(
0
,
i
,
parentPath
);
syms
.
splice
(
0
,
i
,
parentPath
);
break
;
break
;
}
else
if
(
pkg
)
{
//If module name is just the package name, then looking
//for the main module.
if
(
moduleName
===
pkg
.
name
)
{
pkgPath
=
pkg
.
location
+
'
/
'
+
pkg
.
main
;
}
else
{
pkgPath
=
pkg
.
location
;
}
syms
.
splice
(
0
,
i
,
pkgPath
);
break
;
}
}
}
}
...
...
examples/backbone_require/
bower_components/todomvc-common/base
.css
→
examples/backbone_require/
node_modules/todomvc-app-css/index
.css
View file @
3c4b899e
...
@@ -12,25 +12,30 @@ button {
...
@@ -12,25 +12,30 @@ button {
font-size
:
100%
;
font-size
:
100%
;
vertical-align
:
baseline
;
vertical-align
:
baseline
;
font-family
:
inherit
;
font-family
:
inherit
;
font-weight
:
inherit
;
color
:
inherit
;
color
:
inherit
;
-webkit-appearance
:
none
;
-webkit-appearance
:
none
;
-ms-appearance
:
none
;
-ms-appearance
:
none
;
-o-appearance
:
none
;
appearance
:
none
;
appearance
:
none
;
-webkit-font-smoothing
:
antialiased
;
-moz-font-smoothing
:
antialiased
;
-ms-font-smoothing
:
antialiased
;
font-smoothing
:
antialiased
;
}
}
body
{
body
{
font
:
14px
'Helvetica Neue'
,
Helvetica
,
Arial
,
sans-serif
;
font
:
14px
'Helvetica Neue'
,
Helvetica
,
Arial
,
sans-serif
;
line-height
:
1.4em
;
line-height
:
1.4em
;
background
:
#
eaeaea
url('bg.png')
;
background
:
#
f5f5f5
;
color
:
#4d4d4d
;
color
:
#4d4d4d
;
width
:
550px
;
min-width
:
230px
;
max-width
:
550px
;
margin
:
0
auto
;
margin
:
0
auto
;
-webkit-font-smoothing
:
antialiased
;
-webkit-font-smoothing
:
antialiased
;
-moz-font-smoothing
:
antialiased
;
-moz-font-smoothing
:
antialiased
;
-ms-font-smoothing
:
antialiased
;
-ms-font-smoothing
:
antialiased
;
-o-font-smoothing
:
antialiased
;
font-smoothing
:
antialiased
;
font-smoothing
:
antialiased
;
font-weight
:
300
;
}
}
button
,
button
,
...
@@ -38,78 +43,50 @@ input[type="checkbox"] {
...
@@ -38,78 +43,50 @@ input[type="checkbox"] {
outline
:
none
;
outline
:
none
;
}
}
.hidden
{
display
:
none
;
}
#todoapp
{
#todoapp
{
background
:
#fff
;
background
:
#fff
;
background
:
rgba
(
255
,
255
,
255
,
0.9
);
margin
:
130px
0
40px
0
;
margin
:
130px
0
40px
0
;
border
:
1px
solid
#ccc
;
position
:
relative
;
position
:
relative
;
border-top-left-radius
:
2px
;
box-shadow
:
0
2px
4px
0
rgba
(
0
,
0
,
0
,
0.2
),
border-top-right-radius
:
2px
;
0
25px
50px
0
rgba
(
0
,
0
,
0
,
0.1
);
box-shadow
:
0
2px
6px
0
rgba
(
0
,
0
,
0
,
0.2
),
0
25px
50px
0
rgba
(
0
,
0
,
0
,
0.15
);
}
#todoapp
:before
{
content
:
''
;
border-left
:
1px
solid
#f5d6d6
;
border-right
:
1px
solid
#f5d6d6
;
width
:
2px
;
position
:
absolute
;
top
:
0
;
left
:
40px
;
height
:
100%
;
}
}
#todoapp
input
::-webkit-input-placeholder
{
#todoapp
input
::-webkit-input-placeholder
{
font-style
:
italic
;
font-style
:
italic
;
font-weight
:
300
;
color
:
#e6e6e6
;
}
}
#todoapp
input
::-moz-placeholder
{
#todoapp
input
::-moz-placeholder
{
font-style
:
italic
;
font-style
:
italic
;
color
:
#a9a9a9
;
font-weight
:
300
;
color
:
#e6e6e6
;
}
#todoapp
input
::input-placeholder
{
font-style
:
italic
;
font-weight
:
300
;
color
:
#e6e6e6
;
}
}
#todoapp
h1
{
#todoapp
h1
{
position
:
absolute
;
position
:
absolute
;
top
:
-1
20
px
;
top
:
-1
55
px
;
width
:
100%
;
width
:
100%
;
font-size
:
7
0px
;
font-size
:
10
0px
;
font-weight
:
bold
;
font-weight
:
100
;
text-align
:
center
;
text-align
:
center
;
color
:
#b3b3b3
;
color
:
rgba
(
175
,
47
,
47
,
0.15
);
color
:
rgba
(
255
,
255
,
255
,
0.3
);
text-shadow
:
-1px
-1px
rgba
(
0
,
0
,
0
,
0.2
);
-webkit-text-rendering
:
optimizeLegibility
;
-webkit-text-rendering
:
optimizeLegibility
;
-moz-text-rendering
:
optimizeLegibility
;
-moz-text-rendering
:
optimizeLegibility
;
-ms-text-rendering
:
optimizeLegibility
;
-ms-text-rendering
:
optimizeLegibility
;
-o-text-rendering
:
optimizeLegibility
;
text-rendering
:
optimizeLegibility
;
text-rendering
:
optimizeLegibility
;
}
}
#header
{
padding-top
:
15px
;
border-radius
:
inherit
;
}
#header
:before
{
content
:
''
;
position
:
absolute
;
top
:
0
;
right
:
0
;
left
:
0
;
height
:
15px
;
z-index
:
2
;
border-bottom
:
1px
solid
#6c615c
;
background
:
#8d7d77
;
background
:
-webkit-gradient
(
linear
,
left
top
,
left
bottom
,
from
(
rgba
(
132
,
110
,
100
,
0.8
)),
to
(
rgba
(
101
,
84
,
76
,
0.8
)));
background
:
-webkit-linear-gradient
(
top
,
rgba
(
132
,
110
,
100
,
0.8
),
rgba
(
101
,
84
,
76
,
0.8
));
background
:
linear-gradient
(
top
,
rgba
(
132
,
110
,
100
,
0.8
),
rgba
(
101
,
84
,
76
,
0.8
));
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
GradientType
=
0
,
StartColorStr
=
'#9d8b83'
,
EndColorStr
=
'#847670'
);
border-top-left-radius
:
1px
;
border-top-right-radius
:
1px
;
}
#new-todo
,
#new-todo
,
.edit
{
.edit
{
position
:
relative
;
position
:
relative
;
...
@@ -117,6 +94,7 @@ input[type="checkbox"] {
...
@@ -117,6 +94,7 @@ input[type="checkbox"] {
width
:
100%
;
width
:
100%
;
font-size
:
24px
;
font-size
:
24px
;
font-family
:
inherit
;
font-family
:
inherit
;
font-weight
:
inherit
;
line-height
:
1.4em
;
line-height
:
1.4em
;
border
:
0
;
border
:
0
;
outline
:
none
;
outline
:
none
;
...
@@ -124,29 +102,25 @@ input[type="checkbox"] {
...
@@ -124,29 +102,25 @@ input[type="checkbox"] {
padding
:
6px
;
padding
:
6px
;
border
:
1px
solid
#999
;
border
:
1px
solid
#999
;
box-shadow
:
inset
0
-1px
5px
0
rgba
(
0
,
0
,
0
,
0.2
);
box-shadow
:
inset
0
-1px
5px
0
rgba
(
0
,
0
,
0
,
0.2
);
-moz-box-sizing
:
border-box
;
-ms-box-sizing
:
border-box
;
-ms-box-sizing
:
border-box
;
-o-box-sizing
:
border-box
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
-webkit-font-smoothing
:
antialiased
;
-webkit-font-smoothing
:
antialiased
;
-moz-font-smoothing
:
antialiased
;
-moz-font-smoothing
:
antialiased
;
-ms-font-smoothing
:
antialiased
;
-ms-font-smoothing
:
antialiased
;
-o-font-smoothing
:
antialiased
;
font-smoothing
:
antialiased
;
font-smoothing
:
antialiased
;
}
}
#new-todo
{
#new-todo
{
padding
:
16px
16px
16px
60px
;
padding
:
16px
16px
16px
60px
;
border
:
none
;
border
:
none
;
background
:
rgba
(
0
,
0
,
0
,
0.02
);
background
:
rgba
(
0
,
0
,
0
,
0.003
);
z-index
:
2
;
box-shadow
:
inset
0
-2px
1px
rgba
(
0
,
0
,
0
,
0.03
);
box-shadow
:
none
;
}
}
#main
{
#main
{
position
:
relative
;
position
:
relative
;
z-index
:
2
;
z-index
:
2
;
border-top
:
1px
dotted
#adadad
;
border-top
:
1px
solid
#e6e6e6
;
}
}
label
[
for
=
'toggle-all'
]
{
label
[
for
=
'toggle-all'
]
{
...
@@ -155,19 +129,19 @@ label[for='toggle-all'] {
...
@@ -155,19 +129,19 @@ label[for='toggle-all'] {
#toggle-all
{
#toggle-all
{
position
:
absolute
;
position
:
absolute
;
top
:
-42px
;
top
:
-55px
;
left
:
-4px
;
left
:
-12px
;
width
:
40px
;
width
:
60px
;
height
:
34px
;
text-align
:
center
;
text-align
:
center
;
/* Mobile Safari */
border
:
none
;
/* Mobile Safari */
border
:
none
;
}
}
#toggle-all
:before
{
#toggle-all
:before
{
content
:
'
»
'
;
content
:
'
❯
'
;
font-size
:
2
8
px
;
font-size
:
2
2
px
;
color
:
#
d9d9d9
;
color
:
#
e6e6e6
;
padding
:
0
25px
7px
;
padding
:
10px
27px
10px
2
7px
;
}
}
#toggle-all
:checked:before
{
#toggle-all
:checked:before
{
...
@@ -183,7 +157,7 @@ label[for='toggle-all'] {
...
@@ -183,7 +157,7 @@ label[for='toggle-all'] {
#todo-list
li
{
#todo-list
li
{
position
:
relative
;
position
:
relative
;
font-size
:
24px
;
font-size
:
24px
;
border-bottom
:
1px
dotted
#ccc
;
border-bottom
:
1px
solid
#ededed
;
}
}
#todo-list
li
:last-child
{
#todo-list
li
:last-child
{
...
@@ -215,28 +189,18 @@ label[for='toggle-all'] {
...
@@ -215,28 +189,18 @@ label[for='toggle-all'] {
top
:
0
;
top
:
0
;
bottom
:
0
;
bottom
:
0
;
margin
:
auto
0
;
margin
:
auto
0
;
/* Mobile Safari */
border
:
none
;
/* Mobile Safari */
border
:
none
;
-webkit-appearance
:
none
;
-webkit-appearance
:
none
;
-ms-appearance
:
none
;
-ms-appearance
:
none
;
-o-appearance
:
none
;
appearance
:
none
;
appearance
:
none
;
}
}
#todo-list
li
.toggle
:after
{
#todo-list
li
.toggle
:after
{
content
:
'✔'
;
content
:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>')
;
/* 40 + a couple of pixels visual adjustment */
line-height
:
43px
;
font-size
:
20px
;
color
:
#d9d9d9
;
text-shadow
:
0
-1px
0
#bfbfbf
;
}
}
#todo-list
li
.toggle
:checked:after
{
#todo-list
li
.toggle
:checked:after
{
color
:
#85ada7
;
content
:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>')
;
text-shadow
:
0
1px
0
#669991
;
bottom
:
1px
;
position
:
relative
;
}
}
#todo-list
li
label
{
#todo-list
li
label
{
...
@@ -246,12 +210,11 @@ label[for='toggle-all'] {
...
@@ -246,12 +210,11 @@ label[for='toggle-all'] {
margin-left
:
45px
;
margin-left
:
45px
;
display
:
block
;
display
:
block
;
line-height
:
1.2
;
line-height
:
1.2
;
-webkit-transition
:
color
0.4s
;
transition
:
color
0.4s
;
transition
:
color
0.4s
;
}
}
#todo-list
li
.completed
label
{
#todo-list
li
.completed
label
{
color
:
#
a9a9a
9
;
color
:
#
d9d9d
9
;
text-decoration
:
line-through
;
text-decoration
:
line-through
;
}
}
...
@@ -264,21 +227,18 @@ label[for='toggle-all'] {
...
@@ -264,21 +227,18 @@ label[for='toggle-all'] {
width
:
40px
;
width
:
40px
;
height
:
40px
;
height
:
40px
;
margin
:
auto
0
;
margin
:
auto
0
;
font-size
:
22
px
;
font-size
:
30
px
;
color
:
#
a88a8
a
;
color
:
#
cc9a9
a
;
-webkit-transition
:
all
0.2s
;
margin-bottom
:
11px
;
transition
:
all
0.2s
;
transition
:
color
0.2s
ease-out
;
}
}
#todo-list
li
.destroy
:hover
{
#todo-list
li
.destroy
:hover
{
text-shadow
:
0
0
1px
#000
,
color
:
#af5b5e
;
0
0
10px
rgba
(
199
,
107
,
107
,
0.8
);
-webkit-transform
:
scale
(
1.3
);
transform
:
scale
(
1.3
);
}
}
#todo-list
li
.destroy
:after
{
#todo-list
li
.destroy
:after
{
content
:
'
✖
'
;
content
:
'
×
'
;
}
}
#todo-list
li
:hover
.destroy
{
#todo-list
li
:hover
.destroy
{
...
@@ -295,29 +255,25 @@ label[for='toggle-all'] {
...
@@ -295,29 +255,25 @@ label[for='toggle-all'] {
#footer
{
#footer
{
color
:
#777
;
color
:
#777
;
padding
:
0
15px
;
padding
:
10px
15px
;
position
:
absolute
;
right
:
0
;
bottom
:
-31px
;
left
:
0
;
height
:
20px
;
height
:
20px
;
z-index
:
1
;
text-align
:
center
;
text-align
:
center
;
border-top
:
1px
solid
#e6e6e6
;
}
}
#footer
:before
{
#footer
:before
{
content
:
''
;
content
:
''
;
position
:
absolute
;
position
:
absolute
;
right
:
0
;
right
:
0
;
bottom
:
31px
;
bottom
:
0
;
left
:
0
;
left
:
0
;
height
:
50px
;
height
:
50px
;
z-index
:
-1
;
overflow
:
hidden
;
box-shadow
:
0
1px
1px
rgba
(
0
,
0
,
0
,
0.
3
),
box-shadow
:
0
1px
1px
rgba
(
0
,
0
,
0
,
0.
2
),
0
6px
0
-3px
rgba
(
255
,
255
,
255
,
0.8
)
,
0
8px
0
-3px
#f6f6f6
,
0
7px
1px
-3px
rgba
(
0
,
0
,
0
,
0.3
),
0
9px
1px
-3px
rgba
(
0
,
0
,
0
,
0.2
),
0
43px
0
-6px
rgba
(
255
,
255
,
255
,
0.8
)
,
0
16px
0
-6px
#f6f6f6
,
0
44
px
2px
-6px
rgba
(
0
,
0
,
0
,
0.2
);
0
17
px
2px
-6px
rgba
(
0
,
0
,
0
,
0.2
);
}
}
#todo-count
{
#todo-count
{
...
@@ -325,6 +281,10 @@ label[for='toggle-all'] {
...
@@ -325,6 +281,10 @@ label[for='toggle-all'] {
text-align
:
left
;
text-align
:
left
;
}
}
#todo-count
strong
{
font-weight
:
300
;
}
#filters
{
#filters
{
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
...
@@ -339,49 +299,72 @@ label[for='toggle-all'] {
...
@@ -339,49 +299,72 @@ label[for='toggle-all'] {
}
}
#filters
li
a
{
#filters
li
a
{
color
:
#83756f
;
color
:
inherit
;
margin
:
2px
;
margin
:
3px
;
padding
:
3px
7px
;
text-decoration
:
none
;
text-decoration
:
none
;
border
:
1px
solid
transparent
;
border-radius
:
3px
;
}
#filters
li
a
.selected
,
#filters
li
a
:hover
{
border-color
:
rgba
(
175
,
47
,
47
,
0.1
);
}
}
#filters
li
a
.selected
{
#filters
li
a
.selected
{
font-weight
:
bold
;
border-color
:
rgba
(
175
,
47
,
47
,
0.2
)
;
}
}
#clear-completed
{
#clear-completed
,
html
#clear-completed
:active
{
float
:
right
;
float
:
right
;
position
:
relative
;
position
:
relative
;
line-height
:
20px
;
line-height
:
20px
;
text-decoration
:
none
;
text-decoration
:
none
;
background
:
rgba
(
0
,
0
,
0
,
0.1
);
cursor
:
pointer
;
font-size
:
11px
;
visibility
:
hidden
;
padding
:
0
10px
;
position
:
relative
;
border-radius
:
3px
;
}
box-shadow
:
0
-1px
0
0
rgba
(
0
,
0
,
0
,
0.2
);
#clear-completed
::after
{
visibility
:
visible
;
content
:
'Clear completed'
;
position
:
absolute
;
right
:
0
;
white-space
:
nowrap
;
}
}
#clear-completed
:hover
{
#clear-completed
:hover::after
{
background
:
rgba
(
0
,
0
,
0
,
0.15
);
text-decoration
:
underline
;
box-shadow
:
0
-1px
0
0
rgba
(
0
,
0
,
0
,
0.3
);
}
}
#info
{
#info
{
margin
:
65px
auto
0
;
margin
:
65px
auto
0
;
color
:
#
a6a6a6
;
color
:
#
bfbfbf
;
font-size
:
1
2
px
;
font-size
:
1
0
px
;
text-shadow
:
0
1px
0
rgba
(
255
,
255
,
255
,
0.
7
);
text-shadow
:
0
1px
0
rgba
(
255
,
255
,
255
,
0.
5
);
text-align
:
center
;
text-align
:
center
;
}
}
#info
p
{
line-height
:
1
;
}
#info
a
{
#info
a
{
color
:
inherit
;
color
:
inherit
;
text-decoration
:
none
;
font-weight
:
400
;
}
#info
a
:hover
{
text-decoration
:
underline
;
}
}
/*
/*
Hack to remove background from Mobile Safari.
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox
and Opera
Can't use it globally since it destroys checkboxes in Firefox
*/
*/
@media
screen
and
(
-webkit-min-device-pixel-ratio
:
0
)
{
@media
screen
and
(
-webkit-min-device-pixel-ratio
:
0
)
{
#toggle-all
,
#toggle-all
,
#todo-list
li
.toggle
{
#todo-list
li
.toggle
{
...
@@ -393,10 +376,6 @@ label[for='toggle-all'] {
...
@@ -393,10 +376,6 @@ label[for='toggle-all'] {
}
}
#toggle-all
{
#toggle-all
{
top
:
-56px
;
left
:
-15px
;
width
:
65px
;
height
:
41px
;
-webkit-transform
:
rotate
(
90deg
);
-webkit-transform
:
rotate
(
90deg
);
transform
:
rotate
(
90deg
);
transform
:
rotate
(
90deg
);
-webkit-appearance
:
none
;
-webkit-appearance
:
none
;
...
@@ -404,151 +383,12 @@ label[for='toggle-all'] {
...
@@ -404,151 +383,12 @@ label[for='toggle-all'] {
}
}
}
}
.hidden
{
@media
(
max-width
:
430px
)
{
display
:
none
;
#footer
{
}
height
:
50px
;
hr
{
margin
:
20px
0
;
border
:
0
;
border-top
:
1px
dashed
#C5C5C5
;
border-bottom
:
1px
dashed
#F7F7F7
;
}
.learn
a
{
font-weight
:
normal
;
text-decoration
:
none
;
color
:
#b83f45
;
}
.learn
a
:hover
{
text-decoration
:
underline
;
color
:
#787e7e
;
}
.learn
h3
,
.learn
h4
,
.learn
h5
{
margin
:
10px
0
;
font-weight
:
500
;
line-height
:
1.2
;
color
:
#000
;
}
.learn
h3
{
font-size
:
24px
;
}
.learn
h4
{
font-size
:
18px
;
}
.learn
h5
{
margin-bottom
:
0
;
font-size
:
14px
;
}
.learn
ul
{
padding
:
0
;
margin
:
0
0
30px
25px
;
}
.learn
li
{
line-height
:
20px
;
}
.learn
p
{
font-size
:
15px
;
font-weight
:
300
;
line-height
:
1.3
;
margin-top
:
0
;
margin-bottom
:
0
;
}
.quote
{
border
:
none
;
margin
:
20px
0
60px
0
;
}
.quote
p
{
font-style
:
italic
;
}
.quote
p
:before
{
content
:
'“'
;
font-size
:
50px
;
opacity
:
.15
;
position
:
absolute
;
top
:
-20px
;
left
:
3px
;
}
.quote
p
:after
{
content
:
'”'
;
font-size
:
50px
;
opacity
:
.15
;
position
:
absolute
;
bottom
:
-42px
;
right
:
3px
;
}
.quote
footer
{
position
:
absolute
;
bottom
:
-40px
;
right
:
0
;
}
.quote
footer
img
{
border-radius
:
3px
;
}
.quote
footer
a
{
margin-left
:
5px
;
vertical-align
:
middle
;
}
.speech-bubble
{
position
:
relative
;
padding
:
10px
;
background
:
rgba
(
0
,
0
,
0
,
.04
);
border-radius
:
5px
;
}
.speech-bubble
:after
{
content
:
''
;
position
:
absolute
;
top
:
100%
;
right
:
30px
;
border
:
13px
solid
transparent
;
border-top-color
:
rgba
(
0
,
0
,
0
,
.04
);
}
.learn-bar
>
.learn
{
position
:
absolute
;
width
:
272px
;
top
:
8px
;
left
:
-300px
;
padding
:
10px
;
border-radius
:
5px
;
background-color
:
rgba
(
255
,
255
,
255
,
.6
);
-webkit-transition-property
:
left
;
transition-property
:
left
;
-webkit-transition-duration
:
500ms
;
transition-duration
:
500ms
;
}
@media
(
min-width
:
899px
)
{
.learn-bar
{
width
:
auto
;
margin
:
0
0
0
300px
;
}
.learn-bar
>
.learn
{
left
:
8px
;
}
}
.learn-bar
#todoapp
{
#filters
{
width
:
550px
;
bottom
:
10px
;
margin
:
130px
auto
40px
auto
;
}
}
}
}
examples/backbone_require/node_modules/todomvc-common/base.css
0 → 100644
View file @
3c4b899e
hr
{
margin
:
20px
0
;
border
:
0
;
border-top
:
1px
dashed
#c5c5c5
;
border-bottom
:
1px
dashed
#f7f7f7
;
}
.learn
a
{
font-weight
:
normal
;
text-decoration
:
none
;
color
:
#b83f45
;
}
.learn
a
:hover
{
text-decoration
:
underline
;
color
:
#787e7e
;
}
.learn
h3
,
.learn
h4
,
.learn
h5
{
margin
:
10px
0
;
font-weight
:
500
;
line-height
:
1.2
;
color
:
#000
;
}
.learn
h3
{
font-size
:
24px
;
}
.learn
h4
{
font-size
:
18px
;
}
.learn
h5
{
margin-bottom
:
0
;
font-size
:
14px
;
}
.learn
ul
{
padding
:
0
;
margin
:
0
0
30px
25px
;
}
.learn
li
{
line-height
:
20px
;
}
.learn
p
{
font-size
:
15px
;
font-weight
:
300
;
line-height
:
1.3
;
margin-top
:
0
;
margin-bottom
:
0
;
}
#issue-count
{
display
:
none
;
}
.quote
{
border
:
none
;
margin
:
20px
0
60px
0
;
}
.quote
p
{
font-style
:
italic
;
}
.quote
p
:before
{
content
:
'“'
;
font-size
:
50px
;
opacity
:
.15
;
position
:
absolute
;
top
:
-20px
;
left
:
3px
;
}
.quote
p
:after
{
content
:
'”'
;
font-size
:
50px
;
opacity
:
.15
;
position
:
absolute
;
bottom
:
-42px
;
right
:
3px
;
}
.quote
footer
{
position
:
absolute
;
bottom
:
-40px
;
right
:
0
;
}
.quote
footer
img
{
border-radius
:
3px
;
}
.quote
footer
a
{
margin-left
:
5px
;
vertical-align
:
middle
;
}
.speech-bubble
{
position
:
relative
;
padding
:
10px
;
background
:
rgba
(
0
,
0
,
0
,
.04
);
border-radius
:
5px
;
}
.speech-bubble
:after
{
content
:
''
;
position
:
absolute
;
top
:
100%
;
right
:
30px
;
border
:
13px
solid
transparent
;
border-top-color
:
rgba
(
0
,
0
,
0
,
.04
);
}
.learn-bar
>
.learn
{
position
:
absolute
;
width
:
272px
;
top
:
8px
;
left
:
-300px
;
padding
:
10px
;
border-radius
:
5px
;
background-color
:
rgba
(
255
,
255
,
255
,
.6
);
transition-property
:
left
;
transition-duration
:
500ms
;
}
@media
(
min-width
:
899px
)
{
.learn-bar
{
width
:
auto
;
padding-left
:
300px
;
}
.learn-bar
>
.learn
{
left
:
8px
;
}
}
examples/backbone_require/
bower_component
s/todomvc-common/base.js
→
examples/backbone_require/
node_module
s/todomvc-common/base.js
View file @
3c4b899e
/* global _ */
(
function
()
{
(
function
()
{
'
use strict
'
;
'
use strict
'
;
/* jshint ignore:start */
// Underscore's Template Module
// Underscore's Template Module
// Courtesy of underscorejs.org
// Courtesy of underscorejs.org
var
_
=
(
function
(
_
)
{
var
_
=
(
function
(
_
)
{
...
@@ -114,6 +116,7 @@
...
@@ -114,6 +116,7 @@
if
(
location
.
hostname
===
'
todomvc.com
'
)
{
if
(
location
.
hostname
===
'
todomvc.com
'
)
{
window
.
_gaq
=
[[
'
_setAccount
'
,
'
UA-31081062-1
'
],[
'
_trackPageview
'
]];(
function
(
d
,
t
){
var
g
=
d
.
createElement
(
t
),
s
=
d
.
getElementsByTagName
(
t
)[
0
];
g
.
src
=
'
//www.google-analytics.com/ga.js
'
;
s
.
parentNode
.
insertBefore
(
g
,
s
)}(
document
,
'
script
'
));
window
.
_gaq
=
[[
'
_setAccount
'
,
'
UA-31081062-1
'
],[
'
_trackPageview
'
]];(
function
(
d
,
t
){
var
g
=
d
.
createElement
(
t
),
s
=
d
.
getElementsByTagName
(
t
)[
0
];
g
.
src
=
'
//www.google-analytics.com/ga.js
'
;
s
.
parentNode
.
insertBefore
(
g
,
s
)}(
document
,
'
script
'
));
}
}
/* jshint ignore:end */
function
redirect
()
{
function
redirect
()
{
if
(
location
.
hostname
===
'
tastejs.github.io
'
)
{
if
(
location
.
hostname
===
'
tastejs.github.io
'
)
{
...
@@ -175,13 +178,17 @@
...
@@ -175,13 +178,17 @@
if
(
learnJSON
.
backend
)
{
if
(
learnJSON
.
backend
)
{
this
.
frameworkJSON
=
learnJSON
.
backend
;
this
.
frameworkJSON
=
learnJSON
.
backend
;
this
.
frameworkJSON
.
issueLabel
=
framework
;
this
.
append
({
this
.
append
({
backend
:
true
backend
:
true
});
});
}
else
if
(
learnJSON
[
framework
])
{
}
else
if
(
learnJSON
[
framework
])
{
this
.
frameworkJSON
=
learnJSON
[
framework
];
this
.
frameworkJSON
=
learnJSON
[
framework
];
this
.
frameworkJSON
.
issueLabel
=
framework
;
this
.
append
();
this
.
append
();
}
}
this
.
fetchIssueCount
();
}
}
Learn
.
prototype
.
append
=
function
(
opts
)
{
Learn
.
prototype
.
append
=
function
(
opts
)
{
...
@@ -212,6 +219,26 @@
...
@@ -212,6 +219,26 @@
document
.
body
.
insertAdjacentHTML
(
'
afterBegin
'
,
aside
.
outerHTML
);
document
.
body
.
insertAdjacentHTML
(
'
afterBegin
'
,
aside
.
outerHTML
);
};
};
Learn
.
prototype
.
fetchIssueCount
=
function
()
{
var
issueLink
=
document
.
getElementById
(
'
issue-count-link
'
);
if
(
issueLink
)
{
var
url
=
issueLink
.
href
.
replace
(
'
https://github.com
'
,
'
https://api.github.com/repos
'
);
var
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
'
GET
'
,
url
,
true
);
xhr
.
onload
=
function
(
e
)
{
var
parsedResponse
=
JSON
.
parse
(
e
.
target
.
responseText
);
if
(
parsedResponse
instanceof
Array
)
{
var
count
=
parsedResponse
.
length
if
(
count
!==
0
)
{
issueLink
.
innerHTML
=
'
This app has
'
+
count
+
'
open issues
'
;
document
.
getElementById
(
'
issue-count
'
).
style
.
display
=
'
inline
'
;
}
}
};
xhr
.
send
();
}
};
redirect
();
redirect
();
getFile
(
'
learn.json
'
,
Learn
);
getFile
(
'
learn.json
'
,
Learn
);
})();
})();
examples/backbone_require/
bower_component
s/underscore/underscore.js
→
examples/backbone_require/
node_module
s/underscore/underscore.js
View file @
3c4b899e
// Underscore.js 1.
5.2
// Underscore.js 1.
7.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
()
{
...
@@ -14,9 +14,6 @@
...
@@ -14,9 +14,6 @@
// Save the previous value of the `_` variable.
// Save the previous value of the `_` variable.
var
previousUnderscore
=
root
.
_
;
var
previousUnderscore
=
root
.
_
;
// Establish the object that gets returned to break out of a loop iteration.
var
breaker
=
{};
// Save bytes in the minified (but not gzipped) version:
// Save bytes in the minified (but not gzipped) version:
var
ArrayProto
=
Array
.
prototype
,
ObjProto
=
Object
.
prototype
,
FuncProto
=
Function
.
prototype
;
var
ArrayProto
=
Array
.
prototype
,
ObjProto
=
Object
.
prototype
,
FuncProto
=
Function
.
prototype
;
...
@@ -31,15 +28,6 @@
...
@@ -31,15 +28,6 @@
// All **ECMAScript 5** native function implementations that we hope to use
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
// are declared here.
var
var
nativeForEach
=
ArrayProto
.
forEach
,
nativeMap
=
ArrayProto
.
map
,
nativeReduce
=
ArrayProto
.
reduce
,
nativeReduceRight
=
ArrayProto
.
reduceRight
,
nativeFilter
=
ArrayProto
.
filter
,
nativeEvery
=
ArrayProto
.
every
,
nativeSome
=
ArrayProto
.
some
,
nativeIndexOf
=
ArrayProto
.
indexOf
,
nativeLastIndexOf
=
ArrayProto
.
lastIndexOf
,
nativeIsArray
=
Array
.
isArray
,
nativeIsArray
=
Array
.
isArray
,
nativeKeys
=
Object
.
keys
,
nativeKeys
=
Object
.
keys
,
nativeBind
=
FuncProto
.
bind
;
nativeBind
=
FuncProto
.
bind
;
...
@@ -53,8 +41,7 @@
...
@@ -53,8 +41,7 @@
// Export the Underscore object for **Node.js**, with
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// the browser, add `_` as a global object.
// for Closure Compiler "advanced" mode.
if
(
typeof
exports
!==
'
undefined
'
)
{
if
(
typeof
exports
!==
'
undefined
'
)
{
if
(
typeof
module
!==
'
undefined
'
&&
module
.
exports
)
{
if
(
typeof
module
!==
'
undefined
'
&&
module
.
exports
)
{
exports
=
module
.
exports
=
_
;
exports
=
module
.
exports
=
_
;
...
@@ -65,97 +52,125 @@
...
@@ -65,97 +52,125 @@
}
}
// Current version.
// Current version.
_
.
VERSION
=
'
1.5.2
'
;
_
.
VERSION
=
'
1.7.0
'
;
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var
createCallback
=
function
(
func
,
context
,
argCount
)
{
if
(
context
===
void
0
)
return
func
;
switch
(
argCount
==
null
?
3
:
argCount
)
{
case
1
:
return
function
(
value
)
{
return
func
.
call
(
context
,
value
);
};
case
2
:
return
function
(
value
,
other
)
{
return
func
.
call
(
context
,
value
,
other
);
};
case
3
:
return
function
(
value
,
index
,
collection
)
{
return
func
.
call
(
context
,
value
,
index
,
collection
);
};
case
4
:
return
function
(
accumulator
,
value
,
index
,
collection
)
{
return
func
.
call
(
context
,
accumulator
,
value
,
index
,
collection
);
};
}
return
function
()
{
return
func
.
apply
(
context
,
arguments
);
};
};
// A mostly-internal function to generate callbacks that can be applied
// to each element in a collection, returning the desired result — either
// identity, an arbitrary callback, a property matcher, or a property accessor.
_
.
iteratee
=
function
(
value
,
context
,
argCount
)
{
if
(
value
==
null
)
return
_
.
identity
;
if
(
_
.
isFunction
(
value
))
return
createCallback
(
value
,
context
,
argCount
);
if
(
_
.
isObject
(
value
))
return
_
.
matches
(
value
);
return
_
.
property
(
value
);
};
// Collection Functions
// Collection Functions
// --------------------
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles
objects with the built-in `forEach`, arrays, and raw objects.
// Handles
raw objects in addition to array-likes. Treats all
//
Delegates to **ECMAScript 5**'s native `forEach` if availabl
e.
//
sparse array-likes as if they were dens
e.
var
each
=
_
.
each
=
_
.
forEach
=
function
(
obj
,
iterator
,
context
)
{
_
.
each
=
_
.
forEach
=
function
(
obj
,
iteratee
,
context
)
{
if
(
obj
==
null
)
return
;
if
(
obj
==
null
)
return
obj
;
i
f
(
nativeForEach
&&
obj
.
forEach
===
nativeForEach
)
{
i
teratee
=
createCallback
(
iteratee
,
context
);
obj
.
forEach
(
iterator
,
context
)
;
var
i
,
length
=
obj
.
length
;
}
else
if
(
obj
.
length
===
+
obj
.
length
)
{
if
(
length
===
+
length
)
{
for
(
var
i
=
0
,
length
=
obj
.
length
;
i
<
length
;
i
++
)
{
for
(
i
=
0
;
i
<
length
;
i
++
)
{
i
f
(
iterator
.
call
(
context
,
obj
[
i
],
i
,
obj
)
===
breaker
)
return
;
i
teratee
(
obj
[
i
],
i
,
obj
)
;
}
}
}
else
{
}
else
{
var
keys
=
_
.
keys
(
obj
);
var
keys
=
_
.
keys
(
obj
);
for
(
var
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
for
(
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
i
f
(
iterator
.
call
(
context
,
obj
[
keys
[
i
]],
keys
[
i
],
obj
)
===
breaker
)
return
;
i
teratee
(
obj
[
keys
[
i
]],
keys
[
i
],
obj
)
;
}
}
}
}
return
obj
;
};
};
// Return the results of applying the iterator to each element.
// Return the results of applying the iteratee to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_
.
map
=
_
.
collect
=
function
(
obj
,
iteratee
,
context
)
{
_
.
map
=
_
.
collect
=
function
(
obj
,
iterator
,
context
)
{
if
(
obj
==
null
)
return
[];
var
results
=
[];
iteratee
=
_
.
iteratee
(
iteratee
,
context
);
if
(
obj
==
null
)
return
results
;
var
keys
=
obj
.
length
!==
+
obj
.
length
&&
_
.
keys
(
obj
),
if
(
nativeMap
&&
obj
.
map
===
nativeMap
)
return
obj
.
map
(
iterator
,
context
);
length
=
(
keys
||
obj
).
length
,
each
(
obj
,
function
(
value
,
index
,
list
)
{
results
=
Array
(
length
),
results
.
push
(
iterator
.
call
(
context
,
value
,
index
,
list
));
currentKey
;
});
for
(
var
index
=
0
;
index
<
length
;
index
++
)
{
currentKey
=
keys
?
keys
[
index
]
:
index
;
results
[
index
]
=
iteratee
(
obj
[
currentKey
],
currentKey
,
obj
);
}
return
results
;
return
results
;
};
};
var
reduceError
=
'
Reduce of empty array with no initial value
'
;
var
reduceError
=
'
Reduce of empty array with no initial value
'
;
// **Reduce** builds up a single result from a list of values, aka `inject`,
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
// or `foldl`.
_
.
reduce
=
_
.
foldl
=
_
.
inject
=
function
(
obj
,
iterator
,
memo
,
context
)
{
_
.
reduce
=
_
.
foldl
=
_
.
inject
=
function
(
obj
,
iteratee
,
memo
,
context
)
{
var
initial
=
arguments
.
length
>
2
;
if
(
obj
==
null
)
obj
=
[];
if
(
obj
==
null
)
obj
=
[];
if
(
nativeReduce
&&
obj
.
reduce
===
nativeReduce
)
{
iteratee
=
createCallback
(
iteratee
,
context
,
4
);
if
(
context
)
iterator
=
_
.
bind
(
iterator
,
context
);
var
keys
=
obj
.
length
!==
+
obj
.
length
&&
_
.
keys
(
obj
),
return
initial
?
obj
.
reduce
(
iterator
,
memo
)
:
obj
.
reduce
(
iterator
);
length
=
(
keys
||
obj
).
length
,
}
index
=
0
,
currentKey
;
each
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
arguments
.
length
<
3
)
{
if
(
!
initial
)
{
if
(
!
length
)
throw
new
TypeError
(
reduceError
);
memo
=
value
;
memo
=
obj
[
keys
?
keys
[
index
++
]
:
index
++
];
initial
=
true
;
}
}
else
{
for
(;
index
<
length
;
index
++
)
{
memo
=
iterator
.
call
(
context
,
memo
,
value
,
index
,
list
);
currentKey
=
keys
?
keys
[
index
]
:
index
;
memo
=
iteratee
(
memo
,
obj
[
currentKey
],
currentKey
,
obj
);
}
}
});
if
(
!
initial
)
throw
new
TypeError
(
reduceError
);
return
memo
;
return
memo
;
};
};
// The right-associative version of reduce, also known as `foldr`.
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_
.
reduceRight
=
_
.
foldr
=
function
(
obj
,
iteratee
,
memo
,
context
)
{
_
.
reduceRight
=
_
.
foldr
=
function
(
obj
,
iterator
,
memo
,
context
)
{
var
initial
=
arguments
.
length
>
2
;
if
(
obj
==
null
)
obj
=
[];
if
(
obj
==
null
)
obj
=
[];
if
(
nativeReduceRight
&&
obj
.
reduceRight
===
nativeReduceRight
)
{
iteratee
=
createCallback
(
iteratee
,
context
,
4
);
if
(
context
)
iterator
=
_
.
bind
(
iterator
,
context
);
var
keys
=
obj
.
length
!==
+
obj
.
length
&&
_
.
keys
(
obj
),
return
initial
?
obj
.
reduceRight
(
iterator
,
memo
)
:
obj
.
reduceRight
(
iterator
);
index
=
(
keys
||
obj
).
length
,
}
currentKey
;
var
length
=
obj
.
length
;
if
(
arguments
.
length
<
3
)
{
if
(
length
!==
+
length
)
{
if
(
!
index
)
throw
new
TypeError
(
reduceError
);
var
keys
=
_
.
keys
(
obj
);
memo
=
obj
[
keys
?
keys
[
--
index
]
:
--
index
];
length
=
keys
.
length
;
}
}
each
(
obj
,
function
(
value
,
index
,
list
)
{
while
(
index
--
)
{
index
=
keys
?
keys
[
--
length
]
:
--
length
;
currentKey
=
keys
?
keys
[
index
]
:
index
;
if
(
!
initial
)
{
memo
=
iteratee
(
memo
,
obj
[
currentKey
],
currentKey
,
obj
);
memo
=
obj
[
index
];
initial
=
true
;
}
else
{
memo
=
iterator
.
call
(
context
,
memo
,
obj
[
index
],
index
,
list
);
}
}
});
if
(
!
initial
)
throw
new
TypeError
(
reduceError
);
return
memo
;
return
memo
;
};
};
// 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
)
{
predicate
=
_
.
iteratee
(
predicate
,
context
);
if
(
iterator
.
call
(
context
,
value
,
index
,
list
))
{
_
.
some
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
predicate
(
value
,
index
,
list
))
{
result
=
value
;
result
=
value
;
return
true
;
return
true
;
}
}
...
@@ -164,61 +179,58 @@
...
@@ -164,61 +179,58 @@
};
};
// 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.
// 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
);
predicate
=
_
.
iteratee
(
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
(
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
,
_
.
negate
(
_
.
iteratee
(
predicate
)),
context
);
return
!
iterator
.
call
(
context
,
value
,
index
,
list
);
},
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.
// Aliased as `all`.
// Aliased as `all`.
_
.
every
=
_
.
all
=
function
(
obj
,
iterator
,
context
)
{
_
.
every
=
_
.
all
=
function
(
obj
,
predicate
,
context
)
{
iterator
||
(
iterator
=
_
.
identity
);
if
(
obj
==
null
)
return
true
;
var
result
=
true
;
predicate
=
_
.
iteratee
(
predicate
,
context
);
if
(
obj
==
null
)
return
result
;
var
keys
=
obj
.
length
!==
+
obj
.
length
&&
_
.
keys
(
obj
),
if
(
nativeEvery
&&
obj
.
every
===
nativeEvery
)
return
obj
.
every
(
iterator
,
context
);
length
=
(
keys
||
obj
).
length
,
each
(
obj
,
function
(
value
,
index
,
list
)
{
index
,
currentKey
;
if
(
!
(
result
=
result
&&
iterator
.
call
(
context
,
value
,
index
,
list
)))
return
breaker
;
for
(
index
=
0
;
index
<
length
;
index
++
)
{
});
currentKey
=
keys
?
keys
[
index
]
:
index
;
return
!!
result
;
if
(
!
predicate
(
obj
[
currentKey
],
currentKey
,
obj
))
return
false
;
}
return
true
;
};
};
// 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.
// Aliased as `any`.
// Aliased as `any`.
var
any
=
_
.
some
=
_
.
any
=
function
(
obj
,
iterator
,
context
)
{
_
.
some
=
_
.
any
=
function
(
obj
,
predicate
,
context
)
{
iterator
||
(
iterator
=
_
.
identity
);
if
(
obj
==
null
)
return
false
;
var
result
=
false
;
predicate
=
_
.
iteratee
(
predicate
,
context
);
if
(
obj
==
null
)
return
result
;
var
keys
=
obj
.
length
!==
+
obj
.
length
&&
_
.
keys
(
obj
),
if
(
nativeSome
&&
obj
.
some
===
nativeSome
)
return
obj
.
some
(
iterator
,
context
);
length
=
(
keys
||
obj
).
length
,
each
(
obj
,
function
(
value
,
index
,
list
)
{
index
,
currentKey
;
if
(
result
||
(
result
=
iterator
.
call
(
context
,
value
,
index
,
list
)))
return
breaker
;
for
(
index
=
0
;
index
<
length
;
index
++
)
{
});
currentKey
=
keys
?
keys
[
index
]
:
index
;
return
!!
result
;
if
(
predicate
(
obj
[
currentKey
],
currentKey
,
obj
))
return
true
;
}
return
false
;
};
};
// Determine if the array or object contains a given value (using `===`).
// Determine if the array or object contains a given value (using `===`).
// Aliased as `include`.
// Aliased as `include`.
_
.
contains
=
_
.
include
=
function
(
obj
,
target
)
{
_
.
contains
=
_
.
include
=
function
(
obj
,
target
)
{
if
(
obj
==
null
)
return
false
;
if
(
obj
==
null
)
return
false
;
if
(
nativeIndexOf
&&
obj
.
indexOf
===
nativeIndexOf
)
return
obj
.
indexOf
(
target
)
!=
-
1
;
if
(
obj
.
length
!==
+
obj
.
length
)
obj
=
_
.
values
(
obj
);
return
any
(
obj
,
function
(
value
)
{
return
_
.
indexOf
(
obj
,
target
)
>=
0
;
return
value
===
target
;
});
};
};
// Invoke a method (with arguments) on every item in a collection.
// Invoke a method (with arguments) on every item in a collection.
...
@@ -232,94 +244,104 @@
...
@@ -232,94 +244,104 @@
// 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).
// Can't optimize arrays of integers longer than 65,535 elements.
_
.
max
=
function
(
obj
,
iteratee
,
context
)
{
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
var
result
=
-
Infinity
,
lastComputed
=
-
Infinity
,
_
.
max
=
function
(
obj
,
iterator
,
context
)
{
value
,
computed
;
if
(
!
iterator
&&
_
.
isArray
(
obj
)
&&
obj
[
0
]
===
+
obj
[
0
]
&&
obj
.
length
<
65535
)
{
if
(
iteratee
==
null
&&
obj
!=
null
)
{
return
Math
.
max
.
apply
(
Math
,
obj
);
obj
=
obj
.
length
===
+
obj
.
length
?
obj
:
_
.
values
(
obj
);
for
(
var
i
=
0
,
length
=
obj
.
length
;
i
<
length
;
i
++
)
{
value
=
obj
[
i
];
if
(
value
>
result
)
{
result
=
value
;
}
}
}
else
{
iteratee
=
_
.
iteratee
(
iteratee
,
context
);
_
.
each
(
obj
,
function
(
value
,
index
,
list
)
{
computed
=
iteratee
(
value
,
index
,
list
);
if
(
computed
>
lastComputed
||
computed
===
-
Infinity
&&
result
===
-
Infinity
)
{
result
=
value
;
lastComputed
=
computed
;
}
}
if
(
!
iterator
&&
_
.
isEmpty
(
obj
))
return
-
Infinity
;
var
result
=
{
computed
:
-
Infinity
,
value
:
-
Infinity
};
each
(
obj
,
function
(
value
,
index
,
list
)
{
var
computed
=
iterator
?
iterator
.
call
(
context
,
value
,
index
,
list
)
:
value
;
computed
>
result
.
computed
&&
(
result
=
{
value
:
value
,
computed
:
computed
});
});
});
return
result
.
value
;
}
return
result
;
};
};
// Return the minimum element (or element-based computation).
// Return the minimum element (or element-based computation).
_
.
min
=
function
(
obj
,
iterator
,
context
)
{
_
.
min
=
function
(
obj
,
iteratee
,
context
)
{
if
(
!
iterator
&&
_
.
isArray
(
obj
)
&&
obj
[
0
]
===
+
obj
[
0
]
&&
obj
.
length
<
65535
)
{
var
result
=
Infinity
,
lastComputed
=
Infinity
,
return
Math
.
min
.
apply
(
Math
,
obj
);
value
,
computed
;
}
if
(
iteratee
==
null
&&
obj
!=
null
)
{
if
(
!
iterator
&&
_
.
isEmpty
(
obj
))
return
Infinity
;
obj
=
obj
.
length
===
+
obj
.
length
?
obj
:
_
.
values
(
obj
);
var
result
=
{
computed
:
Infinity
,
value
:
Infinity
};
for
(
var
i
=
0
,
length
=
obj
.
length
;
i
<
length
;
i
++
)
{
each
(
obj
,
function
(
value
,
index
,
list
)
{
value
=
obj
[
i
];
var
computed
=
iterator
?
iterator
.
call
(
context
,
value
,
index
,
list
)
:
value
;
if
(
value
<
result
)
{
computed
<
result
.
computed
&&
(
result
=
{
value
:
value
,
computed
:
computed
});
result
=
value
;
}
}
}
else
{
iteratee
=
_
.
iteratee
(
iteratee
,
context
);
_
.
each
(
obj
,
function
(
value
,
index
,
list
)
{
computed
=
iteratee
(
value
,
index
,
list
);
if
(
computed
<
lastComputed
||
computed
===
Infinity
&&
result
===
Infinity
)
{
result
=
value
;
lastComputed
=
computed
;
}
});
});
return
result
.
value
;
}
return
result
;
};
};
// Shuffle a
n array
, using the modern version of the
// Shuffle a
collection
, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_
.
shuffle
=
function
(
obj
)
{
_
.
shuffle
=
function
(
obj
)
{
var
rand
;
var
set
=
obj
&&
obj
.
length
===
+
obj
.
length
?
obj
:
_
.
values
(
obj
)
;
var
index
=
0
;
var
length
=
set
.
length
;
var
shuffled
=
[]
;
var
shuffled
=
Array
(
length
)
;
each
(
obj
,
function
(
value
)
{
for
(
var
index
=
0
,
rand
;
index
<
length
;
index
++
)
{
rand
=
_
.
random
(
index
++
);
rand
=
_
.
random
(
0
,
index
);
shuffled
[
index
-
1
]
=
shuffled
[
rand
];
if
(
rand
!==
index
)
shuffled
[
index
]
=
shuffled
[
rand
];
shuffled
[
rand
]
=
value
;
shuffled
[
rand
]
=
set
[
index
]
;
}
);
}
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
));
};
};
// An internal function to generate lookup iterators.
// Sort the object's values by a criterion produced by an iteratee.
var
lookupIterator
=
function
(
value
)
{
_
.
sortBy
=
function
(
obj
,
iteratee
,
context
)
{
return
_
.
isFunction
(
value
)
?
value
:
function
(
obj
){
return
obj
[
value
];
};
iteratee
=
_
.
iteratee
(
iteratee
,
context
);
};
// Sort the object's values by a criterion produced by an iterator.
_
.
sortBy
=
function
(
obj
,
value
,
context
)
{
var
iterator
=
lookupIterator
(
value
);
return
_
.
pluck
(
_
.
map
(
obj
,
function
(
value
,
index
,
list
)
{
return
_
.
pluck
(
_
.
map
(
obj
,
function
(
value
,
index
,
list
)
{
return
{
return
{
value
:
value
,
value
:
value
,
index
:
index
,
index
:
index
,
criteria
:
iterat
or
.
call
(
context
,
value
,
index
,
list
)
criteria
:
iterat
ee
(
value
,
index
,
list
)
};
};
}).
sort
(
function
(
left
,
right
)
{
}).
sort
(
function
(
left
,
right
)
{
var
a
=
left
.
criteria
;
var
a
=
left
.
criteria
;
...
@@ -334,12 +356,12 @@
...
@@ -334,12 +356,12 @@
// 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
,
valu
e
,
context
)
{
return
function
(
obj
,
iterate
e
,
context
)
{
var
result
=
{};
var
result
=
{};
var
iterator
=
value
==
null
?
_
.
identity
:
lookupIterator
(
value
);
iteratee
=
_
.
iteratee
(
iteratee
,
context
);
each
(
obj
,
function
(
value
,
index
)
{
_
.
each
(
obj
,
function
(
value
,
index
)
{
var
key
=
iterat
or
.
call
(
context
,
value
,
index
,
obj
);
var
key
=
iterat
ee
(
value
,
index
,
obj
);
behavior
(
result
,
key
,
value
);
behavior
(
result
,
value
,
key
);
});
});
return
result
;
return
result
;
};
};
...
@@ -347,32 +369,32 @@
...
@@ -347,32 +369,32 @@
// 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
,
value
,
key
)
{
(
_
.
has
(
result
,
key
)
?
result
[
key
]
:
(
result
[
key
]
=
[])).
push
(
value
)
;
if
(
_
.
has
(
result
,
key
))
result
[
key
].
push
(
value
);
else
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
// when you know that your index values will be unique.
// when you know that your index values will be unique.
_
.
indexBy
=
group
(
function
(
result
,
key
,
value
)
{
_
.
indexBy
=
group
(
function
(
result
,
value
,
key
)
{
result
[
key
]
=
value
;
result
[
key
]
=
value
;
});
});
// Counts instances of an object that group by a certain criterion. Pass
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// either a string attribute to count by, or a function that returns the
// criterion.
// criterion.
_
.
countBy
=
group
(
function
(
result
,
key
)
{
_
.
countBy
=
group
(
function
(
result
,
value
,
key
)
{
_
.
has
(
result
,
key
)
?
result
[
key
]
++
:
result
[
key
]
=
1
;
if
(
_
.
has
(
result
,
key
))
result
[
key
]
++
;
else
result
[
key
]
=
1
;
});
});
// 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
,
iterat
or
,
context
)
{
_
.
sortedIndex
=
function
(
array
,
obj
,
iterat
ee
,
context
)
{
iterat
or
=
iterator
==
null
?
_
.
identity
:
lookupIterator
(
iterator
);
iterat
ee
=
_
.
iteratee
(
iteratee
,
context
,
1
);
var
value
=
iterat
or
.
call
(
context
,
obj
);
var
value
=
iterat
ee
(
obj
);
var
low
=
0
,
high
=
array
.
length
;
var
low
=
0
,
high
=
array
.
length
;
while
(
low
<
high
)
{
while
(
low
<
high
)
{
var
mid
=
(
low
+
high
)
>>>
1
;
var
mid
=
low
+
high
>>>
1
;
i
terator
.
call
(
context
,
array
[
mid
])
<
value
?
low
=
mid
+
1
:
high
=
mid
;
i
f
(
iteratee
(
array
[
mid
])
<
value
)
low
=
mid
+
1
;
else
high
=
mid
;
}
}
return
low
;
return
low
;
};
};
...
@@ -388,7 +410,18 @@
...
@@ -388,7 +410,18 @@
// Return the number of elements in an object.
// Return the number of elements in an object.
_
.
size
=
function
(
obj
)
{
_
.
size
=
function
(
obj
)
{
if
(
obj
==
null
)
return
0
;
if
(
obj
==
null
)
return
0
;
return
(
obj
.
length
===
+
obj
.
length
)
?
obj
.
length
:
_
.
keys
(
obj
).
length
;
return
obj
.
length
===
+
obj
.
length
?
obj
.
length
:
_
.
keys
(
obj
).
length
;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_
.
partition
=
function
(
obj
,
predicate
,
context
)
{
predicate
=
_
.
iteratee
(
predicate
,
context
);
var
pass
=
[],
fail
=
[];
_
.
each
(
obj
,
function
(
value
,
key
,
obj
)
{
(
predicate
(
value
,
key
,
obj
)
?
pass
:
fail
).
push
(
value
);
});
return
[
pass
,
fail
];
};
};
// Array Functions
// Array Functions
...
@@ -399,7 +432,9 @@
...
@@ -399,7 +432,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
...
@@ -407,18 +442,15 @@
...
@@ -407,18 +442,15 @@
// the array, excluding the last N. The **guard** check allows it to work with
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
// `_.map`.
_
.
initial
=
function
(
array
,
n
,
guard
)
{
_
.
initial
=
function
(
array
,
n
,
guard
)
{
return
slice
.
call
(
array
,
0
,
array
.
length
-
((
n
==
null
)
||
guard
?
1
:
n
));
return
slice
.
call
(
array
,
0
,
Math
.
max
(
0
,
array
.
length
-
(
n
==
null
||
guard
?
1
:
n
)
));
};
};
// Get the last element of an array. Passing **n** will return the last N
// Get the last element of an array. Passing **n** will return the last N
// 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`.
...
@@ -426,7 +458,7 @@
...
@@ -426,7 +458,7 @@
// the rest N values in the array. The **guard**
// the rest N values in the array. The **guard**
// check allows it to work with `_.map`.
// check allows it to work with `_.map`.
_
.
rest
=
_
.
tail
=
_
.
drop
=
function
(
array
,
n
,
guard
)
{
_
.
rest
=
_
.
tail
=
_
.
drop
=
function
(
array
,
n
,
guard
)
{
return
slice
.
call
(
array
,
(
n
==
null
)
||
guard
?
1
:
n
);
return
slice
.
call
(
array
,
n
==
null
||
guard
?
1
:
n
);
};
};
// Trim out all falsy values from an array.
// Trim out all falsy values from an array.
...
@@ -435,23 +467,26 @@
...
@@ -435,23 +467,26 @@
};
};
// Internal implementation of a recursive `flatten` function.
// Internal implementation of a recursive `flatten` function.
var
flatten
=
function
(
input
,
shallow
,
output
)
{
var
flatten
=
function
(
input
,
shallow
,
strict
,
output
)
{
if
(
shallow
&&
_
.
every
(
input
,
_
.
isArray
))
{
if
(
shallow
&&
_
.
every
(
input
,
_
.
isArray
))
{
return
concat
.
apply
(
output
,
input
);
return
concat
.
apply
(
output
,
input
);
}
}
each
(
input
,
function
(
value
)
{
for
(
var
i
=
0
,
length
=
input
.
length
;
i
<
length
;
i
++
)
{
if
(
_
.
isArray
(
value
)
||
_
.
isArguments
(
value
))
{
var
value
=
input
[
i
];
shallow
?
push
.
apply
(
output
,
value
)
:
flatten
(
value
,
shallow
,
output
);
if
(
!
_
.
isArray
(
value
)
&&
!
_
.
isArguments
(
value
))
{
if
(
!
strict
)
output
.
push
(
value
);
}
else
if
(
shallow
)
{
push
.
apply
(
output
,
value
);
}
else
{
}
else
{
output
.
push
(
value
);
flatten
(
value
,
shallow
,
strict
,
output
);
}
}
}
});
return
output
;
return
output
;
};
};
// Flatten out an array, either recursively (by default), or just one level.
// Flatten out an array, either recursively (by default), or just one level.
_
.
flatten
=
function
(
array
,
shallow
)
{
_
.
flatten
=
function
(
array
,
shallow
)
{
return
flatten
(
array
,
shallow
,
[]);
return
flatten
(
array
,
shallow
,
false
,
[]);
};
};
// Return a version of the array that does not contain the specified value(s).
// Return a version of the array that does not contain the specified value(s).
...
@@ -462,55 +497,74 @@
...
@@ -462,55 +497,74 @@
// 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`.
_
.
uniq
=
_
.
unique
=
function
(
array
,
isSorted
,
iterator
,
context
)
{
_
.
uniq
=
_
.
unique
=
function
(
array
,
isSorted
,
iteratee
,
context
)
{
if
(
_
.
isFunction
(
isSorted
))
{
if
(
array
==
null
)
return
[];
context
=
iterator
;
if
(
!
_
.
isBoolean
(
isSorted
))
{
iterator
=
isSorted
;
context
=
iteratee
;
iteratee
=
isSorted
;
isSorted
=
false
;
isSorted
=
false
;
}
}
var
initial
=
iterator
?
_
.
map
(
array
,
iterator
,
context
)
:
array
;
if
(
iteratee
!=
null
)
iteratee
=
_
.
iteratee
(
iteratee
,
context
)
;
var
result
s
=
[];
var
result
=
[];
var
seen
=
[];
var
seen
=
[];
each
(
initial
,
function
(
value
,
index
)
{
for
(
var
i
=
0
,
length
=
array
.
length
;
i
<
length
;
i
++
)
{
if
(
isSorted
?
(
!
index
||
seen
[
seen
.
length
-
1
]
!==
value
)
:
!
_
.
contains
(
seen
,
value
))
{
var
value
=
array
[
i
];
seen
.
push
(
value
);
if
(
isSorted
)
{
results
.
push
(
array
[
index
]);
if
(
!
i
||
seen
!==
value
)
result
.
push
(
value
);
seen
=
value
;
}
else
if
(
iteratee
)
{
var
computed
=
iteratee
(
value
,
i
,
array
);
if
(
_
.
indexOf
(
seen
,
computed
)
<
0
)
{
seen
.
push
(
computed
);
result
.
push
(
value
);
}
}
});
}
else
if
(
_
.
indexOf
(
result
,
value
)
<
0
)
{
return
results
;
result
.
push
(
value
);
}
}
return
result
;
};
};
// Produce an array that contains the union: each distinct element from all of
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
// the passed-in arrays.
_
.
union
=
function
()
{
_
.
union
=
function
()
{
return
_
.
uniq
(
_
.
flatten
(
arguments
,
true
));
return
_
.
uniq
(
flatten
(
arguments
,
true
,
true
,
[]
));
};
};
// Produce an array that contains every item shared between all the
// Produce an array that contains every item shared between all the
// passed-in arrays.
// passed-in arrays.
_
.
intersection
=
function
(
array
)
{
_
.
intersection
=
function
(
array
)
{
var
rest
=
slice
.
call
(
arguments
,
1
);
if
(
array
==
null
)
return
[];
return
_
.
filter
(
_
.
uniq
(
array
),
function
(
item
)
{
var
result
=
[];
return
_
.
every
(
rest
,
function
(
other
)
{
var
argsLength
=
arguments
.
length
;
return
_
.
indexOf
(
other
,
item
)
>=
0
;
for
(
var
i
=
0
,
length
=
array
.
length
;
i
<
length
;
i
++
)
{
});
var
item
=
array
[
i
];
});
if
(
_
.
contains
(
result
,
item
))
continue
;
for
(
var
j
=
1
;
j
<
argsLength
;
j
++
)
{
if
(
!
_
.
contains
(
arguments
[
j
],
item
))
break
;
}
if
(
j
===
argsLength
)
result
.
push
(
item
);
}
return
result
;
};
};
// Take the difference between one array and a number of other arrays.
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
// Only the elements present in just the first array will remain.
_
.
difference
=
function
(
array
)
{
_
.
difference
=
function
(
array
)
{
var
rest
=
concat
.
apply
(
ArrayProto
,
slice
.
call
(
arguments
,
1
));
var
rest
=
flatten
(
slice
.
call
(
arguments
,
1
),
true
,
true
,
[]);
return
_
.
filter
(
array
,
function
(
value
){
return
!
_
.
contains
(
rest
,
value
);
});
return
_
.
filter
(
array
,
function
(
value
){
return
!
_
.
contains
(
rest
,
value
);
});
};
};
// 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
(
array
)
{
var
length
=
_
.
max
(
_
.
pluck
(
arguments
,
"
length
"
).
concat
(
0
));
if
(
array
==
null
)
return
[];
var
results
=
new
Array
(
length
);
var
length
=
_
.
max
(
arguments
,
'
length
'
).
length
;
var
results
=
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
);
}
}
return
results
;
return
results
;
};
};
...
@@ -531,10 +585,8 @@
...
@@ -531,10 +585,8 @@
return
result
;
return
result
;
};
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// Return the position of the first occurrence of an item in an array,
// we need this function. Return the position of the first occurrence of an
// or -1 if the item is not included in the array.
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// If the array is large and already in sort order, pass `true`
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
// for **isSorted** to use binary search.
_
.
indexOf
=
function
(
array
,
item
,
isSorted
)
{
_
.
indexOf
=
function
(
array
,
item
,
isSorted
)
{
...
@@ -542,26 +594,23 @@
...
@@ -542,26 +594,23 @@
var
i
=
0
,
length
=
array
.
length
;
var
i
=
0
,
length
=
array
.
length
;
if
(
isSorted
)
{
if
(
isSorted
)
{
if
(
typeof
isSorted
==
'
number
'
)
{
if
(
typeof
isSorted
==
'
number
'
)
{
i
=
(
isSorted
<
0
?
Math
.
max
(
0
,
length
+
isSorted
)
:
isSorted
)
;
i
=
isSorted
<
0
?
Math
.
max
(
0
,
length
+
isSorted
)
:
isSorted
;
}
else
{
}
else
{
i
=
_
.
sortedIndex
(
array
,
item
);
i
=
_
.
sortedIndex
(
array
,
item
);
return
array
[
i
]
===
item
?
i
:
-
1
;
return
array
[
i
]
===
item
?
i
:
-
1
;
}
}
}
}
if
(
nativeIndexOf
&&
array
.
indexOf
===
nativeIndexOf
)
return
array
.
indexOf
(
item
,
isSorted
);
for
(;
i
<
length
;
i
++
)
if
(
array
[
i
]
===
item
)
return
i
;
for
(;
i
<
length
;
i
++
)
if
(
array
[
i
]
===
item
)
return
i
;
return
-
1
;
return
-
1
;
};
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_
.
lastIndexOf
=
function
(
array
,
item
,
from
)
{
_
.
lastIndexOf
=
function
(
array
,
item
,
from
)
{
if
(
array
==
null
)
return
-
1
;
if
(
array
==
null
)
return
-
1
;
var
hasIndex
=
from
!=
null
;
var
idx
=
array
.
length
;
if
(
nativeLastIndexOf
&&
array
.
lastIndexOf
===
nativeLastIndexOf
)
{
if
(
typeof
from
==
'
number
'
)
{
return
hasIndex
?
array
.
lastIndexOf
(
item
,
from
)
:
array
.
lastIndexOf
(
item
);
idx
=
from
<
0
?
idx
+
from
+
1
:
Math
.
min
(
idx
,
from
+
1
);
}
}
var
i
=
(
hasIndex
?
from
:
array
.
length
);
while
(
--
idx
>=
0
)
if
(
array
[
idx
]
===
item
)
return
idx
;
while
(
i
--
)
if
(
array
[
i
]
===
item
)
return
i
;
return
-
1
;
return
-
1
;
};
};
...
@@ -573,15 +622,13 @@
...
@@ -573,15 +622,13 @@
stop
=
start
||
0
;
stop
=
start
||
0
;
start
=
0
;
start
=
0
;
}
}
step
=
arguments
[
2
]
||
1
;
step
=
step
||
1
;
var
length
=
Math
.
max
(
Math
.
ceil
((
stop
-
start
)
/
step
),
0
);
var
length
=
Math
.
max
(
Math
.
ceil
((
stop
-
start
)
/
step
),
0
);
var
idx
=
0
;
var
range
=
Array
(
length
);
var
range
=
new
Array
(
length
);
while
(
idx
<
length
)
{
for
(
var
idx
=
0
;
idx
<
length
;
idx
++
,
start
+=
step
)
{
range
[
idx
++
]
=
start
;
range
[
idx
]
=
start
;
start
+=
step
;
}
}
return
range
;
return
range
;
...
@@ -591,7 +638,7 @@
...
@@ -591,7 +638,7 @@
// ------------------
// ------------------
// Reusable constructor function for prototype setting.
// Reusable constructor function for prototype setting.
var
c
tor
=
function
(){};
var
C
tor
=
function
(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
...
@@ -599,52 +646,68 @@
...
@@ -599,52 +646,68 @@
_
.
bind
=
function
(
func
,
context
)
{
_
.
bind
=
function
(
func
,
context
)
{
var
args
,
bound
;
var
args
,
bound
;
if
(
nativeBind
&&
func
.
bind
===
nativeBind
)
return
nativeBind
.
apply
(
func
,
slice
.
call
(
arguments
,
1
));
if
(
nativeBind
&&
func
.
bind
===
nativeBind
)
return
nativeBind
.
apply
(
func
,
slice
.
call
(
arguments
,
1
));
if
(
!
_
.
isFunction
(
func
))
throw
new
TypeError
;
if
(
!
_
.
isFunction
(
func
))
throw
new
TypeError
(
'
Bind must be called on a function
'
)
;
args
=
slice
.
call
(
arguments
,
2
);
args
=
slice
.
call
(
arguments
,
2
);
return
bound
=
function
()
{
bound
=
function
()
{
if
(
!
(
this
instanceof
bound
))
return
func
.
apply
(
context
,
args
.
concat
(
slice
.
call
(
arguments
)));
if
(
!
(
this
instanceof
bound
))
return
func
.
apply
(
context
,
args
.
concat
(
slice
.
call
(
arguments
)));
c
tor
.
prototype
=
func
.
prototype
;
C
tor
.
prototype
=
func
.
prototype
;
var
self
=
new
c
tor
;
var
self
=
new
C
tor
;
c
tor
.
prototype
=
null
;
C
tor
.
prototype
=
null
;
var
result
=
func
.
apply
(
self
,
args
.
concat
(
slice
.
call
(
arguments
)));
var
result
=
func
.
apply
(
self
,
args
.
concat
(
slice
.
call
(
arguments
)));
if
(
Object
(
result
)
===
result
)
return
result
;
if
(
_
.
isObject
(
result
)
)
return
result
;
return
self
;
return
self
;
};
};
return
bound
;
};
};
// 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
i
,
length
=
arguments
.
length
,
key
;
if
(
funcs
.
length
===
0
)
throw
new
Error
(
"
bindAll must be passed function names
"
);
if
(
length
<=
1
)
throw
new
Error
(
'
bindAll must be passed function names
'
);
each
(
funcs
,
function
(
f
)
{
obj
[
f
]
=
_
.
bind
(
obj
[
f
],
obj
);
});
for
(
i
=
1
;
i
<
length
;
i
++
)
{
key
=
arguments
[
i
];
obj
[
key
]
=
_
.
bind
(
obj
[
key
],
obj
);
}
return
obj
;
return
obj
;
};
};
// Memoize an expensive function by storing its results.
// Memoize an expensive function by storing its results.
_
.
memoize
=
function
(
func
,
hasher
)
{
_
.
memoize
=
function
(
func
,
hasher
)
{
var
memo
=
{};
var
memo
ize
=
function
(
key
)
{
hasher
||
(
hasher
=
_
.
identity
)
;
var
cache
=
memoize
.
cache
;
return
function
()
{
var
address
=
hasher
?
hasher
.
apply
(
this
,
arguments
)
:
key
;
var
key
=
hasher
.
apply
(
this
,
arguments
);
if
(
!
_
.
has
(
cache
,
address
))
cache
[
address
]
=
func
.
apply
(
this
,
arguments
);
return
_
.
has
(
memo
,
key
)
?
memo
[
key
]
:
(
memo
[
key
]
=
func
.
apply
(
this
,
arguments
))
;
return
cache
[
address
]
;
};
};
memoize
.
cache
=
{};
return
memoize
;
};
};
// Delays a function for the given number of milliseconds, and then calls
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
// it with the arguments supplied.
_
.
delay
=
function
(
func
,
wait
)
{
_
.
delay
=
function
(
func
,
wait
)
{
var
args
=
slice
.
call
(
arguments
,
2
);
var
args
=
slice
.
call
(
arguments
,
2
);
return
setTimeout
(
function
(){
return
func
.
apply
(
null
,
args
);
},
wait
);
return
setTimeout
(
function
(){
return
func
.
apply
(
null
,
args
);
},
wait
);
};
};
// Defers a function, scheduling it to run after the current call stack has
// Defers a function, scheduling it to run after the current call stack has
...
@@ -662,23 +725,25 @@
...
@@ -662,23 +725,25 @@
var
context
,
args
,
result
;
var
context
,
args
,
result
;
var
timeout
=
null
;
var
timeout
=
null
;
var
previous
=
0
;
var
previous
=
0
;
options
||
(
options
=
{})
;
if
(
!
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
);
if
(
!
timeout
)
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
;
args
=
arguments
;
args
=
arguments
;
if
(
remaining
<=
0
)
{
if
(
remaining
<=
0
||
remaining
>
wait
)
{
clearTimeout
(
timeout
);
clearTimeout
(
timeout
);
timeout
=
null
;
timeout
=
null
;
previous
=
now
;
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
result
=
func
.
apply
(
context
,
args
);
if
(
!
timeout
)
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
timeout
=
setTimeout
(
later
,
remaining
);
}
}
...
@@ -692,38 +757,33 @@
...
@@ -692,38 +757,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
&&
last
>
0
)
{
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
);
if
(
!
timeout
)
context
=
args
=
null
;
}
}
};
var
callNow
=
immediate
&&
!
timeout
;
if
(
!
timeout
)
{
timeout
=
setTimeout
(
later
,
wait
);
}
}
if
(
callNow
)
result
=
func
.
apply
(
context
,
args
);
return
result
;
};
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_
.
once
=
function
(
func
)
{
var
ran
=
false
,
memo
;
return
function
()
{
return
function
()
{
if
(
ran
)
return
memo
;
context
=
this
;
ran
=
true
;
args
=
arguments
;
memo
=
func
.
apply
(
this
,
arguments
);
timestamp
=
_
.
now
();
func
=
null
;
var
callNow
=
immediate
&&
!
timeout
;
return
memo
;
if
(
!
timeout
)
timeout
=
setTimeout
(
later
,
wait
);
if
(
callNow
)
{
result
=
func
.
apply
(
context
,
args
);
context
=
args
=
null
;
}
return
result
;
};
};
};
};
...
@@ -731,23 +791,26 @@
...
@@ -731,23 +791,26 @@
// 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
_
.
partial
(
wrapper
,
func
);
};
// Returns a negated version of the passed-in predicate.
_
.
negate
=
function
(
predicate
)
{
return
function
()
{
return
function
()
{
var
args
=
[
func
];
return
!
predicate
.
apply
(
this
,
arguments
);
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
// consuming the return value of the function that follows.
// consuming the return value of the function that follows.
_
.
compose
=
function
()
{
_
.
compose
=
function
()
{
var
funcs
=
arguments
;
return
function
()
{
var
args
=
arguments
;
var
args
=
arguments
;
for
(
var
i
=
funcs
.
length
-
1
;
i
>=
0
;
i
--
)
{
var
start
=
args
.
length
-
1
;
args
=
[
funcs
[
i
].
apply
(
this
,
args
)];
return
function
()
{
}
var
i
=
start
;
return
args
[
0
];
var
result
=
args
[
start
].
apply
(
this
,
arguments
);
while
(
i
--
)
result
=
args
[
i
].
call
(
this
,
result
);
return
result
;
};
};
};
};
...
@@ -760,13 +823,31 @@
...
@@ -760,13 +823,31 @@
};
};
};
};
// Returns a function that will only be executed before being called N times.
_
.
before
=
function
(
times
,
func
)
{
var
memo
;
return
function
()
{
if
(
--
times
>
0
)
{
memo
=
func
.
apply
(
this
,
arguments
);
}
else
{
func
=
null
;
}
return
memo
;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_
.
once
=
_
.
partial
(
_
.
before
,
2
);
// Object Functions
// Object Functions
// ----------------
// ----------------
// 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
;
...
@@ -776,7 +857,7 @@
...
@@ -776,7 +857,7 @@
_
.
values
=
function
(
obj
)
{
_
.
values
=
function
(
obj
)
{
var
keys
=
_
.
keys
(
obj
);
var
keys
=
_
.
keys
(
obj
);
var
length
=
keys
.
length
;
var
length
=
keys
.
length
;
var
values
=
new
Array
(
length
);
var
values
=
Array
(
length
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
values
[
i
]
=
obj
[
keys
[
i
]];
values
[
i
]
=
obj
[
keys
[
i
]];
}
}
...
@@ -787,7 +868,7 @@
...
@@ -787,7 +868,7 @@
_
.
pairs
=
function
(
obj
)
{
_
.
pairs
=
function
(
obj
)
{
var
keys
=
_
.
keys
(
obj
);
var
keys
=
_
.
keys
(
obj
);
var
length
=
keys
.
length
;
var
length
=
keys
.
length
;
var
pairs
=
new
Array
(
length
);
var
pairs
=
Array
(
length
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
pairs
[
i
]
=
[
keys
[
i
],
obj
[
keys
[
i
]]];
pairs
[
i
]
=
[
keys
[
i
],
obj
[
keys
[
i
]]];
}
}
...
@@ -816,45 +897,62 @@
...
@@ -816,45 +897,62 @@
// Extend a given object with all the properties in passed-in object(s).
// Extend a given object with all the properties in passed-in object(s).
_
.
extend
=
function
(
obj
)
{
_
.
extend
=
function
(
obj
)
{
each
(
slice
.
call
(
arguments
,
1
),
function
(
source
)
{
if
(
!
_
.
isObject
(
obj
))
return
obj
;
if
(
source
)
{
var
source
,
prop
;
for
(
var
prop
in
source
)
{
for
(
var
i
=
1
,
length
=
arguments
.
length
;
i
<
length
;
i
++
)
{
source
=
arguments
[
i
];
for
(
prop
in
source
)
{
if
(
hasOwnProperty
.
call
(
source
,
prop
))
{
obj
[
prop
]
=
source
[
prop
];
obj
[
prop
]
=
source
[
prop
];
}
}
}
}
}
);
}
return
obj
;
return
obj
;
};
};
// Return a copy of the object only containing the whitelisted properties.
// Return a copy of the object only containing the whitelisted properties.
_
.
pick
=
function
(
obj
)
{
_
.
pick
=
function
(
obj
,
iteratee
,
context
)
{
var
copy
=
{};
var
result
=
{},
key
;
var
keys
=
concat
.
apply
(
ArrayProto
,
slice
.
call
(
arguments
,
1
));
if
(
obj
==
null
)
return
result
;
each
(
keys
,
function
(
key
)
{
if
(
_
.
isFunction
(
iteratee
))
{
if
(
key
in
obj
)
copy
[
key
]
=
obj
[
key
];
iteratee
=
createCallback
(
iteratee
,
context
);
});
for
(
key
in
obj
)
{
return
copy
;
var
value
=
obj
[
key
];
if
(
iteratee
(
value
,
key
,
obj
))
result
[
key
]
=
value
;
}
}
else
{
var
keys
=
concat
.
apply
([],
slice
.
call
(
arguments
,
1
));
obj
=
new
Object
(
obj
);
for
(
var
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
key
=
keys
[
i
];
if
(
key
in
obj
)
result
[
key
]
=
obj
[
key
];
}
}
return
result
;
};
};
// Return a copy of the object without the blacklisted properties.
// Return a copy of the object without the blacklisted properties.
_
.
omit
=
function
(
obj
)
{
_
.
omit
=
function
(
obj
,
iteratee
,
context
)
{
var
copy
=
{};
if
(
_
.
isFunction
(
iteratee
))
{
var
keys
=
concat
.
apply
(
ArrayProto
,
slice
.
call
(
arguments
,
1
));
iteratee
=
_
.
negate
(
iteratee
);
for
(
var
key
in
obj
)
{
}
else
{
if
(
!
_
.
contains
(
keys
,
key
))
copy
[
key
]
=
obj
[
key
];
var
keys
=
_
.
map
(
concat
.
apply
([],
slice
.
call
(
arguments
,
1
)),
String
);
iteratee
=
function
(
value
,
key
)
{
return
!
_
.
contains
(
keys
,
key
);
};
}
}
return
copy
;
return
_
.
pick
(
obj
,
iteratee
,
context
)
;
};
};
// Fill in a given object with default properties.
// Fill in a given object with default properties.
_
.
defaults
=
function
(
obj
)
{
_
.
defaults
=
function
(
obj
)
{
each
(
slice
.
call
(
arguments
,
1
),
function
(
source
)
{
if
(
!
_
.
isObject
(
obj
))
return
obj
;
if
(
source
)
{
for
(
var
i
=
1
,
length
=
arguments
.
length
;
i
<
length
;
i
++
)
{
var
source
=
arguments
[
i
];
for
(
var
prop
in
source
)
{
for
(
var
prop
in
source
)
{
if
(
obj
[
prop
]
===
void
0
)
obj
[
prop
]
=
source
[
prop
];
if
(
obj
[
prop
]
===
void
0
)
obj
[
prop
]
=
source
[
prop
];
}
}
}
}
});
return
obj
;
return
obj
;
};
};
...
@@ -876,7 +974,7 @@
...
@@ -876,7 +974,7 @@
var
eq
=
function
(
a
,
b
,
aStack
,
bStack
)
{
var
eq
=
function
(
a
,
b
,
aStack
,
bStack
)
{
// Identical objects are equal. `0 === -0`, but they aren't identical.
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if
(
a
===
b
)
return
a
!==
0
||
1
/
a
==
1
/
b
;
if
(
a
===
b
)
return
a
!==
0
||
1
/
a
==
=
1
/
b
;
// A strict comparison is necessary because `null == undefined`.
// A strict comparison is necessary because `null == undefined`.
if
(
a
==
null
||
b
==
null
)
return
a
===
b
;
if
(
a
==
null
||
b
==
null
)
return
a
===
b
;
// Unwrap any wrapped objects.
// Unwrap any wrapped objects.
...
@@ -884,29 +982,27 @@
...
@@ -884,29 +982,27 @@
if
(
b
instanceof
_
)
b
=
b
.
_wrapped
;
if
(
b
instanceof
_
)
b
=
b
.
_wrapped
;
// Compare `[[Class]]` names.
// Compare `[[Class]]` names.
var
className
=
toString
.
call
(
a
);
var
className
=
toString
.
call
(
a
);
if
(
className
!=
toString
.
call
(
b
))
return
false
;
if
(
className
!=
=
toString
.
call
(
b
))
return
false
;
switch
(
className
)
{
switch
(
className
)
{
// Strings, numbers, dates, and booleans are compared by value.
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case
'
[object RegExp]
'
:
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case
'
[object String]
'
:
case
'
[object String]
'
:
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
// equivalent to `new String("5")`.
return
a
==
String
(
b
)
;
return
''
+
a
===
''
+
b
;
case
'
[object Number]
'
:
case
'
[object Number]
'
:
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// `NaN`s are equivalent, but non-reflexive.
// other numeric values.
// Object(NaN) is equivalent to NaN
return
a
!=
+
a
?
b
!=
+
b
:
(
a
==
0
?
1
/
a
==
1
/
b
:
a
==
+
b
);
if
(
+
a
!==
+
a
)
return
+
b
!==
+
b
;
// An `egal` comparison is performed for other numeric values.
return
+
a
===
0
?
1
/
+
a
===
1
/
b
:
+
a
===
+
b
;
case
'
[object Date]
'
:
case
'
[object Date]
'
:
case
'
[object Boolean]
'
:
case
'
[object Boolean]
'
:
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
// of `NaN` are not equivalent.
return
+
a
==
+
b
;
return
+
a
===
+
b
;
// RegExps are compared by their source patterns and flags.
case
'
[object RegExp]
'
:
return
a
.
source
==
b
.
source
&&
a
.
global
==
b
.
global
&&
a
.
multiline
==
b
.
multiline
&&
a
.
ignoreCase
==
b
.
ignoreCase
;
}
}
if
(
typeof
a
!=
'
object
'
||
typeof
b
!=
'
object
'
)
return
false
;
if
(
typeof
a
!=
'
object
'
||
typeof
b
!=
'
object
'
)
return
false
;
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// Assume equality for cyclic structures. The algorithm for detecting cyclic
...
@@ -915,24 +1011,29 @@
...
@@ -915,24 +1011,29 @@
while
(
length
--
)
{
while
(
length
--
)
{
// Linear search. Performance is inversely proportional to the number of
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
// unique nested structures.
if
(
aStack
[
length
]
==
a
)
return
bStack
[
length
]
==
b
;
if
(
aStack
[
length
]
==
=
a
)
return
bStack
[
length
]
=
==
b
;
}
}
// Objects with different constructors are not equivalent, but `Object`s
// Objects with different constructors are not equivalent, but `Object`s
// 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
(
_
.
isFunction
(
bCtor
)
&&
(
bCtor
instanceof
bCtor
)))
{
aCtor
!==
bCtor
&&
// Handle Object.create(x) cases
'
constructor
'
in
a
&&
'
constructor
'
in
b
&&
!
(
_
.
isFunction
(
aCtor
)
&&
aCtor
instanceof
aCtor
&&
_
.
isFunction
(
bCtor
)
&&
bCtor
instanceof
bCtor
)
)
{
return
false
;
return
false
;
}
}
// Add the first object to the stack of traversed objects.
// Add the first object to the stack of traversed objects.
aStack
.
push
(
a
);
aStack
.
push
(
a
);
bStack
.
push
(
b
);
bStack
.
push
(
b
);
var
size
=
0
,
result
=
true
;
var
size
,
result
;
// Recursively compare objects and arrays.
// Recursively compare objects and arrays.
if
(
className
==
'
[object Array]
'
)
{
if
(
className
==
=
'
[object Array]
'
)
{
// Compare array lengths to determine if a deep comparison is necessary.
// Compare array lengths to determine if a deep comparison is necessary.
size
=
a
.
length
;
size
=
a
.
length
;
result
=
size
==
b
.
length
;
result
=
size
==
=
b
.
length
;
if
(
result
)
{
if
(
result
)
{
// Deep compare the contents, ignoring non-numeric properties.
// Deep compare the contents, ignoring non-numeric properties.
while
(
size
--
)
{
while
(
size
--
)
{
...
@@ -941,20 +1042,16 @@
...
@@ -941,20 +1042,16 @@
}
}
}
else
{
}
else
{
// Deep compare objects.
// Deep compare objects.
for
(
var
key
in
a
)
{
var
keys
=
_
.
keys
(
a
),
key
;
if
(
_
.
has
(
a
,
key
))
{
size
=
keys
.
length
;
// Count the expected number of properties.
// Ensure that both objects contain the same number of properties before comparing deep equality.
size
++
;
result
=
_
.
keys
(
b
).
length
===
size
;
// Deep compare each member.
if
(
!
(
result
=
_
.
has
(
b
,
key
)
&&
eq
(
a
[
key
],
b
[
key
],
aStack
,
bStack
)))
break
;
}
}
// Ensure that both objects contain the same number of properties.
if
(
result
)
{
if
(
result
)
{
for
(
key
in
b
)
{
while
(
size
--
)
{
if
(
_
.
has
(
b
,
key
)
&&
!
(
size
--
))
break
;
// Deep compare each member
key
=
keys
[
size
];
if
(
!
(
result
=
_
.
has
(
b
,
key
)
&&
eq
(
a
[
key
],
b
[
key
],
aStack
,
bStack
)))
break
;
}
}
result
=
!
size
;
}
}
}
}
// Remove the first object from the stack of traversed objects.
// Remove the first object from the stack of traversed objects.
...
@@ -972,7 +1069,7 @@
...
@@ -972,7 +1069,7 @@
// An "empty" object has no enumerable own-properties.
// An "empty" object has no enumerable own-properties.
_
.
isEmpty
=
function
(
obj
)
{
_
.
isEmpty
=
function
(
obj
)
{
if
(
obj
==
null
)
return
true
;
if
(
obj
==
null
)
return
true
;
if
(
_
.
isArray
(
obj
)
||
_
.
isString
(
obj
))
return
obj
.
length
===
0
;
if
(
_
.
isArray
(
obj
)
||
_
.
isString
(
obj
)
||
_
.
isArguments
(
obj
)
)
return
obj
.
length
===
0
;
for
(
var
key
in
obj
)
if
(
_
.
has
(
obj
,
key
))
return
false
;
for
(
var
key
in
obj
)
if
(
_
.
has
(
obj
,
key
))
return
false
;
return
true
;
return
true
;
};
};
...
@@ -985,18 +1082,19 @@
...
@@ -985,18 +1082,19 @@
// Is a given value an array?
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
// Delegates to ECMA5's native Array.isArray
_
.
isArray
=
nativeIsArray
||
function
(
obj
)
{
_
.
isArray
=
nativeIsArray
||
function
(
obj
)
{
return
toString
.
call
(
obj
)
==
'
[object Array]
'
;
return
toString
.
call
(
obj
)
==
=
'
[object Array]
'
;
};
};
// Is a given variable an object?
// Is a given variable an object?
_
.
isObject
=
function
(
obj
)
{
_
.
isObject
=
function
(
obj
)
{
return
obj
===
Object
(
obj
);
var
type
=
typeof
obj
;
return
type
===
'
function
'
||
type
===
'
object
'
&&
!!
obj
;
};
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
each
([
'
Arguments
'
,
'
Function
'
,
'
String
'
,
'
Number
'
,
'
Date
'
,
'
RegExp
'
],
function
(
name
)
{
_
.
each
([
'
Arguments
'
,
'
Function
'
,
'
String
'
,
'
Number
'
,
'
Date
'
,
'
RegExp
'
],
function
(
name
)
{
_
[
'
is
'
+
name
]
=
function
(
obj
)
{
_
[
'
is
'
+
name
]
=
function
(
obj
)
{
return
toString
.
call
(
obj
)
==
'
[object
'
+
name
+
'
]
'
;
return
toString
.
call
(
obj
)
==
=
'
[object
'
+
name
+
'
]
'
;
};
};
});
});
...
@@ -1004,14 +1102,14 @@
...
@@ -1004,14 +1102,14 @@
// there isn't any inspectable "Arguments" type.
// there isn't any inspectable "Arguments" type.
if
(
!
_
.
isArguments
(
arguments
))
{
if
(
!
_
.
isArguments
(
arguments
))
{
_
.
isArguments
=
function
(
obj
)
{
_
.
isArguments
=
function
(
obj
)
{
return
!!
(
obj
&&
_
.
has
(
obj
,
'
callee
'
)
);
return
_
.
has
(
obj
,
'
callee
'
);
};
};
}
}
// Optimize `isFunction` if appropriate.
// Optimize `isFunction` if appropriate.
Work around an IE 11 bug.
if
(
typeof
(
/./
)
!==
'
function
'
)
{
if
(
typeof
/./
!==
'
function
'
)
{
_
.
isFunction
=
function
(
obj
)
{
_
.
isFunction
=
function
(
obj
)
{
return
typeof
obj
==
=
'
function
'
;
return
typeof
obj
==
'
function
'
||
false
;
};
};
}
}
...
@@ -1022,12 +1120,12 @@
...
@@ -1022,12 +1120,12 @@
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_
.
isNaN
=
function
(
obj
)
{
_
.
isNaN
=
function
(
obj
)
{
return
_
.
isNumber
(
obj
)
&&
obj
!=
+
obj
;
return
_
.
isNumber
(
obj
)
&&
obj
!=
=
+
obj
;
};
};
// Is a given value a boolean?
// Is a given value a boolean?
_
.
isBoolean
=
function
(
obj
)
{
_
.
isBoolean
=
function
(
obj
)
{
return
obj
===
true
||
obj
===
false
||
toString
.
call
(
obj
)
==
'
[object Boolean]
'
;
return
obj
===
true
||
obj
===
false
||
toString
.
call
(
obj
)
==
=
'
[object Boolean]
'
;
};
};
// Is a given value equal to null?
// Is a given value equal to null?
...
@@ -1043,7 +1141,7 @@
...
@@ -1043,7 +1141,7 @@
// Shortcut function for checking if an object has a given property directly
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
// on itself (in other words, not on a prototype).
_
.
has
=
function
(
obj
,
key
)
{
_
.
has
=
function
(
obj
,
key
)
{
return
hasOwnProperty
.
call
(
obj
,
key
);
return
obj
!=
null
&&
hasOwnProperty
.
call
(
obj
,
key
);
};
};
// Utility Functions
// Utility Functions
...
@@ -1056,15 +1154,44 @@
...
@@ -1056,15 +1154,44 @@
return
this
;
return
this
;
};
};
// Keep the identity function around for default iterat
or
s.
// Keep the identity function around for default iterat
ee
s.
_
.
identity
=
function
(
value
)
{
_
.
identity
=
function
(
value
)
{
return
value
;
return
value
;
};
};
_
.
constant
=
function
(
value
)
{
return
function
()
{
return
value
;
};
};
_
.
noop
=
function
(){};
_
.
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
)
{
var
pairs
=
_
.
pairs
(
attrs
),
length
=
pairs
.
length
;
return
function
(
obj
)
{
if
(
obj
==
null
)
return
!
length
;
obj
=
new
Object
(
obj
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
var
pair
=
pairs
[
i
],
key
=
pair
[
0
];
if
(
pair
[
1
]
!==
obj
[
key
]
||
!
(
key
in
obj
))
return
false
;
}
return
true
;
};
};
// Run a function **n** times.
// Run a function **n** times.
_
.
times
=
function
(
n
,
iterat
or
,
context
)
{
_
.
times
=
function
(
n
,
iterat
ee
,
context
)
{
var
accum
=
Array
(
Math
.
max
(
0
,
n
));
var
accum
=
Array
(
Math
.
max
(
0
,
n
));
for
(
var
i
=
0
;
i
<
n
;
i
++
)
accum
[
i
]
=
iterator
.
call
(
context
,
i
);
iteratee
=
createCallback
(
iteratee
,
context
,
1
);
for
(
var
i
=
0
;
i
<
n
;
i
++
)
accum
[
i
]
=
iteratee
(
i
);
return
accum
;
return
accum
;
};
};
...
@@ -1077,52 +1204,45 @@
...
@@ -1077,52 +1204,45 @@
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
escapeMap
=
{
escape
:
{
'
&
'
:
'
&
'
,
'
&
'
:
'
&
'
,
'
<
'
:
'
<
'
,
'
<
'
:
'
<
'
,
'
>
'
:
'
>
'
,
'
>
'
:
'
>
'
,
'
"
'
:
'
"
'
,
'
"
'
:
'
"
'
,
"
'
"
:
'
'
'
"
'
"
:
'
'
'
,
}
'
`
'
:
'
`
'
};
entityMap
.
unescape
=
_
.
invert
(
entityMap
.
escape
);
// Regexes containing the keys and values listed immediately above.
var
entityRegexes
=
{
escape
:
new
RegExp
(
'
[
'
+
_
.
keys
(
entityMap
.
escape
).
join
(
''
)
+
'
]
'
,
'
g
'
),
unescape
:
new
RegExp
(
'
(
'
+
_
.
keys
(
entityMap
.
unescape
).
join
(
'
|
'
)
+
'
)
'
,
'
g
'
)
};
};
var
unescapeMap
=
_
.
invert
(
escapeMap
);
// Functions for escaping and unescaping strings to/from HTML interpolation.
// Functions for escaping and unescaping strings to/from HTML interpolation.
_
.
each
([
'
escape
'
,
'
unescape
'
],
function
(
method
)
{
var
createEscaper
=
function
(
map
)
{
_
[
method
]
=
function
(
string
)
{
var
escaper
=
function
(
match
)
{
if
(
string
==
null
)
return
''
;
return
map
[
match
];
return
(
''
+
string
).
replace
(
entityRegexes
[
method
],
function
(
match
)
{
return
entityMap
[
method
][
match
];
});
};
};
});
// Regexes for identifying a key that needs to be escaped
var
source
=
'
(?:
'
+
_
.
keys
(
map
).
join
(
'
|
'
)
+
'
)
'
;
var
testRegexp
=
RegExp
(
source
);
var
replaceRegexp
=
RegExp
(
source
,
'
g
'
);
return
function
(
string
)
{
string
=
string
==
null
?
''
:
''
+
string
;
return
testRegexp
.
test
(
string
)
?
string
.
replace
(
replaceRegexp
,
escaper
)
:
string
;
};
};
_
.
escape
=
createEscaper
(
escapeMap
);
_
.
unescape
=
createEscaper
(
unescapeMap
);
// If the value of the named `property` is a function then invoke it with the
// If the value of the named `property` is a function then invoke it with the
// `object` as context; otherwise, return it.
// `object` as context; otherwise, return it.
_
.
result
=
function
(
object
,
property
)
{
_
.
result
=
function
(
object
,
property
)
{
if
(
object
==
null
)
return
void
0
;
if
(
object
==
null
)
return
void
0
;
var
value
=
object
[
property
];
var
value
=
object
[
property
];
return
_
.
isFunction
(
value
)
?
value
.
call
(
object
)
:
value
;
return
_
.
isFunction
(
value
)
?
object
[
property
]()
:
value
;
};
// Add your own custom functions to the Underscore object.
_
.
mixin
=
function
(
obj
)
{
each
(
_
.
functions
(
obj
),
function
(
name
)
{
var
func
=
_
[
name
]
=
obj
[
name
];
_
.
prototype
[
name
]
=
function
()
{
var
args
=
[
this
.
_wrapped
];
push
.
apply
(
args
,
arguments
);
return
result
.
call
(
this
,
func
.
apply
(
_
,
args
));
};
});
};
};
// Generate a unique integer id (unique within the entire client session).
// Generate a unique integer id (unique within the entire client session).
...
@@ -1153,22 +1273,26 @@
...
@@ -1153,22 +1273,26 @@
'
\\
'
:
'
\\
'
,
'
\\
'
:
'
\\
'
,
'
\r
'
:
'
r
'
,
'
\r
'
:
'
r
'
,
'
\n
'
:
'
n
'
,
'
\n
'
:
'
n
'
,
'
\t
'
:
'
t
'
,
'
\
u2028
'
:
'
u2028
'
,
'
\
u2028
'
:
'
u2028
'
,
'
\
u2029
'
:
'
u2029
'
'
\
u2029
'
:
'
u2029
'
};
};
var
escaper
=
/
\\
|'|
\r
|
\n
|
\t
|
\u
2028|
\u
2029/g
;
var
escaper
=
/
\\
|'|
\r
|
\n
|
\u
2028|
\u
2029/g
;
var
escapeChar
=
function
(
match
)
{
return
'
\\
'
+
escapes
[
match
];
};
// JavaScript micro-templating, similar to John Resig's implementation.
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
// and correctly escapes quotes within interpolated code.
_
.
template
=
function
(
text
,
data
,
settings
)
{
// NB: `oldSettings` only exists for backwards compatibility.
var
render
;
_
.
template
=
function
(
text
,
settings
,
oldSettings
)
{
if
(
!
settings
&&
oldSettings
)
settings
=
oldSettings
;
settings
=
_
.
defaults
({},
settings
,
_
.
templateSettings
);
settings
=
_
.
defaults
({},
settings
,
_
.
templateSettings
);
// Combine delimiters into one regular expression via alternation.
// Combine delimiters into one regular expression via alternation.
var
matcher
=
new
RegExp
([
var
matcher
=
RegExp
([
(
settings
.
escape
||
noMatch
).
source
,
(
settings
.
escape
||
noMatch
).
source
,
(
settings
.
interpolate
||
noMatch
).
source
,
(
settings
.
interpolate
||
noMatch
).
source
,
(
settings
.
evaluate
||
noMatch
).
source
(
settings
.
evaluate
||
noMatch
).
source
...
@@ -1178,19 +1302,18 @@
...
@@ -1178,19 +1302,18 @@
var
index
=
0
;
var
index
=
0
;
var
source
=
"
__p+='
"
;
var
source
=
"
__p+='
"
;
text
.
replace
(
matcher
,
function
(
match
,
escape
,
interpolate
,
evaluate
,
offset
)
{
text
.
replace
(
matcher
,
function
(
match
,
escape
,
interpolate
,
evaluate
,
offset
)
{
source
+=
text
.
slice
(
index
,
offset
)
source
+=
text
.
slice
(
index
,
offset
)
.
replace
(
escaper
,
escapeChar
);
.
replace
(
escaper
,
function
(
match
)
{
return
'
\\
'
+
escapes
[
match
];
})
;
index
=
offset
+
match
.
length
;
if
(
escape
)
{
if
(
escape
)
{
source
+=
"
'+
\n
((__t=(
"
+
escape
+
"
))==null?'':_.escape(__t))+
\n
'
"
;
source
+=
"
'+
\n
((__t=(
"
+
escape
+
"
))==null?'':_.escape(__t))+
\n
'
"
;
}
}
else
if
(
interpolate
)
{
if
(
interpolate
)
{
source
+=
"
'+
\n
((__t=(
"
+
interpolate
+
"
))==null?'':__t)+
\n
'
"
;
source
+=
"
'+
\n
((__t=(
"
+
interpolate
+
"
))==null?'':__t)+
\n
'
"
;
}
}
else
if
(
evaluate
)
{
if
(
evaluate
)
{
source
+=
"
';
\n
"
+
evaluate
+
"
\n
__p+='
"
;
source
+=
"
';
\n
"
+
evaluate
+
"
\n
__p+='
"
;
}
}
index
=
offset
+
match
.
length
;
// Adobe VMs need the match returned to produce the correct offest.
return
match
;
return
match
;
});
});
source
+=
"
';
\n
"
;
source
+=
"
';
\n
"
;
...
@@ -1200,29 +1323,31 @@
...
@@ -1200,29 +1323,31 @@
source
=
"
var __t,__p='',__j=Array.prototype.join,
"
+
source
=
"
var __t,__p='',__j=Array.prototype.join,
"
+
"
print=function(){__p+=__j.call(arguments,'');};
\n
"
+
"
print=function(){__p+=__j.call(arguments,'');};
\n
"
+
source
+
"
return __p;
\n
"
;
source
+
'
return __p;
\n
'
;
try
{
try
{
render
=
new
Function
(
settings
.
variable
||
'
obj
'
,
'
_
'
,
source
);
var
render
=
new
Function
(
settings
.
variable
||
'
obj
'
,
'
_
'
,
source
);
}
catch
(
e
)
{
}
catch
(
e
)
{
e
.
source
=
source
;
e
.
source
=
source
;
throw
e
;
throw
e
;
}
}
if
(
data
)
return
render
(
data
,
_
);
var
template
=
function
(
data
)
{
var
template
=
function
(
data
)
{
return
render
.
call
(
this
,
data
,
_
);
return
render
.
call
(
this
,
data
,
_
);
};
};
// Provide the compiled function source as a convenience for precompilation.
// Provide the compiled source as a convenience for precompilation.
template
.
source
=
'
function(
'
+
(
settings
.
variable
||
'
obj
'
)
+
'
){
\n
'
+
source
+
'
}
'
;
var
argument
=
settings
.
variable
||
'
obj
'
;
template
.
source
=
'
function(
'
+
argument
+
'
){
\n
'
+
source
+
'
}
'
;
return
template
;
return
template
;
};
};
// Add a "chain" function
, which will delegate to the wrapper
.
// Add a "chain" function
. Start chaining a wrapped Underscore object
.
_
.
chain
=
function
(
obj
)
{
_
.
chain
=
function
(
obj
)
{
return
_
(
obj
).
chain
();
var
instance
=
_
(
obj
);
instance
.
_chain
=
true
;
return
instance
;
};
};
// OOP
// OOP
...
@@ -1236,41 +1361,55 @@
...
@@ -1236,41 +1361,55 @@
return
this
.
_chain
?
_
(
obj
).
chain
()
:
obj
;
return
this
.
_chain
?
_
(
obj
).
chain
()
:
obj
;
};
};
// Add your own custom functions to the Underscore object.
_
.
mixin
=
function
(
obj
)
{
_
.
each
(
_
.
functions
(
obj
),
function
(
name
)
{
var
func
=
_
[
name
]
=
obj
[
name
];
_
.
prototype
[
name
]
=
function
()
{
var
args
=
[
this
.
_wrapped
];
push
.
apply
(
args
,
arguments
);
return
result
.
call
(
this
,
func
.
apply
(
_
,
args
));
};
});
};
// Add all of the Underscore functions to the wrapper object.
// Add all of the Underscore functions to the wrapper object.
_
.
mixin
(
_
);
_
.
mixin
(
_
);
// Add all mutator Array functions to the wrapper.
// Add all mutator Array functions to the wrapper.
each
([
'
pop
'
,
'
push
'
,
'
reverse
'
,
'
shift
'
,
'
sort
'
,
'
splice
'
,
'
unshift
'
],
function
(
name
)
{
_
.
each
([
'
pop
'
,
'
push
'
,
'
reverse
'
,
'
shift
'
,
'
sort
'
,
'
splice
'
,
'
unshift
'
],
function
(
name
)
{
var
method
=
ArrayProto
[
name
];
var
method
=
ArrayProto
[
name
];
_
.
prototype
[
name
]
=
function
()
{
_
.
prototype
[
name
]
=
function
()
{
var
obj
=
this
.
_wrapped
;
var
obj
=
this
.
_wrapped
;
method
.
apply
(
obj
,
arguments
);
method
.
apply
(
obj
,
arguments
);
if
((
name
==
'
shift
'
||
name
==
'
splice
'
)
&&
obj
.
length
===
0
)
delete
obj
[
0
];
if
((
name
==
=
'
shift
'
||
name
=
==
'
splice
'
)
&&
obj
.
length
===
0
)
delete
obj
[
0
];
return
result
.
call
(
this
,
obj
);
return
result
.
call
(
this
,
obj
);
};
};
});
});
// Add all accessor Array functions to the wrapper.
// Add all accessor Array functions to the wrapper.
each
([
'
concat
'
,
'
join
'
,
'
slice
'
],
function
(
name
)
{
_
.
each
([
'
concat
'
,
'
join
'
,
'
slice
'
],
function
(
name
)
{
var
method
=
ArrayProto
[
name
];
var
method
=
ArrayProto
[
name
];
_
.
prototype
[
name
]
=
function
()
{
_
.
prototype
[
name
]
=
function
()
{
return
result
.
call
(
this
,
method
.
apply
(
this
.
_wrapped
,
arguments
));
return
result
.
call
(
this
,
method
.
apply
(
this
.
_wrapped
,
arguments
));
};
};
});
});
_
.
extend
(
_
.
prototype
,
{
// Start chaining a wrapped Underscore object.
chain
:
function
()
{
this
.
_chain
=
true
;
return
this
;
},
// Extracts the result from a wrapped and chained object.
// Extracts the result from a wrapped and chained object.
value
:
function
()
{
_
.
prototype
.
value
=
function
()
{
return
this
.
_wrapped
;
return
this
.
_wrapped
;
}
};
// 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
)
);
examples/backbone_require/package.json
0 → 100644
View file @
3c4b899e
{
"private"
:
true
,
"dependencies"
:
{
"backbone"
:
"^1.1.2"
,
"backbone.localstorage"
:
"^1.1.16"
,
"jquery"
:
"^2.1.3"
,
"requirejs"
:
"^2.1.15"
,
"requirejs-text"
:
"^2.0.12"
,
"todomvc-app-css"
:
"^1.0.0"
,
"todomvc-common"
:
"^1.0.1"
,
"underscore"
:
"^1.7.0"
}
}
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