tolaria 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +66 -0
- data/.yardopts +4 -0
- data/CNAME +1 -0
- data/CONTRIBUTING.md +32 -0
- data/Gemfile +2 -0
- data/LICENSE.md +9 -0
- data/README.md +538 -0
- data/Rakefile +52 -0
- data/app/assets/fonts/admin/fontawesome.eot +0 -0
- data/app/assets/fonts/admin/fontawesome.svg +565 -0
- data/app/assets/fonts/admin/fontawesome.ttf +0 -0
- data/app/assets/fonts/admin/fontawesome.woff +0 -0
- data/app/assets/fonts/admin/fontawesome.woff2 +0 -0
- data/app/assets/images/admin/columbia_banner.png +0 -0
- data/app/assets/images/admin/favicon.ico +0 -0
- data/app/assets/images/admin/noise.png +0 -0
- data/app/assets/images/admin/select_arrows.svg +1 -0
- data/app/assets/javascripts/admin/admin.js +4 -0
- data/app/assets/javascripts/admin/base.js +12 -0
- data/app/assets/javascripts/admin/lib/backbone.js +1888 -0
- data/app/assets/javascripts/admin/lib/jquery.chosen.js +1272 -0
- data/app/assets/javascripts/admin/lib/jquery.js +10361 -0
- data/app/assets/javascripts/admin/lib/jquery.selection.js +352 -0
- data/app/assets/javascripts/admin/lib/moment.js +3103 -0
- data/app/assets/javascripts/admin/lib/no.js +6 -0
- data/app/assets/javascripts/admin/lib/underscore.js +1570 -0
- data/app/assets/javascripts/admin/models/composer_buttons.js +45 -0
- data/app/assets/javascripts/admin/models/rails_meta.js +4 -0
- data/app/assets/javascripts/admin/views/field_with_errors.js +19 -0
- data/app/assets/javascripts/admin/views/fields/attachment_field.js +32 -0
- data/app/assets/javascripts/admin/views/fields/has_many.js +64 -0
- data/app/assets/javascripts/admin/views/fields/image_association_select.js +31 -0
- data/app/assets/javascripts/admin/views/fields/markdown_composer.js +167 -0
- data/app/assets/javascripts/admin/views/fields/searchable_select.js +70 -0
- data/app/assets/javascripts/admin/views/fields/slug_field.js +38 -0
- data/app/assets/javascripts/admin/views/fields/swatch_field.js +55 -0
- data/app/assets/javascripts/admin/views/fields/timestamp_field.js +80 -0
- data/app/assets/javascripts/admin/views/flash_message.js +18 -0
- data/app/assets/javascripts/admin/views/form_orchestrator.js +41 -0
- data/app/assets/javascripts/admin/views/navigation.js +20 -0
- data/app/assets/javascripts/admin/views/resource_form.js +18 -0
- data/app/assets/javascripts/admin/views/search_form.js +20 -0
- data/app/assets/javascripts/admin/views/sessions.js +109 -0
- data/app/assets/javascripts/admin/views/virtual_form.js +47 -0
- data/app/assets/stylesheets/admin/_base.scss +5 -0
- data/app/assets/stylesheets/admin/_reset.scss +149 -0
- data/app/assets/stylesheets/admin/_root.scss +63 -0
- data/app/assets/stylesheets/admin/admin.scss +4 -0
- data/app/assets/stylesheets/admin/components/_blank_slate.scss +44 -0
- data/app/assets/stylesheets/admin/components/_buttons.scss +82 -0
- data/app/assets/stylesheets/admin/components/_flash_message.scss +64 -0
- data/app/assets/stylesheets/admin/components/_footer.scss +9 -0
- data/app/assets/stylesheets/admin/components/_header.scss +107 -0
- data/app/assets/stylesheets/admin/components/_index_table.scss +120 -0
- data/app/assets/stylesheets/admin/components/_main.scss +68 -0
- data/app/assets/stylesheets/admin/components/_markdown_body.scss +109 -0
- data/app/assets/stylesheets/admin/components/_navigation.scss +110 -0
- data/app/assets/stylesheets/admin/components/_pagination.scss +36 -0
- data/app/assets/stylesheets/admin/components/_pill.scss +11 -0
- data/app/assets/stylesheets/admin/components/_resource_form.scss +222 -0
- data/app/assets/stylesheets/admin/components/_search_form.scss +36 -0
- data/app/assets/stylesheets/admin/components/_sessions.scss +152 -0
- data/app/assets/stylesheets/admin/components/_show_table.scss +67 -0
- data/app/assets/stylesheets/admin/components/forms/_attachment_field.scss +59 -0
- data/app/assets/stylesheets/admin/components/forms/_chosen.scss +478 -0
- data/app/assets/stylesheets/admin/components/forms/_image_association_select.scss +20 -0
- data/app/assets/stylesheets/admin/components/forms/_markdown_composer.scss +149 -0
- data/app/assets/stylesheets/admin/components/forms/_nested_fields.scss +63 -0
- data/app/assets/stylesheets/admin/components/forms/_searchable_select.scss +8 -0
- data/app/assets/stylesheets/admin/components/forms/_slug_field.scss +20 -0
- data/app/assets/stylesheets/admin/components/forms/_swatch_field.scss +47 -0
- data/app/assets/stylesheets/admin/components/forms/_timestamp_field.scss +15 -0
- data/app/assets/stylesheets/admin/components/help_link.scss +6 -0
- data/app/assets/stylesheets/admin/mixins/_clearfix.scss +18 -0
- data/app/assets/stylesheets/admin/mixins/_min_max_width.scss +11 -0
- data/app/assets/stylesheets/admin/mixins/_rgbb.scss +7 -0
- data/app/assets/stylesheets/admin/mixins/_visuallyhidden.scss +33 -0
- data/app/assets/stylesheets/admin/settings/_animations.scss +21 -0
- data/app/assets/stylesheets/admin/settings/_breakpoints.scss +2 -0
- data/app/assets/stylesheets/admin/settings/_colors.scss +32 -0
- data/app/assets/stylesheets/admin/settings/_fonts.scss +31 -0
- data/app/assets/stylesheets/admin/settings/_icons.scss +1658 -0
- data/app/controllers/admin/admin_controller.rb +21 -0
- data/app/controllers/admin/sessions_controller.rb +112 -0
- data/app/controllers/tolaria/resource_controller.rb +132 -0
- data/app/controllers/tolaria/tolaria_controller.rb +40 -0
- data/app/helpers/admin/table_helper.rb +175 -0
- data/app/helpers/admin/view_helper.rb +76 -0
- data/app/mailers/passcode_mailer.rb +11 -0
- data/app/models/administrator.rb +146 -0
- data/app/views/admin/administrators/_form.html.erb +16 -0
- data/app/views/admin/administrators/_index.html.erb +20 -0
- data/app/views/admin/administrators/_search.html.erb +5 -0
- data/app/views/admin/administrators/_show.html.erb +14 -0
- data/app/views/admin/help/help_link.html.erb +16 -0
- data/app/views/admin/session/form.html.erb +52 -0
- data/app/views/admin/shared/_flash_messages.html.erb +42 -0
- data/app/views/admin/shared/_footer.html.erb +8 -0
- data/app/views/admin/shared/_head.html.erb +11 -0
- data/app/views/admin/shared/_header.html.erb +43 -0
- data/app/views/admin/shared/_navigation.html.erb +47 -0
- data/app/views/admin/shared/_skiplinks.html.erb +0 -0
- data/app/views/admin/shared/forms/_attachment_field.html.erb +17 -0
- data/app/views/admin/shared/forms/_has_many.html.erb +14 -0
- data/app/views/admin/shared/forms/_has_many_header.html.erb +19 -0
- data/app/views/admin/shared/forms/_image_association_select.html.erb +6 -0
- data/app/views/admin/shared/forms/_image_field.html.erb +19 -0
- data/app/views/admin/shared/forms/_markdown_composer.html.erb +29 -0
- data/app/views/admin/shared/forms/_searchable_select.html.erb +3 -0
- data/app/views/admin/shared/forms/_slug_field.html.erb +9 -0
- data/app/views/admin/shared/forms/_swatch_field.html.erb +4 -0
- data/app/views/admin/shared/forms/_timestamp_field.html.erb +19 -0
- data/app/views/admin/tolaria_resource/_form_buttons.html.erb +10 -0
- data/app/views/admin/tolaria_resource/_index_table.html.erb +73 -0
- data/app/views/admin/tolaria_resource/_search_form.html.erb +32 -0
- data/app/views/admin/tolaria_resource/_show_buttons.html.erb +13 -0
- data/app/views/admin/tolaria_resource/edit.html.erb +34 -0
- data/app/views/admin/tolaria_resource/index.html.erb +36 -0
- data/app/views/admin/tolaria_resource/new.html.erb +1 -0
- data/app/views/admin/tolaria_resource/show.html.erb +52 -0
- data/app/views/kaminari/admin/_first_page.html.erb +9 -0
- data/app/views/kaminari/admin/_last_page.html.erb +9 -0
- data/app/views/kaminari/admin/_next_page.html.erb +9 -0
- data/app/views/kaminari/admin/_page.html.erb +17 -0
- data/app/views/kaminari/admin/_paginator.html.erb +21 -0
- data/app/views/kaminari/admin/_prev_page.html.erb +9 -0
- data/app/views/layouts/admin/admin.html.erb +21 -0
- data/app/views/layouts/admin/sessions.html.erb +12 -0
- data/app/views/passcode_mailer/passcode.text.erb +5 -0
- data/lib/generators/tolaria/install/install_generator.rb +21 -0
- data/lib/generators/tolaria/install/templates/administrators_migration.rb +31 -0
- data/lib/generators/tolaria/install/templates/tolaria_initializer.rb +93 -0
- data/lib/tasks/admin.rake +32 -0
- data/lib/tolaria.rb +27 -0
- data/lib/tolaria/active_record.rb +55 -0
- data/lib/tolaria/admin.rb +4 -0
- data/lib/tolaria/categories.rb +21 -0
- data/lib/tolaria/config.rb +40 -0
- data/lib/tolaria/default_config.rb +74 -0
- data/lib/tolaria/engine.rb +23 -0
- data/lib/tolaria/form_buildable.rb +203 -0
- data/lib/tolaria/help_links.rb +78 -0
- data/lib/tolaria/introspection.rb +13 -0
- data/lib/tolaria/manage.rb +57 -0
- data/lib/tolaria/managed_class.rb +90 -0
- data/lib/tolaria/markdown.rb +28 -0
- data/lib/tolaria/random_tokens.rb +16 -0
- data/lib/tolaria/reload.rb +21 -0
- data/lib/tolaria/routes.rb +33 -0
- data/lib/tolaria/version.rb +13 -0
- data/test/demo/Rakefile +4 -0
- data/test/demo/app/assets/javascripts/application.js +1 -0
- data/test/demo/app/assets/stylesheets/application.scss +1 -0
- data/test/demo/app/controllers/application_controller.rb +5 -0
- data/test/demo/app/controllers/concerns/.keep +0 -0
- data/test/demo/app/controllers/homepage_controller.rb +4 -0
- data/test/demo/app/helpers/application_helper.rb +2 -0
- data/test/demo/app/mailers/.keep +0 -0
- data/test/demo/app/models/.keep +0 -0
- data/test/demo/app/models/blog_post.rb +43 -0
- data/test/demo/app/models/footnote.rb +5 -0
- data/test/demo/app/models/image.rb +19 -0
- data/test/demo/app/models/legal_page.rb +24 -0
- data/test/demo/app/models/miscellany.rb +12 -0
- data/test/demo/app/models/topic.rb +22 -0
- data/test/demo/app/models/video.rb +16 -0
- data/test/demo/app/views/admin/blog_posts/_form.html.erb +48 -0
- data/test/demo/app/views/admin/blog_posts/_search.html.erb +5 -0
- data/test/demo/app/views/admin/help/markdown-help.md +95 -0
- data/test/demo/app/views/admin/images/_form.html.erb +26 -0
- data/test/demo/app/views/admin/legal_pages/_form.html.erb +15 -0
- data/test/demo/app/views/admin/topics/_form.html.erb +3 -0
- data/test/demo/app/views/admin/videos/_form.html.erb +11 -0
- data/test/demo/app/views/homepage/homepage.html.erb +3 -0
- data/test/demo/app/views/layouts/application.html.erb +14 -0
- data/test/demo/bin/bundle +3 -0
- data/test/demo/bin/rails +4 -0
- data/test/demo/bin/rake +4 -0
- data/test/demo/bin/setup +29 -0
- data/test/demo/config.ru +4 -0
- data/test/demo/config/application.rb +26 -0
- data/test/demo/config/boot.rb +4 -0
- data/test/demo/config/database.yml +18 -0
- data/test/demo/config/environment.rb +3 -0
- data/test/demo/config/environments/development.rb +43 -0
- data/test/demo/config/environments/test.rb +44 -0
- data/test/demo/config/initializers/assets.rb +11 -0
- data/test/demo/config/initializers/cookies_serializer.rb +2 -0
- data/test/demo/config/initializers/filter_parameter_logging.rb +3 -0
- data/test/demo/config/initializers/inflections.rb +17 -0
- data/test/demo/config/initializers/markdown.rb +44 -0
- data/test/demo/config/initializers/secret_token.rb +2 -0
- data/test/demo/config/initializers/session_store.rb +2 -0
- data/test/demo/config/initializers/tolaria.rb +17 -0
- data/test/demo/config/initializers/wrap_parameters.rb +14 -0
- data/test/demo/config/routes.rb +4 -0
- data/test/demo/db/migrate/20150601202901_create_administrators.rb +31 -0
- data/test/demo/db/migrate/20150603204006_add_testing_models.rb +27 -0
- data/test/demo/db/migrate/20150609232013_create_footnotes.rb +10 -0
- data/test/demo/db/migrate/20150610135235_create_additional_demo_objects.rb +50 -0
- data/test/demo/db/schema.rb +112 -0
- data/test/demo/log/.keep +0 -0
- data/test/demo/public/404.html +67 -0
- data/test/demo/public/422.html +67 -0
- data/test/demo/public/500.html +66 -0
- data/test/demo/public/favicon.ico +0 -0
- data/test/integration/help_link_test.rb +73 -0
- data/test/integration/interface_test.rb +63 -0
- data/test/integration/router_test.rb +73 -0
- data/test/integration/session_test.rb +88 -0
- data/test/test_helper.rb +58 -0
- data/test/unit/configuration_test.rb +21 -0
- data/test/unit/managed_classes_test.rb +54 -0
- data/test/unit/markdown_test.rb +12 -0
- data/test/unit/menu_test.rb +32 -0
- data/test/unit/random_tokens_test.rb +13 -0
- data/tolaria.gemspec +35 -0
- metadata +499 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
var SwatchFieldView = Backbone.View.extend({
|
2
|
+
|
3
|
+
initialize: function() {
|
4
|
+
this.$swatch = this.$(".swatch-field-swatch");
|
5
|
+
this.$input = this.$("input");
|
6
|
+
this.refreshPreview();
|
7
|
+
},
|
8
|
+
|
9
|
+
colorRegex: /^(?:[0-9a-f]{3})(?:[0-9a-f]{3})?$/i,
|
10
|
+
|
11
|
+
parseColor: function(color) {
|
12
|
+
color = color.replace("#","");
|
13
|
+
if (!!this.colorRegex.exec(color)) {
|
14
|
+
return color.toUpperCase();
|
15
|
+
}
|
16
|
+
else {
|
17
|
+
return false;
|
18
|
+
}
|
19
|
+
},
|
20
|
+
|
21
|
+
refreshPreview: function() {
|
22
|
+
var parsedColor = this.parseColor($.trim(this.$input.val()));
|
23
|
+
if (!!parsedColor) {
|
24
|
+
this.$swatch.attr("style", "background:#" + parsedColor + " !important");
|
25
|
+
this.$swatch.addClass("-active");
|
26
|
+
}
|
27
|
+
else {
|
28
|
+
this.$swatch.attr("style", "");
|
29
|
+
this.$swatch.removeClass("-active");
|
30
|
+
}
|
31
|
+
},
|
32
|
+
|
33
|
+
validateSelf: function() {
|
34
|
+
var inputValue = $.trim(this.$input.val());
|
35
|
+
var parsedColor = this.parseColor(inputValue);
|
36
|
+
if (!parsedColor && inputValue !== "") {
|
37
|
+
this.$el.addClass("field_with_errors");
|
38
|
+
}
|
39
|
+
},
|
40
|
+
|
41
|
+
clearError: function() {
|
42
|
+
this.$el.removeClass("field_with_errors");
|
43
|
+
},
|
44
|
+
|
45
|
+
events: {
|
46
|
+
"keyup": "refreshPreview",
|
47
|
+
"change input": "refreshPreview",
|
48
|
+
"change input": "validateSelf",
|
49
|
+
"blur input": "validateSelf",
|
50
|
+
"focus input": "clearError"
|
51
|
+
}
|
52
|
+
|
53
|
+
});
|
54
|
+
|
55
|
+
FormOrchestrator.register(".swatch-field", "SwatchFieldView");
|
@@ -0,0 +1,80 @@
|
|
1
|
+
moment.locale("en");
|
2
|
+
|
3
|
+
var TimestampFieldView = Backbone.View.extend({
|
4
|
+
|
5
|
+
momentFormats: [
|
6
|
+
"YYYY-MM-DD hh:mm A",
|
7
|
+
"YYYY-MM-DD hh:mm a"
|
8
|
+
],
|
9
|
+
|
10
|
+
initialize: function() {
|
11
|
+
|
12
|
+
this.$year = this.$("select[name*='(1i)']");
|
13
|
+
this.$month = this.$("select[name*='(2i)']");
|
14
|
+
this.$date = this.$("select[name*='(3i)']");
|
15
|
+
this.$hour = this.$("select[name*='(4i)']");
|
16
|
+
this.$minute = this.$("select[name*='(5i)']");
|
17
|
+
|
18
|
+
this.$input = this.$("input[type=text]");
|
19
|
+
this.recoveryValue = this.$input.data("recovery-value");
|
20
|
+
|
21
|
+
},
|
22
|
+
|
23
|
+
attemptRecovery: function() {
|
24
|
+
this.$el.removeClass("field_with_errors");
|
25
|
+
if (!$.trim(this.$input.val())) {
|
26
|
+
this.$input.val(this.recoveryValue);
|
27
|
+
}
|
28
|
+
},
|
29
|
+
|
30
|
+
// Rails expects hours and minutes in two-digit format
|
31
|
+
padSingleDigits: function(numeric) {
|
32
|
+
if (numeric < 10) {
|
33
|
+
return "0" + numeric.toString();
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
return numeric;
|
37
|
+
}
|
38
|
+
},
|
39
|
+
|
40
|
+
parseTime: function() {
|
41
|
+
|
42
|
+
var parsedMoment = moment(this.$input.val(), this.momentFormats);
|
43
|
+
|
44
|
+
if (parsedMoment.isValid()) {
|
45
|
+
this.$year.val(parsedMoment.year());
|
46
|
+
this.$month.val(parsedMoment.month() + 1); // Moment.js months are 0 indexed
|
47
|
+
this.$date.val(parsedMoment.date());
|
48
|
+
this.$hour.val(this.padSingleDigits(parsedMoment.hour()));
|
49
|
+
this.$minute.val(this.padSingleDigits(parsedMoment.minute()));
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
this.$year.val("");
|
53
|
+
this.$month.val("");
|
54
|
+
this.$date.val("");
|
55
|
+
this.$hour.val("");
|
56
|
+
this.$minute.val("");
|
57
|
+
this.$el.addClass("field_with_errors");
|
58
|
+
}
|
59
|
+
|
60
|
+
console.log("Timestamp field changed:", [
|
61
|
+
this.$year.val(),
|
62
|
+
this.$month.val(),
|
63
|
+
this.$date.val(),
|
64
|
+
this.$hour.val(),
|
65
|
+
this.$minute.val(),
|
66
|
+
parsedMoment.format("dddd, MMMM Do YYYY, h:mm:ss a"),
|
67
|
+
this.$input.val()
|
68
|
+
]);
|
69
|
+
|
70
|
+
},
|
71
|
+
|
72
|
+
events: {
|
73
|
+
"change input": "parseTime",
|
74
|
+
"blur input": "parseTime",
|
75
|
+
"focus input": "attemptRecovery",
|
76
|
+
}
|
77
|
+
|
78
|
+
});
|
79
|
+
|
80
|
+
FormOrchestrator.register(".timestamp-field", "TimestampFieldView");
|
@@ -0,0 +1,18 @@
|
|
1
|
+
var FlashMessageView = Backbone.View.extend({
|
2
|
+
|
3
|
+
dismissSelf: function() {
|
4
|
+
this.$el.slideUp(200, function() {
|
5
|
+
this.remove();
|
6
|
+
delete this;
|
7
|
+
});
|
8
|
+
},
|
9
|
+
|
10
|
+
events: {
|
11
|
+
"click": "dismissSelf"
|
12
|
+
}
|
13
|
+
|
14
|
+
});
|
15
|
+
|
16
|
+
$(".flash-message").each(function() {
|
17
|
+
new FlashMessageView({el:this});
|
18
|
+
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
var FormOrchestrator = {
|
2
|
+
|
3
|
+
// Filled with objects that map selectors to Backbone Views that
|
4
|
+
// manage them, such as: ".timestamp-field" → "TimestampView"
|
5
|
+
selectorMappings: [],
|
6
|
+
|
7
|
+
// Register a selector (el) and the BackboneView that should be
|
8
|
+
// created to manage each one
|
9
|
+
register: function(selector, backboneViewName) {
|
10
|
+
this.selectorMappings.push({
|
11
|
+
selector: selector,
|
12
|
+
backboneViewName: backboneViewName
|
13
|
+
});
|
14
|
+
},
|
15
|
+
|
16
|
+
// Build each of the registered Backbone Views that are inside
|
17
|
+
// the given rootSelector (either a CSS selector or a jQuery collection)
|
18
|
+
initializeViewsOver: function(rootSelector) {
|
19
|
+
|
20
|
+
this.selectorMappings.forEach(function(mapEntry) {
|
21
|
+
|
22
|
+
// Passed a string selector, find descendants to initialize
|
23
|
+
if (typeof rootSelector === "string") {
|
24
|
+
$(rootSelector).find(mapEntry.selector).each(function() {
|
25
|
+
new window[mapEntry.backboneViewName]({el:this});
|
26
|
+
});
|
27
|
+
}
|
28
|
+
|
29
|
+
// Passed a jQuery collection, filter it to find elements to initialize
|
30
|
+
if (typeof rootSelector === "object") {
|
31
|
+
$(rootSelector).filter(mapEntry.selector).each(function() {
|
32
|
+
new window[mapEntry.backboneViewName]({el:this});
|
33
|
+
});
|
34
|
+
}
|
35
|
+
|
36
|
+
});
|
37
|
+
|
38
|
+
}
|
39
|
+
|
40
|
+
};
|
41
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
var NavigationView = Backbone.View.extend({
|
2
|
+
|
3
|
+
el: "body",
|
4
|
+
|
5
|
+
initialize: function() {
|
6
|
+
this.$navigation = this.$(".navigation");
|
7
|
+
},
|
8
|
+
|
9
|
+
toggleNavigation: function(event) {
|
10
|
+
event.preventDefault();
|
11
|
+
this.$navigation.toggleClass("-open");
|
12
|
+
},
|
13
|
+
|
14
|
+
events: {
|
15
|
+
"click .header-menu-trigger": "toggleNavigation"
|
16
|
+
}
|
17
|
+
|
18
|
+
});
|
19
|
+
|
20
|
+
new NavigationView;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
var ResourceFormView = Backbone.View.extend({
|
2
|
+
|
3
|
+
el: ".resource-form:not(.search-form)",
|
4
|
+
|
5
|
+
initialize: function() {
|
6
|
+
this.focusFirstInput();
|
7
|
+
},
|
8
|
+
|
9
|
+
focusFirstInput: function() {
|
10
|
+
this.$("input:visible, select:visible, textarea:visible").first().focus();
|
11
|
+
},
|
12
|
+
|
13
|
+
events: {
|
14
|
+
}
|
15
|
+
|
16
|
+
});
|
17
|
+
|
18
|
+
new ResourceFormView;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
var SearchFormView = Backbone.View.extend({
|
2
|
+
|
3
|
+
el: "body",
|
4
|
+
|
5
|
+
initialize: function() {
|
6
|
+
this.$form = this.$(".search-form");
|
7
|
+
},
|
8
|
+
|
9
|
+
toggleForm: function() {
|
10
|
+
this.$form.fadeToggle(100);
|
11
|
+
this.$("input:visible, select:visible, textarea:visible").first().focus();
|
12
|
+
},
|
13
|
+
|
14
|
+
events: {
|
15
|
+
"click .search-form-toggle": "toggleForm"
|
16
|
+
}
|
17
|
+
|
18
|
+
});
|
19
|
+
|
20
|
+
new SearchFormView;
|
@@ -0,0 +1,109 @@
|
|
1
|
+
var SessionView = Backbone.View.extend({
|
2
|
+
|
3
|
+
el: "#session-form",
|
4
|
+
readyToSubmit: false,
|
5
|
+
|
6
|
+
initialize: function () {
|
7
|
+
this.$submitButton = this.$("#session-form-submit");
|
8
|
+
this.$emailInput = this.$("#session-form-email");
|
9
|
+
this.$passcodeInput = this.$("#session-form-passcode");
|
10
|
+
this.$spinner = this.$("#session-spinner");
|
11
|
+
this.$feedbackMessage = this.$("#session-form-feedback");
|
12
|
+
this.$resendButton = this.$("#session-form-resend");
|
13
|
+
this.$rememberGroup = this.$("#session-form-remember-group");
|
14
|
+
},
|
15
|
+
|
16
|
+
requestAuthenticationCode: function(event) {
|
17
|
+
|
18
|
+
var self = this;
|
19
|
+
|
20
|
+
self.$passcodeInput.fadeOut(300);
|
21
|
+
self.$submitButton.fadeOut(300);
|
22
|
+
self.$resendButton.fadeOut(300);
|
23
|
+
self.$feedbackMessage.fadeOut(300);
|
24
|
+
self.$emailInput.fadeOut(300);
|
25
|
+
self.$rememberGroup.fadeOut(300);
|
26
|
+
|
27
|
+
window.setTimeout(function() {
|
28
|
+
|
29
|
+
self.$spinner.fadeIn(400);
|
30
|
+
|
31
|
+
$.ajax({
|
32
|
+
|
33
|
+
type: "POST",
|
34
|
+
url: "/admin/signin/code",
|
35
|
+
data: {
|
36
|
+
"administrator": {
|
37
|
+
"email": self.$emailInput.val()
|
38
|
+
}
|
39
|
+
},
|
40
|
+
|
41
|
+
beforeSend: function(xhr) {
|
42
|
+
xhr.setRequestHeader("X-CSRF-Token", RailsMeta.csrfToken);
|
43
|
+
},
|
44
|
+
|
45
|
+
statusCode: {
|
46
|
+
204: function(data, xstatus, xhr) {
|
47
|
+
self.presentPasscodeInput();
|
48
|
+
},
|
49
|
+
404: function(xhr, status, error) {
|
50
|
+
self.presentErrorMessage(xhr.responseJSON.error)
|
51
|
+
},
|
52
|
+
423: function(xhr, status, error) {
|
53
|
+
self.presentErrorMessage(xhr.responseJSON.error)
|
54
|
+
},
|
55
|
+
500: function(xhr, status, error) {
|
56
|
+
self.presentErrorMessage("An unexpected server error occurred. Developers have been notified. Please try again\xA0later.")
|
57
|
+
}
|
58
|
+
},
|
59
|
+
|
60
|
+
timeout: 29000,
|
61
|
+
error: function(xhr, status, error) {
|
62
|
+
self.presentErrorMessage("Could not connect to the server. Check your network connection and try\xA0again.")
|
63
|
+
}
|
64
|
+
|
65
|
+
});
|
66
|
+
|
67
|
+
}, 300);
|
68
|
+
|
69
|
+
},
|
70
|
+
|
71
|
+
presentErrorMessage: function(message) {
|
72
|
+
var self = this;
|
73
|
+
self.readyToSubmit = false;
|
74
|
+
self.$spinner.fadeOut(400, function() {
|
75
|
+
self.$feedbackMessage.html(message).fadeIn(300);
|
76
|
+
self.$emailInput.fadeIn(300);
|
77
|
+
self.$submitButton.html("Request a passcode").fadeIn(300);
|
78
|
+
});
|
79
|
+
},
|
80
|
+
|
81
|
+
presentPasscodeInput: function() {
|
82
|
+
var self = this;
|
83
|
+
self.readyToSubmit = true;
|
84
|
+
self.$spinner.fadeOut(400, function() {
|
85
|
+
self.$passcodeInput.fadeIn(300).val("").focus();
|
86
|
+
self.$feedbackMessage.html("A passcode was just emailed to you.<br> Enter it here to sign in.").fadeIn(300);
|
87
|
+
self.$submitButton.html("Sign In").fadeIn(300);
|
88
|
+
self.$rememberGroup.fadeIn(300);
|
89
|
+
self.$resendButton.fadeIn(300);
|
90
|
+
});
|
91
|
+
},
|
92
|
+
|
93
|
+
handleSubmit: function(event) {
|
94
|
+
if (!this.readyToSubmit) {
|
95
|
+
event.preventDefault();
|
96
|
+
event.stopPropagation();
|
97
|
+
this.requestAuthenticationCode();
|
98
|
+
}
|
99
|
+
},
|
100
|
+
|
101
|
+
events: {
|
102
|
+
"submit": "handleSubmit",
|
103
|
+
"click button": "handleSubmit",
|
104
|
+
"click #session-form-resend": "requestAuthenticationCode"
|
105
|
+
}
|
106
|
+
|
107
|
+
});
|
108
|
+
|
109
|
+
var SessionView = new SessionView;
|
@@ -0,0 +1,47 @@
|
|
1
|
+
var VirualFormView = Backbone.View.extend({
|
2
|
+
|
3
|
+
el: "body",
|
4
|
+
|
5
|
+
submitVirtualForm: function(event) {
|
6
|
+
|
7
|
+
event.preventDefault();
|
8
|
+
var $link = $(event.currentTarget);
|
9
|
+
|
10
|
+
var confirm = $link.attr("data-confirm");
|
11
|
+
var method = $link.attr("data-method");
|
12
|
+
|
13
|
+
// Check for a confirmation attribute and if so, prompt the user
|
14
|
+
if (!!confirm) {
|
15
|
+
if (!window.confirm(confirm)) {
|
16
|
+
return false;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
var href = $link.attr("href");
|
21
|
+
var target = $link.attr("target");
|
22
|
+
|
23
|
+
var $form = $("<form method='post' action=" + href + "></form>");
|
24
|
+
var $metadataInputs = "<input name='_method' value='" + method + "' type='hidden'>";
|
25
|
+
|
26
|
+
if (!!RailsMeta.csrfParam && !!RailsMeta.csrfToken) {
|
27
|
+
$metadataInputs += "<input name='" + RailsMeta.csrfParam + "' value='" + RailsMeta.csrfToken + "' type='hidden'>";
|
28
|
+
}
|
29
|
+
|
30
|
+
if (!!target) {
|
31
|
+
form.attr("target", target);
|
32
|
+
}
|
33
|
+
|
34
|
+
$form.hide().append($metadataInputs).appendTo(this.$el);
|
35
|
+
$form.submit();
|
36
|
+
|
37
|
+
},
|
38
|
+
|
39
|
+
events: {
|
40
|
+
"click a[data-method=delete]": "submitVirtualForm",
|
41
|
+
"click a[data-method=post]": "submitVirtualForm",
|
42
|
+
"click a[data-method=put]": "submitVirtualForm"
|
43
|
+
}
|
44
|
+
|
45
|
+
});
|
46
|
+
|
47
|
+
new VirualFormView;
|
@@ -0,0 +1,149 @@
|
|
1
|
+
// ---------------------------------------------------------------------------
|
2
|
+
// GENERAL RESETS
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
// `border-box` is love, `border-box` is life
|
6
|
+
|
7
|
+
*, *:before, *:after {
|
8
|
+
-webkit-box-sizing: border-box;
|
9
|
+
-moz-box-sizing: border-box;
|
10
|
+
box-sizing: border-box;
|
11
|
+
}
|
12
|
+
|
13
|
+
// Reset most styles
|
14
|
+
|
15
|
+
a, abbr, acronym, address, applet, article, aside,
|
16
|
+
b, big, blockquote, body, button,
|
17
|
+
canvas, caption, cite, code,
|
18
|
+
dd, del, details, dfn, div, dl, dt,
|
19
|
+
em, fieldset, figcaption, figure, font, footer, form,
|
20
|
+
h1, h2, h3, h4, h5, h6, header, html,
|
21
|
+
i, iframe, img, input, ins,
|
22
|
+
kbd, label, legend, li,
|
23
|
+
main, menu, nav, object, ol, option, p, pre, q,
|
24
|
+
s, samp, section, select, small, span, strike, strong, sub, summary, sup,
|
25
|
+
table, tbody, td, textarea, tfoot, th, thead, tr, tt,
|
26
|
+
ul, var {
|
27
|
+
-ms-appearance: none;
|
28
|
+
-moz-appearance: none;
|
29
|
+
-webkit-appearance: none;
|
30
|
+
appearance: none;
|
31
|
+
background-color: transparent;
|
32
|
+
background-repeat: no-repeat;
|
33
|
+
border-collapse: collapse;
|
34
|
+
border-radius: 0;
|
35
|
+
border-spacing: 0;
|
36
|
+
border: 0;
|
37
|
+
font-size: 100%;
|
38
|
+
font-weight: normal;
|
39
|
+
list-style: none;
|
40
|
+
margin: 0;
|
41
|
+
outline: 0;
|
42
|
+
padding: 0;
|
43
|
+
text-decoration: none;
|
44
|
+
}
|
45
|
+
|
46
|
+
b, i {
|
47
|
+
font-style: inherit;
|
48
|
+
font-weight: inherit;
|
49
|
+
}
|
50
|
+
|
51
|
+
// Add the glove cursor to each
|
52
|
+
// universal element that needs it
|
53
|
+
|
54
|
+
a, button,
|
55
|
+
label, input[type=checkbox],
|
56
|
+
select, option {
|
57
|
+
cursor: pointer;
|
58
|
+
}
|
59
|
+
|
60
|
+
// More sensible font default
|
61
|
+
// Prevent zoom issues on mobile browsers
|
62
|
+
// Force a scrollbar
|
63
|
+
|
64
|
+
html {
|
65
|
+
-ms-text-size-adjust: 100%;
|
66
|
+
-moz-text-size-adjust: 100%;
|
67
|
+
-webkit-text-size-adjust: 100%;
|
68
|
+
height: 100%;
|
69
|
+
margin-bottom: 1px;
|
70
|
+
}
|
71
|
+
|
72
|
+
// Reset `table` border junk
|
73
|
+
|
74
|
+
table {
|
75
|
+
border-collapse: collapse;
|
76
|
+
border-spacing: 0;
|
77
|
+
}
|
78
|
+
|
79
|
+
// Ditch default `quote` styles
|
80
|
+
|
81
|
+
blockquote, q {
|
82
|
+
quotes: none;
|
83
|
+
&:after, &:before {
|
84
|
+
content: "";
|
85
|
+
content: none;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
// Prevent nasty 3rd-party embeds from overlapping
|
90
|
+
// absolute or fixed elements
|
91
|
+
|
92
|
+
iframe,
|
93
|
+
object,
|
94
|
+
embed {
|
95
|
+
z-index: 1 !important;
|
96
|
+
}
|
97
|
+
|
98
|
+
// ---------------------------------------------------------------------------
|
99
|
+
// BROWSER FIXES
|
100
|
+
// ---------------------------------------------------------------------------
|
101
|
+
|
102
|
+
// Fix HTML5 issues where these items are not block-level by default
|
103
|
+
|
104
|
+
article, aside, canvas, details,
|
105
|
+
figcaption, figure, footer,
|
106
|
+
header, hgroup, main, menu, nav,
|
107
|
+
section, summary {
|
108
|
+
display: block;
|
109
|
+
}
|
110
|
+
|
111
|
+
// Fix `textarea` overflow on IE 7/8/9/10
|
112
|
+
|
113
|
+
textarea {
|
114
|
+
overflow: auto;
|
115
|
+
}
|
116
|
+
|
117
|
+
// Prevent modern browsers from displaying `audio` when it doesn't have controls.
|
118
|
+
// Remove excess height in iOS 5 devices.
|
119
|
+
|
120
|
+
audio:not([controls]) {
|
121
|
+
display: none;
|
122
|
+
height: 0;
|
123
|
+
}
|
124
|
+
|
125
|
+
// Remove up/down spinners on some WebKit elements
|
126
|
+
|
127
|
+
::-webkit-inner-spin-button,
|
128
|
+
::-webkit-outer-spin-button {
|
129
|
+
-webkit-appearance: none;
|
130
|
+
}
|
131
|
+
|
132
|
+
// Remove extra padding that Firefox adds to elements
|
133
|
+
|
134
|
+
::-moz-focus-inner {
|
135
|
+
border: 0 !important;
|
136
|
+
margin: 0 !important;
|
137
|
+
padding: 0 !important;
|
138
|
+
}
|
139
|
+
|
140
|
+
// Correct `inline-block` display not defined in IE 8/9.
|
141
|
+
// Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
142
|
+
|
143
|
+
audio,
|
144
|
+
canvas,
|
145
|
+
progress,
|
146
|
+
video {
|
147
|
+
display: inline-block;
|
148
|
+
vertical-align: baseline;
|
149
|
+
}
|