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
00435de1
Commit
00435de1
authored
Feb 13, 2013
by
Addy Osmani
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #352 from petermichaux/gh-pages
Rewrite Maria example to use latest TodoMVC requirements
parents
0d6e84dd
6f5dad67
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
553 additions
and
1106 deletions
+553
-1106
labs/architecture-examples/maria/lib/aristocrat/aristocrat.js
.../architecture-examples/maria/lib/aristocrat/aristocrat.js
+3
-3
labs/architecture-examples/maria/lib/maria/maria.js
labs/architecture-examples/maria/lib/maria/maria.js
+166
-166
labs/architecture-examples/maria/src/css/app.css
labs/architecture-examples/maria/src/css/app.css
+4
-0
labs/architecture-examples/maria/src/css/todos.css
labs/architecture-examples/maria/src/css/todos.css
+0
-511
labs/architecture-examples/maria/src/index.html
labs/architecture-examples/maria/src/index.html
+18
-30
labs/architecture-examples/maria/src/js/bootstrap.js
labs/architecture-examples/maria/src/js/bootstrap.js
+31
-17
labs/architecture-examples/maria/src/js/controllers/TodoController.js
...cture-examples/maria/src/js/controllers/TodoController.js
+31
-39
labs/architecture-examples/maria/src/js/controllers/TodosController.js
...ture-examples/maria/src/js/controllers/TodosController.js
+31
-0
labs/architecture-examples/maria/src/js/controllers/TodosInputController.js
...examples/maria/src/js/controllers/TodosInputController.js
+0
-32
labs/architecture-examples/maria/src/js/controllers/TodosToolbarController.js
...amples/maria/src/js/controllers/TodosToolbarController.js
+0
-21
labs/architecture-examples/maria/src/js/models/TodoModel.js
labs/architecture-examples/maria/src/js/models/TodoModel.js
+40
-37
labs/architecture-examples/maria/src/js/models/TodosModel.js
labs/architecture-examples/maria/src/js/models/TodosModel.js
+59
-42
labs/architecture-examples/maria/src/js/namespace.js
labs/architecture-examples/maria/src/js/namespace.js
+3
-1
labs/architecture-examples/maria/src/js/templates/TodoTemplate.js
...hitecture-examples/maria/src/js/templates/TodoTemplate.js
+10
-11
labs/architecture-examples/maria/src/js/templates/TodosAppTemplate.js
...cture-examples/maria/src/js/templates/TodosAppTemplate.js
+0
-14
labs/architecture-examples/maria/src/js/templates/TodosInputTemplate.js
...ure-examples/maria/src/js/templates/TodosInputTemplate.js
+0
-13
labs/architecture-examples/maria/src/js/templates/TodosListTemplate.js
...ture-examples/maria/src/js/templates/TodosListTemplate.js
+0
-10
labs/architecture-examples/maria/src/js/templates/TodosStatsTemplate.js
...ure-examples/maria/src/js/templates/TodosStatsTemplate.js
+0
-10
labs/architecture-examples/maria/src/js/templates/TodosTemplate.js
...itecture-examples/maria/src/js/templates/TodosTemplate.js
+42
-0
labs/architecture-examples/maria/src/js/templates/TodosToolbarTemplate.js
...e-examples/maria/src/js/templates/TodosToolbarTemplate.js
+0
-15
labs/architecture-examples/maria/src/js/util.js
labs/architecture-examples/maria/src/js/util.js
+14
-0
labs/architecture-examples/maria/src/js/views/TodoView.js
labs/architecture-examples/maria/src/js/views/TodoView.js
+38
-47
labs/architecture-examples/maria/src/js/views/TodosAppView.js
.../architecture-examples/maria/src/js/views/TodosAppView.js
+0
-29
labs/architecture-examples/maria/src/js/views/TodosInputView.js
...rchitecture-examples/maria/src/js/views/TodosInputView.js
+0
-22
labs/architecture-examples/maria/src/js/views/TodosListView.js
...architecture-examples/maria/src/js/views/TodosListView.js
+0
-7
labs/architecture-examples/maria/src/js/views/TodosStatsView.js
...rchitecture-examples/maria/src/js/views/TodosStatsView.js
+0
-10
labs/architecture-examples/maria/src/js/views/TodosToolbarView.js
...hitecture-examples/maria/src/js/views/TodosToolbarView.js
+0
-19
labs/architecture-examples/maria/src/js/views/TodosView.js
labs/architecture-examples/maria/src/js/views/TodosView.js
+63
-0
No files found.
labs/architecture-examples/maria/lib/aristocrat/aristocrat.js
View file @
00435de1
/*
Aristocrat version
1
Aristocrat version
2
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/aristocrat/blob/master/LICENSE
*/
var
aristocrat
=
aristocrat
||
{};
var
aristocrat
=
{};
(
function
()
{
...
...
@@ -78,7 +78,7 @@ aristocrat.removeClass(document.body, 'king');
var
re
=
getRegExp
(
className
);
while
(
re
.
test
(
el
.
className
))
{
// in case multiple occurrences
el
.
className
=
el
.
className
.
replace
(
re
,
'
'
);
}
}
};
/**
...
...
labs/architecture-examples/maria/lib/maria/maria.js
View file @
00435de1
...
...
@@ -4,7 +4,7 @@ Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/evento/blob/master/LICENSE
*/
var
evento
=
evento
||
{};
*/
var
evento
=
{};
/**
@property evento.EventTarget
...
...
@@ -186,7 +186,7 @@ et.dispatchEvent({type:'change', extraData:'abc'});
*/
evento
.
EventTarget
.
prototype
.
dispatchEvent
=
function
(
evt
)
{
// Want to ensure we don't alter the evt object passed in as it
// Want to ensure we don't alter the evt object passed in as it
// may be a bubbling event. So clone it and then setting currentTarget
// won't break some event that is already being dispatched.
evt
=
create
(
evt
);
...
...
@@ -204,9 +204,9 @@ et.dispatchEvent({type:'change', extraData:'abc'});
//
// Without making a copy, one listener removing
// an already-called listener would result in skipping
// a not-yet-called listener. One listener removing
// a not-yet-called listener. One listener removing
// a not-yet-called listener would result in skipping that
// not-yet-called listner. The worst case scenario
// not-yet-called listner. The worst case scenario
// is a listener adding itself again which would
// create an infinite loop.
//
...
...
@@ -285,14 +285,14 @@ o.dispatchEvent({type:'change'});
(
typeof
pt
[
p
]
===
'
function
'
))
{
obj
[
p
]
=
pt
[
p
];
}
}
}
evento
.
EventTarget
.
call
(
obj
);
};
}());
/**
@property evento.
addEventListener
@property evento.
on
@parameter element {EventTarget} The object you'd like to observe.
...
...
@@ -324,27 +324,27 @@ var o = {
};
// late binding. handleEvent is found when each event is dispatched
evento.
addEventListener
(document.body, 'click', o);
evento.
on
(document.body, 'click', o);
// late binding. handleClick is found when each event is dispatched
evento.
addEventListener
(document.body, 'click', o, 'handleClick');
evento.
on
(document.body, 'click', o, 'handleClick');
// early binding. The supplied function is bound now
evento.
addEventListener
(document.body, 'click', o, o.handleClick);
evento.
addEventListener
(document.body, 'click', o, function(){});
evento.
on
(document.body, 'click', o, o.handleClick);
evento.
on
(document.body, 'click', o, function(){});
// supplied function will be called with document.body as this object
evento.
addEventListener
(document.body, 'click', function(){});
evento.
on
(document.body, 'click', function(){});
// The following form is supported but is not neccessary given the options
// above and it is recommended you avoid it.
evento.
addEventListener
(document.body, 'click', this.handleClick, this);
evento.
on
(document.body, 'click', this.handleClick, this);
*/
/**
@property evento.
removeEventListener
@property evento.
off
@parameter element {EventTarget} The object you'd like to stop observing.
...
...
@@ -360,32 +360,32 @@ Removes added listener matching the element/type/listener/auxArg combination exa
If this combination is not found there are no errors.
var o = {handleEvent:function(){}, handleClick:function(){}};
evento.
removeEventListener
(document.body, 'click', o);
evento.
removeEventListener
(document.body, 'click', o, 'handleClick');
evento.
removeEventListener
(document.body, 'click', o, fn);
evento.
removeEventListener
(document.body, 'click', fn);
evento.
removeEventListener
(document.body, 'click', this.handleClick, this);
evento.
off
(document.body, 'click', o);
evento.
off
(document.body, 'click', o, 'handleClick');
evento.
off
(document.body, 'click', o, fn);
evento.
off
(document.body, 'click', fn);
evento.
off
(document.body, 'click', this.handleClick, this);
*/
/**
@property evento.purge
EventListener
@property evento.purge
@parameter listener {EventListener} The listener object that should stop listening.
@description
Removes all registrations of the listener added through evento.
addEventListener
.
Removes all registrations of the listener added through evento.
on
.
This purging should be done before your application code looses its last reference
to listener. (This can also be done with more work using evento.
removeEventListener
for
to listener. (This can also be done with more work using evento.
off
for
each registeration.) If the listeners are not removed or purged, the listener
will continue to observe the EventTarget and cannot be garbage collected. In an
MVC application this can lead to "zombie views" if the model data cannot be
garbage collected. Event listeners need to be removed from event targets in browsers
with circular reference memory leak problems (i.e. old versions of Internet Explorer.)
The primary motivation for this purge function is to easy cleanup in MVC View destroy
The primary motivation for this purge function is to easy cleanup in MVC View destroy
methods. For example,
var APP_BoxView = function(model, controller) {
...
...
@@ -397,8 +397,8 @@ var APP_BoxView = function(model, controller) {
// implementing the EventTarget interface using listener objects
// and specifying method name using the same subscription interface.
//
evento.
addEventListener
(this.rootEl, 'click', this, 'handleClick');
evento.
addEventListener
(this.model, 'change', this, 'handleModelChange');
evento.
on
(this.rootEl, 'click', this, 'handleClick');
evento.
on
(this.model, 'change', this, 'handleModelChange');
};
APP_BoxView.prototype.handleClick = function() {
...
...
@@ -415,7 +415,7 @@ APP_BoxView.prototype.destroy = function() {
// to DOM nodes, model objects, or anything else implementing
// the EventTarget interface in one fell swoop.
//
evento.purge
EventListener
(this);
evento.purge(this);
};
*/
...
...
@@ -471,7 +471,7 @@ APP_BoxView.prototype.destroy = function() {
return
-
1
;
}
evento
.
addEventListener
=
function
(
element
,
type
,
listener
,
/*optional*/
auxArg
)
{
evento
.
on
=
function
(
element
,
type
,
listener
,
/*optional*/
auxArg
)
{
// Want to call createBundle with the same number of arguments
// that were passed to this function. Using apply preserves
// the number of arguments.
...
...
@@ -480,45 +480,45 @@ APP_BoxView.prototype.destroy = function() {
if
(
indexOfBundle
(
listener
.
_evento_bundles
,
bundle
)
>=
0
)
{
// do not add the same listener twice
return
;
}
}
}
else
{
listener
.
_evento_bundles
=
[];
}
if
(
typeof
bundle
.
element
.
addEventListener
===
'
function
'
)
{
bundle
.
element
.
addEventListener
(
bundle
.
type
,
bundle
.
wrappedHandler
,
false
);
bundle
.
element
.
addEventListener
(
bundle
.
type
,
bundle
.
wrappedHandler
,
false
);
}
else
if
((
typeof
bundle
.
element
.
attachEvent
===
'
object
'
)
&&
(
bundle
.
element
.
attachEvent
!==
null
))
{
bundle
.
element
.
attachEvent
(
'
on
'
+
bundle
.
type
,
bundle
.
wrappedHandler
);
}
else
{
throw
new
Error
(
'
evento.
addEventListener
: Supported EventTarget interface not found.
'
);
throw
new
Error
(
'
evento.
on
: Supported EventTarget interface not found.
'
);
}
listener
.
_evento_bundles
.
push
(
bundle
);
};
var
remove
=
evento
.
removeEventListener
=
function
(
element
,
type
,
listener
,
/*optional*/
auxArg
)
{
var
remove
=
evento
.
off
=
function
(
element
,
type
,
listener
,
/*optional*/
auxArg
)
{
if
(
listener
.
_evento_bundles
)
{
var
i
=
indexOfBundle
(
listener
.
_evento_bundles
,
createBundle
.
apply
(
null
,
arguments
));
if
(
i
>=
0
)
{
var
bundle
=
listener
.
_evento_bundles
[
i
];
if
(
typeof
bundle
.
element
.
removeEventListener
===
'
function
'
)
{
bundle
.
element
.
removeEventListener
(
bundle
.
type
,
bundle
.
wrappedHandler
,
false
);
}
}
else
if
((
typeof
bundle
.
element
.
detachEvent
===
'
object
'
)
&&
(
bundle
.
element
.
detachEvent
!==
null
))
{
bundle
.
element
.
detachEvent
(
'
on
'
+
bundle
.
type
,
bundle
.
wrappedHandler
);
}
}
else
{
throw
new
Error
(
'
evento.
removeEventListener
: Supported EventTarget interface not found.
'
);
}
throw
new
Error
(
'
evento.
off
: Supported EventTarget interface not found.
'
);
}
listener
.
_evento_bundles
.
splice
(
i
,
1
);
}
}
};
evento
.
purge
EventListener
=
function
(
listener
)
{
evento
.
purge
=
function
(
listener
)
{
if
(
listener
.
_evento_bundles
)
{
var
bundles
=
listener
.
_evento_bundles
.
slice
(
0
);
for
(
var
i
=
0
,
ilen
=
bundles
.
length
;
i
<
ilen
;
i
++
)
{
...
...
@@ -535,12 +535,13 @@ APP_BoxView.prototype.destroy = function() {
}());
/*
Hijos version
0 - JavaScript classes for building tree structures and the composite design pattern
Hijos version
2
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/hijos/blob/master/LICENSE
*/
var
hijos
=
hijos
||
{};
*/
var
hijos
=
{};
/**
@property hijos.Leaf
...
...
@@ -914,12 +915,12 @@ hijos.Node.mixin = function(obj) {
hijos
.
Node
.
call
(
obj
);
};
/*
Arbutus version
1
Arbutus version
2
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/arbutus/blob/master/LICENSE
*/
var
arbutus
=
arbutus
||
{};
*/
var
arbutus
=
{};
(
function
()
{
var
trimLeft
=
/^
\s
+/
,
...
...
@@ -962,7 +963,6 @@ https://github.com/petermichaux/arbutus/blob/master/LICENSE
var
parser
=
doc
.
createElement
(
'
div
'
);
var
fragment
=
doc
.
createDocumentFragment
();
parser
.
innerHTML
=
this
.
before
+
html
+
this
.
after
;
// console.log(parser.innerHTML);
var
node
=
this
.
getFirstResult
(
parser
);
var
nextNode
;
while
(
node
)
{
...
...
@@ -1025,13 +1025,13 @@ don't want to have a loop of thousands with calls to this function.
}());
/*
Grail version
2
Grail version
3
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/grail/blob/master/LICENSE
*/
var
grail
=
grail
||
{};
var
grail
=
{};
(
function
()
{
var
trimLeft
=
/^
\s
+/
;
...
...
@@ -1211,13 +1211,13 @@ The rest of the details are the same as for grail.findAll.
}());
/*
Hormigas version
1
Hormigas version
3
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/hormigas/blob/master/LICENSE
*/
var
hormigas
=
hormigas
||
{};
var
hormigas
=
{};
(
function
()
{
var
nextId
=
0
;
...
...
@@ -1268,6 +1268,25 @@ Harmony Set proposal and the Array.prototype iterators.
/**
@property hormigas.ObjectSet.prototype.isEmpty
@description
Returns true if set is empty. Otherwise returns false.
var alpha = {};
var set = new hormigas.ObjectSet(alpha);
set.isEmpty(); // false
set['delete'](alpha);
set.isEmpty(); // true
*/
hormigas
.
ObjectSet
.
prototype
.
isEmpty
=
function
()
{
return
this
.
length
<
1
;
};
/**
@property hormigas.ObjectSet.prototype.has
@parameter element
...
...
@@ -1656,12 +1675,28 @@ hormigas.ObjectSet.mixin = function(obj) {
hormigas
.
ObjectSet
.
call
(
obj
);
};
/*
Maria release candidate
1
- an MVC framework for JavaScript applications
Maria release candidate
5
- an MVC framework for JavaScript applications
Copyright (c) 2012, Peter Michaux
All rights reserved.
Licensed under the Simplified BSD License.
https://github.com/petermichaux/maria/blob/master/LICENSE
*/
var
maria
=
maria
||
{};
*/
var
maria
=
{};
// Not all browsers supported by Maria have Object.create
maria
.
create
=
(
function
()
{
function
F
()
{}
return
function
(
obj
)
{
F
.
prototype
=
obj
;
return
new
F
();
};
}());
maria
.
borrow
=
function
(
sink
,
source
)
{
for
(
var
p
in
source
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
source
,
p
))
{
sink
[
p
]
=
source
[
p
];
}
}
};
// "this" must be a constructor function
// mix the "subclass" function into your constructor function
//
...
...
@@ -1669,10 +1704,13 @@ maria.subclass = function(namespace, name, options) {
options
=
options
||
{};
var
properties
=
options
.
properties
;
var
SuperConstructor
=
this
;
var
Constructor
=
namespace
[
name
]
=
function
()
{
SuperConstructor
.
apply
(
this
,
arguments
);
};
var
prototype
=
Constructor
.
prototype
=
new
SuperConstructor
();
var
Constructor
=
namespace
[
name
]
=
Object
.
prototype
.
hasOwnProperty
.
call
(
options
,
'
constructor
'
)
?
options
.
constructor
:
function
()
{
SuperConstructor
.
apply
(
this
,
arguments
);
};
var
prototype
=
Constructor
.
prototype
=
maria
.
create
(
SuperConstructor
.
prototype
);
prototype
.
constructor
=
Constructor
;
if
(
properties
)
{
maria
.
borrow
(
prototype
,
properties
);
...
...
@@ -1681,18 +1719,17 @@ maria.subclass = function(namespace, name, options) {
SuperConstructor
.
subclass
.
apply
(
this
,
arguments
);
};
};
maria
.
borrow
=
function
(
sink
,
source
)
{
for
(
var
p
in
source
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
source
,
p
))
{
sink
[
p
]
=
source
[
p
];
}
}
maria
.
on
=
function
()
{
evento
.
on
.
apply
(
this
,
arguments
);
};
maria
.
off
=
function
()
{
evento
.
off
.
apply
(
this
,
arguments
);
};
maria
.
purge
=
function
()
{
evento
.
purge
.
apply
(
this
,
arguments
);
};
maria
.
borrow
(
maria
,
evento
);
maria
.
borrow
(
maria
,
hijos
);
maria
.
borrow
(
maria
,
arbutus
);
maria
.
borrow
(
maria
,
grail
);
maria
.
borrow
(
maria
,
hormigas
);
/**
@property maria.Model
...
...
@@ -1716,7 +1753,7 @@ when a "change" event is dispatched on the model objects.
alert('The model changed!');
}
};
maria.
addEventListener
(model, 'change', view, 'update');
maria.
on
(model, 'change', view, 'update');
The model can dispatch a "change" event on itself when the model
changes.
...
...
@@ -1741,7 +1778,7 @@ including that data on the event object.
An event listener can be removed from a model object.
maria.
removeEventListener
(model, 'change', view, 'update');
maria.
off
(model, 'change', view, 'update');
A particularly useful pattern is using maria.Model as the "superclass"
of your application's model. The following example shows how this
...
...
@@ -1751,7 +1788,7 @@ See maria.Model.subclass for a more compact way to accomplish the same.
checkit.TodoModel = function() {
maria.Model.apply(this, arguments);
};
checkit.TodoModel.prototype =
new maria.Model(
);
checkit.TodoModel.prototype =
maria.create(maria.Model.prototype
);
checkit.TodoModel.prototype.constructor = checkit.TodoModel;
checkit.TodoModel.prototype._content = '';
checkit.TodoModel.prototype._isDone = false;
...
...
@@ -1759,7 +1796,7 @@ See maria.Model.subclass for a more compact way to accomplish the same.
return this._content;
};
checkit.TodoModel.prototype.setContent = function(content) {
content =
('' + content).replace(/^\s+|\s+$/g, ''
);
content =
checkit.trim('' + content
);
if (this._content !== content) {
this._content = content;
this.dispatchEvent({type: 'change'});
...
...
@@ -1779,14 +1816,6 @@ See maria.Model.subclass for a more compact way to accomplish the same.
this.setDone(!this.isDone());
};
The above TodoModel example does not have an "initialize" method;
however, if some special initialization is requried, maria.Model will
automatically call your "initialize" method.
checkit.TodoModel.prototype.initialize = function() {
alert('Another to-do has been created. You better get busy.');
};
When a model's "destroy" method is called, a "destroy" event is
dispatched and all event listeners who've been added for this event
type will be notified.
...
...
@@ -1796,13 +1825,11 @@ using "addParentEventTarget" and "removeParentEventTarget".)
*/
maria
.
Model
=
function
()
{
maria
.
EventTarget
.
call
(
this
);
this
.
initialize
();
evento
.
EventTarget
.
call
(
this
);
};
maria
.
EventTarget
.
mixin
(
maria
.
Model
.
prototype
);
maria
.
Model
.
prototype
.
initialize
=
function
()
{};
maria
.
Model
.
prototype
=
maria
.
create
(
evento
.
EventTarget
.
prototype
);
maria
.
Model
.
prototype
.
constructor
=
maria
.
Model
;
maria
.
Model
.
prototype
.
destroy
=
function
()
{
this
.
dispatchEvent
({
type
:
'
destroy
'
});
...
...
@@ -1829,7 +1856,7 @@ with those elements.
You can create an empty set model object.
var setModel = new maria.SetModel();
var setModel = new maria.SetModel();
What makes a set model object interesting in comparison to a set is
that a set model object is a model object that dispatches "change"
...
...
@@ -1840,7 +1867,7 @@ events when elements are added or deleted from the the set.
alert(setModel.length + ' element(s) in the set.');
}
};
maria.
addEventListener
(setModel, 'change', view, 'update');
maria.
on
(setModel, 'change', view, 'update');
You can add elements to the set. Adding an element
that is already in the set has no effect. The add method returns
...
...
@@ -1948,11 +1975,8 @@ to accomplish the same.
checkit.TodosModel = function() {
maria.SetModel.apply(this, arguments);
};
checkit.TodosModel.prototype =
new maria.SetModel(
);
checkit.TodosModel.prototype =
maria.create(maria.SetModel.prototype
);
checkit.TodosModel.prototype.constructor = checkit.TodosModel;
checkit.TodosModel.prototype.isEmpty = function() {
return this.length === 0;
};
checkit.TodosModel.prototype.getDone = function() {
return this.filter(function(todo) {
return todo.isDone();
...
...
@@ -1989,14 +2013,14 @@ example. This can complement well the flyweight pattern used in a view.
*/
maria
.
SetModel
=
function
()
{
maria
.
ObjectSet
.
apply
(
this
,
arguments
);
hormigas
.
ObjectSet
.
apply
(
this
,
arguments
);
maria
.
Model
.
call
(
this
);
};
maria
.
SetModel
.
prototype
=
new
maria
.
Model
(
);
maria
.
SetModel
.
prototype
=
maria
.
create
(
maria
.
Model
.
prototype
);
maria
.
SetModel
.
prototype
.
constructor
=
maria
.
SetModel
;
maria
.
ObjectSet
.
mixin
(
maria
.
SetModel
.
prototype
);
hormigas
.
ObjectSet
.
mixin
(
maria
.
SetModel
.
prototype
);
// Wrap the set mutator methods to dispatch events.
...
...
@@ -2006,11 +2030,11 @@ maria.SetModel.prototype.add = function() {
var
added
=
[];
for
(
var
i
=
0
,
ilen
=
arguments
.
length
;
i
<
ilen
;
i
++
)
{
var
argument
=
arguments
[
i
];
if
(
maria
.
ObjectSet
.
prototype
.
add
.
call
(
this
,
argument
))
{
if
(
hormigas
.
ObjectSet
.
prototype
.
add
.
call
(
this
,
argument
))
{
added
.
push
(
argument
);
if
((
typeof
argument
.
addEventListener
===
'
function
'
)
&&
(
typeof
argument
.
removeEventListener
===
'
function
'
))
{
argument
.
addEventListener
(
'
destroy
'
,
this
);
argument
.
addEventListener
(
'
destroy
'
,
this
);
}
if
((
typeof
argument
.
addParentEventTarget
===
'
function
'
)
&&
// want to know can remove later
...
...
@@ -2032,7 +2056,7 @@ maria.SetModel.prototype['delete'] = function() {
var
deleted
=
[];
for
(
var
i
=
0
,
ilen
=
arguments
.
length
;
i
<
ilen
;
i
++
)
{
var
argument
=
arguments
[
i
];
if
(
maria
.
ObjectSet
.
prototype
[
'
delete
'
].
call
(
this
,
argument
))
{
if
(
hormigas
.
ObjectSet
.
prototype
[
'
delete
'
].
call
(
this
,
argument
))
{
deleted
.
push
(
argument
);
if
(
typeof
argument
.
removeEventListener
===
'
function
'
)
{
argument
.
removeEventListener
(
'
destroy
'
,
this
);
...
...
@@ -2051,7 +2075,7 @@ maria.SetModel.prototype['delete'] = function() {
maria
.
SetModel
.
prototype
.
empty
=
function
()
{
var
deleted
=
this
.
toArray
();
var
result
=
maria
.
ObjectSet
.
prototype
.
empty
.
call
(
this
);
var
result
=
hormigas
.
ObjectSet
.
prototype
.
empty
.
call
(
this
);
if
(
result
)
{
for
(
var
i
=
0
,
ilen
=
deleted
.
length
;
i
<
ilen
;
i
++
)
{
var
element
=
deleted
[
i
];
...
...
@@ -2140,14 +2164,12 @@ A view has a controller. You can get the current controller.
view.getController();
The view's controller is created lazily the first time the
getController method is called. The view's
getController method is called. The view's
getDefaultControllerConstructor method returns the constructor function
to create the controller object and the getDefaultController actually
calls that constructor. Your application may redefine or override
either of these methods.
A view's initialize method is called when the view is constructed.
A view has a destroy method which should be called before your
application looses its last reference to the view.
...
...
@@ -2183,7 +2205,7 @@ accomplish the same.
myapp.MyView = function() {
maria.View.apply(this, arguments);
};
myapp.MyView.prototype =
new maria.View(
);
myapp.MyView.prototype =
maria.create(maria.View.prototype
);
myapp.MyView.prototype.constructor = myapp.MyView;
myapp.MyView.prototype.getModelActions = function() {
return {
...
...
@@ -2204,36 +2226,24 @@ accomplish the same.
alert('another method');
};
The above MyView example does not have an "initialize" method;
however, if some special initialization is requried, maria.View
will automatically call your "initialize" method.
myapp.MyView.prototype.initialize = function() {
alert('Another view has been created.');
};
*/
maria
.
View
=
function
(
model
,
controller
)
{
maria
.
Node
.
call
(
this
);
this
.
initialize
();
hijos
.
Node
.
call
(
this
);
this
.
setModel
(
model
);
this
.
setController
(
controller
);
};
maria
.
Node
.
mixin
(
maria
.
View
.
prototype
);
maria
.
View
.
prototype
.
initialize
=
function
()
{
// to be overridden by concrete view subclasses
};
maria
.
View
.
prototype
=
maria
.
create
(
hijos
.
Node
.
prototype
);
maria
.
View
.
prototype
.
constructor
=
maria
.
View
;
maria
.
View
.
prototype
.
destroy
=
function
()
{
maria
.
purge
EventListener
(
this
);
maria
.
purge
(
this
);
this
.
_model
=
null
;
if
(
this
.
_controller
)
{
this
.
_controller
.
destroy
();
this
.
_controller
=
null
;
}
maria
.
Node
.
prototype
.
destroy
.
call
(
this
);
hijos
.
Node
.
prototype
.
destroy
.
call
(
this
);
};
maria
.
View
.
prototype
.
update
=
function
()
{
...
...
@@ -2279,7 +2289,7 @@ maria.View.prototype._setModelAndController = function(model, controller) {
eventMap
=
this
.
_lastModelActions
;
for
(
type
in
eventMap
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
eventMap
,
type
))
{
maria
.
removeEventListener
(
this
.
_model
,
type
,
this
,
eventMap
[
type
]);
maria
.
off
(
this
.
_model
,
type
,
this
,
eventMap
[
type
]);
}
}
delete
this
.
_lastModelActions
;
...
...
@@ -2288,7 +2298,7 @@ maria.View.prototype._setModelAndController = function(model, controller) {
eventMap
=
this
.
_lastModelActions
=
this
.
getModelActions
()
||
{};
for
(
type
in
eventMap
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
eventMap
,
type
))
{
maria
.
addEventListener
(
model
,
type
,
this
,
eventMap
[
type
]);
maria
.
on
(
model
,
type
,
this
,
eventMap
[
type
]);
}
}
}
...
...
@@ -2410,7 +2420,7 @@ the same.
checkit.TodoView = function() {
maria.ElementView.apply(this, arguments);
};
checkit.TodoView.prototype =
new maria.ElementView(
);
checkit.TodoView.prototype =
maria.create(maria.ElementView.prototype
);
checkit.TodoView.prototype.constructor = checkit.TodoView;
checkit.TodoView.prototype.getDefaultControllerConstructor = function() {
return checkit.TodoController;
...
...
@@ -2445,8 +2455,7 @@ the same.
checkit.TodoView.prototype.buildData = function() {
var model = this.getModel();
var content = model.getContent();
this.find('.todo-content').innerHTML =
content.replace('&', '&').replace('<', '<');
this.find('.todo-content').innerHTML = checkit.escapeHTML(content);
this.find('.check').checked = model.isDone();
aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done');
};
...
...
@@ -2478,7 +2487,7 @@ maria.ElementView = function(model, controller, doc) {
this
.
setDocument
(
doc
);
};
maria
.
ElementView
.
prototype
=
new
maria
.
View
(
);
maria
.
ElementView
.
prototype
=
maria
.
create
(
maria
.
View
.
prototype
);
maria
.
ElementView
.
prototype
.
constructor
=
maria
.
ElementView
;
maria
.
ElementView
.
prototype
.
getDocument
=
function
()
{
...
...
@@ -2513,7 +2522,7 @@ maria.ElementView.prototype.build = function() {
maria
.
ElementView
.
prototype
.
buildTemplate
=
function
()
{
// parseHTML returns a DocumentFragment so take firstChild as the rootEl
this
.
_rootEl
=
maria
.
parseHTML
(
this
.
getTemplate
(),
this
.
getDocument
()).
firstChild
;
this
.
_rootEl
=
arbutus
.
parseHTML
(
this
.
getTemplate
(),
this
.
getDocument
()).
firstChild
;
};
(
function
()
{
...
...
@@ -2527,9 +2536,9 @@ maria.ElementView.prototype.buildTemplate = function() {
eventType
=
matches
[
1
],
selector
=
matches
[
2
],
methodName
=
uiActions
[
key
],
elements
=
maria
.
findAll
(
selector
,
this
.
_rootEl
);
elements
=
this
.
findAll
(
selector
,
this
.
_rootEl
);
for
(
var
i
=
0
,
ilen
=
elements
.
length
;
i
<
ilen
;
i
++
)
{
maria
.
addEventListener
(
elements
[
i
],
eventType
,
this
,
methodName
);
maria
.
on
(
elements
[
i
],
eventType
,
this
,
methodName
);
}
}
}
...
...
@@ -2548,10 +2557,6 @@ maria.ElementView.prototype.buildChildViews = function() {
}
};
maria
.
ElementView
.
prototype
.
update
=
function
()
{
// to be overridden by concrete ElementView subclasses
};
maria
.
ElementView
.
prototype
.
getContainerEl
=
function
()
{
return
this
.
build
();
};
...
...
@@ -2571,11 +2576,11 @@ maria.ElementView.prototype.removeChild = function(oldChild) {
};
maria
.
ElementView
.
prototype
.
find
=
function
(
selector
)
{
return
maria
.
find
(
selector
,
this
.
build
());
return
grail
.
find
(
selector
,
this
.
build
());
};
maria
.
ElementView
.
prototype
.
findAll
=
function
(
selector
)
{
return
maria
.
findAll
(
selector
,
this
.
build
());
return
grail
.
findAll
(
selector
,
this
.
build
());
};
/**
...
...
@@ -2617,7 +2622,7 @@ maria.SetView.subclass for a more compact way to accomplish the same.
checkit.TodosListView = function() {
maria.SetView.apply(this, arguments);
};
checkit.TodosListView.prototype =
new maria.SetView(
);
checkit.TodosListView.prototype =
maria.create(maria.SetView.prototype
);
checkit.TodosListView.prototype.constructor = checkit.TodosListView;
checkit.TodosListView.prototype.getTemplate = function() {
return checkit.TodosListTemplate;
...
...
@@ -2631,7 +2636,7 @@ maria.SetView = function() {
maria
.
ElementView
.
apply
(
this
,
arguments
);
};
maria
.
SetView
.
prototype
=
new
maria
.
ElementView
(
);
maria
.
SetView
.
prototype
=
maria
.
create
(
maria
.
ElementView
.
prototype
);
maria
.
SetView
.
prototype
.
constructor
=
maria
.
SetView
;
maria
.
SetView
.
prototype
.
buildChildViews
=
function
()
{
...
...
@@ -2733,7 +2738,7 @@ to accomplish the same.
checkit.TodoController = function() {
maria.Controller.apply(this, arguments);
};
checkit.TodoController.prototype =
new maria.Controller(
);
checkit.TodoController.prototype =
maria.create(maria.Controller.prototype
);
checkit.TodoController.prototype.constructor = checkit.TodoController;
checkit.TodoController.prototype.onClickCheck = function() {
this.getModel().toggleDone();
...
...
@@ -2743,10 +2748,10 @@ to accomplish the same.
};
checkit.TodoController.prototype.onKeyupInput = function() {
var view = this.getView();
if (/\S/.test(view.getInputValue())) {
view.showToolTip();
} else {
if (checkit.isBlank(view.getInputValue())) {
view.hideToolTip();
} else {
view.showToolTip();
}
};
checkit.TodoController.prototype.onKeypressInput = function(evt) {
...
...
@@ -2759,25 +2764,13 @@ to accomplish the same.
var value = view.getInputValue();
view.hideToolTip();
view.showDisplay();
if (!
/^\s*$/.test
(value)) {
if (!
checkit.isBlank
(value)) {
this.getModel().setContent(value);
}
};
The above TodoController example does not have an "initialize" method;
however, if some special initialization is requried, maria.Controller
will automatically call your "initialize" method.
checkit.TodoController.prototype.initialize = function() {
alert('Another to-do controller has been created.');
};
*/
maria
.
Controller
=
function
()
{
this
.
initialize
();
};
maria
.
Controller
.
prototype
.
initialize
=
function
()
{};
maria
.
Controller
=
function
()
{};
maria
.
Controller
.
prototype
.
destroy
=
function
()
{
this
.
_model
=
null
;
...
...
@@ -2791,6 +2784,9 @@ maria.Controller.prototype.getModel = function() {
return
this
.
_model
;
};
// setModel is intended to be called *only* by
// the view _setModelAndController method.
// Do otherwise at your own risk.
maria
.
Controller
.
prototype
.
setModel
=
function
(
model
)
{
this
.
_model
=
model
;
};
...
...
@@ -2799,6 +2795,9 @@ maria.Controller.prototype.getView = function() {
return
this
.
_view
;
};
// setView is intended to be called *only* by
// the view _setModelAndController method.
// Do otherwise at your own risk.
maria
.
Controller
.
prototype
.
setView
=
function
(
view
)
{
this
.
_view
=
view
;
};
...
...
@@ -2822,7 +2821,7 @@ for maria.Model.
return this._content;
},
setContent: function(content) {
content =
('' + content).replace(/^\s+|\s+$/g, ''
);
content =
checkit.trim('' + content
);
if (this._content !== content) {
this._content = content;
this.dispatchEvent({type: 'change'});
...
...
@@ -2845,7 +2844,9 @@ for maria.Model.
});
*/
maria
.
Model
.
subclass
=
maria
.
subclass
;
maria
.
Model
.
subclass
=
function
()
{
maria
.
subclass
.
apply
(
this
,
arguments
);
};
/**
@property maria.SetModel.subclass
...
...
@@ -2860,9 +2861,6 @@ for maria.SetModel.
maria.SetModel.subclass(checkit, 'TodosModel', {
properties: {
isEmpty: function() {
return this.length === 0;
},
getDone: function() {
return this.filter(function(todo) {
return todo.isDone();
...
...
@@ -2894,7 +2892,9 @@ for maria.SetModel.
});
*/
maria
.
SetModel
.
subclass
=
maria
.
Model
.
subclass
;
maria
.
SetModel
.
subclass
=
function
()
{
maria
.
Model
.
subclass
.
apply
(
this
,
arguments
);
};
/**
@property maria.View.subclass
...
...
@@ -2981,8 +2981,7 @@ for maria.ElementView.
buildData: function() {
var model = this.getModel();
var content = model.getContent();
this.find('.todo-content').innerHTML =
content.replace('&', '&').replace('<', '<');
this.find('.todo-content').innerHTML = checkit.escapeHTML(content);
this.find('.check').checked = model.isDone();
aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done');
},
...
...
@@ -3012,12 +3011,11 @@ for maria.ElementView.
This subclassing function implements options following the
"convention over configuration" philosophy. The checkit.TodoView will,
by convention, use the checkit.Todo
Model, checkit.Todo
Controller
by convention, use the checkit.TodoController
and checkit.TodoTemplate objects. All of these can be configured
explicit
e
ly if these conventions do not match your view's needs.
explicitly if these conventions do not match your view's needs.
maria.ElementView.subclass(checkit, 'TodoView', {
modelConstructor : checkit.TodoModel ,
controllerConstructor: checkit.TodoController,
template : checkit.TodoTemplate ,
uiActions: {
...
...
@@ -3028,7 +3026,6 @@ objects in the application's namespace object (i.e. the checkit object
in this example).
maria.ElementView.subclass(checkit, 'TodoView', {
modelConstructorName : 'TodoModel' ,
controllerConstructorName: 'TodoController',
templateName : 'TodoTemplate' ,
uiActions: {
...
...
@@ -3090,7 +3087,6 @@ function equivalent to the more verbose example shown in the
documentation for maria.SetView.
maria.SetView.subclass(checkit, 'TodosListView', {
modelConstructor: checkit.TodosModel,
properties: {
createChildView: function(todoModel) {
return new checkit.TodoView(todoModel);
...
...
@@ -3099,7 +3095,9 @@ documentation for maria.SetView.
});
*/
maria
.
SetView
.
subclass
=
maria
.
ElementView
.
subclass
;
maria
.
SetView
.
subclass
=
function
()
{
maria
.
ElementView
.
subclass
.
apply
(
this
,
arguments
);
};
/**
@property maria.Controller.subclass
...
...
@@ -3122,10 +3120,10 @@ the documentation for maria.Controller.
},
onKeyupInput: function() {
var view = this.getView();
if (/\S/.test(view.getInputValue())) {
view.showToolTip();
} else {
if (checkit.isBlank(view.getInputValue())) {
view.hideToolTip();
} else {
view.showToolTip();
}
},
onKeypressInput: function(evt) {
...
...
@@ -3138,7 +3136,7 @@ the documentation for maria.Controller.
var value = view.getInputValue();
view.hideToolTip();
view.showDisplay();
if (!
/^\s*$/.test
(value)) {
if (!
checkit.isBlank
(value)) {
this.getModel().setContent(value);
}
}
...
...
@@ -3146,4 +3144,6 @@ the documentation for maria.Controller.
});
*/
maria
.
Controller
.
subclass
=
maria
.
subclass
;
maria
.
Controller
.
subclass
=
function
()
{
maria
.
subclass
.
apply
(
this
,
arguments
);
};
labs/architecture-examples/maria/src/css/app.css
0 → 100644
View file @
00435de1
ul
.completed
li
.incompleted
,
ul
.incompleted
li
.completed
{
display
:
none
;
}
labs/architecture-examples/maria/src/css/todos.css
deleted
100644 → 0
View file @
0d6e84dd
html
,
body
,
div
,
span
,
applet
,
object
,
iframe
,
h1
,
h2
,
h3
,
h4
,
h5
,
h6
,
p
,
blockquote
,
pre
,
a
,
abbr
,
acronym
,
address
,
big
,
cite
,
code
,
del
,
dfn
,
em
,
font
,
img
,
ins
,
kbd
,
q
,
s
,
samp
,
small
,
strike
,
strong
,
sub
,
sup
,
tt
,
var
,
dl
,
dt
,
dd
,
ol
,
ul
,
li
,
fieldset
,
form
,
label
,
legend
,
table
,
caption
,
tbody
,
tfoot
,
thead
,
tr
,
th
,
td
{
margin
:
0
;
padding
:
0
;
border
:
0
;
outline
:
0
;
font-style
:
inherit
;
font-size
:
100%
;
font-family
:
inherit
;
vertical-align
:
baseline
;
}
body
{
line-height
:
1
;
color
:
black
;
background
:
white
;
}
ol
,
ul
{
list-style
:
none
;
}
a
img
{
border
:
none
;
}
html
{
background
:
#eeeeee
;
}
body
{
font-family
:
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
14px
;
line-height
:
1.4em
;
background
:
#eeeeee
;
color
:
#333333
;
}
.todos-app
{
width
:
480px
;
margin
:
0
auto
40px
;
background
:
white
;
padding
:
20px
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
5px
6px
0
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
5px
6px
0
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
5px
6px
0
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
5px
6px
0
;
}
.todos-app
h1
{
font-size
:
36px
;
font-weight
:
bold
;
text-align
:
center
;
padding
:
20px
0
30px
0
;
line-height
:
1
;
}
.create-todo
{
position
:
relative
;
}
.create-todo
input
{
width
:
466px
;
font-size
:
24px
;
font-family
:
inherit
;
line-height
:
1.4em
;
border
:
0
;
outline
:
none
;
padding
:
6px
;
border
:
1px
solid
#999999
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
}
.create-todo
span
{
position
:
absolute
;
z-index
:
999
;
width
:
170px
;
left
:
50%
;
margin-left
:
-85px
;
}
.todos-list
{
margin-top
:
10px
;
}
.todos-list
li
{
padding
:
12px
20px
11px
0
;
position
:
relative
;
font-size
:
24px
;
line-height
:
1.1em
;
border-bottom
:
1px
solid
#cccccc
;
}
.todos-list
li
:after
{
content
:
"\0020"
;
display
:
block
;
height
:
0
;
clear
:
both
;
overflow
:
hidden
;
visibility
:
hidden
;
}
.todos-list
li
.editing
{
padding
:
0
;
border-bottom
:
0
;
}
.todos-list
.editing
.display
,
.todos-list
.edit
{
display
:
none
;
}
.todos-list
.editing
.edit
{
display
:
block
;
position
:
relative
;
}
.todos-list
.editing
input
{
width
:
444px
;
font-size
:
24px
;
font-family
:
inherit
;
margin
:
0
;
line-height
:
1.6em
;
border
:
0
;
outline
:
none
;
padding
:
10px
7px
0px
27px
;
border
:
1px
solid
#999999
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
}
.todos-list
.check
{
position
:
relative
;
top
:
9px
;
margin
:
0
10px
0
7px
;
float
:
left
;
}
.todos-list
.todo-content
{
width
:
400px
;
display
:
block
;
}
.todos-list
.done
.todo-content
{
text-decoration
:
line-through
;
color
:
#777777
;
}
.todos-list
.todo-destroy
{
cursor
:
pointer
;
position
:
absolute
;
right
:
5px
;
top
:
14px
;
display
:
none
;
}
.todos-list
.todo-hover
.todo-destroy
{
display
:
block
;
}
.todos-stats
{
*
zoom
:
1
;
margin-top
:
10px
;
color
:
#777777
;
}
.todos-stats
:after
{
content
:
"\0020"
;
display
:
block
;
height
:
0
;
clear
:
both
;
overflow
:
hidden
;
visibility
:
hidden
;
}
.todos-stats
.todo-count
{
float
:
left
;
}
.todos-stats
.todo-count
.number
{
font-weight
:
bold
;
color
:
#333333
;
}
.todos-stats
.todo-clear
{
float
:
right
;
}
.todos-stats
.todo-clear
a
{
color
:
#777777
;
font-size
:
12px
;
}
.todos-stats
.todo-clear
a
:visited
{
color
:
#777777
;
}
.todos-stats
.todo-clear
a
:hover
{
color
:
#336699
;
}
/*
* François 'cahnory' Germain
*/
.ui-tooltip
,
.ui-tooltip-top
,
.ui-tooltip-right
,
.ui-tooltip-bottom
,
.ui-tooltip-left
{
color
:
#ffffff
;
cursor
:
normal
;
display
:
-moz-inline-stack
;
display
:
inline-block
;
font-size
:
12px
;
font-family
:
arial
;
padding
:
.5em
1em
;
position
:
relative
;
text-align
:
center
;
text-shadow
:
0
-1px
1px
#111111
;
-webkit-border-top-left-radius
:
4px
;
-webkit-border-top-right-radius
:
4px
;
-webkit-border-bottom-right-radius
:
4px
;
-webkit-border-bottom-left-radius
:
4px
;
-khtml-border-top-left-radius
:
4px
;
-khtml-border-top-right-radius
:
4px
;
-khtml-border-bottom-right-radius
:
4px
;
-khtml-border-bottom-left-radius
:
4px
;
-moz-border-radius-topleft
:
4px
;
-moz-border-radius-topright
:
4px
;
-moz-border-radius-bottomright
:
4px
;
-moz-border-radius-bottomleft
:
4px
;
border-top-left-radius
:
4px
;
border-top-right-radius
:
4px
;
border-bottom-right-radius
:
4px
;
border-bottom-left-radius
:
4px
;
-o-box-shadow
:
0
1px
2px
#000000
,
inset
0
0
0
1px
#222222
,
inset
0
2px
#666666
,
inset
0
-2px
2px
#444444
;
-moz-box-shadow
:
0
1px
2px
#000000
,
inset
0
0
0
1px
#222222
,
inset
0
2px
#666666
,
inset
0
-2px
2px
#444444
;
-khtml-box-shadow
:
0
1px
2px
#000000
,
inset
0
0
0
1px
#222222
,
inset
0
2px
#666666
,
inset
0
-2px
2px
#444444
;
-webkit-box-shadow
:
0
1px
2px
#000000
,
inset
0
0
0
1px
#222222
,
inset
0
2px
#666666
,
inset
0
-2px
2px
#444444
;
box-shadow
:
0
1px
2px
#000000
,
inset
0
0
0
1px
#222222
,
inset
0
2px
#666666
,
inset
0
-2px
2px
#444444
;
background-color
:
#3b3b3b
;
background-image
:
-moz-linear-gradient
(
top
,
#555555
,
#222222
);
background-image
:
-webkit-gradient
(
linear
,
left
top
,
left
bottom
,
color-stop
(
0
,
#555555
),
color-stop
(
1
,
#222222
));
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorStr
=
#555555
,
EndColorStr
=
#222222
);
-ms-filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorStr
=
#555555
,
EndColorStr
=
#222222
);
}
.ui-tooltip
:after
,
.ui-tooltip-top
:after
,
.ui-tooltip-right
:after
,
.ui-tooltip-bottom
:after
,
.ui-tooltip-left
:after
{
content
:
"\25B8"
;
display
:
block
;
font-size
:
2em
;
height
:
0
;
line-height
:
0
;
position
:
absolute
;
}
.ui-tooltip
:after
,
.ui-tooltip-bottom
:after
{
color
:
#2a2a2a
;
bottom
:
0
;
left
:
1px
;
text-align
:
center
;
text-shadow
:
1px
0
2px
#000000
;
-o-transform
:
rotate
(
90deg
);
-moz-transform
:
rotate
(
90deg
);
-khtml-transform
:
rotate
(
90deg
);
-webkit-transform
:
rotate
(
90deg
);
width
:
100%
;
}
.ui-tooltip-top
:after
{
bottom
:
auto
;
color
:
#4f4f4f
;
left
:
-2px
;
top
:
0
;
text-align
:
center
;
text-shadow
:
none
;
-o-transform
:
rotate
(
-90deg
);
-moz-transform
:
rotate
(
-90deg
);
-khtml-transform
:
rotate
(
-90deg
);
-webkit-transform
:
rotate
(
-90deg
);
width
:
100%
;
}
.ui-tooltip-right
:after
{
color
:
#222222
;
right
:
-0.375em
;
top
:
50%
;
margin-top
:
-.05em
;
text-shadow
:
0
1px
2px
#000000
;
-o-transform
:
rotate
(
0
);
-moz-transform
:
rotate
(
0
);
-khtml-transform
:
rotate
(
0
);
-webkit-transform
:
rotate
(
0
);
}
.ui-tooltip-left
:after
{
color
:
#222222
;
left
:
-0.375em
;
top
:
50%
;
margin-top
:
.1em
;
text-shadow
:
0
-1px
2px
#000000
;
-o-transform
:
rotate
(
180deg
);
-moz-transform
:
rotate
(
180deg
);
-khtml-transform
:
rotate
(
180deg
);
-webkit-transform
:
rotate
(
180deg
);
}
/*the following changes require some cleanup and integration with the above.**/
/* line 9 */
/* line 17 */
.todos-app
{
background
:
white
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
2px
6px
0
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
2px
6px
0
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
2px
6px
0
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
2px
6px
0
;
-moz-border-radius-bottomleft
:
5px
;
-webkit-border-bottom-left-radius
:
5px
;
-o-border-bottom-left-radius
:
5px
;
-ms-border-bottom-left-radius
:
5px
;
-khtml-border-bottom-left-radius
:
5px
;
border-bottom-left-radius
:
5px
;
-moz-border-radius-bottomright
:
5px
;
-webkit-border-bottom-right-radius
:
5px
;
-o-border-bottom-right-radius
:
5px
;
-ms-border-bottom-right-radius
:
5px
;
-khtml-border-bottom-right-radius
:
5px
;
border-bottom-right-radius
:
5px
;
}
/* line 24 */
/* line 32 */
.todos-app
.content
.create-todo
{
position
:
relative
;
}
/* line 34 */
.todos-app
.content
.create-todo
input
{
font-size
:
24px
;
font-family
:
inherit
;
line-height
:
1.4em
;
border
:
0
;
outline
:
none
;
padding
:
6px
;
border
:
1px
solid
#999999
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
}
/* line 47 */
.todos-app
.content
.create-todo
span
{
position
:
absolute
;
z-index
:
999
;
width
:
170px
;
left
:
50%
;
margin-left
:
-85px
;
}
/* line 55 */
.todos-app
.content
ul
.todos-list
{
margin-top
:
10px
;
}
/* line 57 */
.todos-app
.content
ul
.todos-list
li
{
padding
:
15px
20px
15px
0
;
position
:
relative
;
font-size
:
24px
;
border-bottom
:
1px
solid
#cccccc
;
*
zoom
:
1
;
}
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.todos-app
.content
ul
.todos-list
li
:after
{
content
:
"\0020"
;
display
:
block
;
height
:
0
;
clear
:
both
;
overflow
:
hidden
;
visibility
:
hidden
;
}
/* line 64 */
.todos-app
.content
ul
.todos-list
li
.editing
{
padding
:
0
;
border-bottom
:
0
;
}
/* line 67 */
.todos-app
.content
ul
.todos-list
li
.editing
.todo-input
{
display
:
block
;
width
:
466px
;
font-size
:
24px
;
font-family
:
inherit
;
line-height
:
1.4em
;
border
:
0
;
outline
:
none
;
padding
:
6px
;
border
:
1px
solid
#999999
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
1px
2px
0
inset
;
}
/* line 79 */
.todos-app
.content
ul
.todos-list
li
.editing
.todo-content
{
display
:
none
;
}
/* line 81 */
.todos-app
.content
ul
.todos-list
li
.editing
.todo-check
{
display
:
none
;
}
/* line 83 */
.todos-app
.content
ul
.todos-list
li
.editing
.todo-destroy
{
display
:
none
!important
;
}
/* line 85 */
.todos-app
.content
ul
.todos-list
li
.todo-input
{
display
:
none
;
}
/* line 87 */
.todos-app
.content
ul
.todos-list
li
.todo-check
{
position
:
relative
;
top
:
6px
;
margin
:
0
10px
0
7px
;
float
:
left
;
}
/* line 93 */
.todos-app
.content
ul
.todos-list
li
.done
.todo-content
{
text-decoration
:
line-through
;
color
:
#777777
;
}
/* line 109 */
.todos-app
.todos-stats
{
*
zoom
:
1
;
margin-top
:
10px
;
color
:
#555555
;
-moz-border-radius-bottomleft
:
5px
;
-webkit-border-bottom-left-radius
:
5px
;
-o-border-bottom-left-radius
:
5px
;
-ms-border-bottom-left-radius
:
5px
;
-khtml-border-bottom-left-radius
:
5px
;
border-bottom-left-radius
:
5px
;
-moz-border-radius-bottomright
:
5px
;
-webkit-border-bottom-right-radius
:
5px
;
-o-border-bottom-right-radius
:
5px
;
-ms-border-bottom-right-radius
:
5px
;
-khtml-border-bottom-right-radius
:
5px
;
border-bottom-right-radius
:
5px
;
background
:
#f4fce8
;
border-top
:
1px
solid
#ededed
;
padding
:
0
20px
;
line-height
:
36px
;
}
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.todos-app
.todos-stats
:after
{
content
:
"\0020"
;
display
:
block
;
height
:
0
;
clear
:
both
;
overflow
:
hidden
;
visibility
:
hidden
;
}
/* line 118 */
.todos-app
.todos-stats
.todo-count
{
float
:
left
;
}
/* line 120 */
.todos-app
.todos-stats
.todo-count
.number
{
font-weight
:
bold
;
color
:
#555555
;
}
/* line 123 */
.todos-app
.todos-stats
.todo-clear
{
float
:
right
;
}
/* line 125 */
.todos-app
.todos-stats
.todo-clear
a
{
display
:
block
;
line-height
:
20px
;
text-decoration
:
none
;
-moz-border-radius
:
12px
;
-webkit-border-radius
:
12px
;
-o-border-radius
:
12px
;
-ms-border-radius
:
12px
;
-khtml-border-radius
:
12px
;
border-radius
:
12px
;
background
:
rgba
(
0
,
0
,
0
,
0.1
);
color
:
#555555
;
font-size
:
11px
;
margin-top
:
8px
;
padding
:
0
10px
1px
;
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
-1px
0
0
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
-1px
0
0
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
-1px
0
0
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.2
)
0
-1px
0
0
;
}
/* line 136 */
.todos-app
.todos-stats
.todo-clear
a
:hover
,
.todos-app
.todos-stats
.todo-clear
a
:focus
{
background
:
rgba
(
0
,
0
,
0
,
0.15
);
-moz-box-shadow
:
rgba
(
0
,
0
,
0
,
0.3
)
0
-1px
0
0
;
-webkit-box-shadow
:
rgba
(
0
,
0
,
0
,
0.3
)
0
-1px
0
0
;
-o-box-shadow
:
rgba
(
0
,
0
,
0
,
0.3
)
0
-1px
0
0
;
box-shadow
:
rgba
(
0
,
0
,
0
,
0.3
)
0
-1px
0
0
;
}
/* line 139 */
.todos-app
.todos-stats
.todo-clear
a
:active
{
position
:
relative
;
top
:
1px
;
}
.todos-app
.copyright
{
padding
:
0.5em
;
text-align
:
center
;
}
.todos-app
ul
.todos-toolbar
{
list-style-type
:
none
;
margin
:
0
;
margin-top
:
10px
;
padding
:
0
;
}
.todos-app
.todos-toolbar
li
{
margin
:
0
;
padding
:
0
;
padding-right
:
1em
;
cursor
:
pointer
;
display
:
inline
;
font-size
:
90%
;
text-decoration
:
underline
;
}
labs/architecture-examples/maria/src/index.html
View file @
00435de1
<!DOCTYPE html>
<html>
<head>
<title>
To-do App
</title>
<meta
charset=
"utf-8"
>
<title>
Maria • TodoMVC
</title>
<link
href=
"css/todos.css"
rel=
"stylesheet"
type=
"text/css"
>
<link
href=
"../../../../assets/base.css"
rel=
"stylesheet"
>
<link
href=
"css/app.css"
rel=
"stylesheet"
>
</head>
<body>
<noscript>
<p>
This application uses JavaScript. Please enable JavaScript in your browser and refresh the page.
</p>
</noscript>
<script>
document
.
write
(
'
<p id="loading">loading...</p>
'
);
</script>
<script
src=
"../lib/maria/maria.js"
></script>
<script
src=
"../lib/aristocrat/aristocrat.js"
></script>
<script
src=
"../../../../assets/director.min.js"
></script>
<script
src=
"../lib/maria/maria.js"
></script>
<script
src=
"../lib/aristocrat/aristocrat.js"
></script>
<script
src=
"js/namespace.js"
></script>
<script
src=
"js/models/TodoModel.js"
></script>
<script
src=
"js/models/TodosModel.js"
></script>
<script
src=
"js/templates/TodosInputTemplate.js"
></script>
<script
src=
"js/views/TodosInputView.js"
></script>
<script
src=
"js/templates/TodosListTemplate.js"
></script>
<script
src=
"js/views/TodosListView.js"
></script>
<script
src=
"js/templates/TodosToolbarTemplate.js"
></script>
<script
src=
"js/views/TodosToolbarView.js"
></script>
<script
src=
"js/controllers/TodosToolbarController.js"
></script>
<script
src=
"js/templates/TodosStatsTemplate.js"
></script>
<script
src=
"js/views/TodosStatsView.js"
></script>
<script
src=
"js/templates/TodosAppTemplate.js"
></script>
<script
src=
"js/views/TodosAppView.js"
></script>
<script
src=
"js/controllers/TodosInputController.js"
></script>
<script
src=
"js/templates/TodoTemplate.js"
></script>
<script
src=
"js/views/TodoView.js"
></script>
<script
src=
"js/controllers/TodoController.js"
></script>
<script
src=
"js/bootstrap.js"
></script>
<script
src=
"js/namespace.js"
></script>
<script
src=
"js/util.js"
></script>
<script
src=
"js/models/TodoModel.js"
></script>
<script
src=
"js/models/TodosModel.js"
></script>
<script
src=
"js/templates/TodosTemplate.js"
></script>
<script
src=
"js/views/TodosView.js"
></script>
<script
src=
"js/controllers/TodosController.js"
></script>
<script
src=
"js/templates/TodoTemplate.js"
></script>
<script
src=
"js/views/TodoView.js"
></script>
<script
src=
"js/controllers/TodoController.js"
></script>
<script
src=
"js/bootstrap.js"
></script>
</body>
</html>
labs/architecture-examples/maria/src/js/bootstrap.js
View file @
00435de1
maria
.
addEventListener
(
window
,
'
load
'
,
function
()
{
var
loading
=
document
.
getElementById
(
'
loading
'
);
loading
.
parentNode
.
removeChild
(
loading
);
/*jshint strict: false */
/*global maria, Router, checkit */
var
model
;
if
((
typeof
localStorage
===
'
object
'
)
&&
(
typeof
JSON
===
'
object
'
))
{
var
store
=
localStorage
.
getItem
(
'
todos-maria
'
);
model
=
store
?
checkit
.
TodosModel
.
fromJSON
(
JSON
.
parse
(
store
))
:
new
checkit
.
TodosModel
();
evento
.
addEventListener
(
model
,
'
change
'
,
function
()
{
localStorage
.
setItem
(
'
todos-maria
'
,
JSON
.
stringify
(
model
.
toJSON
()));
});
}
else
{
model
=
new
checkit
.
TodosModel
();
}
maria
.
on
(
window
,
'
load
'
,
function
()
{
var
model
;
if
((
typeof
localStorage
===
'
object
'
)
&&
(
typeof
JSON
===
'
object
'
))
{
var
store
=
localStorage
.
getItem
(
'
todos-maria
'
);
model
=
store
?
checkit
.
TodosModel
.
fromJSON
(
JSON
.
parse
(
store
))
:
new
checkit
.
TodosModel
();
maria
.
on
(
model
,
'
change
'
,
function
()
{
localStorage
.
setItem
(
'
todos-maria
'
,
JSON
.
stringify
(
model
.
toJSON
()));
});
}
else
{
model
=
new
checkit
.
TodosModel
();
}
var
view
=
new
checkit
.
TodosAppView
(
model
);
document
.
body
.
appendChild
(
view
.
build
());
var
routes
=
{
'
/
'
:
function
()
{
model
.
setMode
(
'
all
'
);
},
'
/active
'
:
function
()
{
model
.
setMode
(
'
incompleted
'
);
},
'
/completed
'
:
function
()
{
model
.
setMode
(
'
completed
'
);
}
};
var
router
=
Router
(
routes
);
router
.
init
();
var
view
=
new
checkit
.
TodosAppView
(
model
);
document
.
body
.
appendChild
(
view
.
build
());
});
labs/architecture-examples/maria/src/js/controllers/TodoController.js
View file @
00435de1
/*jshint strict: false */
/*global maria, checkit */
maria
.
Controller
.
subclass
(
checkit
,
'
TodoController
'
,
{
properties
:
{
onMouseoverRoot
:
function
()
{
this
.
getView
().
showHoverState
();
},
onMouseoutRoot
:
function
()
{
this
.
getView
().
hideHoverState
();
},
onClickCheck
:
function
()
{
this
.
getModel
().
toggleDone
();
},
onClickDestroy
:
function
()
{
this
.
getModel
().
destroy
();
},
onDblclickDisplay
:
function
()
{
this
.
getView
().
showEdit
();
},
onKeyupInput
:
function
()
{
var
view
=
this
.
getView
();
if
(
/
\S
/
.
test
(
view
.
getInputValue
()))
{
view
.
showToolTip
();
}
else
{
view
.
hideToolTip
();
}
},
onKeypressInput
:
function
(
evt
)
{
if
(
evt
.
keyCode
===
13
)
{
this
.
onBlurInput
();
}
},
onBlurInput
:
function
()
{
var
view
=
this
.
getView
();
var
value
=
view
.
getInputValue
();
view
.
hideToolTip
();
view
.
showDisplay
();
if
(
!
/^
\s
*$/
.
test
(
value
))
{
this
.
getModel
().
setContent
(
value
);
}
}
}
properties
:
{
onClickDestroy
:
function
()
{
this
.
getModel
().
destroy
();
},
onClickToggle
:
function
()
{
this
.
getModel
().
toggleCompleted
();
},
onDblclickLabel
:
function
()
{
this
.
getView
().
showEdit
();
},
onKeyupEdit
:
function
(
evt
)
{
if
(
checkit
.
isEnterKeyCode
(
evt
.
keyCode
))
{
this
.
onBlurEdit
();
}
},
onBlurEdit
:
function
()
{
var
model
=
this
.
getModel
();
var
view
=
this
.
getView
();
var
value
=
view
.
getInputValue
();
view
.
showDisplay
();
if
(
checkit
.
isBlank
(
value
))
{
model
.
destroy
();
}
else
{
model
.
setTitle
(
value
);
}
}
}
});
labs/architecture-examples/maria/src/js/controllers/TodosController.js
0 → 100644
View file @
00435de1
/*jshint strict: false */
/*global maria, checkit */
maria
.
Controller
.
subclass
(
checkit
,
'
TodosAppController
'
,
{
properties
:
{
onKeyupNewTodo
:
function
(
evt
)
{
if
(
checkit
.
isEnterKeyCode
(
evt
.
keyCode
))
{
var
view
=
this
.
getView
();
var
value
=
view
.
getInputValue
();
if
(
!
checkit
.
isBlank
(
value
))
{
var
todo
=
new
checkit
.
TodoModel
();
todo
.
setTitle
(
value
);
this
.
getModel
().
add
(
todo
);
view
.
clearInput
();
}
}
},
onClickToggleAll
:
function
()
{
var
model
=
this
.
getModel
();
if
(
model
.
isAllCompleted
())
{
model
.
markAllIncompleted
();
}
else
{
model
.
markAllCompleted
();
}
},
onClickClearCompleted
:
function
()
{
this
.
getModel
().
deleteCompleted
();
}
}
});
labs/architecture-examples/maria/src/js/controllers/TodosInputController.js
deleted
100644 → 0
View file @
0d6e84dd
maria
.
Controller
.
subclass
(
checkit
,
'
TodosInputController
'
,
{
properties
:
{
onFocusInput
:
function
()
{
this
.
onKeyupInput
();
},
onBlurInput
:
function
()
{
this
.
getView
().
hideToolTip
();
},
onKeyupInput
:
function
()
{
var
view
=
this
.
getView
();
if
(
/
\S
/
.
test
(
view
.
getInputValue
()))
{
view
.
showToolTip
();
}
else
{
view
.
hideToolTip
();
}
},
onKeypressInput
:
function
(
evt
)
{
if
(
evt
.
keyCode
!=
13
)
{
return
;
}
var
view
=
this
.
getView
();
var
value
=
view
.
getInputValue
();
if
(
/^
\s
*$/
.
test
(
value
))
{
// don't create an empty Todo
return
;
}
var
todo
=
new
checkit
.
TodoModel
();
todo
.
setContent
(
value
);
this
.
getModel
().
add
(
todo
);
view
.
clearInput
();
}
}
});
labs/architecture-examples/maria/src/js/controllers/TodosToolbarController.js
deleted
100644 → 0
View file @
0d6e84dd
maria
.
Controller
.
subclass
(
checkit
,
'
TodosToolbarController
'
,
{
properties
:
{
onClickAllCheckbox
:
function
()
{
var
model
=
this
.
getModel
();
if
(
model
.
isAllDone
())
{
model
.
markAllUndone
();
}
else
{
model
.
markAllDone
();
}
},
onClickMarkAllDone
:
function
()
{
this
.
getModel
().
markAllDone
();
},
onClickMarkAllUndone
:
function
()
{
this
.
getModel
().
markAllUndone
();
},
onClickDeleteDone
:
function
()
{
this
.
getModel
().
deleteDone
();
}
}
});
labs/architecture-examples/maria/src/js/models/TodoModel.js
View file @
00435de1
/*jshint strict: false */
/*global maria, checkit */
maria
.
Model
.
subclass
(
checkit
,
'
TodoModel
'
,
{
properties
:
{
_content
:
''
,
_isDone
:
false
,
getContent
:
function
()
{
return
this
.
_content
;
},
setContent
:
function
(
content
)
{
content
=
(
''
+
content
).
replace
(
/^
\s
+|
\s
+$/g
,
''
);
if
(
this
.
_content
!==
content
)
{
this
.
_content
=
content
;
this
.
dispatchEvent
({
type
:
'
change
'
});
}
},
isDone
:
function
()
{
return
this
.
_isDone
;
},
setDone
:
function
(
isDone
)
{
isDone
=
!!
isDone
;
if
(
this
.
_isDone
!==
isDone
)
{
this
.
_isDone
=
isDone
;
this
.
dispatchEvent
({
type
:
'
change
'
});
}
},
toggleDone
:
function
()
{
this
.
setDone
(
!
this
.
isDone
());
},
toJSON
:
function
()
{
return
{
content
:
this
.
_content
,
is_done
:
this
.
_isDone
};
}
}
properties
:
{
_title
:
''
,
_completed
:
false
,
getTitle
:
function
()
{
return
this
.
_title
;
},
setTitle
:
function
(
title
)
{
title
=
(
''
+
title
).
trim
(
);
if
(
this
.
_title
!==
title
)
{
this
.
_title
=
title
;
this
.
dispatchEvent
({
type
:
'
change
'
});
}
},
isCompleted
:
function
()
{
return
this
.
_completed
;
},
setCompleted
:
function
(
completed
)
{
completed
=
!!
completed
;
if
(
this
.
_completed
!==
completed
)
{
this
.
_completed
=
completed
;
this
.
dispatchEvent
({
type
:
'
change
'
});
}
},
toggleCompleted
:
function
()
{
this
.
setCompleted
(
!
this
.
isCompleted
());
},
toJSON
:
function
()
{
return
{
title
:
this
.
_title
,
completed
:
this
.
_completed
};
}
}
});
checkit
.
TodoModel
.
fromJSON
=
function
(
todoJSON
)
{
var
model
=
new
checkit
.
TodoModel
();
model
.
_content
=
todoJSON
.
content
;
model
.
_isDone
=
todoJSON
.
is_done
;
return
model
;
var
model
=
new
checkit
.
TodoModel
();
model
.
_title
=
todoJSON
.
title
;
model
.
_completed
=
todoJSON
.
completed
;
return
model
;
};
labs/architecture-examples/maria/src/js/models/TodosModel.js
View file @
00435de1
/*jshint strict: false */
/*global maria, checkit */
maria
.
SetModel
.
subclass
(
checkit
,
'
TodosModel
'
,
{
properties
:
{
isEmpty
:
function
()
{
return
this
.
length
===
0
;
},
getDone
:
function
()
{
return
this
.
filter
(
function
(
todo
)
{
return
todo
.
isDone
();
});
},
getUndone
:
function
()
{
return
this
.
filter
(
function
(
todo
)
{
return
!
todo
.
isDone
();
});
},
isAllDone
:
function
()
{
return
this
.
length
>
0
&&
(
this
.
getDone
().
length
===
this
.
length
);
},
markAllDone
:
function
()
{
this
.
forEach
(
function
(
todo
)
{
todo
.
setDone
(
true
);
});
},
markAllUndone
:
function
()
{
this
.
forEach
(
function
(
todo
)
{
todo
.
setDone
(
false
);
});
},
deleteDone
:
function
()
{
this
[
'
delete
'
].
apply
(
this
,
this
.
getDone
());
},
toJSON
:
function
()
{
return
this
.
map
(
function
(
todo
)
{
return
todo
.
toJSON
();
});
}
}
properties
:
{
_mode
:
'
all
'
,
getPossibleModes
:
function
()
{
return
[
'
all
'
,
'
incompleted
'
,
'
completed
'
];
},
getMode
:
function
()
{
return
this
.
_mode
;
},
setMode
:
function
(
mode
)
{
if
(
this
.
getPossibleModes
().
some
(
function
(
m
)
{
return
m
===
mode
;}))
{
if
(
this
.
_mode
!==
mode
)
{
this
.
_mode
=
mode
;
this
.
dispatchEvent
({
type
:
'
change
'
});
}
}
else
{
throw
new
Error
(
'
checkit.TodosModel.prototype.setMode: unsupported mode "
'
+
mode
+
'
".
'
);
}
},
getCompleted
:
function
()
{
return
this
.
filter
(
function
(
todo
)
{
return
todo
.
isCompleted
();
});
},
getIncompleted
:
function
()
{
return
this
.
filter
(
function
(
todo
)
{
return
!
todo
.
isCompleted
();
});
},
isAllCompleted
:
function
()
{
return
(
this
.
length
>
0
)
&&
(
this
.
getCompleted
().
length
===
this
.
length
);
},
markAllCompleted
:
function
()
{
this
.
forEach
(
function
(
todo
)
{
todo
.
setCompleted
(
true
);
});
},
markAllIncompleted
:
function
()
{
this
.
forEach
(
function
(
todo
)
{
todo
.
setCompleted
(
false
);
});
},
deleteCompleted
:
function
()
{
this
[
'
delete
'
].
apply
(
this
,
this
.
getCompleted
());
},
toJSON
:
function
()
{
return
this
.
map
(
function
(
todo
)
{
return
todo
.
toJSON
();
});
}
}
});
checkit
.
TodosModel
.
fromJSON
=
function
(
todosJSON
)
{
var
model
=
new
checkit
.
TodosModel
();
for
(
var
i
=
0
,
ilen
=
todosJSON
.
length
;
i
<
ilen
;
i
++
)
{
model
.
add
(
checkit
.
TodoModel
.
fromJSON
(
todosJSON
[
i
]));
}
return
model
;
var
model
=
new
checkit
.
TodosModel
();
for
(
var
i
=
0
,
ilen
=
todosJSON
.
length
;
i
<
ilen
;
i
++
)
{
model
.
add
(
checkit
.
TodoModel
.
fromJSON
(
todosJSON
[
i
]));
}
return
model
;
};
labs/architecture-examples/maria/src/js/namespace.js
View file @
00435de1
var
checkit
=
checkit
||
{};
/*jshint unused:false */
var
checkit
=
{};
labs/architecture-examples/maria/src/js/templates/TodoTemplate.js
View file @
00435de1
/*global checkit */
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
...
...
@@ -7,14 +9,11 @@
// included here.
//
checkit
.
TodoTemplate
=
'
<li class="todo">
'
+
'
<div class="display">
'
+
'
<input class="check" type="checkbox">
'
+
'
<span class="todo-content"></span>
'
+
'
<span class="todo-destroy">delete</span>
'
+
'
</div>
'
+
'
<div class="edit">
'
+
'
<input class="todo-input" type="text">
'
+
'
<span class="ui-tooltip-top" style="display:none;">Press enter to update this task.</span>
'
+
'
</div>
'
+
'
</li>
'
;
'
<li>
'
+
'
<div class="view">
'
+
'
<input class="toggle" type="checkbox">
'
+
'
<label></label>
'
+
'
<button class="destroy"></span>
'
+
'
</div>
'
+
'
<input class="edit">
'
+
'
</li>
'
;
labs/architecture-examples/maria/src/js/templates/TodosAppTemplate.js
deleted
100644 → 0
View file @
0d6e84dd
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit
.
TodosAppTemplate
=
'
<div class="todos-app">
'
+
'
<h1>Todos</h1>
'
+
'
<div class="content"></div>
'
+
'
<p class="copyright">Another fine widget from AlphaBeta.</p>
'
+
'
</div>
'
;
labs/architecture-examples/maria/src/js/templates/TodosInputTemplate.js
deleted
100644 → 0
View file @
0d6e84dd
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit
.
TodosInputTemplate
=
'
<div class="create-todo">
'
+
'
<input class="new-todo" placeholder="What needs to be done?" type="text">
'
+
'
<span class="ui-tooltip-top" style="display:none;">Press enter to add this task.</span>
'
+
'
</div>
'
;
labs/architecture-examples/maria/src/js/templates/TodosListTemplate.js
deleted
100644 → 0
View file @
0d6e84dd
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit
.
TodosListTemplate
=
'
<ul class="todos-list"></ul>
'
;
labs/architecture-examples/maria/src/js/templates/TodosStatsTemplate.js
deleted
100644 → 0
View file @
0d6e84dd
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit
.
TodosStatsTemplate
=
'
<div class="todos-stats"><strong class="todos-count"></strong> todos in list</div>
'
;
labs/architecture-examples/maria/src/js/templates/TodosTemplate.js
0 → 100644
View file @
00435de1
/*global checkit */
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit
.
TodosAppTemplate
=
'
<section id="todoapp">
'
+
'
<header id="header">
'
+
'
<h1>todos</h1>
'
+
'
<input id="new-todo" placeholder="What needs to be done?" autofocus>
'
+
'
</header>
'
+
'
<section id="main">
'
+
'
<input id="toggle-all" type="checkbox">
'
+
'
<label for="toggle-all">Mark all as completed</label>
'
+
'
<ul id="todo-list"></ul>
'
+
'
</section>
'
+
'
<footer id="footer">
'
+
'
<span id="todo-count"></span>
'
+
'
<ul id="filters">
'
+
'
<li>
'
+
'
<a class="all-filter" href="#/">All</a>
'
+
'
</li>
'
+
'
<li>
'
+
'
<a class="incompleted-filter" href="#/active">Active</a>
'
+
'
</li>
'
+
'
<li>
'
+
'
<a class="completed-filter" href="#/completed">Completed</a>
'
+
'
</li>
'
+
'
</ul>
'
+
'
<button id="clear-completed"></button>
'
+
'
</footer>
'
+
'
</section>
'
+
'
<footer id="info">
'
+
'
<p>Double-click to edit a todo</p>
'
+
'
<p>Inspired by the official <a href="https://github.com/maccman/spine.todos">Spine.Todos</a></p>
'
+
'
<p>Created by <a href="http://github.com/petermichaux">Peter Michaux</a></p>
'
+
'
</footer>
'
;
labs/architecture-examples/maria/src/js/templates/TodosToolbarTemplate.js
deleted
100644 → 0
View file @
0d6e84dd
// In a full development environment this template would be expressed
// in a file containing only HTML and be compiled to the following as part
// of the server/build functionality.
//
// Due to the limitations of a simple example that does not require
// any special server environment to try, the manually compiled version is
// included here.
//
checkit
.
TodosToolbarTemplate
=
'
<ul class="todos-toolbar">
'
+
'
<li><input type="checkbox" class="allCheckbox"></li>
'
+
'
<li class="markallDone">mark all as complete</li>
'
+
'
<li class="markallUndone">mark all as incomplete</li>
'
+
'
<li class="deleteComplete">delete complete</li>
'
+
'
</ul>
'
;
labs/architecture-examples/maria/src/js/util.js
0 → 100644
View file @
00435de1
/*jshint strict: false */
/*global checkit */
checkit
.
isBlank
=
function
(
str
)
{
return
(
/^
\s
*$/
).
test
(
str
);
};
checkit
.
escapeHTML
=
function
(
str
)
{
return
str
.
replace
(
'
&
'
,
'
&
'
).
replace
(
'
<
'
,
'
<
'
);
};
checkit
.
isEnterKeyCode
=
function
(
keyCode
)
{
return
keyCode
===
13
;
};
labs/architecture-examples/maria/src/js/views/TodoView.js
View file @
00435de1
/*jshint strict: false */
/*global maria, aristocrat, checkit */
maria
.
ElementView
.
subclass
(
checkit
,
'
TodoView
'
,
{
uiActions
:
{
'
mouseover .todo
'
:
'
onMouseoverRoot
'
,
'
mouseout .todo
'
:
'
onMouseoutRoot
'
,
'
click .check
'
:
'
onClickCheck
'
,
'
click .todo-destroy
'
:
'
onClickDestroy
'
,
'
dblclick .todo-content
'
:
'
onDblclickDisplay
'
,
'
keyup .todo-input
'
:
'
onKeyupInput
'
,
'
keypress .todo-input
'
:
'
onKeypressInput
'
,
'
blur .todo-input
'
:
'
onBlurInput
'
},
properties
:
{
buildData
:
function
()
{
var
model
=
this
.
getModel
();
var
content
=
model
.
getContent
();
this
.
find
(
'
.todo-content
'
).
innerHTML
=
content
.
replace
(
'
&
'
,
'
&
'
).
replace
(
'
<
'
,
'
<
'
);
this
.
find
(
'
.check
'
).
checked
=
model
.
isDone
();
aristocrat
[
model
.
isDone
()
?
'
addClass
'
:
'
removeClass
'
](
this
.
find
(
'
.todo
'
),
'
done
'
);
},
update
:
function
()
{
this
.
buildData
();
},
showEdit
:
function
()
{
var
input
=
this
.
find
(
'
.todo-input
'
);
input
.
value
=
this
.
getModel
().
getContent
();
aristocrat
.
addClass
(
this
.
find
(
'
.todo
'
),
'
editing
'
);
input
.
focus
();
},
showDisplay
:
function
()
{
aristocrat
.
removeClass
(
this
.
find
(
'
.todo
'
),
'
editing
'
);
},
getInputValue
:
function
()
{
return
this
.
find
(
'
.todo-input
'
).
value
;
},
showHoverState
:
function
()
{
aristocrat
.
addClass
(
this
.
find
(
'
.todo
'
),
'
todo-hover
'
);
},
hideHoverState
:
function
()
{
aristocrat
.
removeClass
(
this
.
find
(
'
.todo
'
),
'
todo-hover
'
);
},
showToolTip
:
function
()
{
this
.
find
(
'
.ui-tooltip-top
'
).
style
.
display
=
'
block
'
;
},
hideToolTip
:
function
()
{
this
.
find
(
'
.ui-tooltip-top
'
).
style
.
display
=
'
none
'
;
}
}
uiActions
:
{
'
click .destroy
'
:
'
onClickDestroy
'
,
'
click .toggle
'
:
'
onClickToggle
'
,
'
dblclick label
'
:
'
onDblclickLabel
'
,
'
keyup .edit
'
:
'
onKeyupEdit
'
,
'
blur .edit
'
:
'
onBlurEdit
'
},
properties
:
{
buildData
:
function
()
{
var
model
=
this
.
getModel
();
var
item
=
this
.
find
(
'
li
'
);
aristocrat
.
removeClass
(
item
,
'
(in|)completed
'
);
aristocrat
.
addClass
(
item
,
(
model
.
isCompleted
()
?
'
completed
'
:
'
incompleted
'
));
this
.
find
(
'
label
'
).
innerHTML
=
checkit
.
escapeHTML
(
model
.
getTitle
());
this
.
find
(
'
.toggle
'
).
checked
=
model
.
isCompleted
();
},
update
:
function
()
{
this
.
buildData
();
},
showEdit
:
function
()
{
var
input
=
this
.
find
(
'
.edit
'
);
input
.
value
=
this
.
getModel
().
getTitle
();
aristocrat
.
addClass
(
this
.
find
(
'
li
'
),
'
editing
'
);
input
.
focus
();
},
showDisplay
:
function
()
{
aristocrat
.
removeClass
(
this
.
find
(
'
li
'
),
'
editing
'
);
},
getInputValue
:
function
()
{
return
this
.
find
(
'
.edit
'
).
value
;
}
}
});
labs/architecture-examples/maria/src/js/views/TodosAppView.js
deleted
100644 → 0
View file @
0d6e84dd
// All the subviews of a TodosAppView will always have
// the same model as the TodosAppView has.
//
maria
.
ElementView
.
subclass
(
checkit
,
'
TodosAppView
'
,
{
properties
:
{
getContainerEl
:
function
()
{
return
this
.
find
(
'
.content
'
);
// child views will be appended to this element
},
initialize
:
function
()
{
this
.
appendChild
(
new
checkit
.
TodosInputView
());
this
.
appendChild
(
new
checkit
.
TodosToolbarView
());
this
.
appendChild
(
new
checkit
.
TodosListView
());
this
.
appendChild
(
new
checkit
.
TodosStatsView
());
},
insertBefore
:
function
(
newChild
,
oldChild
)
{
newChild
.
setModel
(
this
.
getModel
());
maria
.
ElementView
.
prototype
.
insertBefore
.
call
(
this
,
newChild
,
oldChild
);
},
setModel
:
function
(
model
)
{
if
(
model
!==
this
.
getModel
())
{
maria
.
ElementView
.
prototype
.
setModel
.
call
(
this
,
model
);
var
childViews
=
this
.
childNodes
;
for
(
var
i
=
0
,
ilen
=
childViews
.
length
;
i
<
ilen
;
i
++
)
{
childViews
[
i
].
setModel
(
model
);
}
}
}
}
});
labs/architecture-examples/maria/src/js/views/TodosInputView.js
deleted
100644 → 0
View file @
0d6e84dd
maria
.
ElementView
.
subclass
(
checkit
,
'
TodosInputView
'
,
{
uiActions
:
{
'
focus .new-todo
'
:
'
onFocusInput
'
,
'
blur .new-todo
'
:
'
onBlurInput
'
,
'
keyup .new-todo
'
:
'
onKeyupInput
'
,
'
keypress .new-todo
'
:
'
onKeypressInput
'
},
properties
:
{
getInputValue
:
function
()
{
return
this
.
find
(
'
.new-todo
'
).
value
;
},
clearInput
:
function
()
{
this
.
find
(
'
.new-todo
'
).
value
=
''
;
},
showToolTip
:
function
()
{
this
.
find
(
'
.ui-tooltip-top
'
).
style
.
display
=
'
block
'
;
},
hideToolTip
:
function
()
{
this
.
find
(
'
.ui-tooltip-top
'
).
style
.
display
=
'
none
'
;
}
}
});
labs/architecture-examples/maria/src/js/views/TodosListView.js
deleted
100644 → 0
View file @
0d6e84dd
maria
.
SetView
.
subclass
(
checkit
,
'
TodosListView
'
,
{
properties
:
{
createChildView
:
function
(
todoModel
)
{
return
new
checkit
.
TodoView
(
todoModel
);
}
}
});
labs/architecture-examples/maria/src/js/views/TodosStatsView.js
deleted
100644 → 0
View file @
0d6e84dd
maria
.
ElementView
.
subclass
(
checkit
,
'
TodosStatsView
'
,
{
properties
:
{
buildData
:
function
()
{
this
.
find
(
'
.todos-count
'
).
innerHTML
=
this
.
getModel
().
length
;
},
update
:
function
()
{
this
.
buildData
();
}
}
});
labs/architecture-examples/maria/src/js/views/TodosToolbarView.js
deleted
100644 → 0
View file @
0d6e84dd
maria
.
ElementView
.
subclass
(
checkit
,
'
TodosToolbarView
'
,
{
uiActions
:
{
'
click .allCheckbox
'
:
'
onClickAllCheckbox
'
,
'
click .markallDone
'
:
'
onClickMarkAllDone
'
,
'
click .markallUndone
'
:
'
onClickMarkAllUndone
'
,
'
click .deleteComplete
'
:
'
onClickDeleteDone
'
},
properties
:
{
buildData
:
function
()
{
var
model
=
this
.
getModel
();
var
checkbox
=
this
.
find
(
'
.allCheckbox
'
);
checkbox
.
checked
=
model
.
isAllDone
();
checkbox
.
disabled
=
model
.
isEmpty
();
},
update
:
function
()
{
this
.
buildData
();
}
}
});
labs/architecture-examples/maria/src/js/views/TodosView.js
0 → 100644
View file @
00435de1
/*jshint strict: false */
/*global maria, aristocrat, checkit */
maria
.
SetView
.
subclass
(
checkit
,
'
TodosAppView
'
,
{
uiActions
:
{
'
keyup #new-todo
'
:
'
onKeyupNewTodo
'
,
'
click #toggle-all
'
:
'
onClickToggleAll
'
,
'
click #clear-completed
'
:
'
onClickClearCompleted
'
},
properties
:
{
buildData
:
function
()
{
var
model
=
this
.
getModel
();
var
length
=
model
.
length
;
this
.
find
(
'
#main
'
).
style
.
display
=
(
length
>
0
)
?
''
:
'
none
'
;
this
.
find
(
'
#footer
'
).
style
.
display
=
(
length
>
0
)
?
''
:
'
none
'
;
var
checkbox
=
this
.
find
(
'
#toggle-all
'
);
checkbox
.
checked
=
model
.
isAllCompleted
();
checkbox
.
disabled
=
model
.
isEmpty
();
var
todoList
=
this
.
find
(
'
#todo-list
'
);
model
.
getPossibleModes
().
forEach
(
function
(
mode
)
{
aristocrat
.
removeClass
(
todoList
,
mode
);
});
aristocrat
.
addClass
(
todoList
,
model
.
getMode
());
var
incompletedLength
=
model
.
getIncompleted
().
length
;
this
.
find
(
'
#todo-count
'
).
innerHTML
=
'
<strong>
'
+
incompletedLength
+
'
</strong>
'
+
((
incompletedLength
===
1
)
?
'
item
'
:
'
items
'
)
+
'
left
'
;
var
selected
=
this
.
find
(
'
.selected
'
);
if
(
selected
)
{
aristocrat
.
removeClass
(
selected
,
'
selected
'
);
}
aristocrat
.
addClass
(
this
.
find
(
'
.
'
+
model
.
getMode
()
+
'
-filter
'
),
'
selected
'
);
var
completedLength
=
model
.
getCompleted
().
length
;
var
clearButton
=
this
.
find
(
'
#clear-completed
'
);
clearButton
.
style
.
display
=
(
completedLength
>
0
)
?
''
:
'
none
'
;
clearButton
.
innerHTML
=
'
Clear completed (
'
+
completedLength
+
'
)
'
;
},
update
:
function
(
evt
)
{
maria
.
SetView
.
prototype
.
update
.
call
(
this
,
evt
);
this
.
buildData
();
},
getContainerEl
:
function
()
{
// child views will be appended to this element
return
this
.
find
(
'
#todo-list
'
);
},
createChildView
:
function
(
todoModel
)
{
return
new
checkit
.
TodoView
(
todoModel
);
},
getInputValue
:
function
()
{
return
this
.
find
(
'
#new-todo
'
).
value
;
},
clearInput
:
function
()
{
this
.
find
(
'
#new-todo
'
).
value
=
''
;
}
}
});
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