documentation 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/documentation/link.svg +28 -0
  3. data/app/assets/images/documentation/logo-black.svg +23 -0
  4. data/app/assets/images/documentation/logo-white.svg +23 -0
  5. data/app/assets/images/documentation/page.svg +16 -0
  6. data/app/assets/images/documentation/pin.svg +15 -0
  7. data/app/assets/images/documentation/recommendation.svg +11 -0
  8. data/app/assets/images/documentation/search.svg +10 -0
  9. data/app/assets/images/documentation/unhappy.svg +15 -0
  10. data/app/assets/images/documentation/warning.svg +16 -0
  11. data/app/assets/javascripts/documentation/application.coffee +14 -0
  12. data/app/assets/javascripts/documentation/jquery-ui.js +4146 -0
  13. data/app/assets/javascripts/documentation/jquery.autosize.js +263 -0
  14. data/app/assets/stylesheets/documentation/application.scss +320 -0
  15. data/app/assets/stylesheets/documentation/markdown.scss +168 -0
  16. data/app/assets/stylesheets/documentation/page_form.scss +38 -0
  17. data/app/assets/stylesheets/documentation/reset.scss +101 -0
  18. data/app/controllers/documentation/application_controller.rb +21 -0
  19. data/app/controllers/documentation/pages_controller.rb +74 -0
  20. data/app/helpers/documentation/application_helper.rb +13 -0
  21. data/app/models/documentation/page.rb +213 -0
  22. data/app/views/documentation/pages/_admin_buttons.html.haml +18 -0
  23. data/app/views/documentation/pages/form.html.haml +12 -0
  24. data/app/views/documentation/pages/index.html.haml +13 -0
  25. data/app/views/documentation/pages/positioning.html.haml +22 -0
  26. data/app/views/documentation/pages/search.html.haml +26 -0
  27. data/app/views/documentation/pages/show.html.haml +14 -0
  28. data/app/views/documentation/shared/access_denied.html.haml +10 -0
  29. data/app/views/documentation/shared/not_found.html.haml +10 -0
  30. data/app/views/layouts/documentation/_header.html.haml +3 -0
  31. data/app/views/layouts/documentation/_search.html.haml +5 -0
  32. data/app/views/layouts/documentation/application.html.haml +18 -0
  33. data/config/locales/en.yml +56 -0
  34. data/config/routes.rb +10 -0
  35. data/db/migrate/20140711185212_create_documentation_pages.rb +10 -0
  36. data/db/seeds.rb +15 -0
  37. data/lib/documentation.rb +16 -0
  38. data/lib/documentation/authorizer.rb +52 -0
  39. data/lib/documentation/config.rb +31 -0
  40. data/lib/documentation/engine.rb +29 -0
  41. data/lib/documentation/errors.rb +7 -0
  42. data/lib/documentation/generators/setup_generator.rb +13 -0
  43. data/lib/documentation/markdown_renderer.rb +62 -0
  44. data/lib/documentation/search_result.rb +84 -0
  45. data/lib/documentation/searchers/abstract.rb +47 -0
  46. data/lib/documentation/searchers/simple.rb +40 -0
  47. data/lib/documentation/version.rb +1 -1
  48. data/lib/documentation/view_helpers.rb +113 -0
  49. data/lib/tasks/documentation.rake +6 -0
  50. metadata +219 -3
@@ -0,0 +1,263 @@
1
+ /*!
2
+ Autosize v1.18.4 - 2014-01-11
3
+ Automatically adjust textarea height based on user input.
4
+ (c) 2014 Jack Moore - http://www.jacklmoore.com/autosize
5
+ license: http://www.opensource.org/licenses/mit-license.php
6
+ */
7
+ (function ($) {
8
+ var
9
+ defaults = {
10
+ className: 'autosizejs',
11
+ append: '',
12
+ callback: false,
13
+ resizeDelay: 10,
14
+ placeholder: true
15
+ },
16
+
17
+ // border:0 is unnecessary, but avoids a bug in Firefox on OSX
18
+ copy = '<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"/>',
19
+
20
+ // line-height is conditionally included because IE7/IE8/old Opera do not return the correct value.
21
+ typographyStyles = [
22
+ 'fontFamily',
23
+ 'fontSize',
24
+ 'fontWeight',
25
+ 'fontStyle',
26
+ 'letterSpacing',
27
+ 'textTransform',
28
+ 'wordSpacing',
29
+ 'textIndent'
30
+ ],
31
+
32
+ // to keep track which textarea is being mirrored when adjust() is called.
33
+ mirrored,
34
+
35
+ // the mirror element, which is used to calculate what size the mirrored element should be.
36
+ mirror = $(copy).data('autosize', true)[0];
37
+
38
+ // test that line-height can be accurately copied.
39
+ mirror.style.lineHeight = '99px';
40
+ if ($(mirror).css('lineHeight') === '99px') {
41
+ typographyStyles.push('lineHeight');
42
+ }
43
+ mirror.style.lineHeight = '';
44
+
45
+ $.fn.autosize = function (options) {
46
+ if (!this.length) {
47
+ return this;
48
+ }
49
+
50
+ options = $.extend({}, defaults, options || {});
51
+
52
+ if (mirror.parentNode !== document.body) {
53
+ $(document.body).append(mirror);
54
+ }
55
+
56
+ return this.each(function () {
57
+ var
58
+ ta = this,
59
+ $ta = $(ta),
60
+ maxHeight,
61
+ minHeight,
62
+ boxOffset = 0,
63
+ callback = $.isFunction(options.callback),
64
+ originalStyles = {
65
+ height: ta.style.height,
66
+ overflow: ta.style.overflow,
67
+ overflowY: ta.style.overflowY,
68
+ wordWrap: ta.style.wordWrap,
69
+ resize: ta.style.resize
70
+ },
71
+ timeout,
72
+ width = $ta.width();
73
+
74
+ if ($ta.data('autosize')) {
75
+ // exit if autosize has already been applied, or if the textarea is the mirror element.
76
+ return;
77
+ }
78
+ $ta.data('autosize', true);
79
+
80
+ if ($ta.css('box-sizing') === 'border-box' || $ta.css('-moz-box-sizing') === 'border-box' || $ta.css('-webkit-box-sizing') === 'border-box'){
81
+ boxOffset = $ta.outerHeight() - $ta.height();
82
+ }
83
+
84
+ // IE8 and lower return 'auto', which parses to NaN, if no min-height is set.
85
+ minHeight = Math.max(parseInt($ta.css('minHeight'), 10) - boxOffset || 0, $ta.height());
86
+
87
+ $ta.css({
88
+ overflow: 'hidden',
89
+ overflowY: 'hidden',
90
+ wordWrap: 'break-word', // horizontal overflow is hidden, so break-word is necessary for handling words longer than the textarea width
91
+ resize: ($ta.css('resize') === 'none' || $ta.css('resize') === 'vertical') ? 'none' : 'horizontal'
92
+ });
93
+
94
+ // The mirror width must exactly match the textarea width, so using getBoundingClientRect because it doesn't round the sub-pixel value.
95
+ // window.getComputedStyle, getBoundingClientRect returning a width are unsupported, but also unneeded in IE8 and lower.
96
+ function setWidth() {
97
+ var width;
98
+ var style = window.getComputedStyle ? window.getComputedStyle(ta, null) : false;
99
+
100
+ if (style) {
101
+
102
+ width = ta.getBoundingClientRect().width;
103
+
104
+ if (width === 0) {
105
+ width = parseInt(style.width,10);
106
+ }
107
+
108
+ $.each(['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'], function(i,val){
109
+ width -= parseInt(style[val],10);
110
+ });
111
+ } else {
112
+ width = Math.max($ta.width(), 0);
113
+ }
114
+
115
+ mirror.style.width = width + 'px';
116
+ }
117
+
118
+ function initMirror() {
119
+ var styles = {};
120
+
121
+ mirrored = ta;
122
+ mirror.className = options.className;
123
+ maxHeight = parseInt($ta.css('maxHeight'), 10);
124
+
125
+ // mirror is a duplicate textarea located off-screen that
126
+ // is automatically updated to contain the same text as the
127
+ // original textarea. mirror always has a height of 0.
128
+ // This gives a cross-browser supported way getting the actual
129
+ // height of the text, through the scrollTop property.
130
+ $.each(typographyStyles, function(i,val){
131
+ styles[val] = $ta.css(val);
132
+ });
133
+ $(mirror).css(styles);
134
+
135
+ setWidth();
136
+
137
+ // Chrome-specific fix:
138
+ // When the textarea y-overflow is hidden, Chrome doesn't reflow the text to account for the space
139
+ // made available by removing the scrollbar. This workaround triggers the reflow for Chrome.
140
+ if (window.chrome) {
141
+ var width = ta.style.width;
142
+ ta.style.width = '0px';
143
+ var ignore = ta.offsetWidth;
144
+ ta.style.width = width;
145
+ }
146
+ }
147
+
148
+ // Using mainly bare JS in this function because it is going
149
+ // to fire very often while typing, and needs to very efficient.
150
+ function adjust() {
151
+ var height, original;
152
+
153
+ if (mirrored !== ta) {
154
+ initMirror();
155
+ } else {
156
+ setWidth();
157
+ }
158
+
159
+ if (!ta.value && options.placeholder) {
160
+ // If the textarea is empty, copy the placeholder text into
161
+ // the mirror control and use that for sizing so that we
162
+ // don't end up with placeholder getting trimmed.
163
+ mirror.value = ($(ta).attr("placeholder") || '') + options.append;
164
+ } else {
165
+ mirror.value = ta.value + options.append;
166
+ }
167
+
168
+ mirror.style.overflowY = ta.style.overflowY;
169
+ original = parseInt(ta.style.height,10);
170
+
171
+ // Setting scrollTop to zero is needed in IE8 and lower for the next step to be accurately applied
172
+ mirror.scrollTop = 0;
173
+
174
+ mirror.scrollTop = 9e4;
175
+
176
+ // Using scrollTop rather than scrollHeight because scrollHeight is non-standard and includes padding.
177
+ height = mirror.scrollTop;
178
+
179
+ if (maxHeight && height > maxHeight) {
180
+ ta.style.overflowY = 'scroll';
181
+ height = maxHeight;
182
+ } else {
183
+ ta.style.overflowY = 'hidden';
184
+ if (height < minHeight) {
185
+ height = minHeight;
186
+ }
187
+ }
188
+
189
+ height += boxOffset;
190
+
191
+ if (original !== height) {
192
+ ta.style.height = height + 'px';
193
+ if (callback) {
194
+ options.callback.call(ta,ta);
195
+ }
196
+ }
197
+ }
198
+
199
+ function resize () {
200
+ clearTimeout(timeout);
201
+ timeout = setTimeout(function(){
202
+ var newWidth = $ta.width();
203
+
204
+ if (newWidth !== width) {
205
+ width = newWidth;
206
+ adjust();
207
+ }
208
+ }, parseInt(options.resizeDelay,10));
209
+ }
210
+
211
+ if ('onpropertychange' in ta) {
212
+ if ('oninput' in ta) {
213
+ // Detects IE9. IE9 does not fire onpropertychange or oninput for deletions,
214
+ // so binding to onkeyup to catch most of those occasions. There is no way that I
215
+ // know of to detect something like 'cut' in IE9.
216
+ $ta.on('input.autosize keyup.autosize', adjust);
217
+ } else {
218
+ // IE7 / IE8
219
+ $ta.on('propertychange.autosize', function(){
220
+ if(event.propertyName === 'value'){
221
+ adjust();
222
+ }
223
+ });
224
+ }
225
+ } else {
226
+ // Modern Browsers
227
+ $ta.on('input.autosize', adjust);
228
+ }
229
+
230
+ // Set options.resizeDelay to false if using fixed-width textarea elements.
231
+ // Uses a timeout and width check to reduce the amount of times adjust needs to be called after window resize.
232
+
233
+ if (options.resizeDelay !== false) {
234
+ $(window).on('resize.autosize', resize);
235
+ }
236
+
237
+ // Event for manual triggering if needed.
238
+ // Should only be needed when the value of the textarea is changed through JavaScript rather than user input.
239
+ $ta.on('autosize.resize', adjust);
240
+
241
+ // Event for manual triggering that also forces the styles to update as well.
242
+ // Should only be needed if one of typography styles of the textarea change, and the textarea is already the target of the adjust method.
243
+ $ta.on('autosize.resizeIncludeStyle', function() {
244
+ mirrored = null;
245
+ adjust();
246
+ });
247
+
248
+ $ta.on('autosize.destroy', function(){
249
+ mirrored = null;
250
+ clearTimeout(timeout);
251
+ $(window).off('resize', resize);
252
+ $ta
253
+ .off('autosize')
254
+ .off('.autosize')
255
+ .css(originalStyles)
256
+ .removeData('autosize');
257
+ });
258
+
259
+ // Call adjust in case the textarea already contains text.
260
+ adjust();
261
+ });
262
+ };
263
+ }(window.jQuery || window.$)); // jQuery or jQuery-like library, such as Zepto
@@ -0,0 +1,320 @@
1
+ /*
2
+ *= require documentation/reset
3
+ *= require_self
4
+ *= require documentation/markdown
5
+ *= require documentation/page_form
6
+ */
7
+
8
+ $font: 'Helvetica Neue', Helvetica, Arial, sans-serif;
9
+ input, textarea { font-family:$font;}
10
+
11
+ body {
12
+ font-family: $font;
13
+ font-size:14px;
14
+ }
15
+
16
+ //
17
+ // Main page header
18
+ //
19
+ header {
20
+ background:#354050;
21
+ height:45px;
22
+ position:fixed;
23
+ top:0;
24
+ width:100%;
25
+ h1 {
26
+ margin:10px 0 0 15px;
27
+ float:left;
28
+ a {
29
+ display:block;
30
+ background:image-url('documentation/logo-white.svg') no-repeat;
31
+ background-size:20px;
32
+ width:20px;
33
+ height:20px;
34
+ text-indent:-40000px;
35
+ }
36
+ }
37
+ p.back {
38
+ float:right;
39
+ margin:14px 15px 0 0;
40
+ a { color:#97a4b7; text-decoration:none; }
41
+ a:hover { color:#fff;}
42
+ }
43
+ }
44
+
45
+ //
46
+ // Search Form
47
+ //
48
+ .searchForm {
49
+ padding:0 15px;
50
+ margin-bottom:15px;
51
+ input {
52
+ width:100%;
53
+ background:image-url('documentation/search.svg') white no-repeat 5px 6px;
54
+ font-family:$font;
55
+ background-size:14px;
56
+ border:2px solid #bbc5da;
57
+ border-radius:4px;
58
+ padding:6px 6px 6px 25px;
59
+ }
60
+ }
61
+
62
+ //
63
+ // Left-side navigation
64
+ //
65
+ nav.pages {
66
+ position:fixed;
67
+ top:45px;
68
+ bottom:0;
69
+ width:249px;
70
+ border-right:1px solid #E2E7F1;
71
+ background:#F5F7FB;
72
+ font-size:0.9em;
73
+ div.inner {
74
+ padding:15px 0;
75
+ ul {
76
+ li {
77
+ a {
78
+ text-decoration:none;
79
+ color:#333;
80
+ padding:5px 15px;
81
+ display:block;
82
+ &:hover {
83
+ background:#e2e7f1;
84
+ }
85
+ &.active {
86
+ background:#35A4D4;
87
+ color:#fff;
88
+ }
89
+ }
90
+ ul li a { padding-left:35px;}
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ //
97
+ // Main content area
98
+ //
99
+ section.content {
100
+ position:fixed;
101
+ top:45px;
102
+ left:250px;
103
+ bottom:0;
104
+ right:0;
105
+ background:#fff;
106
+ overflow-y:scroll;
107
+ }
108
+
109
+ //
110
+ // The breadcrumb
111
+ //
112
+ nav.breadcrumb {
113
+ font-size:0.85em;
114
+ background:#E2E7F1;
115
+ margin-bottom:10px;
116
+ padding:10px 35px;
117
+ ul {
118
+ overflow:hidden;
119
+ li {
120
+ float:left; margin-right:7px;
121
+ &:after { content:"\21D2"; padding-left:7px; color:#abb6cd;}
122
+ &:last-child:after { color:#E2E7F1; padding-left:0;}
123
+ a {color:#8e9bb4;}
124
+ a:hover { color:#748098;}
125
+ &:last-child a { text-decoration:none;}
126
+ &:last-child a:hover {color:#8e9bb4;}
127
+ }
128
+ }
129
+ }
130
+
131
+ //
132
+ // A page
133
+ //
134
+ section.page {
135
+ margin:25px 35px 35px 35px;
136
+ h1 {
137
+ font-size:2.2em;
138
+ font-weight:300 ;
139
+ margin-bottom:4px;
140
+ }
141
+
142
+ p.updated {
143
+ color:#999;
144
+ font-size:0.85em;
145
+ margin-bottom:10px;
146
+ }
147
+
148
+ p.previewLink {
149
+ float:right;
150
+ margin-top:4px;
151
+ }
152
+
153
+ p.adminButtons {
154
+ border-top:1px dashed #ddd;
155
+ padding:15px 0;
156
+ margin-top:30px;
157
+ text-align:right;
158
+ }
159
+
160
+ form.reordering {
161
+ padding:0 0 0 0;
162
+ }
163
+ form.reordering ul {
164
+ padding:25px 0 0 0;
165
+ }
166
+ form.reordering ul li {
167
+ background:#F5F7FB;
168
+ font-size:1.1em;
169
+ margin-bottom:7px;
170
+ padding:10px;
171
+ cursor:pointer;
172
+ border:1px dashed #748098;
173
+ background:image-url('documentation/page.svg') #F5F7FB no-repeat 16px 10px;
174
+ background-size:14px;
175
+ padding-left:40px;
176
+ }
177
+
178
+ }
179
+
180
+ //
181
+ // Generic button style
182
+ //
183
+ a.button, input.button {
184
+ display:inline-block;
185
+ border:2px solid lighten(#9357B0, 20%);
186
+ text-decoration:none;
187
+ background:#fff;
188
+ color:#9357B0;
189
+ font-weight:500;
190
+ padding:3px 10px;
191
+ font-size:12px;
192
+ background:#fff;
193
+ border-radius:5px;
194
+ margin-left:5px;
195
+ appearance:none;
196
+ &.delete {
197
+ color:#F6744F;
198
+ border-color:lighten(#F6744F, 20%);
199
+ }
200
+ &.new {
201
+ color:#65BA65;
202
+ border-color:lighten(#65BA65, 20%);
203
+ }
204
+ &.preview {
205
+ color:#999;
206
+ border-color:#ccc;
207
+ }
208
+ }
209
+
210
+ //
211
+ // Flash message - for notices
212
+ //
213
+ #flash-notice {
214
+ background:#65BA65;
215
+ padding:15px 35px;
216
+ color:#fff;
217
+ font-size:1.2em;
218
+ font-weight:600;
219
+ }
220
+
221
+ //
222
+ // Flash message - for alerts
223
+ //
224
+ #flash-alert {
225
+ background:#F6744F;
226
+ padding:15px 35px;
227
+ color:#fff;
228
+ font-size:1.2em;
229
+ font-weight:600;
230
+ }
231
+
232
+ //
233
+ // Welcome message on homepage
234
+ //
235
+ section.welcome {
236
+ text-align:center;
237
+ margin:60px 0;
238
+ background:image-url('documentation/logo-black.svg') no-repeat top center;
239
+ background-size:100px;
240
+ padding-top:150px;
241
+ h1 { font-size:3.6em; font-weight:300;}
242
+ h2 { color:#aaa; margin-top:2px; font-size:1.5em; font-weight:300;}
243
+ .override {
244
+ background:#fdffe0;
245
+ width:80%;
246
+ margin:50px auto;
247
+ font-size:1.1em;
248
+ line-height:1.7;
249
+ padding:25px;
250
+ border:1px solid #ced0ad;
251
+ color:#727457;
252
+ code { font-weight:bold; }
253
+ }
254
+ }
255
+
256
+ //
257
+ // Access denied
258
+ //
259
+ html.errorPage {
260
+ background:lighten(#354050, 70%);
261
+ }
262
+
263
+ section.errorMessage {
264
+ width:450px;
265
+ margin:100px auto;
266
+ box-shadow: 0 0 35px lighten(#354050, 60%);
267
+ background:white;
268
+ text-align:center;
269
+ h2 {
270
+ background:#354050;
271
+ color:#fff;
272
+ padding:15px;
273
+ font-size:1.5em;
274
+ font-weight:300;
275
+ }
276
+ p {
277
+ padding:25px 15px;
278
+ line-height:1.5;
279
+ font-size:0.9em;
280
+ color:lighten(#354050, 30%);
281
+ }
282
+ }
283
+
284
+ //
285
+ // Search results
286
+ //
287
+ ul.searchResults {
288
+ margin:25px 0;
289
+ a { color:inherit; text-decoration:none;}
290
+ a:hover { text-decoration:underline;}
291
+ li {
292
+ margin-bottom:25px;
293
+ h4 { font-weight:600; color:#35A4D4; }
294
+ p.in { font-size:0.85em; color:#92BBC9; margin-top:4px;}
295
+ p.excerpt { margin-top:5px; line-height:1.5;}
296
+ p.excerpt mark { background:#fffdca; border-bottom:1px solid #d9d33b; }
297
+ }
298
+ }
299
+
300
+ //
301
+ // Search summary
302
+ //
303
+ p.searchSummary {
304
+ color:#999; margin-top:5px;
305
+ }
306
+
307
+ //
308
+ // No search results
309
+ //
310
+ p.noSearchResults {
311
+ text-align:center;
312
+ margin:100px 0;
313
+ color:#999;
314
+ font-style:italic;
315
+ font-size:1.5em;
316
+ font-weight:300;
317
+ background:image-url('documentation/unhappy.svg') no-repeat center top;
318
+ background-size:170px;
319
+ padding-top:200px;
320
+ }