spade 0.1.0 → 0.1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -11
- data/.gitmodules +3 -6
- data/Gemfile +10 -0
- data/bin/spade +3 -1
- data/lib/spade.rb +70 -0
- data/lib/spade/bundle.rb +180 -0
- data/lib/spade/cli.rb +1 -17
- data/lib/spade/cli/base.rb +182 -0
- data/lib/spade/console.rb +39 -0
- data/lib/spade/context.rb +107 -0
- data/lib/spade/evaluator.rb +34 -0
- data/lib/spade/exports.rb +70 -0
- data/lib/spade/loader.rb +208 -0
- data/lib/spade/package/.gitignore +1 -0
- data/lib/spade/package/Gemfile +15 -0
- data/lib/spade/package/lib/spade.js +1283 -0
- data/lib/spade/package/lib/wrapper.js +15 -0
- data/lib/spade/package/package.json +17 -0
- data/lib/spade/package/spec/javascript/async-test.js +123 -0
- data/lib/spade/package/spec/javascript/compiler/javascript.js +13 -0
- data/lib/spade/package/spec/javascript/compiler/ruby.js +14 -0
- data/lib/spade/package/spec/javascript/loader-test.js +64 -0
- data/lib/spade/package/spec/javascript/normalize-test.js +73 -0
- data/lib/spade/package/spec/javascript/packages-test.js +50 -0
- data/lib/spade/package/spec/javascript/relative-require-test.js +72 -0
- data/lib/spade/package/spec/javascript/require-test.js +117 -0
- data/lib/spade/package/spec/javascript/sandbox/creation.js +44 -0
- data/lib/spade/package/spec/javascript/sandbox/evaluate.js +37 -0
- data/lib/spade/package/spec/javascript/sandbox/format.js +79 -0
- data/lib/spade/package/spec/javascript/sandbox/misc.js +58 -0
- data/lib/spade/package/spec/javascript/sandbox/preprocessor.js +81 -0
- data/lib/spade/package/spec/javascript/sandbox/require.js +48 -0
- data/lib/spade/package/spec/javascript/sandbox/run-command.js +21 -0
- data/lib/spade/package/spec/javascript/spade/externs.js +14 -0
- data/lib/spade/package/spec/javascript/spade/load-factory.js +15 -0
- data/lib/spade/package/spec/javascript/spade/misc.js +23 -0
- data/lib/spade/package/spec/javascript/spade/ready.js +12 -0
- data/lib/spade/package/spec/javascript/spade/register.js +13 -0
- data/lib/spade/package/spec/javascript_spec.rb +7 -0
- data/lib/spade/package/spec/spec_helper.rb +3 -0
- data/lib/spade/package/spec/support/core_test.rb +67 -0
- data/lib/spade/reactor.rb +159 -0
- data/lib/spade/server.rb +66 -0
- data/lib/spade/shell.rb +85 -0
- data/lib/spade/version.rb +1 -1
- data/spade.gemspec +15 -4
- data/spec/cli/update_spec.rb +65 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/cli.rb +103 -0
- data/spec/support/matchers.rb +12 -0
- data/spec/support/path.rb +66 -0
- metadata +146 -78
- data/.rspec +0 -1
- data/Buildfile +0 -18
- data/README.md +0 -152
- data/Rakefile +0 -9
- data/examples/format-app/lib/hello.coffee +0 -1
- data/examples/format-app/lib/main.js +0 -6
- data/examples/format-app/package.json +0 -10
- data/examples/format-app/resources/README.txt +0 -1
- data/examples/format-app/resources/config.json +0 -3
- data/examples/path-test/lib/hello.js +0 -1
- data/examples/path-test/lib/main.js +0 -1
- data/examples/path-test/package.json +0 -5
- data/examples/sc-app/index.html +0 -13
- data/examples/sc-app/lib/main.js +0 -24
- data/examples/sc-app/package.json +0 -8
- data/examples/single-file.js +0 -22
- data/examples/todos/index.html +0 -11
- data/examples/todos/lib/main.js +0 -11
- data/examples/todos/lib/todos.js +0 -93
- data/examples/todos/package.json +0 -10
- data/examples/todos/resources/stylesheets/todos.css +0 -162
- data/examples/todos/resources/templates/todos.handlebars +0 -31
- data/examples/web-app/README.md +0 -83
- data/examples/web-app/index.html +0 -12
- data/examples/web-app/lib/main.js +0 -3
- data/examples/web-app/package.json +0 -6
- data/examples/web-app/tests.html +0 -12
- data/examples/web-app/tests/ct-example-test.js +0 -39
- data/examples/web-app/tests/qunit-test.js +0 -23
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|
data/Buildfile
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# ===========================================================================
|
2
|
-
# Project: Spade
|
3
|
-
# Copyright: ©2009 Apple Inc.
|
4
|
-
# ===========================================================================
|
5
|
-
|
6
|
-
#######################################################
|
7
|
-
## CORE TIKI FRAMEWORK
|
8
|
-
##
|
9
|
-
|
10
|
-
config :spade,
|
11
|
-
:required => [],
|
12
|
-
:debug_required => [],
|
13
|
-
#:test_dynamic_required => ['core-test'],
|
14
|
-
:use_modules => true,
|
15
|
-
:use_package_info => false,
|
16
|
-
:factory_format => :function, # string is not needed here
|
17
|
-
:module_lib => ['lib'],
|
18
|
-
:combine_javascript => true # always improve load times
|
data/README.md
DELETED
@@ -1,152 +0,0 @@
|
|
1
|
-
`===========================================================================
|
2
|
-
Project: Spade - CommonJS Microkernel
|
3
|
-
Copyright: ©2011 Strobe Inc.
|
4
|
-
===========================================================================`
|
5
|
-
|
6
|
-
Spade makes it easy to share and run JavaScript in both the browser and on the
|
7
|
-
command line.
|
8
|
-
|
9
|
-
# Setup
|
10
|
-
|
11
|
-
Please note that, as of now, Spade depends on your rubygem to be version 1.7.2.
|
12
|
-
You can install rubygems 1.7.2 with the following command:
|
13
|
-
gem update --system 1.7.2
|
14
|
-
|
15
|
-
The following commands will get you started on spade with an initial set of
|
16
|
-
packages:
|
17
|
-
|
18
|
-
git clone git://github.com/strobecorp/spade.git
|
19
|
-
cd spade
|
20
|
-
git submodule update --init
|
21
|
-
bundle
|
22
|
-
|
23
|
-
You should now be able to run the demos in the examples folder. Be sure to
|
24
|
-
check out any README files in the example folders for instructions there.
|
25
|
-
|
26
|
-
Run the test suite:
|
27
|
-
|
28
|
-
rake
|
29
|
-
|
30
|
-
Run an individual test:
|
31
|
-
|
32
|
-
bundle exec rspec spec/login_spec.rb
|
33
|
-
|
34
|
-
To install the gem for global use of the spade command:
|
35
|
-
|
36
|
-
gem build spade.gemspec
|
37
|
-
gem install spade-0.0.1.gem
|
38
|
-
|
39
|
-
# Quick Start Guide
|
40
|
-
|
41
|
-
## From the Command Line
|
42
|
-
|
43
|
-
Let's write a simple script. Create a new file called 'main.js' and put in
|
44
|
-
the following:
|
45
|
-
|
46
|
-
console.log('Hello World');
|
47
|
-
|
48
|
-
Now run this from the command line:
|
49
|
-
|
50
|
-
spade main.js
|
51
|
-
|
52
|
-
Now we want to run this in the browser. To run in the browser, you need to
|
53
|
-
make a JavaScript _package_. A package is simply a folder containing your
|
54
|
-
JavaScript structured in a way that the module system can understand. All
|
55
|
-
shared libraries that you load are also packages.
|
56
|
-
|
57
|
-
## From the Browser
|
58
|
-
|
59
|
-
To make the hello-world app package, create a folder called 'hello-world'.
|
60
|
-
Inside of that, create a folder called 'lib' and put your main.js in there.
|
61
|
-
You should also create index.html and package.json files. The folder
|
62
|
-
structure should look like this:
|
63
|
-
|
64
|
-
/hello-world
|
65
|
-
index.html
|
66
|
-
package.json
|
67
|
-
/lib
|
68
|
-
main.js <-- your previous main.js file
|
69
|
-
|
70
|
-
Your index.html should contain the following:
|
71
|
-
|
72
|
-
<html>
|
73
|
-
<head>
|
74
|
-
<script src="spade-boot.js" data-require="hello-world"></script>
|
75
|
-
</head>
|
76
|
-
<body>
|
77
|
-
</body>
|
78
|
-
</html>
|
79
|
-
|
80
|
-
This index.html file will simply load a boot script that we are about to
|
81
|
-
generate.
|
82
|
-
|
83
|
-
The package.json should list at minimum the app name and dependencies:
|
84
|
-
|
85
|
-
{
|
86
|
-
"name": "hello-world"
|
87
|
-
}
|
88
|
-
|
89
|
-
Next, we need to setup this package so it includes any dependencies. To do
|
90
|
-
this, use the `spade update` command:
|
91
|
-
|
92
|
-
spade update
|
93
|
-
|
94
|
-
This will create a new, hidden '.spade' directory with info along with a new
|
95
|
-
file called spade-boot.js. This contains the bootstrap needed to get your
|
96
|
-
modules loading in the browser.
|
97
|
-
|
98
|
-
Finally, to load in the browser, you will need to access your files through a server. You could use Apache or Rails, but spade comes with a built-in preview as well (which currently is just a static file server). Start the
|
99
|
-
preview server with:
|
100
|
-
|
101
|
-
spade preview
|
102
|
-
|
103
|
-
Then visit http://localhost:4020/index.html
|
104
|
-
|
105
|
-
If you open the JavaScript console you should see `Hello World` printed out.
|
106
|
-
|
107
|
-
Note that you can still run main.js from the command line:
|
108
|
-
|
109
|
-
spade lib/main.js
|
110
|
-
|
111
|
-
## From the Console
|
112
|
-
|
113
|
-
Now that you have a package setup you can also easily use the interactive
|
114
|
-
console that comes with spade. When you drop into the console you can load
|
115
|
-
modules from your project onto the command line.
|
116
|
-
|
117
|
-
spade console
|
118
|
-
|
119
|
-
From within the console, load your main hello-world module to see it log:
|
120
|
-
|
121
|
-
require('hello-world/main');
|
122
|
-
|
123
|
-
You should see it log 'Hello World'.
|
124
|
-
|
125
|
-
# Defining Packages
|
126
|
-
|
127
|
-
In addition to creating packages as apps, as we did above. You can also
|
128
|
-
define shared package libraries.
|
129
|
-
|
130
|
-
TODO: Finish this...
|
131
|
-
|
132
|
-
## Ruby Modules
|
133
|
-
|
134
|
-
Drop a ruby file into a package and then you can require it. The Ruby should
|
135
|
-
set the Spade.exports to a new instance of a class to make it into the exports
|
136
|
-
for the class.
|
137
|
-
|
138
|
-
Note that Ruby modules only work when code is run from the command line.
|
139
|
-
|
140
|
-
## Distributing your packages
|
141
|
-
|
142
|
-
Distributing your spade packages is easy, first:
|
143
|
-
|
144
|
-
spade login
|
145
|
-
|
146
|
-
Once you've bundled your package...
|
147
|
-
|
148
|
-
spade push pkg/awesome-0.0.0.spade
|
149
|
-
|
150
|
-
Then it should be available for install with:
|
151
|
-
|
152
|
-
spade install awesome
|
data/Rakefile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
console.log "hello world"
|
@@ -1 +0,0 @@
|
|
1
|
-
This is an example file. It should load as plain text.
|
@@ -1 +0,0 @@
|
|
1
|
-
console.log('hello world');
|
@@ -1 +0,0 @@
|
|
1
|
-
require ('./hello');
|
data/examples/sc-app/index.html
DELETED
data/examples/sc-app/lib/main.js
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require('sproutcore-runtime');
|
2
|
-
require('jquery'); // Override SC's jquery-core
|
3
|
-
|
4
|
-
var testObj = SC.Object.create({
|
5
|
-
|
6
|
-
random: null,
|
7
|
-
|
8
|
-
value: function(){
|
9
|
-
return "Random: "+this.get('random');
|
10
|
-
}.property('random').cacheable(),
|
11
|
-
|
12
|
-
randomize: function(){
|
13
|
-
this.set('random', Math.random());
|
14
|
-
},
|
15
|
-
|
16
|
-
_valueDidChange: function(){
|
17
|
-
$('h1').html(this.get('value'));
|
18
|
-
}.observes('value')
|
19
|
-
|
20
|
-
});
|
21
|
-
|
22
|
-
$(document.body).click(function(){
|
23
|
-
testObj.randomize();
|
24
|
-
});
|
data/examples/single-file.js
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
To run this file just type `spade ./single-file.js`. It should just write
|
3
|
-
out to the console. Note that since this file is not included inside of a
|
4
|
-
package, the only packages available are those installed on the system.
|
5
|
-
|
6
|
-
The ivory package is a set of standardized APIs for accessing the filesystem
|
7
|
-
|
8
|
-
Usage: spade ./single-file.js
|
9
|
-
*/
|
10
|
-
/*globals $fs */
|
11
|
-
|
12
|
-
require('ivory'); // defines $fs and other utils
|
13
|
-
|
14
|
-
var data = $fs.STDIN.read();
|
15
|
-
console.log(data);
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
data/examples/todos/index.html
DELETED
data/examples/todos/lib/main.js
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require('sproutcore-corefoundation');
|
2
|
-
|
3
|
-
// Remove loading text
|
4
|
-
$(document.body).html('');
|
5
|
-
|
6
|
-
// Trigger onReady handler
|
7
|
-
SC.onReady.done();
|
8
|
-
|
9
|
-
require('./todos');
|
10
|
-
require('./~resources/templates/todos');
|
11
|
-
require('./~resources/stylesheets/todos');
|
data/examples/todos/lib/todos.js
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
// ==========================================================================
|
2
|
-
// Project: Todos
|
3
|
-
// Copyright: ©2011 My Company, Inc.
|
4
|
-
// ==========================================================================
|
5
|
-
/*globals Todos */
|
6
|
-
|
7
|
-
Todos = SC.Application.create();
|
8
|
-
|
9
|
-
Todos.Todo = SC.Object.extend({
|
10
|
-
title: null,
|
11
|
-
isDone: false
|
12
|
-
});
|
13
|
-
|
14
|
-
Todos.todoListController = SC.ArrayController.create({
|
15
|
-
content: [],
|
16
|
-
|
17
|
-
createTodo: function(title) {
|
18
|
-
var todo = Todos.Todo.create({ title: title });
|
19
|
-
this.pushObject(todo);
|
20
|
-
},
|
21
|
-
|
22
|
-
remaining: function() {
|
23
|
-
return this.filterProperty('isDone', false).get('length');
|
24
|
-
}.property('@each.isDone'),
|
25
|
-
|
26
|
-
clearCompletedTodos: function() {
|
27
|
-
this.filterProperty('isDone', true).forEach(this.removeObject, this);
|
28
|
-
},
|
29
|
-
|
30
|
-
allAreDone: function(key, value) {
|
31
|
-
if (value !== undefined) {
|
32
|
-
this.setEach('isDone', value);
|
33
|
-
return value;
|
34
|
-
} else {
|
35
|
-
return this.get('length') && this.everyProperty('isDone', true);
|
36
|
-
}
|
37
|
-
}.property('@each.isDone')
|
38
|
-
});
|
39
|
-
|
40
|
-
Todos.CreateTodoView = SC.TemplateView.create(SC.TextFieldSupport, {
|
41
|
-
insertNewline: function() {
|
42
|
-
var value = this.get('value');
|
43
|
-
|
44
|
-
if (value) {
|
45
|
-
Todos.todoListController.createTodo(value);
|
46
|
-
this.set('value', '');
|
47
|
-
}
|
48
|
-
}
|
49
|
-
});
|
50
|
-
|
51
|
-
Todos.clearCompletedView = SC.TemplateView.create({
|
52
|
-
mouseUp: function() {
|
53
|
-
Todos.todoListController.clearCompletedTodos();
|
54
|
-
}
|
55
|
-
});
|
56
|
-
|
57
|
-
Todos.todoListView = SC.TemplateCollectionView.create({
|
58
|
-
contentBinding: 'Todos.todoListController',
|
59
|
-
|
60
|
-
itemView: SC.TemplateView.extend({
|
61
|
-
isDoneDidChange: function() {
|
62
|
-
var isDone = this.getPath('content.isDone');
|
63
|
-
this.$().toggleClass('done', isDone);
|
64
|
-
}.observes('.content.isDone')
|
65
|
-
})
|
66
|
-
});
|
67
|
-
|
68
|
-
Todos.CheckboxView = SC.TemplateView.extend(SC.CheckboxSupport, {
|
69
|
-
valueBinding: '.parentView.content.isDone'
|
70
|
-
});
|
71
|
-
|
72
|
-
Todos.statsView = SC.TemplateView.create({
|
73
|
-
remainingBinding: 'Todos.todoListController.remaining',
|
74
|
-
|
75
|
-
displayRemaining: function() {
|
76
|
-
var remaining = this.get('remaining');
|
77
|
-
|
78
|
-
return remaining + (remaining === 1 ? " item" : " items");
|
79
|
-
}.property('remaining').cacheable()
|
80
|
-
});
|
81
|
-
|
82
|
-
Todos.markAllDoneView = SC.TemplateView.create(SC.CheckboxSupport, {
|
83
|
-
valueBinding: 'Todos.todoListController.allAreDone'
|
84
|
-
});
|
85
|
-
|
86
|
-
jQuery(document).ready(function() {
|
87
|
-
Todos.mainPane = SC.TemplatePane.append({
|
88
|
-
layerId: 'todos',
|
89
|
-
templateName: 'resources/templates/todos'
|
90
|
-
});
|
91
|
-
});
|
92
|
-
|
93
|
-
|
data/examples/todos/package.json
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
@import "compass/css3";
|
2
|
-
|
3
|
-
/* CSS Reset */
|
4
|
-
html, body, div, span, applet, object, iframe,
|
5
|
-
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
6
|
-
a, abbr, acronym, address, big, cite, code,
|
7
|
-
del, dfn, em, img, ins, kbd, q, s, samp,
|
8
|
-
small, strike, strong, sub, sup, tt, var,
|
9
|
-
b, u, i, center,
|
10
|
-
dl, dt, dd, ol, ul, li,
|
11
|
-
fieldset, form, label, legend,
|
12
|
-
table, caption, tbody, tfoot, thead, tr, th, td,
|
13
|
-
article, aside, canvas, details, embed,
|
14
|
-
figure, figcaption, footer, header, hgroup,
|
15
|
-
menu, nav, output, ruby, section, summary,
|
16
|
-
time, mark, audio, video {
|
17
|
-
margin: 0;
|
18
|
-
padding: 0;
|
19
|
-
border: 0;
|
20
|
-
font-size: 100%;
|
21
|
-
font: inherit;
|
22
|
-
vertical-align: baseline;
|
23
|
-
}
|
24
|
-
/* HTML5 display-role reset for older browsers */
|
25
|
-
article, aside, details, figcaption, figure,
|
26
|
-
footer, header, hgroup, menu, nav, section {
|
27
|
-
display: block;
|
28
|
-
}
|
29
|
-
body {
|
30
|
-
line-height: 1;
|
31
|
-
}
|
32
|
-
ol, ul {
|
33
|
-
list-style: none;
|
34
|
-
}
|
35
|
-
blockquote, q {
|
36
|
-
quotes: none;
|
37
|
-
}
|
38
|
-
blockquote:before, blockquote:after,
|
39
|
-
q:before, q:after {
|
40
|
-
content: '';
|
41
|
-
content: none;
|
42
|
-
}
|
43
|
-
table {
|
44
|
-
border-collapse: collapse;
|
45
|
-
border-spacing: 0;
|
46
|
-
}
|
47
|
-
|
48
|
-
/* App CSS */
|
49
|
-
body, html {
|
50
|
-
color: #777;
|
51
|
-
background-color: #F2F4F5;
|
52
|
-
}
|
53
|
-
|
54
|
-
.sc-view {
|
55
|
-
position: relative;
|
56
|
-
overflow: visible;
|
57
|
-
}
|
58
|
-
|
59
|
-
$width: 600px;
|
60
|
-
$border: 1px solid #bbb;
|
61
|
-
|
62
|
-
#todos {
|
63
|
-
@include box-shadow(rgba(0,0,0,0.6), 0, 0, 1px);
|
64
|
-
@include border-radius(8px);
|
65
|
-
|
66
|
-
$padding: 10px;
|
67
|
-
$header-height: 20px;
|
68
|
-
|
69
|
-
position: absolute;
|
70
|
-
width: 600px;
|
71
|
-
left: 50%;
|
72
|
-
margin-top: 38px;
|
73
|
-
border: $border;
|
74
|
-
margin-left: -300px;
|
75
|
-
background-color: #fff;
|
76
|
-
padding: ($header-height + $padding * 2) $padding $padding;
|
77
|
-
|
78
|
-
div.remaining {
|
79
|
-
overflow: hidden;
|
80
|
-
width: 100%;
|
81
|
-
padding: 5px $padding;
|
82
|
-
margin: $padding ($padding * -1);
|
83
|
-
background-color: #eee;
|
84
|
-
border-top: 1px solid #aaa;
|
85
|
-
border-bottom: 1px solid #aaa;
|
86
|
-
line-height: 25px;
|
87
|
-
|
88
|
-
button {
|
89
|
-
float: right;
|
90
|
-
padding: 5px;
|
91
|
-
}
|
92
|
-
}
|
93
|
-
|
94
|
-
input[type='text'] {
|
95
|
-
@include border-radius(5px);
|
96
|
-
@include box-shadow(rgba(0,0,0,0.6), 0, 0, 10px, -2px);
|
97
|
-
color: #999;
|
98
|
-
background-color: rgb(240,240,240);
|
99
|
-
width: $width - ($padding) - 2px;
|
100
|
-
font-size: 30px;
|
101
|
-
font-family: Helvetica, sans-serif;
|
102
|
-
padding: 5px;
|
103
|
-
border: $border;
|
104
|
-
font-weight: 500;
|
105
|
-
|
106
|
-
&::-webkit-input-placeholder {
|
107
|
-
color: #aaa;
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
h1 {
|
112
|
-
@include border-top-radius(8px);
|
113
|
-
@include linear-gradient(color-stops(white, rgb(244,244,244) 49%, rgb(237,237,237) 51%, #dedede));
|
114
|
-
@include text-shadow(white, 0, 1px, 1px);
|
115
|
-
|
116
|
-
font-size: 15px;
|
117
|
-
position: absolute;
|
118
|
-
width: $width;
|
119
|
-
height: $header-height;
|
120
|
-
color: rgb(83,86,94);
|
121
|
-
top: 0;
|
122
|
-
left: 0;
|
123
|
-
padding: ($padding / 2) $padding;
|
124
|
-
border-bottom: $border;
|
125
|
-
}
|
126
|
-
|
127
|
-
label {
|
128
|
-
font-size: 15px;
|
129
|
-
|
130
|
-
input {
|
131
|
-
margin-top: 6px;
|
132
|
-
margin-right: 5px;
|
133
|
-
float: left;
|
134
|
-
}
|
135
|
-
}
|
136
|
-
|
137
|
-
label.done-label {
|
138
|
-
margin-left: 6px;
|
139
|
-
display: block;
|
140
|
-
margin-top: 10px;
|
141
|
-
font-weight: bold;
|
142
|
-
}
|
143
|
-
|
144
|
-
input[type=checkbox] {
|
145
|
-
float: left;
|
146
|
-
margin-top: 5px;
|
147
|
-
margin-right: 7px;
|
148
|
-
}
|
149
|
-
|
150
|
-
ul {
|
151
|
-
margin-left: 6px;
|
152
|
-
li {
|
153
|
-
margin-bottom: 5px;
|
154
|
-
}
|
155
|
-
|
156
|
-
li.done {
|
157
|
-
text-decoration: line-through;
|
158
|
-
}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
|
162
|
-
|