diff --git a/Gemfile.lock b/Gemfile.lock
index 4b18c531..bbaa7460 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1013,7 +1013,7 @@ GEM
multi_json (~> 1)
statsd-ruby (~> 1.1)
bcrypt (3.1.16)
- better_errors (2.7.1)
+ better_errors (2.8.3)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
rack (>= 0.9.0)
@@ -1041,7 +1041,7 @@ GEM
cocoon (1.2.15)
codeclimate-test-reporter (1.0.9)
simplecov (<= 0.13)
- coderay (1.1.2)
+ coderay (1.1.3)
coffee-rails (5.0.0)
coffee-script (>= 2.2.0)
railties (>= 5.2.0)
diff --git a/app/assets/javascripts/_initialization.coffee b/app/assets/javascripts/_initialization.coffee
deleted file mode 100644
index 83da2147..00000000
--- a/app/assets/javascripts/_initialization.coffee
+++ /dev/null
@@ -1,29 +0,0 @@
-## This file is prepended with an underscore to ensure it comes alphabetically-first
-## when application.js includes all JS files in the directory with require_tree.
-## Here be dragons.
-
-window.Notebook ||= {}
-Notebook.init = ->
- # Initialize MaterializeCSS stuff
- M.AutoInit()
- $('.sidenav').sidenav()
- $('.quick-reference-sidenav').sidenav {
- closeOnClick: true,
- edge: 'right',
- draggable: false
- }
- $('#recent-edits-sidenav').sidenav {
- closeOnClick: true,
- edge: 'right',
- draggable: false
- }
- $('.slider').slider { height: 200, indicators: false }
- $('.dropdown-trigger').dropdown { coverTrigger: false }
- $('.tooltipped').tooltip { enterDelay: 50 }
- $('.with-character-counter').characterCounter();
- $('.materialboxed').materialbox();
-
-# We're using $ -> here for document readiness, but if we ever use Turbolinks we'd want:
-# $(document).on "turbolinks:load", ->
-$ ->
- Notebook.init()
\ No newline at end of file
diff --git a/app/assets/javascripts/_initialization.js b/app/assets/javascripts/_initialization.js
new file mode 100644
index 00000000..47bf8d7c
--- /dev/null
+++ b/app/assets/javascripts/_initialization.js
@@ -0,0 +1,27 @@
+//# This file is prepended with an underscore to ensure it comes alphabetically-first
+//# when application.js includes all JS files in the directory with require_tree.
+//# Here be dragons.
+
+if (!window.Notebook) { window.Notebook = {}; }
+Notebook.init = function() {
+ // Initialize MaterializeCSS stuff
+ M.AutoInit();
+ $('.sidenav').sidenav();
+ $('.quick-reference-sidenav').sidenav({
+ closeOnClick: true,
+ edge: 'right',
+ draggable: false
+ });
+ $('#recent-edits-sidenav').sidenav({
+ closeOnClick: true,
+ edge: 'right',
+ draggable: false
+ });
+ $('.slider').slider({ height: 200, indicators: false });
+ $('.dropdown-trigger').dropdown({ coverTrigger: false });
+ $('.tooltipped').tooltip({ enterDelay: 50 });
+ $('.with-character-counter').characterCounter();
+ $('.materialboxed').materialbox();
+};
+
+$(() => Notebook.init());
diff --git a/app/assets/javascripts/collaboration.coffee b/app/assets/javascripts/collaboration.coffee
deleted file mode 100644
index fcec61f4..00000000
--- a/app/assets/javascripts/collaboration.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-$ ->
- # When a user clicks to remove a collaborator, we should remove them from the list of collaborators after the remote request finishes
- $('a.js-remove-contributor[data-remote]').on 'ajax:success', (e, data, status, xhr) ->
-
- # Remove the image from the UI
- $(this).closest('.collection-item').fadeOut().remove() # todo use animate.css for something more fun
-
- return
\ No newline at end of file
diff --git a/app/assets/javascripts/collaboration.js b/app/assets/javascripts/collaboration.js
new file mode 100644
index 00000000..8183bf3e
--- /dev/null
+++ b/app/assets/javascripts/collaboration.js
@@ -0,0 +1,5 @@
+// When a user clicks to remove a collaborator, we should remove them from the list of collaborators after the remote request finishes
+$('a.js-remove-contributor[data-remote]').on('ajax:success', function(e, data, status, xhr) {
+ // Remove the image from the UI
+ $(this).closest('.collection-item').fadeOut().remove(); // todo use animate.css for something more fun
+});
diff --git a/app/assets/javascripts/document_editor.coffee b/app/assets/javascripts/document_editor.coffee
deleted file mode 100644
index 2c9ac9f0..00000000
--- a/app/assets/javascripts/document_editor.coffee
+++ /dev/null
@@ -1,117 +0,0 @@
-class Notebook.DocumentEditor
- constructor: (@el) ->
- return unless @el.length > 0
-
- window.editor = new MediumEditor('#editor',
- targetBlank: true
- autoLink: false
- buttonLabels: 'fontawesome'
- toolbar: buttons: [
- 'bold'
- 'italic'
- 'underline'
- 'strikethrough'
- {
- name: 'h1'
- action: 'append-h2'
- aria: 'header type 1'
- tagNames: [ 'h2' ]
- contentDefault: 'H1'
- classList: [ 'custom-class-h1' ]
- attrs: 'data-custom-attr': 'attr-value-h1'
- }
- {
- name: 'h2'
- action: 'append-h3'
- aria: 'header type 2'
- tagNames: [ 'h3' ]
- contentDefault: 'H2'
- classList: [ 'custom-class-h2' ]
- attrs: 'data-custom-attr': 'attr-value-h2'
- }
- {
- name: 'h3'
- action: 'append-h4'
- aria: 'header type 3'
- tagNames: [ 'h4' ]
- contentDefault: 'H3'
- classList: [ 'custom-class-h3' ]
- attrs: 'data-custom-attr': 'attr-value-h3'
- }
- 'justifyLeft'
- 'justifyCenter'
- 'justifyRight'
- 'justifyFull'
- 'orderedlist'
- 'unorderedlist'
- 'quote'
- 'anchor'
- 'removeFormat'
- ]
- anchorPreview: hideDelay: 0
- placeholder: text: 'Write as little or as much as you want!'
- paste: forcePlainText: false)
-
- # Autosave
- autosave_event = null
- last_autosave = null
-
- autosave = ->
- if autosave_event == null
-
- console.log 'Queueing autosave'
- $('.js-autosave-icon').addClass 'grey-text'
- $('.js-autosave-icon').removeClass 'black-text'
- $('.js-autosave-icon').removeClass 'red-text'
- $('.js-autosave-status').text 'Saving changes...'
-
- autosave_event = setTimeout((->
- console.log 'Autosaving...'
- $('.js-autosave-status').text 'Saving...'
- autosave_event = null
-
- # Do the autosave
- last_autosave = $.ajax(
- type: 'PATCH'
- url: $('#editor').data('save-url'),
- data: document:
- title: $('#document_title').val()
- body: $('#editor').html()
- )
-
- last_autosave.fail (jqXHR, textStatus) ->
- $('.js-autosave-status').text 'There was a problem saving! We will try to save again, but please make sure you back up any changes.'
- $('.js-autosave-status').addClass 'red-text'
- $('.js-autosave-status').removeClass 'grey-text'
- $('.js-autosave-status').removeClass 'black-text'
- return
-
- # Done!
- $('.js-autosave-icon').addClass 'black-text'
- $('.js-autosave-icon').removeClass 'grey-text'
- $('.js-autosave-icon').removeClass 'red-text'
- $('.js-autosave-status').text 'Saved!'
-
- return
- ), 2500)
-
- else
- console.log 'Waiting for existing autosave'
-
- return
-
- editor.subscribe 'editableInput', autosave
- $('#document_title').on 'change', autosave
- $('#document_title').on 'keydown', autosave
- $('.js-autosave-status').on 'click', autosave
-
- # Allow entering `tab` into the editor
- $(document).delegate '#editor', 'keydown', (e) ->
- keyCode = e.keyCode or e.which
- if keyCode == 9
- e.preventDefault()
-
- return
-
-$ ->
- new Notebook.DocumentEditor $("body.documents.edit")
\ No newline at end of file
diff --git a/app/assets/javascripts/document_editor.js b/app/assets/javascripts/document_editor.js
new file mode 100644
index 00000000..8e4e2a2b
--- /dev/null
+++ b/app/assets/javascripts/document_editor.js
@@ -0,0 +1,128 @@
+Notebook.DocumentEditor = class DocumentEditor {
+ constructor(el) {
+ this.el = el;
+ if (!(this.el.length > 0)) { return; }
+
+ window.editor = new MediumEditor('#editor', {
+ targetBlank: true,
+ autoLink: false,
+ buttonLabels: 'fontawesome',
+ toolbar: { buttons: [
+ 'bold',
+ 'italic',
+ 'underline',
+ 'strikethrough',
+ {
+ name: 'h1',
+ action: 'append-h2',
+ aria: 'header type 1',
+ tagNames: [ 'h2' ],
+ contentDefault: 'H1',
+ classList: [ 'custom-class-h1' ],
+ attrs: { 'data-custom-attr': 'attr-value-h1'
+ }
+ },
+ {
+ name: 'h2',
+ action: 'append-h3',
+ aria: 'header type 2',
+ tagNames: [ 'h3' ],
+ contentDefault: 'H2',
+ classList: [ 'custom-class-h2' ],
+ attrs: { 'data-custom-attr': 'attr-value-h2'
+ }
+ },
+ {
+ name: 'h3',
+ action: 'append-h4',
+ aria: 'header type 3',
+ tagNames: [ 'h4' ],
+ contentDefault: 'H3',
+ classList: [ 'custom-class-h3' ],
+ attrs: { 'data-custom-attr': 'attr-value-h3'
+ }
+ },
+ 'justifyLeft',
+ 'justifyCenter',
+ 'justifyRight',
+ 'justifyFull',
+ 'orderedlist',
+ 'unorderedlist',
+ 'quote',
+ 'anchor',
+ 'removeFormat'
+ ]
+ },
+ anchorPreview: { hideDelay: 0
+ },
+ placeholder: { text: 'Write as little or as much as you want!'
+ },
+ paste: { forcePlainText: false
+ }
+ });
+
+ // Autosave
+ let autosave_event = null;
+ let last_autosave = null;
+
+ const autosave = function() {
+ if (autosave_event === null) {
+
+ console.log('Queueing autosave');
+ $('.js-autosave-icon').addClass('grey-text');
+ $('.js-autosave-icon').removeClass('black-text');
+ $('.js-autosave-icon').removeClass('red-text');
+ $('.js-autosave-status').text('Saving changes...');
+
+ autosave_event = setTimeout((function() {
+ console.log('Autosaving...');
+ $('.js-autosave-status').text('Saving...');
+ autosave_event = null;
+
+ // Do the autosave
+ last_autosave = $.ajax({
+ type: 'PATCH',
+ url: $('#editor').data('save-url'),
+ data: { document: {
+ title: $('#document_title').val(),
+ body: $('#editor').html()
+ }
+ }
+ });
+
+ last_autosave.fail(function(jqXHR, textStatus) {
+ $('.js-autosave-status').text('There was a problem saving! We will try to save again, but please make sure you back up any changes.');
+ $('.js-autosave-status').addClass('red-text');
+ $('.js-autosave-status').removeClass('grey-text');
+ $('.js-autosave-status').removeClass('black-text');
+ });
+
+ // Done!
+ $('.js-autosave-icon').addClass('black-text');
+ $('.js-autosave-icon').removeClass('grey-text');
+ $('.js-autosave-icon').removeClass('red-text');
+ $('.js-autosave-status').text('Saved!');
+
+ }), 2500);
+
+ } else {
+ console.log('Waiting for existing autosave');
+ }
+ };
+
+ editor.subscribe('editableInput', autosave);
+ $('#document_title').on('change', autosave);
+ $('#document_title').on('keydown', autosave);
+ $('.js-autosave-status').on('click', autosave);
+
+ // Allow entering `tab` into the editor
+ $(document).delegate('#editor', 'keydown', function(e) {
+ const keyCode = e.keyCode || e.which;
+ if (keyCode === 9) {
+ e.preventDefault();
+ }
+ });
+ }
+};
+
+$(() => new Notebook.DocumentEditor($("body.documents.edit")));
diff --git a/app/assets/javascripts/generators.js b/app/assets/javascripts/generators.js
new file mode 100644
index 00000000..2fe9da4c
--- /dev/null
+++ b/app/assets/javascripts/generators.js
@@ -0,0 +1,41 @@
+$(document).ready(function() {
+
+ // Character name generator
+ $('.character_name_generator').click(function() {
+ const target = $(this).closest('.row').find('input[type=text]');
+ $.ajax({
+ dataType: 'text',
+ url: '/generate/character/name',
+ success(data) {
+ target.val(data);
+ }
+ });
+ return 0;
+ });
+
+ // Character age generator
+ $('.character_age_generator').click(function() {
+ const target = $(this).closest('.row').find('input[type=text]');
+ $.ajax({
+ dataType: 'text',
+ url: '/generate/character/age',
+ success(data) {
+ target.val(data);
+ }
+ });
+ return 0;
+ });
+
+ // Location name generator
+ $('.location_name_generator').click(function() {
+ const target = $(this).closest('.row').find('input[type=text]');
+ $.ajax({
+ dataType: 'text',
+ url: '/generate/location/name',
+ success(data) {
+ target.val(data);
+ }
+ });
+ return 0;
+ });
+});
diff --git a/app/assets/javascripts/generators.js.coffee b/app/assets/javascripts/generators.js.coffee
deleted file mode 100644
index 94b745f3..00000000
--- a/app/assets/javascripts/generators.js.coffee
+++ /dev/null
@@ -1,31 +0,0 @@
-$(document).ready ->
-
- # Character name generator
- $('.character_name_generator').click ->
- target = $(this).closest('.row').find('input[type=text]')
- $.ajax
- dataType: 'text'
- url: '/generate/character/name'
- success: (data) ->
- target.val data
- 0
-
- # Character age generator
- $('.character_age_generator').click ->
- target = $(this).closest('.row').find('input[type=text]')
- $.ajax
- dataType: 'text'
- url: '/generate/character/age'
- success: (data) ->
- target.val data
- 0
-
- # Location name generator
- $('.location_name_generator').click ->
- target = $(this).closest('.row').find('input[type=text]')
- $.ajax
- dataType: 'text'
- url: '/generate/location/name'
- success: (data) ->
- target.val data
- 0
diff --git a/app/assets/javascripts/help.coffee b/app/assets/javascripts/help.coffee
deleted file mode 100644
index 24f83d18..00000000
--- a/app/assets/javascripts/help.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/javascripts/image_uploads.coffee b/app/assets/javascripts/image_uploads.coffee
deleted file mode 100644
index fb1db7e8..00000000
--- a/app/assets/javascripts/image_uploads.coffee
+++ /dev/null
@@ -1,6 +0,0 @@
-$ ->
- # When a user clicks to delete an image, we should remove it from the list of images after the remote request finishes
- $('a.js-remove-image[data-remote]').on 'ajax:success', (e, data, status, xhr) ->
- # Remove the image from the UI
- $(this).closest('.row').fadeOut().remove() # todo use animate.css for something more fun
- return
diff --git a/app/assets/javascripts/image_uploads.js b/app/assets/javascripts/image_uploads.js
new file mode 100644
index 00000000..7fb373f0
--- /dev/null
+++ b/app/assets/javascripts/image_uploads.js
@@ -0,0 +1,5 @@
+// When a user clicks to delete an image, we should remove it from the list of images after the remote request finishes
+$('a.js-remove-image[data-remote]').on('ajax:success', function(e, data, status, xhr) {
+ // Remove the image from the UI
+ $(this).closest('.row').fadeOut().remove(); // todo use animate.css for something more fun
+});
diff --git a/app/assets/javascripts/pickers.js b/app/assets/javascripts/pickers.js
new file mode 100644
index 00000000..d96602f1
--- /dev/null
+++ b/app/assets/javascripts/pickers.js
@@ -0,0 +1,4 @@
+$(document).ready(() => $('.dropdown-picker li a').click(function() {
+ const val = $(this).text();
+ $(this).closest('.row').find('input[type=text]').val(val);
+}));
diff --git a/app/assets/javascripts/pickers.js.coffee b/app/assets/javascripts/pickers.js.coffee
deleted file mode 100644
index 2268a4a5..00000000
--- a/app/assets/javascripts/pickers.js.coffee
+++ /dev/null
@@ -1,4 +0,0 @@
-$(document).ready ->
- $('.dropdown-picker li a').click ->
- val = $(this).text()
- $(this).closest('.row').find('input[type=text]').val(val)
diff --git a/app/assets/javascripts/stripe.coffee b/app/assets/javascripts/stripe.coffee
deleted file mode 100644
index c321be5b..00000000
--- a/app/assets/javascripts/stripe.coffee
+++ /dev/null
@@ -1,36 +0,0 @@
-class Notebook.StripeHandler
- constructor: (@el) ->
- return unless @el.length > 0
-
- $form = $('#payment-form')
- stripeResponseHandler = (status, response) ->
- $form = $('#payment-form')
- if response.error
- # Show the errors on the form:
- $form.find('.payment-errors').text response.error.message
- $form.find('.submit').prop 'disabled', false
-
- else
- # Insert the created token ID into the form so it gets submitted to the server:
- token = response.id
- $form.append $('').val(token)
-
- # Submit the form:
- $form.get(0).submit()
-
- return
-
- $form.submit (event) ->
- # Disable the submit button to prevent repeated clicks:
- $form.find('.submit').prop 'disabled', true
-
- # Request a token from Stripe:
- Stripe.card.createToken $form, stripeResponseHandler
-
- # Prevent the form from being submitted:
- false
-
- return
-
-$ ->
- new Notebook.StripeHandler $("body.subscriptions.information")
\ No newline at end of file
diff --git a/app/assets/javascripts/stripe.js b/app/assets/javascripts/stripe.js
new file mode 100644
index 00000000..ed844853
--- /dev/null
+++ b/app/assets/javascripts/stripe.js
@@ -0,0 +1,39 @@
+Notebook.StripeHandler = class StripeHandler {
+ constructor(el) {
+ this.el = el;
+ if (!(this.el.length > 0)) { return; }
+
+ let $form = $('#payment-form');
+ const stripeResponseHandler = function(status, response) {
+ $form = $('#payment-form');
+ if (response.error) {
+ // Show the errors on the form:
+ $form.find('.payment-errors').text(response.error.message);
+ $form.find('.submit').prop('disabled', false);
+
+ } else {
+ // Insert the created token ID into the form so it gets submitted to the server:
+ const token = response.id;
+ $form.append($('').val(token));
+
+ // Submit the form:
+ $form.get(0).submit();
+ }
+
+ };
+
+ $form.submit(function(event) {
+ // Disable the submit button to prevent repeated clicks:
+ $form.find('.submit').prop('disabled', true);
+
+ // Request a token from Stripe:
+ Stripe.card.createToken($form, stripeResponseHandler);
+
+ // Prevent the form from being submitted:
+ return false;
+ });
+
+ }
+};
+
+$(() => new Notebook.StripeHandler($("body.subscriptions.information")));
diff --git a/app/assets/javascripts/thredded_proxy.coffee b/app/assets/javascripts/thredded_proxy.coffee
deleted file mode 100644
index 24f83d18..00000000
--- a/app/assets/javascripts/thredded_proxy.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/