Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
todomvc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eugene Shen
todomvc
Commits
466307fa
Commit
466307fa
authored
Sep 19, 2012
by
RYan Eastridge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial thorax todos commit
parent
83cf863f
Changes
12
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
2816 additions
and
0 deletions
+2816
-0
labs/architecture-examples/thorax/index.html
labs/architecture-examples/thorax/index.html
+80
-0
labs/architecture-examples/thorax/js/app.js
labs/architecture-examples/thorax/js/app.js
+9
-0
labs/architecture-examples/thorax/js/collections/todos.js
labs/architecture-examples/thorax/js/collections/todos.js
+49
-0
labs/architecture-examples/thorax/js/lib/backbone-localstorage.js
...hitecture-examples/thorax/js/lib/backbone-localstorage.js
+84
-0
labs/architecture-examples/thorax/js/lib/backbone-min.js
labs/architecture-examples/thorax/js/lib/backbone-min.js
+38
-0
labs/architecture-examples/thorax/js/lib/thorax.js
labs/architecture-examples/thorax/js/lib/thorax.js
+2255
-0
labs/architecture-examples/thorax/js/lib/underscore-min.js
labs/architecture-examples/thorax/js/lib/underscore-min.js
+32
-0
labs/architecture-examples/thorax/js/models/todo.js
labs/architecture-examples/thorax/js/models/todo.js
+28
-0
labs/architecture-examples/thorax/js/routers/router.js
labs/architecture-examples/thorax/js/routers/router.js
+24
-0
labs/architecture-examples/thorax/js/views/app.js
labs/architecture-examples/thorax/js/views/app.js
+82
-0
labs/architecture-examples/thorax/js/views/stats.js
labs/architecture-examples/thorax/js/views/stats.js
+47
-0
labs/architecture-examples/thorax/js/views/todo-item.js
labs/architecture-examples/thorax/js/views/todo-item.js
+88
-0
No files found.
labs/architecture-examples/thorax/index.html
0 → 100644
View file @
466307fa
<!doctype html>
<html
lang=
"en"
>
<head>
<meta
charset=
"utf-8"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge,chrome=1"
>
<title>
Thorax • TodoMVC
</title>
<link
rel=
"stylesheet"
href=
"../../../assets/base.css"
>
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<script
type=
"text/template"
data-template-name=
"app"
>
<
section
id
=
"
todoapp
"
>
<
header
id
=
"
header
"
>
<
h1
>
todos
<
/h1
>
<
input
id
=
"
new-todo
"
placeholder
=
"
What needs to be done?
"
autofocus
>
<
/header
>
{{
^
empty
todosCollection
}}
<
section
id
=
"
main
"
>
<
input
id
=
"
toggle-all
"
type
=
"
checkbox
"
>
<
label
for
=
"
toggle-all
"
>
Mark
all
as
complete
<
/label
>
{{
#
collection
todosCollection
item
-
view
=
"
todo-item
"
tag
=
"
ul
"
id
=
"
todo-list
"
}}
<
div
class
=
"
view
"
>
<
input
class
=
"
toggle
"
type
=
"
checkbox
"
{{
#
if
completed
}}
checked
{{
/if}}
>
<
label
>
{{
title
}}
<
/label
>
<
button
class
=
"
destroy
"
><
/button
>
<
/div
>
<
input
class
=
"
edit
"
value
=
"
{{title}}
"
>
{{
/
collection
}}
<
/section
>
{{
view
"
stats
"
tag
=
"
footer
"
id
=
"
footer
"
}}
{{
/empty}
}
<
/section
>
<
div
id
=
"
info
"
>
<
p
>
Double
-
click
to
edit
a
todo
<
/p
>
<
p
>
Written
by
<
a
href
=
"
https://github.com/addyosmani
"
>
Addy
Osmani
<
/a> & <a href="https:/
/
github
.
com
/
beastridge
"
>Ryan Eastridge</a></p>
<p>Part of <a href=
"
http
:
//todomvc.com">TodoMVC
<
/a></
p
>
<
/div
>
</script>
<script
type=
"text/template"
data-template-name=
"stats"
>
<
span
id
=
"
todo-count
"
><
strong
>
{{
remaining
}}
<
/strong> {{itemText}} left</
span
>
<
ul
id
=
"
filters
"
>
<
li
>
{{
#
link
"
/
"
class
=
"
selected
"
}}
All
{{
/
link
}}
<
/li
>
<
li
>
{{
#
link
"
/active
"
}}
Active
{{
/
link
}}
<
/li
>
<
li
>
{{
#
link
"
/completed
"
}}
Completed
{{
/
link
}}
<
/li
>
<
/ul
>
{{
#
if
completed
}}
<
button
id
=
"
clear-completed
"
>
Clear
completed
({{
completed
}})
<
/button
>
{{
/
if
}}
</script>
<script
src=
"../../../assets/base.js"
></script>
<script
src=
"../../../assets/jquery.min.js"
></script>
<script
src=
"../../../assets/lodash.min.js"
></script>
<script
src=
"../../../assets/handlebars.min.js"
></script>
<script
src=
"js/lib/backbone-min.js"
></script>
<script
src=
"js/lib/backbone-localstorage.js"
></script>
<script
src=
"js/lib/thorax.js"
></script>
<script>
// Grab the text from the templates we created above
Thorax
.
templates
=
{
app
:
Handlebars
.
compile
(
$
(
'
script[data-template-name="app"]
'
).
html
()),
stats
:
Handlebars
.
compile
(
$
(
'
script[data-template-name="stats"]
'
).
html
())
};
</script>
<script
src=
"js/models/todo.js"
></script>
<script
src=
"js/collections/todos.js"
></script>
<script
src=
"js/views/todo-item.js"
></script>
<script
src=
"js/views/stats.js"
></script>
<script
src=
"js/views/app.js"
></script>
<script
src=
"js/routers/router.js"
></script>
<script
src=
"js/app.js"
></script>
</body>
</html>
labs/architecture-examples/thorax/js/app.js
0 → 100644
View file @
466307fa
var
app
=
app
||
{};
var
ENTER_KEY
=
13
;
$
(
function
()
{
// Kick things off by creating the **App**.
var
view
=
new
Thorax
.
Views
[
'
app
'
]();
$
(
'
body
'
).
append
(
view
.
el
);
});
labs/architecture-examples/thorax/js/collections/todos.js
0 → 100644
View file @
466307fa
var
app
=
app
||
{};
(
function
()
{
'
use strict
'
;
// Todo Collection
// ---------------
// The collection of todos is backed by *localStorage* instead of a remote
// server.
var
TodoList
=
Backbone
.
Collection
.
extend
({
// Reference to this collection's model.
model
:
app
.
Todo
,
// Save all of the todo items under the `"todos"` namespace.
localStorage
:
new
Store
(
'
todos-backbone
'
),
// Filter down the list of all todo items that are finished.
completed
:
function
()
{
return
this
.
filter
(
function
(
todo
)
{
return
todo
.
get
(
'
completed
'
);
});
},
// Filter down the list to only todo items that are still not finished.
remaining
:
function
()
{
return
this
.
without
.
apply
(
this
,
this
.
completed
()
);
},
// We keep the Todos in sequential order, despite being saved by unordered
// GUID in the database. This generates the next order number for new items.
nextOrder
:
function
()
{
if
(
!
this
.
length
)
{
return
1
;
}
return
this
.
last
().
get
(
'
order
'
)
+
1
;
},
// Todos are sorted by their original insertion order.
comparator
:
function
(
todo
)
{
return
todo
.
get
(
'
order
'
);
}
});
// Create our global collection of **Todos**.
app
.
Todos
=
new
TodoList
();
}());
labs/architecture-examples/thorax/js/lib/backbone-localstorage.js
0 → 100644
View file @
466307fa
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.
// Generate four random hex digits.
function
S4
()
{
return
(((
1
+
Math
.
random
())
*
0x10000
)
|
0
).
toString
(
16
).
substring
(
1
);
};
// Generate a pseudo-GUID by concatenating random hexadecimal.
function
guid
()
{
return
(
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
());
};
// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
var
Store
=
function
(
name
)
{
this
.
name
=
name
;
var
store
=
localStorage
.
getItem
(
this
.
name
);
this
.
data
=
(
store
&&
JSON
.
parse
(
store
))
||
{};
};
_
.
extend
(
Store
.
prototype
,
{
// Save the current state of the **Store** to *localStorage*.
save
:
function
()
{
localStorage
.
setItem
(
this
.
name
,
JSON
.
stringify
(
this
.
data
));
},
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
// have an id of it's own.
create
:
function
(
model
)
{
if
(
!
model
.
id
)
model
.
id
=
model
.
attributes
.
id
=
guid
();
this
.
data
[
model
.
id
]
=
model
;
this
.
save
();
return
model
;
},
// Update a model by replacing its copy in `this.data`.
update
:
function
(
model
)
{
this
.
data
[
model
.
id
]
=
model
;
this
.
save
();
return
model
;
},
// Retrieve a model from `this.data` by id.
find
:
function
(
model
)
{
return
this
.
data
[
model
.
id
];
},
// Return the array of all models currently in storage.
findAll
:
function
()
{
return
_
.
values
(
this
.
data
);
},
// Delete a model from `this.data`, returning it.
destroy
:
function
(
model
)
{
delete
this
.
data
[
model
.
id
];
this
.
save
();
return
model
;
}
});
// Override `Backbone.sync` to use delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`.
Backbone
.
sync
=
function
(
method
,
model
,
options
)
{
var
resp
;
var
store
=
model
.
localStorage
||
model
.
collection
.
localStorage
;
switch
(
method
)
{
case
"
read
"
:
resp
=
model
.
id
?
store
.
find
(
model
)
:
store
.
findAll
();
break
;
case
"
create
"
:
resp
=
store
.
create
(
model
);
break
;
case
"
update
"
:
resp
=
store
.
update
(
model
);
break
;
case
"
delete
"
:
resp
=
store
.
destroy
(
model
);
break
;
}
if
(
resp
)
{
options
.
success
(
resp
);
}
else
{
options
.
error
(
"
Record not found
"
);
}
};
labs/architecture-examples/thorax/js/lib/backbone-min.js
0 → 100644
View file @
466307fa
This diff is collapsed.
Click to expand it.
labs/architecture-examples/thorax/js/lib/thorax.js
0 → 100644
View file @
466307fa
This diff is collapsed.
Click to expand it.
labs/architecture-examples/thorax/js/lib/underscore-min.js
0 → 100644
View file @
466307fa
This diff is collapsed.
Click to expand it.
labs/architecture-examples/thorax/js/models/todo.js
0 → 100644
View file @
466307fa
var
app
=
app
||
{};
(
function
()
{
'
use strict
'
;
// Todo Model
// ----------
// Our basic **Todo** model has `title`, `order`, and `completed` attributes.
app
.
Todo
=
Backbone
.
Model
.
extend
({
// Default attributes for the todo
// and ensure that each todo created has `title` and `completed` keys.
defaults
:
{
title
:
''
,
completed
:
false
},
// Toggle the `completed` state of this todo item.
toggle
:
function
()
{
this
.
save
({
completed
:
!
this
.
get
(
'
completed
'
)
});
}
});
}());
labs/architecture-examples/thorax/js/routers/router.js
0 → 100644
View file @
466307fa
var
app
=
app
||
{};
(
function
()
{
'
use strict
'
;
// Todo Router
// ----------
app
.
TodoRouter
=
new
(
Thorax
.
Router
.
extend
({
routes
:
{
'
*filter
'
:
'
setFilter
'
},
setFilter
:
function
(
param
)
{
// Set the current filter to be used
window
.
app
.
TodoFilter
=
param
.
trim
()
||
''
;
// Trigger a collection filter event, causing hiding/unhiding
// of Todo view items
window
.
app
.
Todos
.
trigger
(
'
filter
'
);
}
}));
}());
labs/architecture-examples/thorax/js/views/app.js
0 → 100644
View file @
466307fa
var
app
=
app
||
{};
$
(
function
(
$
)
{
'
use strict
'
;
// The Application
// ---------------
// Our overall **AppView** is the top-level piece of UI.
Thorax
.
View
.
extend
({
// This will assign the template Thorax.templates['app'] to the view and
// create a view class at Thorax.Views['app']
name
:
'
app
'
,
// Delegated events for creating new items, and clearing completed ones.
events
:
{
'
keypress #new-todo
'
:
'
createOnEnter
'
,
'
click #toggle-all
'
:
'
toggleAllComplete
'
,
// The collection helper in the template will bind the collection
// to the view. Any events in this hash will be bound to the
// collection.
collection
:
{
all
:
'
toggleToggleAllButton
'
,
'
change:completed
'
:
'
filterOne
'
,
'
filter
'
:
'
filterAll
'
},
rendered
:
'
toggleToggleAllButton
'
},
// Unless the "context" method is overriden any attributes on the view
// will be availble to the context / scope of the template, make the
// global Todos collection available to the template.
// Load any preexisting todos that might be saved in *localStorage*.
initialize
:
function
()
{
this
.
todosCollection
=
app
.
Todos
;
this
.
todosCollection
.
fetch
();
this
.
render
();
},
toggleToggleAllButton
:
function
()
{
this
.
$
(
'
#toggle-all
'
).
attr
(
'
checked
'
,
!
this
.
todosCollection
.
remaining
().
length
);
},
filterOne
:
function
(
todo
)
{
todo
.
trigger
(
"
visible
"
);
},
filterAll
:
function
()
{
app
.
Todos
.
each
(
this
.
filterOne
,
this
);
},
// Generate the attributes for a new Todo item.
newAttributes
:
function
()
{
return
{
title
:
this
.
$
(
'
#new-todo
'
).
val
().
trim
(),
order
:
app
.
Todos
.
nextOrder
(),
completed
:
false
};
},
// If you hit return in the main input field, create new **Todo** model,
// persisting it to *localStorage*.
createOnEnter
:
function
(
e
)
{
if
(
e
.
which
!==
ENTER_KEY
||
!
this
.
$
(
'
#new-todo
'
).
val
().
trim
()
)
{
return
;
}
app
.
Todos
.
create
(
this
.
newAttributes
()
);
this
.
$
(
'
#new-todo
'
).
val
(
''
);
},
toggleAllComplete
:
function
()
{
var
completed
=
this
.
$
(
'
#toggle-all
'
)[
0
].
checked
;
app
.
Todos
.
each
(
function
(
todo
)
{
todo
.
save
({
'
completed
'
:
completed
});
});
}
});
});
labs/architecture-examples/thorax/js/views/stats.js
0 → 100644
View file @
466307fa
Thorax
.
View
.
extend
({
name
:
'
stats
'
,
events
:
{
'
click #clear-completed
'
:
'
clearCompleted
'
,
// The "rendered" event is triggered by Thorax each time render()
// is called and the result of the template has been appended
// to the View's $el
rendered
:
'
highlightFilter
'
},
initialize
:
function
()
{
// Whenever the Todos collection changes re-render the stats
// render() needs to be called with no arguments, otherwise calling
// it with arguments will insert the arguments as content
window
.
app
.
Todos
.
on
(
'
all
'
,
_
.
debounce
(
function
()
{
this
.
render
();
}),
this
);
},
// Clear all completed todo items, destroying their models.
clearCompleted
:
function
()
{
_
.
each
(
window
.
app
.
Todos
.
completed
(),
function
(
todo
)
{
todo
.
destroy
();
});
return
false
;
},
// Each time the stats view is rendered this function will
// be called to generate the context / scope that the template
// will be called with. "context" defaults to "return this"
context
:
function
()
{
return
{
completed
:
app
.
Todos
.
completed
().
length
,
remaining
:
app
.
Todos
.
remaining
().
length
};
},
// Highlight which filter will appear to be active
highlightFilter
:
function
()
{
this
.
$
(
'
#filters li a
'
)
.
removeClass
(
'
selected
'
)
.
filter
(
'
[href="#/
'
+
(
app
.
TodoFilter
||
''
)
+
'
"]
'
)
.
addClass
(
'
selected
'
);
}
});
\ No newline at end of file
labs/architecture-examples/thorax/js/views/todo-item.js
0 → 100644
View file @
466307fa
var
app
=
app
||
{};
$
(
function
()
{
'
use strict
'
;
// Todo Item View
// --------------
// The DOM element for a todo item...
Thorax
.
View
.
extend
({
//... is a list tag.
tagName
:
'
li
'
,
// Cache the template function for a single item.
name
:
'
todo-item
'
,
// The DOM events specific to an item.
events
:
{
'
click .toggle
'
:
'
toggleCompleted
'
,
'
dblclick label
'
:
'
edit
'
,
'
click .destroy
'
:
'
clear
'
,
'
keypress .edit
'
:
'
updateOnEnter
'
,
'
blur .edit
'
:
'
close
'
,
// Events in this hash will be bound to the model
// when it is assigned to the view
model
:
{
visible
:
'
toggleVisible
'
},
// The "rendered" event is triggered by Thorax each time render()
// is called and the result of the template has been appended
// to the View's $el
rendered
:
function
()
{
this
.
$el
.
toggleClass
(
'
completed
'
,
this
.
model
.
get
(
'
completed
'
)
);
this
.
toggleVisible
();
this
.
input
=
this
.
$
(
'
.edit
'
);
}
},
toggleVisible
:
function
()
{
this
.
$el
.
toggleClass
(
'
hidden
'
,
this
.
isHidden
());
},
isHidden
:
function
()
{
var
isCompleted
=
this
.
model
.
get
(
'
completed
'
);
return
(
// hidden cases only
(
!
isCompleted
&&
app
.
TodoFilter
===
'
completed
'
)
||
(
isCompleted
&&
app
.
TodoFilter
===
'
active
'
)
);
},
// Toggle the `"completed"` state of the model.
toggleCompleted
:
function
()
{
this
.
model
.
toggle
();
},
// Switch this view into `"editing"` mode, displaying the input field.
edit
:
function
()
{
this
.
$el
.
addClass
(
'
editing
'
);
this
.
input
.
focus
();
},
// Close the `"editing"` mode, saving changes to the todo.
close
:
function
()
{
var
value
=
this
.
input
.
val
().
trim
();
if
(
value
)
{
this
.
model
.
save
({
title
:
value
});
}
else
{
this
.
clear
();
}
this
.
$el
.
removeClass
(
'
editing
'
);
},
// If you hit `enter`, we're through editing the item.
updateOnEnter
:
function
(
e
)
{
if
(
e
.
which
===
ENTER_KEY
)
{
this
.
close
();
}
},
// Remove the item, destroy the model from *localStorage* and delete its view.
clear
:
function
()
{
this
.
model
.
destroy
();
}
});
});
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