grat 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. data/README.rdoc +3 -3
  2. data/VERSION +1 -1
  3. data/grat.gemspec +21 -3
  4. data/lib/grat.rb +66 -3
  5. data/lib/grat/content.rb +18 -1
  6. data/public/gratfiles/application.js +24 -22
  7. data/public/gratfiles/custom.css +59 -2
  8. data/public/gratfiles/custom2.css +280 -0
  9. data/public/gratfiles/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  10. data/public/gratfiles/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  11. data/public/gratfiles/images/ui-bg_flat_10_000000_40x100.png +0 -0
  12. data/public/gratfiles/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  13. data/public/gratfiles/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  14. data/public/gratfiles/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  15. data/public/gratfiles/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  16. data/public/gratfiles/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  17. data/public/gratfiles/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  18. data/public/gratfiles/images/ui-icons_222222_256x240.png +0 -0
  19. data/public/gratfiles/images/ui-icons_228ef1_256x240.png +0 -0
  20. data/public/gratfiles/images/ui-icons_ef8c08_256x240.png +0 -0
  21. data/public/gratfiles/images/ui-icons_ffd27a_256x240.png +0 -0
  22. data/public/gratfiles/images/ui-icons_ffffff_256x240.png +0 -0
  23. data/public/gratfiles/jquery-combined.min.js +289 -2
  24. data/public/gratfiles/jquery-ui.css +406 -0
  25. data/public/gratfiles/reset.css +52 -0
  26. data/views/content_form.haml +48 -48
  27. data/views/import_form.haml +1 -3
  28. data/views/layout.haml +15 -6
  29. data/views/list.haml +19 -18
  30. data/views/page_list.haml +19 -0
  31. metadata +20 -2
@@ -25,13 +25,13 @@ Use it like so:
25
25
  4. rackup (or passenger, if you know how)
26
26
 
27
27
  5. http://localhost:9292/__admin/edit/mypage edits a page that will be available at http://localhost:9292/mypage
28
- 6. http://localhost:9292/__admin/all for a list of all pages
28
+ 6. http://localhost:9292/__admin/ for a list of all pages
29
29
  7. http://localhost:9292/__admin/export to get a json dump of all pages
30
30
  8. http://localhost:9292/__admin/import to import one of those dumps
31
31
 
32
32
  9. Protect from writes by strangers with Rack::If
33
33
  # http://github.com/samsm/Rackif
34
-
34
+
35
35
  use Rack::If, {:method => /(POST)|(PUT)|(DELETE)/, :path => /__admin/}, :any do
36
36
  use Rack::Auth::Basic, "Grat protected" do |username, password|
37
37
  'secret' == password
@@ -40,7 +40,7 @@ Use it like so:
40
40
 
41
41
 
42
42
  == Note on Patches/Pull Requests
43
-
43
+
44
44
  * Fork the project.
45
45
  * Make your feature addition or bug fix.
46
46
  * Add tests for it. This is important so I don't break it in a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{grat}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Sam Schenkman-Moore"]
12
- s.date = %q{2010-01-12}
12
+ s.date = %q{2010-01-17}
13
13
  s.description = %q{Basic interface for making webpages with Haml and Erb. Supports nested templates.}
14
14
  s.email = %q{samsm@samsm.com}
15
15
  s.extra_rdoc_files = [
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
38
38
  "lib/grat/system.rb",
39
39
  "public/gratfiles/application.js",
40
40
  "public/gratfiles/custom.css",
41
+ "public/gratfiles/custom2.css",
41
42
  "public/gratfiles/einars-js-beautify/HTML-Beautify.js",
42
43
  "public/gratfiles/einars-js-beautify/beautify-cl.js",
43
44
  "public/gratfiles/einars-js-beautify/beautify-tests.js",
@@ -52,7 +53,22 @@ Gem::Specification.new do |s|
52
53
  "public/gratfiles/einars-js-beautify/unmaintained/opera-userscript/make_opera_userscript.sh",
53
54
  "public/gratfiles/einars-js-beautify/unmaintained/opera-userscript/opera_userscript.js",
54
55
  "public/gratfiles/favicon.ico",
56
+ "public/gratfiles/images/ui-bg_diagonals-thick_18_b81900_40x40.png",
57
+ "public/gratfiles/images/ui-bg_diagonals-thick_20_666666_40x40.png",
58
+ "public/gratfiles/images/ui-bg_flat_10_000000_40x100.png",
59
+ "public/gratfiles/images/ui-bg_glass_100_f6f6f6_1x400.png",
60
+ "public/gratfiles/images/ui-bg_glass_100_fdf5ce_1x400.png",
61
+ "public/gratfiles/images/ui-bg_glass_65_ffffff_1x400.png",
62
+ "public/gratfiles/images/ui-bg_gloss-wave_35_f6a828_500x100.png",
63
+ "public/gratfiles/images/ui-bg_highlight-soft_100_eeeeee_1x100.png",
64
+ "public/gratfiles/images/ui-bg_highlight-soft_75_ffe45c_1x100.png",
65
+ "public/gratfiles/images/ui-icons_222222_256x240.png",
66
+ "public/gratfiles/images/ui-icons_228ef1_256x240.png",
67
+ "public/gratfiles/images/ui-icons_ef8c08_256x240.png",
68
+ "public/gratfiles/images/ui-icons_ffd27a_256x240.png",
69
+ "public/gratfiles/images/ui-icons_ffffff_256x240.png",
55
70
  "public/gratfiles/jquery-combined.min.js",
71
+ "public/gratfiles/jquery-ui.css",
56
72
  "public/gratfiles/js-beautifier.min.js",
57
73
  "public/gratfiles/oocss.min.css",
58
74
  "public/gratfiles/oocss/content.css",
@@ -66,6 +82,7 @@ Gem::Specification.new do |s|
66
82
  "public/gratfiles/oocss/talk_skins.css",
67
83
  "public/gratfiles/oocss/template.css",
68
84
  "public/gratfiles/oocss/template_debug.css",
85
+ "public/gratfiles/reset.css",
69
86
  "views/content_form.haml",
70
87
  "views/css/_content.sass",
71
88
  "views/css/_custom.sass",
@@ -81,7 +98,8 @@ Gem::Specification.new do |s|
81
98
  "views/import_form.haml",
82
99
  "views/layout.haml",
83
100
  "views/list.haml",
84
- "views/missing.haml"
101
+ "views/missing.haml",
102
+ "views/page_list.haml"
85
103
  ]
86
104
  s.homepage = %q{http://github.com/samsm/grat}
87
105
  s.rdoc_options = ["--charset=UTF-8"]
@@ -19,8 +19,8 @@ class Grat::Application < Sinatra::Base
19
19
  file_data
20
20
  end
21
21
 
22
- get '/__admin/all' do
23
- @pages = model.all
22
+ get '/__admin/' do
23
+ pages
24
24
  @templates = templates
25
25
  haml :list
26
26
  end
@@ -39,7 +39,7 @@ class Grat::Application < Sinatra::Base
39
39
  post '/__admin/import' do
40
40
  json_text = file_import_text || params[:import][:text]
41
41
  @import_results = import(json_text, params[:import][:strategy])
42
- redirect '/__admin/all'
42
+ redirect '/__admin/'
43
43
  end
44
44
 
45
45
  # Rather inefficient at present.
@@ -77,6 +77,7 @@ class Grat::Application < Sinatra::Base
77
77
  end
78
78
 
79
79
  get '/__admin/edit/*' do
80
+ @page_heading_text = "Editing: <a href='#{url}'>#{url}</a>"
80
81
  haml :content_form
81
82
  end
82
83
 
@@ -185,6 +186,68 @@ class Grat::Application < Sinatra::Base
185
186
  def form_nest(name)
186
187
  "content[#{name}]"
187
188
  end
189
+
190
+ # The next few methods build the tree for the file list
191
+ # This can likely be greatly simpified and more efficient.
192
+ def peel(pages, start)
193
+ pages.each do |page|
194
+ if under?(start,page)
195
+ if immediate_child?(start,page)
196
+ start.children << page
197
+ else
198
+ # Skip if already done
199
+ unless start.children.detect {|ec| ec.url == next_dir(start,page) }
200
+ ec = Grat::EmptyContent.new(next_dir(start,page))
201
+ peel(pages,ec)
202
+ unless start.children.detect {|c| c.url == ec.url }
203
+ start.children << ec
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ def under?(start,other)
212
+ other.url.index(start.url) == 0 && other.url != start.url
213
+ end
214
+
215
+ def next_dir(start,other)
216
+ other.url.match(/#{start.url}?[^\/]+\//)[0]
217
+ end
218
+
219
+ def immediate_child?(start,other)
220
+ !url_difference(start,other).index('/')
221
+ end
222
+
223
+ def url_difference(start,other)
224
+ other.url.sub(/#{start.url}/, '')
225
+ end
226
+
227
+ def recursive_url_list(page)
228
+ puts page.url
229
+ page.children.each { |c| recursive_url_list(c) }
230
+ end
231
+
232
+ # only works if there's a url '/'
233
+ def nested_root
234
+ sorted_pages = pages.sort_by {|p| p.url }
235
+ first = sorted_pages.first
236
+ peel(sorted_pages, first)
237
+ first
238
+ end
239
+
240
+ def pages
241
+ @pages ||= model.all
242
+ end
243
+
244
+ def nested_root_list
245
+ to_list([nested_root])
246
+ end
247
+
248
+ def page_heading_text
249
+ @page_heading_text or 'Unnamed page.'
250
+ end
188
251
  end
189
252
 
190
253
  end
@@ -118,4 +118,21 @@ class Grat::Content
118
118
  def suggested_fields
119
119
  @suggested_fields or []
120
120
  end
121
- end
121
+
122
+ def children
123
+ @children ||= []
124
+ end
125
+
126
+ end
127
+
128
+ class Grat::EmptyContent
129
+ attr_accessor :url
130
+ def initialize(url)
131
+ self.url = url
132
+ end
133
+
134
+ def children
135
+ @children ||= []
136
+ end
137
+
138
+ end
@@ -1,6 +1,6 @@
1
1
  // once page is loaded ...
2
2
  $(document).ready(function(){
3
-
3
+
4
4
  // Collapse fields
5
5
  $('.collapsable').each(function() {
6
6
  parent_div = $(this);
@@ -19,7 +19,7 @@ $(document).ready(function(){
19
19
  parent_div.addClass('activeCollapse');
20
20
  }
21
21
  })
22
-
22
+
23
23
  // Add fields for selected template.
24
24
  $('.template select').change(function() {
25
25
  // if template has url
@@ -37,26 +37,26 @@ $(document).ready(function(){
37
37
  })
38
38
  }
39
39
  })
40
-
40
+
41
41
  // New field button + features
42
42
  $('a[href=#new_field]').click(function(){
43
-
43
+
44
44
  $('#new_fields').prepend("<div class='new_field'><p class='myEditableText sameaslabel'>Write the title here</p><input name='content[new_field]' value='' /></div>");
45
-
45
+
46
46
  // upon click make label editable and other junk associated with customizing the new field
47
47
  $('.myEditableText').click(function(){
48
48
  editable = $(this);
49
-
49
+
50
50
  editable.attr('contentEditable',true);
51
51
  editable.addClass('editing'); // style for editing
52
52
  editable.focus(); // put cursor in element
53
-
53
+
54
54
  // this should only clear if default text is in there
55
55
  if (!editable[0].className.match(/edited/)) {
56
56
  editable.text(''); // clear text
57
57
  editable.addClass('edited')
58
58
  }
59
-
59
+
60
60
  // On focus of input, change name= to correspond to p sibling
61
61
  editable.parent().children().filter('input').focus(function() {
62
62
  input = $(this);
@@ -64,19 +64,19 @@ $(document).ready(function(){
64
64
  // need to sanitize key
65
65
  sanitized_key = key.replace(/[^a-zA-Z]/g,'_').toLowerCase().replace(/[^a-z]/,'').toLowerCase()
66
66
  new_name = 'content[' + sanitized_key + ']';
67
-
67
+
68
68
  input.attr('name',new_name);
69
69
  })
70
-
70
+
71
71
  // Move to input field on enter
72
72
  editable.keypress(function(event){
73
-
73
+
74
74
  // move to field input is cancelled if enter is pressed
75
75
  if (event.which == 13) {
76
-
76
+
77
77
  // Remove editing class -- should add edited class maybe
78
78
  editable.removeClass('editing');
79
-
79
+
80
80
  // forward to text input
81
81
  $(editable).parent().children().filter('input').focus();
82
82
  return false
@@ -84,28 +84,30 @@ $(document).ready(function(){
84
84
  return event.which
85
85
  }
86
86
  });
87
-
87
+
88
88
  editable.change(function() {
89
89
  console.log('blur');
90
90
  editable.removeClass('editing');
91
91
  })
92
-
92
+
93
93
  });
94
-
94
+
95
95
  // bind an event listener that will be called when
96
96
  // user saves changed content
97
97
  $('.editableText').change(function(){
98
98
  var newValue = $(this).html();
99
99
  });
100
-
101
-
102
-
100
+
101
+
102
+
103
103
  return false;
104
104
  })
105
-
105
+
106
106
  // Beautify default data textarea
107
107
  $('#default_content_vars').each(function() {
108
108
  this.innerHTML = js_beautify(this.innerHTML, {'indent_size':2});
109
- })
110
-
109
+ });
110
+
111
+ $('.tabs').tabs();
112
+
111
113
  });
@@ -1,4 +1,4 @@
1
- /* @override
1
+ /* @override
2
2
  http://localhost:9393/custom.css
3
3
  http://grat.local/css/custom.css
4
4
  http://localhost:9393/gratfiles/custom.css
@@ -80,4 +80,61 @@ a.collapse {
80
80
  }
81
81
  .expander, .collapser {
82
82
  margin-left: 1em;
83
- }
83
+ }
84
+
85
+ .pages {
86
+ background-color: #573515;
87
+ color: whitesmoke;
88
+ border-bottom: solid black;
89
+ -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1);
90
+ -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1);
91
+ box-shadow: 0 1px 10px rgba(0,0,0,.1);
92
+ font-weight: normal;
93
+ font-style: normal;
94
+ font-family: "Lucida Grande", Lucida, Verdana, sans-serif;
95
+ padding: 1em;
96
+ }
97
+
98
+ .pages a.emptycontent {
99
+ color: #b6ff48;
100
+ }
101
+ .pages .missing_message {
102
+ font-size: .75em;
103
+ visibility: hidden;
104
+ }
105
+
106
+ .pages a {
107
+ color: white;
108
+ }
109
+
110
+ .pages li {
111
+ margin: 0;
112
+ margin-bottom: 0.5em;
113
+ padding-left: 1em;
114
+ border-top: solid 1px rgba(250,250,250,.3);
115
+ }
116
+ .pages ol {
117
+ padding: 0;
118
+ padding-top: 0.25em;
119
+ padding-bottom: 0;
120
+ padding-left: 0;
121
+ }
122
+
123
+ .tags, .template, .created {
124
+ margin-left: 2em;
125
+ float: right;
126
+ }
127
+
128
+
129
+ /*.pages ol:before {
130
+ content: "collapse";
131
+ }*/
132
+
133
+
134
+
135
+ /*.pages li:nth-child(odd) {
136
+ background-color: #86B486;
137
+ }
138
+ .pages li:nth-child(even) {
139
+ background-color: red;
140
+ }*/
@@ -0,0 +1,280 @@
1
+ /* @override http://localhost:9393/gratfiles/custom2.css */
2
+
3
+ /*
4
+ rgba(114,123,127,1) // medium grey
5
+ rgba(204,234,234,1) // very light blue
6
+ rgba(122,117,86,1) // medium brown
7
+ rgba(46,33,37,1) // dark brown
8
+ rgba(68,202,204,1) // bright blue
9
+
10
+
11
+ rgba(255,255,255,1) // white
12
+ rgba(0,0,0,1) // black
13
+ */
14
+ body {
15
+ font: normal 62.5% helvetica, arial, sans-serif;
16
+ background-color: rgba(204,234,234,1);
17
+ color: rgba(0,0,0,.8);
18
+ }
19
+
20
+ .container {
21
+ /*margin-left: 10em;*/
22
+ }
23
+
24
+ .mod:after {
25
+ content: ".";
26
+ display: block;
27
+ height: 0;
28
+ clear: both;
29
+ visibility: hidden;
30
+ }
31
+
32
+
33
+ .masthead {
34
+ background-color: rgba(46,33,37,1);
35
+ padding: 1em;
36
+ height: 4em;
37
+ }
38
+
39
+ .masthead h1, .masthead h2 {
40
+ text-shadow: 1px 1px 1px rgba(68,202,204,.4);
41
+ color: rgba(204,234,234,1);
42
+ }
43
+
44
+ .masthead h1 {
45
+ font-size: 4em;
46
+ float: left;
47
+ }
48
+ .masthead h2 {
49
+ margin-top: 1em;
50
+ font-size: 2em;
51
+ float: right;
52
+ }
53
+ .masthead h2 a, .masthead h1 a {
54
+ color: inherit;
55
+ }
56
+ .masthead h1 a {
57
+ text-decoration: none;
58
+ }
59
+
60
+ .panel {
61
+ margin: 0 auto;
62
+ width: 30em;
63
+ background-color: rgba(255,255,255,1);
64
+ padding: 1em;
65
+ padding-top: 2em;
66
+ float: left;
67
+
68
+ border-right: 2px solid rgba(114,123,127,1);
69
+ margin-bottom: 2em;
70
+ -webkit-box-shadow: 0 1px 5px rgba(114,123,127,.5);
71
+ -moz-box-shadow: 0 1px 5px rgba(114,123,127,.5);
72
+ box-shadow: 0 1px 5px rgba(114,123,127,.5);
73
+
74
+ margin-right: 2.2em;
75
+
76
+ /* Make column go to bottom of screen */
77
+ margin-bottom: -1000px;
78
+ padding-bottom: 1000px;
79
+ }
80
+ .panel h2 {
81
+ font-size: 2em;
82
+ color: rgba(46,33,37,1);
83
+ text-shadow: 2px 2px 2px rgba(114,123,127,.4);
84
+ }
85
+
86
+ .pages {
87
+ float: left;
88
+ }
89
+ .pages li {
90
+ margin-left: 1em;
91
+ margin-top: 1em;
92
+ }
93
+
94
+ /* form stuffs */
95
+ .container {
96
+ margin-top: 1em;
97
+ margin-left: 17em;
98
+ width: 40em;
99
+ font-size: 2em;
100
+ }
101
+
102
+ input, textarea, label, .sameaslabel {
103
+ display: block;
104
+ width: 99%;
105
+ }
106
+
107
+ .sameaslabel, label {
108
+ margin-top: .5em;
109
+ }
110
+
111
+ textarea {
112
+ font-family: "Courier New", Courier, mono;
113
+ font-weight: bold;
114
+ height: 13em;
115
+ }
116
+ .sameaslabel {
117
+ padding-left: 0; // no padding like p has
118
+ }
119
+
120
+ .submit input {
121
+ width: auto;
122
+ }
123
+
124
+
125
+ p.editing {
126
+ min-height: 1em;
127
+ background-color: yellow;
128
+ }
129
+
130
+ input[type=file] {
131
+ padding-top: .5em;
132
+ font-size: 1.5em;
133
+ }
134
+
135
+ input[type=radio] {
136
+ width: 1em;
137
+ float: left;
138
+ margin-top: .25em;
139
+ }
140
+
141
+ input {
142
+ width: 33%;
143
+ }
144
+ input[type=submit] {
145
+ width: auto;
146
+ display: inline;
147
+ }
148
+
149
+ a.collapse {
150
+ font-size: .5em;
151
+ font-weight: normal;
152
+ }
153
+
154
+ .activeCollapse textarea {
155
+ display: none;
156
+ }
157
+
158
+ .activeCollapse .collapser {
159
+ display:none;
160
+ }
161
+
162
+ a.button {
163
+ color: rgba(68,202,204,1);
164
+ padding: .5em;
165
+ -moz-border-radius: 1em;
166
+ -webkit-border-radius: 1em;
167
+ border-radius: 1em;
168
+
169
+ background-color: rgba(46,33,37,1);
170
+ text-decoration: none;
171
+
172
+ -webkit-box-shadow: 0 1px 5px rgba(122,117,86,.5);
173
+ -moz-box-shadow: 0 1px 5px rgba(122,117,86,.5);
174
+ box-shadow: 0 1px 5px rgba(122,117,86,.5);
175
+ }
176
+ #new_fields p {
177
+ margin-top: 1em;
178
+ }
179
+ .expander {
180
+ display: none;
181
+ float: left;
182
+ }
183
+ .collapser {
184
+ float: right;
185
+ margin-top: -1.5em;
186
+ margin-right: 1em;
187
+ }
188
+ .activeCollapse .expander {
189
+ display: inline;
190
+ }
191
+ .expander, .collapser {
192
+ font-size: .65em;
193
+ font-weight: normal;
194
+ color: rgba(68,202,204,1);
195
+ text-decoration: none;
196
+ }
197
+
198
+ /* JQuery UI Tabs tweaks */
199
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
200
+ .ui-tabs .ui-tabs-hide { display: none !important; }
201
+
202
+ .tabs ul.mod {
203
+ height: 1.8em;
204
+ }
205
+ .tabs li {
206
+ float: right;
207
+ background-color: rgba(46,33,37,1);
208
+ border: solid 2px rgba(46,33,37,1);
209
+ margin-right: .5em;
210
+ padding: 1em;
211
+ padding-bottom: .5em;
212
+
213
+ border-bottom: 0;
214
+ -moz-border-radius-topleft: 1.5em;
215
+ -webkit-border-top-left-radius: 1.5em;
216
+
217
+ -moz-border-radius-topright: .5em;
218
+ -webkit-border-top-right-radius: .5em;
219
+ /*border-radius: .5em;*/
220
+
221
+ font-size: .65em;
222
+
223
+
224
+ /*-webkit-box-shadow: 0 1px 5px rgba(114,123,127,.5);
225
+ -moz-box-shadow: 0 1px 5px rgba(114,123,127,.5);
226
+ box-shadow: 0 1px 5px rgba(114,123,127,.5);*/
227
+ /*letter-spacing: 0em;*/
228
+ }
229
+ .tabs li.ui-tabs-selected {
230
+ background-color: rgba(122,117,86,1);
231
+ border-bottom: solid 3px rgba(122,117,86,1);
232
+ }
233
+ .tabs li a {
234
+ color: rgba(68,202,204,1);
235
+ text-decoration: none;
236
+ }
237
+ #basics, #data, #history {
238
+ border-top: solid 2px;
239
+ border-left: dotted 1px rgba(46,33,37,.5);
240
+ border-right: dotted 1px rgba(46,33,37,.5);
241
+ background-color: rgba(122,117,86,1);
242
+ padding: 1em;
243
+ }
244
+
245
+ /* Radio buttons on import */
246
+ .import_replace_or_add input {
247
+ float: left;
248
+ margin-top: .5em;
249
+ display: inline;
250
+ }
251
+ .import_replace_or_add label {
252
+ margin-left: .5em;
253
+ display: inline;
254
+ }
255
+ .import_replace_or_add div {
256
+ margin-top: .5em;
257
+ }
258
+
259
+ .bulk-options li {
260
+ margin-bottom: 2em;
261
+ }
262
+ .new_page {
263
+ margin-bottom: .5em;
264
+ }
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+