serif 0.0.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,539 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <meta charset="UTF-8">
4
+ <head>
5
+ <title>Admin</title>
6
+
7
+ <style>
8
+ body {
9
+ width: 40%;
10
+ margin: 0 auto;
11
+ padding-top: 0;
12
+ }
13
+
14
+ body > nav {
15
+ text-align: center;
16
+ opacity: 0.5;
17
+ margin-bottom: 2em;
18
+ -webkit-transition: 0.2s;
19
+ -moz-transition: 0.2s;
20
+ -o-transition: 0.2s;
21
+ transition: 0.2s;
22
+ }
23
+
24
+ body > nav.hidden {
25
+ opacity: 0;
26
+ }
27
+
28
+ body > nav ul {
29
+ margin-left: 0;
30
+ margin-right: 0;
31
+ }
32
+
33
+ body > nav ul li {
34
+ display: inline;
35
+ }
36
+
37
+ body > nav ul li:last-child {
38
+ margin-left: 1em;
39
+ }
40
+
41
+ #edit input[disabled] {
42
+ color: inherit;
43
+ background: none;
44
+ }
45
+
46
+ #edit #slug {
47
+ color: #aaaaaa;
48
+ text-transform: lowercase;
49
+ margin-bottom: 0;
50
+ }
51
+
52
+ /* get the input to use up whatever remaining space there is using overflow: hidden; */
53
+
54
+ #edit #slug span:first-child {
55
+ float: left;
56
+ padding: 0.15em 0;
57
+ }
58
+
59
+ #edit #slug span:last-child {
60
+ overflow: hidden;
61
+ display: block;
62
+ padding: 0.15em 0; /* same padding as above, to force vertical alignment */
63
+ }
64
+
65
+ #edit #slug input {
66
+ font: inherit;
67
+ border: none;
68
+ outline: none;
69
+ width: 100%;
70
+ text-shadow: inherit;
71
+ -o-box-sizing: border-box;
72
+ -moz-box-sizing: border-box;
73
+ -webkit-box-sizing: border-box;
74
+ box-sizing: border-box;
75
+ margin: 0;
76
+ padding: 0;
77
+ }
78
+
79
+ #edit #content {
80
+ width: 100%;
81
+ max-width: 100%;
82
+ display: block;
83
+ min-height: 20em;
84
+ margin: 0 auto;
85
+ font-size: inherit;
86
+ font-family: inherit;
87
+ outline: none;
88
+ border: none;
89
+ padding: 1em;
90
+ margin-left: -1em;
91
+ color: inherit;
92
+ text-rendering: inherit;
93
+ resize: none;
94
+ }
95
+
96
+ #edit #content::-webkit-scrollbar {
97
+ width: 0.5em;
98
+ }
99
+
100
+ #edit #content::-webkit-scrollbar-track {
101
+ border-radius: 4px;
102
+ background: rgba(0,0,0,0.05);
103
+ }
104
+
105
+ #edit #content::-webkit-scrollbar-thumb {
106
+ border-radius: 4px;
107
+ background: rgba(0,0,0,0.2);
108
+ }
109
+
110
+ #edit #heading textarea {
111
+ -webkit-appearance: none;
112
+ font-family: inherit;
113
+ color: inherit;
114
+ text-rendering: inherit;
115
+ font-size: inherit;
116
+ width: 100%;
117
+ display: block;
118
+ text-align: inherit;
119
+ outline: none;
120
+ border: none;
121
+ resize: none;
122
+ height: 1.2em;
123
+ }
124
+
125
+ #edit {
126
+ position: relative;
127
+ }
128
+
129
+ #edit > form {
130
+ position: relative;
131
+ }
132
+
133
+ #edit #save {
134
+ margin: 0;
135
+ }
136
+
137
+ #edit #save,
138
+ #edit #delete input,
139
+ #edit #delete input + label,
140
+ #edit #publish + label,
141
+ #render-preview + label {
142
+ width: 6em;
143
+ padding: 0.5em 1em;
144
+ text-align: center;
145
+
146
+ /* webkit defines box-sizing: border-box; as a UA style by default,
147
+ meaning the width is of the final computed element with padding
148
+ and border. */
149
+ -webkit-box-sizing: content-box;
150
+ -moz-box-sizing: content-box;
151
+ -o-box-sizing: content-box;
152
+ box-sizing: content-box;
153
+ }
154
+
155
+ #render-preview,
156
+ #edit #publish,
157
+ #edit #delete #confirm-delete {
158
+ display: none;
159
+ }
160
+
161
+ #render-preview + label,
162
+ #edit #publish + label {
163
+ font-family: inherit;
164
+ background: #191919;
165
+ color: white;
166
+ padding: 0.5em 1em;
167
+ border-radius: 0.2em;
168
+ cursor: pointer;
169
+ display: inline-block;
170
+ }
171
+
172
+ #render-preview + label {
173
+ opacity: 0.5;
174
+ }
175
+
176
+ #render-preview + label.active {
177
+ opacity: 1.0;
178
+ }
179
+
180
+ #edit #content-areas {
181
+ position: relative;
182
+ min-height: 20em;
183
+ }
184
+
185
+ #edit #entry {
186
+ display: none;
187
+ width: 100%;
188
+ max-width: 100%;
189
+ min-height: 20em;
190
+ border: none;
191
+ padding: 1em;
192
+ margin-left: -1em;
193
+ }
194
+
195
+ #edit #writers-block {
196
+ color: grey;
197
+ }
198
+
199
+ #edit #save,
200
+ #edit #delete input,
201
+ #edit #delete input + label {
202
+ display: inline-block;
203
+ border: none;
204
+ font-size: inherit;
205
+ font-family: inherit;
206
+ background: #191919;
207
+ color: white;
208
+ border-radius: 0.2em;
209
+ cursor: pointer;
210
+ }
211
+
212
+ #edit #save:hover {
213
+ background: rgba(0, 0, 255, 0.5);
214
+ }
215
+
216
+ #edit #slug input::-webkit-input-placeholder,
217
+ #edit #heading textarea::-webkit-input-placeholder {
218
+ color: #191919;
219
+ opacity: 0.4;
220
+ }
221
+
222
+ #edit #slug input:focus::-webkit-input-placeholder,
223
+ #edit #heading textarea:focus::-webkit-input-placeholder {
224
+ color: #bbbbbb;
225
+ opacity: 1.0;
226
+ }
227
+
228
+ #error-message {
229
+ padding: 1em 0;
230
+ }
231
+
232
+ #error-message p {
233
+ font-size: 1em;
234
+ font-style: italic;
235
+ }
236
+
237
+ #error-message p:before {
238
+ content: "\26a0";
239
+ display: block;
240
+ float: left;
241
+ margin-left: -2em;
242
+ width: 2em;
243
+ color: #9B111E;
244
+ font-style: normal;
245
+ }
246
+
247
+ #edit .error {
248
+ color: #9B111E;
249
+ font-style: italic;
250
+ font-weight: bold;
251
+ border-bottom: 1px solid red !important;
252
+ }
253
+
254
+ #shortcuts {
255
+ display: none;
256
+ position: fixed;
257
+ top: 5%;
258
+ left: 5%;
259
+ width: 90%;
260
+ height: 90%;
261
+ background: rgba(25, 25, 25, 0.9);
262
+ color: white;
263
+ z-index: 50;
264
+ border-radius: 0.5em;
265
+ }
266
+
267
+ #shortcuts table {
268
+ margin: 10% auto;
269
+ height: 80%;
270
+ }
271
+
272
+ #shortcuts table td {
273
+ display: inline-block;
274
+ width: 40%;
275
+ }
276
+
277
+ #shortcuts table td:first-child {
278
+ text-align: right;
279
+ padding-right: 1em;
280
+ }
281
+
282
+ #shortcuts table td:last-child {
283
+ padding-left: 1em;
284
+ text-align: left;
285
+ }
286
+
287
+ #edit #publish + label {
288
+ position: absolute;
289
+ bottom: 0;
290
+ right: 0;
291
+ background: #A72525;
292
+ }
293
+
294
+ #edit #publish + label:after {
295
+ content: "\2715";
296
+ margin-left: 1em;
297
+ }
298
+
299
+ #edit #publish:checked + label {
300
+ background: #2ED149;
301
+ color: black;
302
+ }
303
+
304
+ #edit #publish:checked + label:after {
305
+ content: "\2713";
306
+ }
307
+
308
+ #edit #delete {
309
+ position: absolute;
310
+ bottom: 0;
311
+
312
+ /* 6em for the publish button width + 2 * 1em left/right padding + 0.25em for space */
313
+ right: 8.25em;
314
+ }
315
+
316
+ #edit #delete input[type=submit] {
317
+ margin: 0;
318
+ }
319
+
320
+ #edit #delete #confirm-delete + label {
321
+ display: none;
322
+ position: absolute;
323
+ right: 0;
324
+ top: -2.5em;
325
+ background: red;
326
+ color: black;
327
+ }
328
+
329
+ #edit #delete #confirm-delete:checked + label {
330
+ background: #2ED149;
331
+ color: black;
332
+ }
333
+ </style>
334
+
335
+ <link rel="stylesheet" type="text/css" href="/css/admin/admin.css">
336
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
337
+ <script src="/admin/js/jquery.autosize.js"></script>
338
+ <script src="/admin/js/mousetrap.min.js"></script>
339
+
340
+ <script>
341
+ $("#edit").ready(function() {
342
+ $("#slug input").blur(function() {
343
+ $(this).val($(this).val().trim().replace(/\s+/g, '-').replace(/^-+|-+$/g, '').toLowerCase());
344
+ });
345
+
346
+ $("#slug input").keyup(function(event) {
347
+ var code = event.keyCode;
348
+ if (code == 32) {
349
+ $(this).val($(this).val().replace(/\s+/g, "-"));
350
+ }
351
+ });
352
+
353
+ $("#heading textarea").keyup(function(event) {
354
+ $(this).html($(this).html().replace(/[^\040-\176\200-\377]/gi, ""));
355
+ });
356
+
357
+ $("#confirm-delete + label").text("Delete");
358
+
359
+ $("#delete input[type=submit]").click(function(event) {
360
+ var el = $(this);
361
+
362
+ if (el.hasClass("active")) {
363
+ el.attr("value", "Delete");
364
+ } else {
365
+ el.attr("value", "Cancel");
366
+ }
367
+
368
+ event.preventDefault();
369
+ el.toggleClass("active");
370
+ $("#confirm-delete + label").fadeToggle();
371
+ });
372
+
373
+ $("#confirm-delete + label").click(function(event) {
374
+ event.preventDefault();
375
+ $(this).parent("form").submit();
376
+ });
377
+
378
+ $("label.preview").click(function(event) {
379
+ var previewButton = $(this);
380
+
381
+ if ($("#entry").attr("data-state") == "hidden") {
382
+ if ($("#content").val().trim() == "") {
383
+ $("#entry").html("<p id='writers-block'>(Nothing yet. Keep trying, it'll come to you.)</p>");
384
+ /*
385
+ * here be dragons: we have entry first so that we don't have both
386
+ * the markdown source element and the preview element hidden at the
387
+ * same time, since that causes a jump to the top of the page.
388
+ */
389
+ $("#entry").toggle();
390
+ $("#content").toggle();
391
+ $("#entry").attr("data-state", "active");
392
+ previewButton.html("Markdown");
393
+ previewButton.toggleClass("active");
394
+ } else {
395
+ $.post("/admin/convert-markdown", { "content": $("#content").val() }, function(formattedContent, status, response) {
396
+ if (status == "success") {
397
+ $("#entry").html(formattedContent);
398
+ $("#entry").toggle();
399
+ $("#content").toggle();
400
+ $("#entry").attr("data-state", "active");
401
+ previewButton.toggleClass("active");
402
+ previewButton.html("Markdown");
403
+ }
404
+ });
405
+ }
406
+ } else {
407
+ previewButton.html("Preview");
408
+ previewButton.toggleClass("active");
409
+ /*
410
+ * here be dragons: we have content first so that we don't have both
411
+ * the markdown source element and the preview element hidden at the
412
+ * same time, since that causes a jump to the top of the page.
413
+ */
414
+ $("#content").toggle();
415
+ $("#entry").toggle();
416
+ $("#entry").empty();
417
+ $("#entry").attr("data-state", "hidden");
418
+ }
419
+ });
420
+
421
+ Mousetrap.bind(["ctrl+enter", "command+enter"], function(e) {
422
+ $("label.preview").click();
423
+ $("#shortcuts").hide();
424
+ return false;
425
+ });
426
+
427
+ Mousetrap.bind(["ctrl+s", "command+s"], function(e) {
428
+ $("#edit form input[type=submit]").click();
429
+ $("#shortcuts").hide();
430
+ return false;
431
+ });
432
+
433
+ Mousetrap.bind(["ctrl+h", "command+h"], function() {
434
+ $("#heading textarea").focus();
435
+ $("#heading textarea").val($("#heading textarea").val());
436
+ $("#shortcuts").hide();
437
+ return false;
438
+ });
439
+
440
+ Mousetrap.bind(["ctrl+u", "command+u"], function() {
441
+ $("#slug input").focus();
442
+ $("#slug input").val($("#slug input").val());
443
+ $("#shortcuts").hide();
444
+ return false;
445
+ });
446
+
447
+ Mousetrap.bind(["ctrl+.", "command+."], function(e) {
448
+ $("#delete, #save, #render-preview + label, #publish + label").fadeToggle();
449
+ $("#slug, .post > header time").slideToggle();
450
+ $("#content").focus();
451
+ $("body > nav").toggleClass("hidden");
452
+ return false;
453
+ });
454
+
455
+ Mousetrap.bind(["esc", "ctrl+[", "command+["], function(e) {
456
+ $(e.srcElement).blur();
457
+ });
458
+
459
+ // remove the full text selection on autofocus
460
+ $("input.error[autofocus]").val($("input.error[autofocus]").val());
461
+ });
462
+
463
+ $(document).ready(function() {
464
+ $("textarea").autosize();
465
+
466
+ // force Mousetrap to prevent default behaviour even in input, textarea and select
467
+ $("#edit input, #edit textarea").addClass("mousetrap");
468
+
469
+ Mousetrap.bind(["ctrl+/", "command+/"], function(e) {
470
+ $("#shortcuts").toggle();
471
+ return false;
472
+ });
473
+
474
+ Mousetrap.bind("g h", function(e) {
475
+ var el = e.srcElement;
476
+
477
+ if (el.type == "textarea" || el.type == "text") {
478
+ // skip it
479
+ } else {
480
+ window.location.href = "/admin";
481
+ }
482
+ });
483
+
484
+ Mousetrap.bind("g n", function(e) {
485
+ var el = e.srcElement;
486
+
487
+ if (el.type == "textarea" || el.type == "text") {
488
+ // skip it
489
+ } else {
490
+ window.location.href = "/admin/new/draft";
491
+ }
492
+ });
493
+ });
494
+ </script>
495
+ </head>
496
+ <body>
497
+ <nav>
498
+ <ul>
499
+ <li><a href="/admin">Admin</a></li>
500
+ <li><a href="/admin/new/draft">New draft</a></li>
501
+ </ul>
502
+ </nav>
503
+
504
+ {{ content }}
505
+
506
+ <div id="shortcuts">
507
+ <table>
508
+ <tbody>
509
+ <tr><td><code>Ctrl-/ / Command-/</code></td>
510
+ <td>Show/hide keyboard shortcut</td></tr>
511
+
512
+ <tr><td><code>g h</code></td>
513
+ <td>Go to the admin homepage</td></tr>
514
+
515
+ <tr><td><code>g n</code></td>
516
+ <td>Go to the new draft page</td></tr>
517
+
518
+ <tr><td><code>ESC / Ctrl-[ / Command-[</code></td>
519
+ <td>Remove any <code>&lt;input&gt;</code> focus</td></tr>
520
+
521
+ <tr><td><code>Ctrl-. / Command-.</code></td>
522
+ <td>Toggle focused view</td></tr>
523
+
524
+ <tr><td><code>Ctrl-S / Command-S</code></td>
525
+ <td><b>S</b>ave</td></tr>
526
+
527
+ <tr><td><code>Ctrl-U / Command-U</code></td>
528
+ <td>Jump to <b>U</b>RL name</td></tr>
529
+
530
+ <tr><td><code>Ctrl-H / Command-H</code></td>
531
+ <td>Jump to title/<b>h</b>eading</td></tr>
532
+
533
+ <tr><td><code>Ctrl-Enter / Command-Enter</code></td>
534
+ <td>Toggle rendered preview</td></tr>
535
+ </tbody>
536
+ </table>
537
+ </div>
538
+ </body>
539
+ </html>
@@ -0,0 +1,35 @@
1
+ {% if error_message %}
2
+ <div id="error-message">
3
+ <p>{{ error_message }}</p>
4
+ </div>
5
+ {% endif %}
6
+
7
+ <div id="edit">
8
+ <form action="/admin/new/draft" method="post">
9
+ <input type="hidden" name="original_slug" value="{% if post.slug %}{{ post.slug | escape }}{% endif %}">
10
+
11
+ <h2 id="slug">
12
+ <code>
13
+ <span>drafts/</span><span><input{% if conflicting_name %}{{ ' class="error" title="Pick a different name"' }}{% endif %} name="slug" placeholder="a-url-fragment" value="{{ post.slug | escape }}"{% if autofocus == "slug" %}{{ " autofocus" }}{% endif %}></span>
14
+ </code>
15
+ </h2>
16
+
17
+ <div class="post draft">
18
+ <header>
19
+ <h1 id="heading" class="post">
20
+ <textarea spellcheck="false" placeholder="It was a dark and stormy night" name="title"{% if autofocus == "title" %}{{ " autofocus" }}{% endif %}>{% if post.title %}{{ post.title | escape }}{% endif %}</textarea>
21
+ </h1>
22
+ </header>
23
+ </div>
24
+ <div id="content-areas">
25
+ <textarea spellcheck="false" id="content" placeholder="Lorem ipsum dolor sit amet." name="markdown"{% if autofocus == "markdown" %}{{ " autofocus" }}{% endif %}>{{ post.content | strip | escape }}</textarea>
26
+
27
+ <article id="entry" class="post" data-state="hidden"></article>
28
+ </div>
29
+
30
+ <input id="save" type="submit" value="Save draft">
31
+
32
+ <input type="checkbox" id="render-preview"> <label class="preview" for="render-preview">Preview</label>
33
+ </form>
34
+
35
+ </div>