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
Sven Franck
todomvc
Commits
89c41418
Commit
89c41418
authored
Nov 23, 2014
by
Pascal Hartig
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1075 from podefr/master
fix #1071: Olives: Update Olives and Emily to latest 1.x versions
parents
b9c3b488
9df98e41
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
3934 additions
and
2909 deletions
+3934
-2909
examples/olives/bower.json
examples/olives/bower.json
+2
-2
examples/olives/bower_components/emily/build/Emily.js
examples/olives/bower_components/emily/build/Emily.js
+1423
-1005
examples/olives/bower_components/olives/build/Olives.js
examples/olives/bower_components/olives/build/Olives.js
+1518
-964
examples/olives/bower_components/olives/src/Bind.plugin.js
examples/olives/bower_components/olives/src/Bind.plugin.js
+604
-573
examples/olives/bower_components/olives/src/DomUtils.js
examples/olives/bower_components/olives/src/DomUtils.js
+2
-0
examples/olives/bower_components/olives/src/Event.plugin.js
examples/olives/bower_components/olives/src/Event.plugin.js
+118
-116
examples/olives/bower_components/olives/src/LocalStore.js
examples/olives/bower_components/olives/src/LocalStore.js
+3
-1
examples/olives/bower_components/olives/src/OObject.js
examples/olives/bower_components/olives/src/OObject.js
+180
-174
examples/olives/bower_components/olives/src/Place.plugin.js
examples/olives/bower_components/olives/src/Place.plugin.js
+67
-65
examples/olives/bower_components/olives/src/Plugins.js
examples/olives/bower_components/olives/src/Plugins.js
+2
-0
examples/olives/bower_components/olives/src/SocketIOTransport.js
...s/olives/bower_components/olives/src/SocketIOTransport.js
+15
-9
No files found.
examples/olives/bower.json
View file @
89c41418
...
...
@@ -2,8 +2,8 @@
"name"
:
"todomvc-olives"
,
"version"
:
"0.0.0"
,
"dependencies"
:
{
"olives"
:
"~1.
4
.0"
,
"emily"
:
"~1.
3.5
"
,
"olives"
:
"~1.
6
.0"
,
"emily"
:
"~1.
8.1
"
,
"requirejs"
:
"~2.1.5"
,
"todomvc-common"
:
"~0.3.0"
}
...
...
examples/olives/bower_components/emily/build/Emily.js
View file @
89c41418
...
...
@@ -7,7 +7,7 @@
*/
/**
* Emily
* Emily
.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
...
...
@@ -19,6 +19,36 @@ define('Tools',[],
*/
function
Tools
(){
/**
* Get the closest number in an array
* @param {Number} item the base number
* @param {Array} array the array to search into
* @param {Function} getDiff returns the difference between the base number and
* and the currently read item in the array. The item which returned the smallest difference wins.
* @private
*/
function
_getClosest
(
item
,
array
,
getDiff
)
{
var
closest
,
diff
;
if
(
!
array
)
{
return
;
}
array
.
forEach
(
function
(
comparedItem
,
comparedItemIndex
)
{
var
thisDiff
=
getDiff
(
comparedItem
,
item
);
if
(
thisDiff
>=
0
&&
(
typeof
diff
==
"
undefined
"
||
thisDiff
<
diff
))
{
diff
=
thisDiff
;
closest
=
comparedItemIndex
;
}
});
return
closest
;
}
return
{
/**
* For applications that don't run in a browser, window is not the global object.
...
...
@@ -261,7 +291,7 @@ function Tools(){
*/
getNestedProperty
:
function
getNestedProperty
(
object
,
property
)
{
if
(
object
&&
object
instanceof
Object
)
{
if
(
typeof
property
==
"
string
"
&&
property
!
=
""
)
{
if
(
typeof
property
==
"
string
"
&&
property
!=
=
""
)
{
var
split
=
property
.
split
(
"
.
"
);
return
split
.
reduce
(
function
(
obj
,
prop
)
{
return
obj
&&
obj
[
prop
];
...
...
@@ -286,7 +316,7 @@ function Tools(){
*/
setNestedProperty
:
function
setNestedProperty
(
object
,
property
,
value
)
{
if
(
object
&&
object
instanceof
Object
)
{
if
(
typeof
property
==
"
string
"
&&
property
!
=
""
)
{
if
(
typeof
property
==
"
string
"
&&
property
!=
=
""
)
{
var
split
=
property
.
split
(
"
.
"
);
return
split
.
reduce
(
function
(
obj
,
prop
,
idx
)
{
obj
[
prop
]
=
obj
[
prop
]
||
{};
...
...
@@ -304,6 +334,45 @@ function Tools(){
}
else
{
return
object
;
}
},
/**
* Get the closest number in an array given a base number
* Example: closest(30, [20, 0, 50, 29]) will return 3 as 29 is the closest item
* @param {Number} item the base number
* @param {Array} array the array of numbers to search into
* @returns {Number} the index of the closest item in the array
*/
closest
:
function
closest
(
item
,
array
)
{
return
_getClosest
(
item
,
array
,
function
(
comparedItem
,
item
)
{
return
Math
.
abs
(
comparedItem
-
item
);
});
},
/**
* Get the closest greater number in an array given a base number
* Example: closest(30, [20, 0, 50, 29]) will return 2 as 50 is the closest greater item
* @param {Number} item the base number
* @param {Array} array the array of numbers to search into
* @returns {Number} the index of the closest item in the array
*/
closestGreater
:
function
closestGreater
(
item
,
array
)
{
return
_getClosest
(
item
,
array
,
function
(
comparedItem
,
item
)
{
return
comparedItem
-
item
;
});
},
/**
* Get the closest lower number in an array given a base number
* Example: closest(30, [20, 0, 50, 29]) will return 0 as 20 is the closest lower item
* @param {Number} item the base number
* @param {Array} array the array of numbers to search into
* @returns {Number} the index of the closest item in the array
*/
closestLower
:
function
closestLower
(
item
,
array
)
{
return
_getClosest
(
item
,
array
,
function
(
comparedItem
,
item
)
{
return
item
-
comparedItem
;
});
}
...
...
@@ -315,7 +384,7 @@ function Tools(){
/**
* Emily
* Emily
.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
...
...
@@ -330,6 +399,8 @@ define('Observable',["Tools"],
*/
function
Observable
(
Tools
)
{
/**
* Defines the Observable
* @private
...
...
@@ -363,6 +434,21 @@ function Observable(Tools) {
}
};
/**
* Listen to an event just once before removing the handler
* @param {String} topic the topic to observe
* @param {Function} callback the callback to execute
* @param {Object} scope the scope in which to execute the callback
* @returns handle
*/
this
.
once
=
function
once
(
topic
,
callback
,
scope
)
{
var
handle
=
this
.
watch
(
topic
,
function
()
{
callback
.
apply
(
scope
,
arguments
);
this
.
unwatch
(
handle
);
},
this
);
return
handle
;
};
/**
* Remove an observer
* @param {Handle} handle returned by the watch method
...
...
@@ -398,14 +484,16 @@ function Observable(Tools) {
if
(
observers
)
{
Tools
.
loop
(
observers
,
function
(
value
)
{
try
{
value
&&
value
[
0
].
apply
(
value
[
1
]
||
null
,
args
);
if
(
value
)
{
value
[
0
].
apply
(
value
[
1
]
||
null
,
args
);
}
}
catch
(
err
)
{
}
});
return
true
;
}
else
{
return
false
;
}
}
,
}
;
/**
* Check if topic has the described observer
...
...
@@ -444,7 +532,7 @@ function Observable(Tools) {
});
/**
* Emily
* Emily
.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
...
...
@@ -456,6 +544,8 @@ define('StateMachine',["Tools"],
*/
function
StateMachine
(
Tools
)
{
/**
* @param initState {String} the initial state
* @param diagram {Object} the diagram that describes the state machine
...
...
@@ -511,7 +601,8 @@ function StateMachine(Tools) {
*/
this
.
add
=
function
add
(
name
)
{
if
(
!
_states
[
name
])
{
return
_states
[
name
]
=
new
Transition
();
var
transition
=
_states
[
name
]
=
new
Transition
();
return
transition
;
}
else
{
return
_states
[
name
];
}
...
...
@@ -629,8 +720,8 @@ function StateMachine(Tools) {
return
false
;
}
if
(
typeof
event
==
"
string
"
&&
typeof
action
==
"
function
"
)
{
if
(
typeof
event
==
"
string
"
&&
typeof
action
==
"
function
"
)
{
arr
[
0
]
=
action
;
...
...
@@ -680,8 +771,8 @@ function StateMachine(Tools) {
* @private
* @returns false if error, the next state or undefined if success (that sounds weird)
*/
this
.
event
=
function
event
(
e
vent
)
{
var
_transition
=
_transitions
[
e
vent
];
this
.
event
=
function
event
(
newE
vent
)
{
var
_transition
=
_transitions
[
newE
vent
];
if
(
_transition
)
{
_transition
[
0
].
apply
(
_transition
[
1
],
Tools
.
toArray
(
arguments
).
slice
(
1
));
return
_transition
[
2
];
...
...
@@ -689,14 +780,14 @@ function StateMachine(Tools) {
return
false
;
}
};
};
}
return
StateMachineConstructor
;
});
/**
* Emily
* Emily
.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
...
...
@@ -708,6 +799,8 @@ define('Promise',["Observable", "StateMachine"],
*/
function
Promise
(
Observable
,
StateMachine
)
{
return
function
PromiseConstructor
()
{
/**
...
...
@@ -726,7 +819,7 @@ function Promise(Observable, StateMachine) {
* The funky observable
* @private
*/
_observable
=
new
Observable
,
_observable
=
new
Observable
()
,
/**
* The state machine States & transitions
...
...
@@ -822,7 +915,7 @@ function Promise(Observable, StateMachine) {
* @returns {Promise} the new promise
*/
this
.
then
=
function
then
()
{
var
promise
=
new
PromiseConstructor
;
var
promise
=
new
PromiseConstructor
()
;
// If a fulfillment callback is given
if
(
arguments
[
0
]
instanceof
Function
)
{
...
...
@@ -903,7 +996,7 @@ function Promise(Observable, StateMachine) {
promise
.
reject
(
err
);
}
}
};
};
/**
...
...
@@ -954,7 +1047,7 @@ function Promise(Observable, StateMachine) {
return
_states
;
};
}
};
...
...
@@ -962,7 +1055,7 @@ function Promise(Observable, StateMachine) {
});
/**
* Emily
* Emily
.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
...
...
@@ -975,6 +1068,8 @@ define('Store',["Observable", "Tools"],
*/
function
Store
(
Observable
,
Tools
)
{
/**
* Defines the Store
* @param {Array/Object} the data to initialize the store with
...
...
@@ -1000,6 +1095,12 @@ define('Store',["Observable", "Tools"],
*/
_valueObservable
=
new
Observable
(),
/**
* Saves the handles for the subscriptions of the computed properties
* @private
*/
_computed
=
[],
/**
* Gets the difference between two objects and notifies them
* @private
...
...
@@ -1131,9 +1232,12 @@ define('Store',["Observable", "Tools"],
};
/**
* Alter the data be
calling one of it's method
* Alter the data by
calling one of it's method
* When the modifications are done, it notifies on changes.
* If the function called doesn't alter the data, consider using proxy instead
* which is much, much faster.
* @param {String} func the name of the method
* @params {*} any number of params to be given to the func
* @returns the result of the method call
*/
this
.
alter
=
function
alter
(
func
)
{
...
...
@@ -1142,8 +1246,9 @@ define('Store',["Observable", "Tools"],
if
(
_data
[
func
])
{
previousData
=
Tools
.
clone
(
_data
);
apply
=
_data
[
func
].
apply
(
_data
,
Array
.
prototype
.
slice
.
call
(
arguments
,
1
)
);
apply
=
this
.
proxy
.
apply
(
this
,
arguments
);
_notifyDiffs
(
previousData
);
_storeObservable
.
notify
(
"
altered
"
,
_data
,
previousData
);
return
apply
;
}
else
{
return
false
;
...
...
@@ -1151,9 +1256,20 @@ define('Store',["Observable", "Tools"],
};
/**
* proxy is an alias for alter
* Proxy is similar to alter but doesn't trigger events.
* It's preferable to call proxy for functions that don't
* update the interal data source, like slice or filter.
* @param {String} func the name of the method
* @params {*} any number of params to be given to the func
* @returns the result of the method call
*/
this
.
proxy
=
this
.
alter
;
this
.
proxy
=
function
proxy
(
func
)
{
if
(
_data
[
func
])
{
return
_data
[
func
].
apply
(
_data
,
Array
.
prototype
.
slice
.
call
(
arguments
,
1
));
}
else
{
return
false
;
}
};
/**
* Watch the store's modifications
...
...
@@ -1234,6 +1350,7 @@ define('Store',["Observable", "Tools"],
var
previousData
=
Tools
.
clone
(
_data
);
_data
=
Tools
.
clone
(
data
)
||
{};
_notifyDiffs
(
previousData
);
_storeObservable
.
notify
(
"
resetted
"
,
_data
,
previousData
);
return
true
;
}
else
{
return
false
;
...
...
@@ -1241,6 +1358,65 @@ define('Store',["Observable", "Tools"],
};
/**
* Compute a new property from other properties.
* The computed property will look exactly similar to any none
* computed property, it can be watched upon.
* @param {String} name the name of the computed property
* @param {Array} computeFrom a list of properties to compute from
* @param {Function} callback the callback to compute the property
* @param {Object} scope the scope in which to execute the callback
* @returns {Boolean} false if wrong params given to the function
*/
this
.
compute
=
function
compute
(
name
,
computeFrom
,
callback
,
scope
)
{
var
args
=
[];
if
(
typeof
name
==
"
string
"
&&
typeof
computeFrom
==
"
object
"
&&
typeof
callback
==
"
function
"
&&
!
this
.
isCompute
(
name
))
{
_computed
[
name
]
=
[];
Tools
.
loop
(
computeFrom
,
function
(
property
)
{
_computed
[
name
].
push
(
this
.
watchValue
(
property
,
function
()
{
this
.
set
(
name
,
callback
.
call
(
scope
));
},
this
));
},
this
);
this
.
set
(
name
,
callback
.
call
(
scope
));
return
true
;
}
else
{
return
false
;
}
};
/**
* Remove a computed property
* @param {String} name the name of the computed to remove
* @returns {Boolean} true if the property is removed
*/
this
.
removeCompute
=
function
removeCompute
(
name
)
{
if
(
this
.
isCompute
(
name
))
{
Tools
.
loop
(
_computed
[
name
],
function
(
handle
)
{
this
.
unwatchValue
(
handle
);
},
this
);
this
.
del
(
name
);
return
true
;
}
else
{
return
false
;
}
};
/**
* Tells if a property is a computed property
* @param {String} name the name of the property to test
* @returns {Boolean} true if it's a computed property
*/
this
.
isCompute
=
function
isCompute
(
name
)
{
return
!!
_computed
[
name
];
};
/**
* Returns a JSON version of the data
* Use dump if you want all the data as a plain js object
...
...
@@ -1261,11 +1437,10 @@ define('Store',["Observable", "Tools"],
});
/**
* Emily
* Emily
.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
define
(
'
Transport
'
,[],
/**
* @class
...
...
@@ -1275,6 +1450,8 @@ define('Transport',[],
*/
function
Transport
()
{
/**
* Create a Transport
* @param {Emily Store} [optionanl] $reqHandlers an object containing the request handlers
...
...
@@ -1319,11 +1496,13 @@ function Transport() {
* @returns
*/
this
.
request
=
function
request
(
reqHandler
,
data
,
callback
,
scope
)
{
if
(
_reqHandlers
.
has
(
reqHandler
)
&&
typeof
data
!=
"
undefined
"
)
{
if
(
_reqHandlers
.
has
(
reqHandler
)
&&
typeof
data
!=
"
undefined
"
)
{
_reqHandlers
.
get
(
reqHandler
)(
data
,
function
()
{
callback
&&
callback
.
apply
(
scope
,
arguments
);
if
(
callback
)
{
callback
.
apply
(
scope
,
arguments
);
}
});
return
true
;
}
else
{
...
...
@@ -1341,9 +1520,9 @@ function Transport() {
* @returns {Function} the abort function to call to stop listening
*/
this
.
listen
=
function
listen
(
reqHandler
,
data
,
callback
,
scope
)
{
if
(
_reqHandlers
.
has
(
reqHandler
)
&&
typeof
data
!=
"
undefined
"
&&
typeof
callback
==
"
function
"
)
{
if
(
_reqHandlers
.
has
(
reqHandler
)
&&
typeof
data
!=
"
undefined
"
&&
typeof
callback
==
"
function
"
)
{
var
func
=
function
()
{
callback
.
apply
(
scope
,
arguments
);
...
...
@@ -1368,3 +1547,242 @@ function Transport() {
};
});
/**
* Emily.js - http://flams.github.com/emily/
* Copyright(c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com>
* MIT Licensed
*/
define
(
'
Router
'
,[
"
Observable
"
,
"
Store
"
,
"
Tools
"
],
/**
* @class
* Routing allows for navigating in an application by defining routes.
*/
function
Router
(
Observable
,
Store
,
Tools
)
{
return
function
RouterConstructor
()
{
/**
* The routes observable (the applications use it)
* @private
*/
var
_routes
=
new
Observable
(),
/**
* The events observable (used by Routing)
* @private
*/
_events
=
new
Observable
(),
/**
* The routing history
* @private
*/
_history
=
new
Store
([]),
/**
* For navigating through the history, remembers the current position
* @private
*/
_currentPos
=
-
1
,
/**
* The depth of the history
* @private
*/
_maxHistory
=
10
;
/**
* Only for debugging
* @private
*/
this
.
getRoutesObservable
=
function
getRoutesObservable
()
{
return
_routes
;
};
/**
* Only for debugging
* @private
*/
this
.
getEventsObservable
=
function
getEventsObservable
()
{
return
_events
;
};
/**
* Set the maximum length of history
* As the user navigates through the application, the
* routeur keeps track of the history. Set the depth of the history
* depending on your need and the amount of memory that you can allocate it
* @param {Number} maxHistory the depth of history
* @returns {Boolean} true if maxHistory is equal or greater than 0
*/
this
.
setMaxHistory
=
function
setMaxHistory
(
maxHistory
)
{
if
(
maxHistory
>=
0
)
{
_maxHistory
=
maxHistory
;
return
true
;
}
else
{
return
false
;
}
};
/**
* Get the current max history setting
* @returns {Number} the depth of history
*/
this
.
getMaxHistory
=
function
getMaxHistory
()
{
return
_maxHistory
;
};
/**
* Set a new route
* @param {String} route the name of the route
* @param {Function} func the function to be execute when navigating to the route
* @param {Object} scope the scope in which to execute the function
* @returns a handle to remove the route
*/
this
.
set
=
function
set
()
{
return
_routes
.
watch
.
apply
(
_routes
,
arguments
);
};
/**
* Remove a route
* @param {Object} handle the handle provided by the set method
* @returns true if successfully removed
*/
this
.
unset
=
function
unset
(
handle
)
{
return
_routes
.
unwatch
(
handle
);
};
/**
* Navigate to a route
* @param {String} route the route to navigate to
* @param {*} *params
* @returns
*/
this
.
navigate
=
function
get
(
route
,
params
)
{
if
(
this
.
load
.
apply
(
this
,
arguments
))
{
// Before adding a new route to the history, we must clear the forward history
_history
.
proxy
(
"
splice
"
,
_currentPos
+
1
,
_history
.
count
());
_history
.
proxy
(
"
push
"
,
Tools
.
toArray
(
arguments
));
this
.
ensureMaxHistory
(
_history
);
_currentPos
=
_history
.
count
()
-
1
;
return
true
;
}
else
{
return
false
;
}
};
/**
* Ensure that history doesn't grow bigger than the max history setting
* @param {Store} history the history store
* @private
*/
this
.
ensureMaxHistory
=
function
ensureMaxHistory
(
history
)
{
var
count
=
history
.
count
(),
max
=
this
.
getMaxHistory
(),
excess
=
count
-
max
;
if
(
excess
>
0
)
{
history
.
proxy
(
"
splice
"
,
0
,
excess
);
}
};
/**
* Actually loads the route
* @private
*/
this
.
load
=
function
load
()
{
var
copy
=
Tools
.
toArray
(
arguments
);
if
(
_routes
.
notify
.
apply
(
_routes
,
copy
))
{
copy
.
unshift
(
"
route
"
);
_events
.
notify
.
apply
(
_events
,
copy
);
return
true
;
}
else
{
return
false
;
}
};
/**
* Watch for route changes
* @param {Function} func the func to execute when the route changes
* @param {Object} scope the scope in which to execute the function
* @returns {Object} the handle to unwatch for route changes
*/
this
.
watch
=
function
watch
(
func
,
scope
)
{
return
_events
.
watch
(
"
route
"
,
func
,
scope
);
};
/**
* Unwatch routes changes
* @param {Object} handle the handle was returned by the watch function
* @returns true if unwatch
*/
this
.
unwatch
=
function
unwatch
(
handle
)
{
return
_events
.
unwatch
(
handle
);
};
/**
* Get the history store, for debugging only
* @private
*/
this
.
getHistoryStore
=
function
getHistoryStore
()
{
return
_history
;
};
/**
* Get the current length of history
* @returns {Number} the length of history
*/
this
.
getHistoryCount
=
function
getHistoryCount
()
{
return
_history
.
count
();
};
/**
* Flush the entire history
*/
this
.
clearHistory
=
function
clearHistory
()
{
_history
.
reset
([]);
};
/**
* Go back and forth in the history
* @param {Number} nb the amount of history to rewind/forward
* @returns true if history exists
*/
this
.
go
=
function
go
(
nb
)
{
var
history
=
_history
.
get
(
_currentPos
+
nb
);
if
(
history
)
{
_currentPos
+=
nb
;
this
.
load
.
apply
(
this
,
history
);
return
true
;
}
else
{
return
false
;
}
};
/**
* Go back in the history, short for go(-1)
* @returns
*/
this
.
back
=
function
back
()
{
return
this
.
go
(
-
1
);
};
/**
* Go forward in the history, short for go(1)
* @returns
*/
this
.
forward
=
function
forward
()
{
return
this
.
go
(
1
);
};
};
});
\ No newline at end of file
examples/olives/bower_components/olives/build/Olives.js
View file @
89c41418
...
...
@@ -12,6 +12,8 @@
define
(
'
DomUtils
'
,[
"
Tools
"
],
function
(
Tools
)
{
return
{
/**
* Returns a NodeList including the given dom node,
...
...
@@ -127,6 +129,8 @@ define('Bind.plugin',["Store", "Observable", "Tools", "DomUtils"],
*/
function
BindPlugin
(
Store
,
Observable
,
Tools
,
DomUtils
)
{
return
function
BindPluginConstructor
(
$model
,
$bindings
)
{
/**
...
...
@@ -146,14 +150,28 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* each foreach has its itemRenderer
* @private
*/
_itemRenderers
=
{};
_itemRenderers
=
{},
/**
* The observers handlers
* for debugging only
* @private
*/
this
.
observers
=
{};
_observers
=
{};
/**
* Exposed for debugging purpose
* @private
*/
this
.
observers
=
_observers
;
function
_removeObserversForId
(
id
)
{
if
(
_observers
[
id
])
{
_observers
[
id
].
forEach
(
function
(
handler
)
{
_model
.
unwatchValue
(
handler
);
});
delete
_observers
[
id
];
}
}
/**
* Define the model to watch for
...
...
@@ -247,7 +265,9 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
_rootNode
=
rootNode
;
renderer
=
_rootNode
.
querySelector
(
"
*
"
);
this
.
setRenderer
(
renderer
);
renderer
&&
_rootNode
.
removeChild
(
renderer
);
if
(
renderer
)
{
_rootNode
.
removeChild
(
renderer
);
}
return
true
;
}
else
{
return
false
;
...
...
@@ -287,7 +307,7 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* The nodes created from the items are stored here
* @private
*/
this
.
items
=
new
Store
([])
;
this
.
items
=
{}
;
/**
* Set the start limit
...
...
@@ -296,7 +316,8 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns the value
*/
this
.
setStart
=
function
setStart
(
start
)
{
return
_start
=
parseInt
(
start
,
10
);
_start
=
parseInt
(
start
,
10
);
return
_start
;
};
/**
...
...
@@ -315,7 +336,8 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns the value
*/
this
.
setNb
=
function
setNb
(
nb
)
{
return
_nb
=
nb
==
"
*
"
?
nb
:
parseInt
(
nb
,
10
);
_nb
=
nb
==
"
*
"
?
nb
:
parseInt
(
nb
,
10
);
return
_nb
;
};
/**
...
...
@@ -337,12 +359,16 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
var
node
,
next
;
if
(
typeof
id
==
"
number
"
&&
!
this
.
items
.
get
(
id
))
{
if
(
typeof
id
==
"
number
"
&&
!
this
.
items
[
id
])
{
next
=
this
.
getNextItem
(
id
);
node
=
this
.
create
(
id
);
if
(
node
)
{
// IE (until 9) apparently fails to appendChild when insertBefore's second argument is null, hence this.
next
=
this
.
getNextItem
(
id
);
next
?
_rootNode
.
insertBefore
(
node
,
next
)
:
_rootNode
.
appendChild
(
node
);
if
(
next
)
{
_rootNode
.
insertBefore
(
node
,
next
);
}
else
{
_rootNode
.
appendChild
(
node
);
}
return
true
;
}
else
{
return
false
;
...
...
@@ -359,11 +385,18 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns
*/
this
.
getNextItem
=
function
getNextItem
(
id
)
{
return
this
.
items
.
alter
(
"
slice
"
,
id
+
1
).
filter
(
function
(
value
)
{
if
(
DomUtils
.
isAcceptedType
(
value
))
{
return
true
;
var
keys
=
Object
.
keys
(
this
.
items
).
map
(
function
(
string
)
{
return
Number
(
string
);
}),
closest
=
Tools
.
closestGreater
(
id
,
keys
),
closestId
=
keys
[
closest
];
// Only return if different
if
(
closestId
!=
id
)
{
return
this
.
items
[
closestId
];
}
else
{
return
;
}
})[
0
];
};
/**
...
...
@@ -373,10 +406,11 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns
*/
this
.
removeItem
=
function
removeItem
(
id
)
{
var
item
=
this
.
items
.
get
(
id
)
;
var
item
=
this
.
items
[
id
]
;
if
(
item
)
{
_rootNode
.
removeChild
(
item
);
this
.
items
.
set
(
id
);
delete
this
.
items
[
id
];
_removeObserversForId
(
id
);
return
true
;
}
else
{
return
false
;
...
...
@@ -400,7 +434,7 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
child
.
setAttribute
(
"
data-
"
+
_plugins
.
name
+
"
_id
"
,
id
);
});
this
.
items
.
set
(
id
,
newNode
)
;
this
.
items
[
id
]
=
newNode
;
_plugins
.
apply
(
newNode
);
return
newNode
;
}
...
...
@@ -424,8 +458,10 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
if
(
_nb
!==
null
&&
_start
!==
null
)
{
// Loop through the existing items
this
.
items
.
loop
(
function
(
value
,
idx
)
{
Tools
.
loop
(
this
.
items
,
function
(
value
,
idx
)
{
// If an item is out of the boundary
idx
=
Number
(
idx
);
if
(
idx
<
_start
||
idx
>=
(
_start
+
_tmpNb
)
||
!
_model
.
has
(
idx
))
{
// Mark it
marked
.
push
(
idx
);
...
...
@@ -492,10 +528,7 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
_model
.
watch
(
"
deleted
"
,
function
(
idx
)
{
itemRenderer
.
render
();
// Also remove all observers
this
.
observers
[
idx
]
&&
this
.
observers
[
idx
].
forEach
(
function
(
handler
)
{
_model
.
unwatchValue
(
handler
);
},
this
);
delete
this
.
observers
[
idx
];
_removeObserversForId
(
idx
);
},
this
);
this
.
setItemRenderer
(
idItemRenderer
,
itemRenderer
);
...
...
@@ -647,14 +680,14 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
/**
* Prevents the submit and set the model with all form's inputs
* @param {HTMLFormElement} for
m
* @param {HTMLFormElement} DOMfro
m
* @returns true if valid form
*/
this
.
form
=
function
form
(
form
)
{
if
(
form
&&
form
.
nodeName
==
"
FORM
"
)
{
this
.
form
=
function
form
(
DOM
form
)
{
if
(
DOMform
&&
DOM
form
.
nodeName
==
"
FORM
"
)
{
var
that
=
this
;
form
.
addEventListener
(
"
submit
"
,
function
(
event
)
{
Tools
.
toArray
(
form
.
querySelectorAll
(
"
[name]
"
)).
forEach
(
that
.
set
,
that
);
DOM
form
.
addEventListener
(
"
submit
"
,
function
(
event
)
{
Tools
.
toArray
(
DOM
form
.
querySelectorAll
(
"
[name]
"
)).
forEach
(
that
.
set
,
that
);
event
.
preventDefault
();
},
true
);
return
true
;
...
...
@@ -754,6 +787,8 @@ define('Event.plugin',["DomUtils"],
*/
function
EventPlugin
(
Utils
)
{
/**
* The event plugin constructor.
* ex: new EventPlugin({method: function(){} ...}, false);
...
...
@@ -890,6 +925,8 @@ define('LocalStore',["Store", "Tools"],
*/
function
LocalStore
(
Store
,
Tools
)
{
function
LocalStoreConstructor
()
{
/**
...
...
@@ -971,7 +1008,7 @@ function LocalStore(Store, Tools) {
return
function
LocalStoreFactory
(
init
)
{
LocalStoreConstructor
.
prototype
=
new
Store
(
init
);
return
new
LocalStoreConstructor
;
return
new
LocalStoreConstructor
()
;
};
});
...
...
@@ -995,6 +1032,8 @@ define('Plugins',["Tools", "DomUtils"],
*/
function
Plugins
(
Tools
,
DomUtils
)
{
return
function
PluginsConstructor
(
$plugins
)
{
/**
...
...
@@ -1147,6 +1186,8 @@ define('OObject',["StateMachine", "Store", "Plugins", "DomUtils", "Tools"],
*/
function
OObject
(
StateMachine
,
Store
,
Plugins
,
DomUtils
,
Tools
)
{
return
function
OObjectConstructor
(
otherStore
)
{
/**
...
...
@@ -1179,7 +1220,7 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
// as it wouldn't be possible to know which node would belong to which UI
// This is probably a DOM limitation.
if
(
baseNode
.
childNodes
.
length
>
1
)
{
thro
w
Error
(
"
UI.template should have only one parent node
"
);
throw
ne
w
Error
(
"
UI.template should have only one parent node
"
);
}
else
{
UI
.
dom
=
baseNode
.
childNodes
[
0
];
}
...
...
@@ -1188,7 +1229,7 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
}
else
{
// An explicit message I hope
thro
w
Error
(
"
UI.template must be set prior to render
"
);
throw
ne
w
Error
(
"
UI.template must be set prior to render
"
);
}
},
...
...
@@ -1197,13 +1238,17 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
* This dom node should be somewhere in the dom of the application
* @private
*/
place
=
function
place
(
UI
,
place
,
beforeNode
)
{
if
(
place
)
{
place
=
function
place
(
UI
,
DOM
place
,
beforeNode
)
{
if
(
DOM
place
)
{
// IE (until 9) apparently fails to appendChild when insertBefore's second argument is null, hence this.
beforeNode
?
place
.
insertBefore
(
UI
.
dom
,
beforeNode
)
:
place
.
appendChild
(
UI
.
dom
);
if
(
beforeNode
)
{
DOMplace
.
insertBefore
(
UI
.
dom
,
beforeNode
);
}
else
{
DOMplace
.
appendChild
(
UI
.
dom
);
}
// Also save the new place, so next renderings
// will be made inside it
_currentPlace
=
place
;
_currentPlace
=
DOM
place
;
}
},
...
...
@@ -1242,7 +1287,7 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
* It has set/get/del/has/watch/unwatch methods
* @see Emily's doc for more info on how it works.
*/
this
.
model
=
otherStore
instanceof
Store
?
otherStore
:
new
Store
;
this
.
model
=
otherStore
instanceof
Store
?
otherStore
:
new
Store
()
;
/**
* The module that will manage the plugins for this UI
...
...
@@ -1338,6 +1383,8 @@ define('Place.plugin',["OObject", "Tools"],
*/
function
PlacePlugin
(
OObject
,
Tools
)
{
/**
* Intilialize a Place.plugin with a list of OObjects
* @param {Object} $uis a list of OObjects such as:
...
...
@@ -1427,6 +1474,8 @@ define('SocketIOTransport',["Observable", "Tools"],
*/
function
SocketIOTransport
(
Observable
,
Tools
)
{
/**
* Defines the SocketIOTransport
* @private
...
...
@@ -1462,7 +1511,7 @@ function SocketIOTransport(Observable, Tools) {
*/
this
.
getSocket
=
function
getSocket
()
{
return
_socket
;
}
,
}
;
/**
* Subscribe to a socket event
...
...
@@ -1471,7 +1520,7 @@ function SocketIOTransport(Observable, Tools) {
*/
this
.
on
=
function
on
(
event
,
func
)
{
return
_socket
.
on
(
event
,
func
);
}
,
}
;
/**
* Subscribe to a socket event but disconnect as soon as it fires.
...
...
@@ -1510,15 +1559,17 @@ function SocketIOTransport(Observable, Tools) {
* @param {Object} scope the scope in which to execute the callback
*/
this
.
request
=
function
request
(
channel
,
data
,
func
,
scope
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
)
{
var
reqData
=
{
eventId
:
Date
.
now
()
+
Math
.
floor
(
Math
.
random
()
*
1
e6
),
data
:
data
},
boundCallback
=
function
()
{
func
&&
func
.
apply
(
scope
||
null
,
arguments
);
if
(
func
)
{
func
.
apply
(
scope
||
null
,
arguments
);
}
};
this
.
once
(
reqData
.
eventId
,
boundCallback
);
...
...
@@ -1540,9 +1591,9 @@ function SocketIOTransport(Observable, Tools) {
* @returns
*/
this
.
listen
=
function
listen
(
channel
,
data
,
func
,
scope
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
&&
typeof
func
==
"
function
"
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
&&
typeof
func
==
"
function
"
)
{
var
reqData
=
{
eventId
:
Date
.
now
()
+
Math
.
floor
(
Math
.
random
()
*
1
e6
),
...
...
@@ -1550,7 +1601,9 @@ function SocketIOTransport(Observable, Tools) {
keepAlive
:
true
},
boundCallback
=
function
()
{
func
&&
func
.
apply
(
scope
||
null
,
arguments
);
if
(
func
)
{
func
.
apply
(
scope
||
null
,
arguments
);
}
},
that
=
this
;
...
...
@@ -1573,3 +1626,504 @@ function SocketIOTransport(Observable, Tools) {
this
.
setSocket
(
$socket
);
};
});
/**
* Olives http://flams.github.com/olives
* The MIT License (MIT)
* Copyright (c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
*/
define
(
'
Stack
'
,[
'
Tools
'
],
/**
* @class
* A Stack is a tool for managing DOM elements as groups. Within a group, dom elements
* can be added, removed, moved around. The group can be moved to another parent node
* while keeping the DOM elements in the same order, excluding the parent dom elements's
* children that are not in the Stack.
*/
function
Stack
()
{
var
Tools
=
require
(
"
Tools
"
);
return
function
StackConstructor
(
$parent
)
{
/**
* The parent DOM element is a documentFragment by default
* @private
*/
var
_parent
=
document
.
createDocumentFragment
(),
/**
* The place where the dom elements hide
* @private
*/
_hidePlace
=
document
.
createElement
(
"
div
"
),
/**
* The list of dom elements that are part of the stack
* Helps for excluding elements that are not part of it
* @private
*/
_childNodes
=
[],
_lastTransit
=
null
;
/**
* Add a DOM element to the stack. It will be appended.
* @param {HTMLElement} dom the DOM element to add
* @returns {HTMLElement} dom
*/
this
.
add
=
function
add
(
dom
)
{
if
(
!
this
.
has
(
dom
)
&&
dom
instanceof
HTMLElement
)
{
_parent
.
appendChild
(
dom
);
_childNodes
.
push
(
dom
);
return
dom
;
}
else
{
return
false
;
}
};
/**
* Remove a DOM element from the stack.
* @param {HTMLElement} dom the DOM element to remove
* @returns {HTMLElement} dom
*/
this
.
remove
=
function
remove
(
dom
)
{
var
index
;
if
(
this
.
has
(
dom
))
{
index
=
_childNodes
.
indexOf
(
dom
);
_parent
.
removeChild
(
dom
);
_childNodes
.
splice
(
index
,
1
);
return
dom
;
}
else
{
return
false
;
}
};
/**
* Place a stack by appending its DOM elements to a new parent
* @param {HTMLElement} newParentDom the new DOM element to append the stack to
* @returns {HTMLElement} newParentDom
*/
this
.
place
=
function
place
(
newParentDom
)
{
if
(
newParentDom
instanceof
HTMLElement
)
{
[].
slice
.
call
(
_parent
.
childNodes
).
forEach
(
function
(
childDom
)
{
if
(
this
.
has
(
childDom
))
{
newParentDom
.
appendChild
(
childDom
);
}
},
this
);
return
this
.
_setParent
(
newParentDom
);
}
else
{
return
false
;
}
};
/**
* Move an element up in the stack
* @param {HTMLElement} dom the dom element to move up
* @returns {HTMLElement} dom
*/
this
.
up
=
function
up
(
dom
)
{
if
(
this
.
has
(
dom
))
{
var
domPosition
=
this
.
getPosition
(
dom
);
this
.
move
(
dom
,
domPosition
+
1
);
return
dom
;
}
else
{
return
false
;
}
};
/**
* Move an element down in the stack
* @param {HTMLElement} dom the dom element to move down
* @returns {HTMLElement} dom
*/
this
.
down
=
function
down
(
dom
)
{
if
(
this
.
has
(
dom
))
{
var
domPosition
=
this
.
getPosition
(
dom
);
this
.
move
(
dom
,
domPosition
-
1
);
return
dom
;
}
else
{
return
false
;
}
};
/**
* Move an element that is already in the stack to a new position
* @param {HTMLElement} dom the dom element to move
* @param {Number} position the position to which to move the DOM element
* @returns {HTMLElement} dom
*/
this
.
move
=
function
move
(
dom
,
position
)
{
if
(
this
.
has
(
dom
))
{
var
domIndex
=
_childNodes
.
indexOf
(
dom
);
_childNodes
.
splice
(
domIndex
,
1
);
// Preventing a bug in IE when insertBefore is not given a valid
// second argument
var
nextElement
=
getNextElementInDom
(
position
);
if
(
nextElement
)
{
_parent
.
insertBefore
(
dom
,
nextElement
);
}
else
{
_parent
.
appendChild
(
dom
);
}
_childNodes
.
splice
(
position
,
0
,
dom
);
return
dom
;
}
else
{
return
false
;
}
};
function
getNextElementInDom
(
position
)
{
if
(
position
>=
_childNodes
.
length
)
{
return
;
}
var
nextElement
=
_childNodes
[
position
];
if
(
Tools
.
toArray
(
_parent
.
childNodes
).
indexOf
(
nextElement
)
==
-
1
)
{
return
getNextElementInDom
(
position
+
1
);
}
else
{
return
nextElement
;
}
}
/**
* Insert a new element at a specific position in the stack
* @param {HTMLElement} dom the dom element to insert
* @param {Number} position the position to which to insert the DOM element
* @returns {HTMLElement} dom
*/
this
.
insert
=
function
insert
(
dom
,
position
)
{
if
(
!
this
.
has
(
dom
)
&&
dom
instanceof
HTMLElement
)
{
_childNodes
.
splice
(
position
,
0
,
dom
);
_parent
.
insertBefore
(
dom
,
_parent
.
childNodes
[
position
]);
return
dom
;
}
else
{
return
false
;
}
};
/**
* Get the position of an element in the stack
* @param {HTMLElement} dom the dom to get the position from
* @returns {HTMLElement} dom
*/
this
.
getPosition
=
function
getPosition
(
dom
)
{
return
_childNodes
.
indexOf
(
dom
);
};
/**
* Count the number of elements in a stack
* @returns {Number} the number of items
*/
this
.
count
=
function
count
()
{
return
_parent
.
childNodes
.
length
;
};
/**
* Tells if a DOM element is in the stack
* @param {HTMLElement} dom the dom to tell if its in the stack
* @returns {HTMLElement} dom
*/
this
.
has
=
function
has
(
childDom
)
{
return
this
.
getPosition
(
childDom
)
>=
0
;
};
/**
* Hide a dom element that was previously added to the stack
* It will be taken out of the dom until displayed again
* @param {HTMLElement} dom the dom to hide
* @return {boolean} if dom element is in the stack
*/
this
.
hide
=
function
hide
(
dom
)
{
if
(
this
.
has
(
dom
))
{
_hidePlace
.
appendChild
(
dom
);
return
true
;
}
else
{
return
false
;
}
};
/**
* Show a dom element that was previously hidden
* It will be added back to the dom
* @param {HTMLElement} dom the dom to show
* @return {boolean} if dom element is current hidden
*/
this
.
show
=
function
show
(
dom
)
{
if
(
this
.
has
(
dom
)
&&
dom
.
parentNode
===
_hidePlace
)
{
this
.
move
(
dom
,
_childNodes
.
indexOf
(
dom
));
return
true
;
}
else
{
return
false
;
}
};
/**
* Helper function for hiding all the dom elements
*/
this
.
hideAll
=
function
hideAll
()
{
_childNodes
.
forEach
(
this
.
hide
,
this
);
};
/**
* Helper function for showing all the dom elements
*/
this
.
showAll
=
function
showAll
()
{
_childNodes
.
forEach
(
this
.
show
,
this
);
};
/**
* Get the parent node that a stack is currently attached to
* @returns {HTMLElement} parent node
*/
this
.
getParent
=
function
_getParent
()
{
return
_parent
;
};
/**
* Set the parent element (without appending the stacks dom elements to)
* @private
*/
this
.
_setParent
=
function
_setParent
(
parent
)
{
if
(
parent
instanceof
HTMLElement
)
{
_parent
=
parent
;
return
_parent
;
}
else
{
return
false
;
}
};
/**
* Get the place where the DOM elements are hidden
* @private
*/
this
.
getHidePlace
=
function
getHidePlace
()
{
return
_hidePlace
;
};
/**
* Set the place where the DOM elements are hidden
* @private
*/
this
.
setHidePlace
=
function
setHidePlace
(
hidePlace
)
{
if
(
hidePlace
instanceof
HTMLElement
)
{
_hidePlace
=
hidePlace
;
return
true
;
}
else
{
return
false
;
}
};
/**
* Get the last dom element that the stack transitted to
* @returns {HTMLElement} the last dom element
*/
this
.
getLastTransit
=
function
getLastTransit
()
{
return
_lastTransit
;
};
/**
* Transit between views, will show the new one and hide the previous
* element that the stack transitted to, if any.
* @param {HTMLElement} dom the element to transit to
* @returns {Boolean} false if the element can't be shown
*/
this
.
transit
=
function
transit
(
dom
)
{
if
(
_lastTransit
)
{
this
.
hide
(
_lastTransit
);
}
if
(
this
.
show
(
dom
))
{
_lastTransit
=
dom
;
return
true
;
}
else
{
return
false
;
}
};
this
.
_setParent
(
$parent
);
};
});
/**
* Olives http://flams.github.com/olives
* The MIT License (MIT)
* Copyright (c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
*/
define
(
'
LocationRouter
'
,[
"
Router
"
,
"
Tools
"
],
/**
* @class
* A locationRouter is a router which navigates to the route defined in the URL and updates this URL
* while navigating. It's a subtype of Emily's Router
*/
function
LocationRouter
(
Router
,
Tools
)
{
function
LocationRouterConstructor
()
{
/**
* The handle on the watch
* @private
*/
var
_watchHandle
,
/**
* The default route to navigate to when nothing is supplied in the url
* @private
*/
_defaultRoute
=
""
,
/**
* The last route that was navigated to
* @private
*/
_lastRoute
=
window
.
location
.
hash
;
/**
* Navigates to the current hash or to the default route if none is supplied in the url
* @private
*/
/*jshint validthis:true*/
function
doNavigate
()
{
if
(
window
.
location
.
hash
)
{
var
parsedHash
=
this
.
parse
(
window
.
location
.
hash
);
this
.
navigate
.
apply
(
this
,
parsedHash
);
}
else
{
this
.
navigate
(
_defaultRoute
);
}
}
/**
* Set the default route to navigate to when nothing is defined in the url
* @param {String} defaultRoute the defaultRoute to navigate to
* @returns {Boolean} true if it's not an empty string
*/
this
.
setDefaultRoute
=
function
setDefaultRoute
(
defaultRoute
)
{
if
(
defaultRoute
&&
typeof
defaultRoute
==
"
string
"
)
{
_defaultRoute
=
defaultRoute
;
return
true
;
}
else
{
return
false
;
}
};
/**
* Get the currently set default route
* @returns {String} the default route
*/
this
.
getDefaultRoute
=
function
getDefaultRoute
()
{
return
_defaultRoute
;
};
/**
* The function that parses the url to determine the route to navigate to.
* It has a default behavior explained below, but can be overriden as long as
* it has the same contract.
* @param {String} hash the hash coming from window.location.has
* @returns {Array} has to return an array with the list of arguments to call
* navigate with. The first item of the array must be the name of the route.
*
* Example: #album/holiday/2013
* will navigate to the route "album" and give two arguments "holiday" and "2013"
*/
this
.
parse
=
function
parse
(
hash
)
{
return
hash
.
split
(
"
#
"
).
pop
().
split
(
"
/
"
);
};
/**
* The function that converts, or serialises the route and its arguments to a valid URL.
* It has a default behavior below, but can be overriden as long as it has the same contract.
* @param {Array} args the list of arguments to serialize
* @returns {String} the serialized arguments to add to the url hashmark
*
* Example:
* ["album", "holiday", "2013"];
* will give "album/holiday/2013"
*
*/
this
.
toUrl
=
function
toUrl
(
args
)
{
return
args
.
join
(
"
/
"
);
};
/**
* When all the routes and handlers have been defined, start the location router
* so it parses the URL and navigates to the corresponding route.
* It will also start listening to route changes and hashmark changes to navigate.
* While navigating, the hashmark itself will also change to reflect the current route state
*/
this
.
start
=
function
start
(
defaultRoute
)
{
this
.
setDefaultRoute
(
defaultRoute
);
doNavigate
.
call
(
this
);
this
.
bindOnHashChange
();
this
.
bindOnRouteChange
();
};
/**
* Remove the events handler for cleaning.
*/
this
.
destroy
=
function
destroy
()
{
this
.
unwatch
(
_watchHandle
);
window
.
removeEventListener
(
"
hashchange
"
,
this
.
boundOnHashChange
,
true
);
};
/**
* Parse the hash and navigate to the corresponding url
* @private
*/
this
.
onHashChange
=
function
onHashChange
()
{
if
(
window
.
location
.
hash
!=
_lastRoute
)
{
doNavigate
.
call
(
this
);
}
};
/**
* The bound version of onHashChange for add/removeEventListener
* @private
*/
this
.
boundOnHashChange
=
this
.
onHashChange
.
bind
(
this
);
/**
* Add an event listener to hashchange to navigate to the corresponding route
* when it changes
* @private
*/
this
.
bindOnHashChange
=
function
bindOnHashChange
()
{
window
.
addEventListener
(
"
hashchange
"
,
this
.
boundOnHashChange
,
true
);
};
/**
* Watch route change events from the router to update the location
* @private
*/
this
.
bindOnRouteChange
=
function
bindOnRouteChange
()
{
_watchHandle
=
this
.
watch
(
this
.
onRouteChange
,
this
);
};
/**
* The handler for when the route changes
* It updates the location
* @private
*/
this
.
onRouteChange
=
function
onRouteChange
()
{
window
.
location
.
hash
=
this
.
toUrl
(
Tools
.
toArray
(
arguments
));
_lastRoute
=
window
.
location
.
hash
;
};
this
.
getLastRoute
=
function
getLastRoute
()
{
return
_lastRoute
;
};
}
return
function
LocationRouterFactory
()
{
LocationRouterConstructor
.
prototype
=
new
Router
();
return
new
LocationRouterConstructor
();
};
});
examples/olives/bower_components/olives/src/Bind.plugin.js
View file @
89c41418
...
...
@@ -13,6 +13,8 @@ define(["Store", "Observable", "Tools", "DomUtils"],
*/
function
BindPlugin
(
Store
,
Observable
,
Tools
,
DomUtils
)
{
"
use strict
"
;
return
function
BindPluginConstructor
(
$model
,
$bindings
)
{
/**
...
...
@@ -32,14 +34,28 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* each foreach has its itemRenderer
* @private
*/
_itemRenderers
=
{};
_itemRenderers
=
{},
/**
* The observers handlers
* for debugging only
* @private
*/
this
.
observers
=
{};
_observers
=
{};
/**
* Exposed for debugging purpose
* @private
*/
this
.
observers
=
_observers
;
function
_removeObserversForId
(
id
)
{
if
(
_observers
[
id
])
{
_observers
[
id
].
forEach
(
function
(
handler
)
{
_model
.
unwatchValue
(
handler
);
});
delete
_observers
[
id
];
}
}
/**
* Define the model to watch for
...
...
@@ -133,7 +149,9 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
_rootNode
=
rootNode
;
renderer
=
_rootNode
.
querySelector
(
"
*
"
);
this
.
setRenderer
(
renderer
);
renderer
&&
_rootNode
.
removeChild
(
renderer
);
if
(
renderer
)
{
_rootNode
.
removeChild
(
renderer
);
}
return
true
;
}
else
{
return
false
;
...
...
@@ -173,7 +191,7 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* The nodes created from the items are stored here
* @private
*/
this
.
items
=
new
Store
([])
;
this
.
items
=
{}
;
/**
* Set the start limit
...
...
@@ -182,7 +200,8 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns the value
*/
this
.
setStart
=
function
setStart
(
start
)
{
return
_start
=
parseInt
(
start
,
10
);
_start
=
parseInt
(
start
,
10
);
return
_start
;
};
/**
...
...
@@ -201,7 +220,8 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns the value
*/
this
.
setNb
=
function
setNb
(
nb
)
{
return
_nb
=
nb
==
"
*
"
?
nb
:
parseInt
(
nb
,
10
);
_nb
=
nb
==
"
*
"
?
nb
:
parseInt
(
nb
,
10
);
return
_nb
;
};
/**
...
...
@@ -223,12 +243,16 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
var
node
,
next
;
if
(
typeof
id
==
"
number
"
&&
!
this
.
items
.
get
(
id
))
{
if
(
typeof
id
==
"
number
"
&&
!
this
.
items
[
id
])
{
next
=
this
.
getNextItem
(
id
);
node
=
this
.
create
(
id
);
if
(
node
)
{
// IE (until 9) apparently fails to appendChild when insertBefore's second argument is null, hence this.
next
=
this
.
getNextItem
(
id
);
next
?
_rootNode
.
insertBefore
(
node
,
next
)
:
_rootNode
.
appendChild
(
node
);
if
(
next
)
{
_rootNode
.
insertBefore
(
node
,
next
);
}
else
{
_rootNode
.
appendChild
(
node
);
}
return
true
;
}
else
{
return
false
;
...
...
@@ -245,11 +269,18 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns
*/
this
.
getNextItem
=
function
getNextItem
(
id
)
{
return
this
.
items
.
alter
(
"
slice
"
,
id
+
1
).
filter
(
function
(
value
)
{
if
(
DomUtils
.
isAcceptedType
(
value
))
{
return
true
;
var
keys
=
Object
.
keys
(
this
.
items
).
map
(
function
(
string
)
{
return
Number
(
string
);
}),
closest
=
Tools
.
closestGreater
(
id
,
keys
),
closestId
=
keys
[
closest
];
// Only return if different
if
(
closestId
!=
id
)
{
return
this
.
items
[
closestId
];
}
else
{
return
;
}
})[
0
];
};
/**
...
...
@@ -259,10 +290,11 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
* @returns
*/
this
.
removeItem
=
function
removeItem
(
id
)
{
var
item
=
this
.
items
.
get
(
id
)
;
var
item
=
this
.
items
[
id
]
;
if
(
item
)
{
_rootNode
.
removeChild
(
item
);
this
.
items
.
set
(
id
);
delete
this
.
items
[
id
];
_removeObserversForId
(
id
);
return
true
;
}
else
{
return
false
;
...
...
@@ -286,7 +318,7 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
child
.
setAttribute
(
"
data-
"
+
_plugins
.
name
+
"
_id
"
,
id
);
});
this
.
items
.
set
(
id
,
newNode
)
;
this
.
items
[
id
]
=
newNode
;
_plugins
.
apply
(
newNode
);
return
newNode
;
}
...
...
@@ -310,8 +342,10 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
if
(
_nb
!==
null
&&
_start
!==
null
)
{
// Loop through the existing items
this
.
items
.
loop
(
function
(
value
,
idx
)
{
Tools
.
loop
(
this
.
items
,
function
(
value
,
idx
)
{
// If an item is out of the boundary
idx
=
Number
(
idx
);
if
(
idx
<
_start
||
idx
>=
(
_start
+
_tmpNb
)
||
!
_model
.
has
(
idx
))
{
// Mark it
marked
.
push
(
idx
);
...
...
@@ -378,10 +412,7 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
_model
.
watch
(
"
deleted
"
,
function
(
idx
)
{
itemRenderer
.
render
();
// Also remove all observers
this
.
observers
[
idx
]
&&
this
.
observers
[
idx
].
forEach
(
function
(
handler
)
{
_model
.
unwatchValue
(
handler
);
},
this
);
delete
this
.
observers
[
idx
];
_removeObserversForId
(
idx
);
},
this
);
this
.
setItemRenderer
(
idItemRenderer
,
itemRenderer
);
...
...
@@ -533,14 +564,14 @@ function BindPlugin(Store, Observable, Tools, DomUtils) {
/**
* Prevents the submit and set the model with all form's inputs
* @param {HTMLFormElement} for
m
* @param {HTMLFormElement} DOMfro
m
* @returns true if valid form
*/
this
.
form
=
function
form
(
form
)
{
if
(
form
&&
form
.
nodeName
==
"
FORM
"
)
{
this
.
form
=
function
form
(
DOM
form
)
{
if
(
DOMform
&&
DOM
form
.
nodeName
==
"
FORM
"
)
{
var
that
=
this
;
form
.
addEventListener
(
"
submit
"
,
function
(
event
)
{
Tools
.
toArray
(
form
.
querySelectorAll
(
"
[name]
"
)).
forEach
(
that
.
set
,
that
);
DOM
form
.
addEventListener
(
"
submit
"
,
function
(
event
)
{
Tools
.
toArray
(
DOM
form
.
querySelectorAll
(
"
[name]
"
)).
forEach
(
that
.
set
,
that
);
event
.
preventDefault
();
},
true
);
return
true
;
...
...
examples/olives/bower_components/olives/src/DomUtils.js
View file @
89c41418
...
...
@@ -6,6 +6,8 @@
define
([
"
Tools
"
],
function
(
Tools
)
{
"
use strict
"
;
return
{
/**
* Returns a NodeList including the given dom node,
...
...
examples/olives/bower_components/olives/src/Event.plugin.js
View file @
89c41418
...
...
@@ -14,6 +14,8 @@ define(["DomUtils"],
*/
function
EventPlugin
(
Utils
)
{
"
use strict
"
;
/**
* The event plugin constructor.
* ex: new EventPlugin({method: function(){} ...}, false);
...
...
examples/olives/bower_components/olives/src/LocalStore.js
View file @
89c41418
...
...
@@ -15,6 +15,8 @@ define(["Store", "Tools"],
*/
function
LocalStore
(
Store
,
Tools
)
{
"
use strict
"
;
function
LocalStoreConstructor
()
{
/**
...
...
@@ -96,7 +98,7 @@ function LocalStore(Store, Tools) {
return
function
LocalStoreFactory
(
init
)
{
LocalStoreConstructor
.
prototype
=
new
Store
(
init
);
return
new
LocalStoreConstructor
;
return
new
LocalStoreConstructor
()
;
};
});
examples/olives/bower_components/olives/src/OObject.js
View file @
89c41418
...
...
@@ -13,6 +13,8 @@ define(["StateMachine", "Store", "Plugins", "DomUtils", "Tools"],
*/
function
OObject
(
StateMachine
,
Store
,
Plugins
,
DomUtils
,
Tools
)
{
"
use strict
"
;
return
function
OObjectConstructor
(
otherStore
)
{
/**
...
...
@@ -45,7 +47,7 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
// as it wouldn't be possible to know which node would belong to which UI
// This is probably a DOM limitation.
if
(
baseNode
.
childNodes
.
length
>
1
)
{
thro
w
Error
(
"
UI.template should have only one parent node
"
);
throw
ne
w
Error
(
"
UI.template should have only one parent node
"
);
}
else
{
UI
.
dom
=
baseNode
.
childNodes
[
0
];
}
...
...
@@ -54,7 +56,7 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
}
else
{
// An explicit message I hope
thro
w
Error
(
"
UI.template must be set prior to render
"
);
throw
ne
w
Error
(
"
UI.template must be set prior to render
"
);
}
},
...
...
@@ -63,13 +65,17 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
* This dom node should be somewhere in the dom of the application
* @private
*/
place
=
function
place
(
UI
,
place
,
beforeNode
)
{
if
(
place
)
{
place
=
function
place
(
UI
,
DOM
place
,
beforeNode
)
{
if
(
DOM
place
)
{
// IE (until 9) apparently fails to appendChild when insertBefore's second argument is null, hence this.
beforeNode
?
place
.
insertBefore
(
UI
.
dom
,
beforeNode
)
:
place
.
appendChild
(
UI
.
dom
);
if
(
beforeNode
)
{
DOMplace
.
insertBefore
(
UI
.
dom
,
beforeNode
);
}
else
{
DOMplace
.
appendChild
(
UI
.
dom
);
}
// Also save the new place, so next renderings
// will be made inside it
_currentPlace
=
place
;
_currentPlace
=
DOM
place
;
}
},
...
...
@@ -108,7 +114,7 @@ function OObject(StateMachine, Store, Plugins, DomUtils, Tools) {
* It has set/get/del/has/watch/unwatch methods
* @see Emily's doc for more info on how it works.
*/
this
.
model
=
otherStore
instanceof
Store
?
otherStore
:
new
Store
;
this
.
model
=
otherStore
instanceof
Store
?
otherStore
:
new
Store
()
;
/**
* The module that will manage the plugins for this UI
...
...
examples/olives/bower_components/olives/src/Place.plugin.js
View file @
89c41418
...
...
@@ -12,6 +12,8 @@ define(["OObject", "Tools"],
*/
function
PlacePlugin
(
OObject
,
Tools
)
{
"
use strict
"
;
/**
* Intilialize a Place.plugin with a list of OObjects
* @param {Object} $uis a list of OObjects such as:
...
...
examples/olives/bower_components/olives/src/Plugins.js
View file @
89c41418
...
...
@@ -17,6 +17,8 @@ define(["Tools", "DomUtils"],
*/
function
Plugins
(
Tools
,
DomUtils
)
{
"
use strict
"
;
return
function
PluginsConstructor
(
$plugins
)
{
/**
...
...
examples/olives/bower_components/olives/src/SocketIOTransport.js
View file @
89c41418
...
...
@@ -12,6 +12,8 @@ define(["Observable", "Tools"],
*/
function
SocketIOTransport
(
Observable
,
Tools
)
{
"
use strict
"
;
/**
* Defines the SocketIOTransport
* @private
...
...
@@ -47,7 +49,7 @@ function SocketIOTransport(Observable, Tools) {
*/
this
.
getSocket
=
function
getSocket
()
{
return
_socket
;
}
,
}
;
/**
* Subscribe to a socket event
...
...
@@ -56,7 +58,7 @@ function SocketIOTransport(Observable, Tools) {
*/
this
.
on
=
function
on
(
event
,
func
)
{
return
_socket
.
on
(
event
,
func
);
}
,
}
;
/**
* Subscribe to a socket event but disconnect as soon as it fires.
...
...
@@ -95,15 +97,17 @@ function SocketIOTransport(Observable, Tools) {
* @param {Object} scope the scope in which to execute the callback
*/
this
.
request
=
function
request
(
channel
,
data
,
func
,
scope
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
)
{
var
reqData
=
{
eventId
:
Date
.
now
()
+
Math
.
floor
(
Math
.
random
()
*
1
e6
),
data
:
data
},
boundCallback
=
function
()
{
func
&&
func
.
apply
(
scope
||
null
,
arguments
);
if
(
func
)
{
func
.
apply
(
scope
||
null
,
arguments
);
}
};
this
.
once
(
reqData
.
eventId
,
boundCallback
);
...
...
@@ -125,9 +129,9 @@ function SocketIOTransport(Observable, Tools) {
* @returns
*/
this
.
listen
=
function
listen
(
channel
,
data
,
func
,
scope
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
&&
typeof
func
==
"
function
"
)
{
if
(
typeof
channel
==
"
string
"
&&
typeof
data
!=
"
undefined
"
&&
typeof
func
==
"
function
"
)
{
var
reqData
=
{
eventId
:
Date
.
now
()
+
Math
.
floor
(
Math
.
random
()
*
1
e6
),
...
...
@@ -135,7 +139,9 @@ function SocketIOTransport(Observable, Tools) {
keepAlive
:
true
},
boundCallback
=
function
()
{
func
&&
func
.
apply
(
scope
||
null
,
arguments
);
if
(
func
)
{
func
.
apply
(
scope
||
null
,
arguments
);
}
},
that
=
this
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment