From 7e7b147786cded3cade794e567bef7c070a61cd4 Mon Sep 17 00:00:00 2001 From: Sarah Harvey Date: Tue, 16 Apr 2019 10:55:52 -0700 Subject: [PATCH] Move inline JS to rendered files to support CSP --- app/controllers/teaspoon/suite_controller.rb | 6 ++++++ app/views/teaspoon/suite/_boot.html.erb | 4 +--- .../teaspoon/suite/_boot_require_js.html.erb | 20 +------------------ app/views/teaspoon/suite/config.js.erb | 2 ++ app/views/teaspoon/suite/require.js.erb | 17 ++++++++++++++++ app/views/teaspoon/suite/show.html.erb | 5 +---- app/views/teaspoon/suite/vanilla.js.erb | 1 + lib/teaspoon/engine.rb | 1 + 8 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 app/views/teaspoon/suite/config.js.erb create mode 100644 app/views/teaspoon/suite/require.js.erb create mode 100644 app/views/teaspoon/suite/vanilla.js.erb diff --git a/app/controllers/teaspoon/suite_controller.rb b/app/controllers/teaspoon/suite_controller.rb index 3537ae6c..302a5d59 100644 --- a/app/controllers/teaspoon/suite_controller.rb +++ b/app/controllers/teaspoon/suite_controller.rb @@ -16,6 +16,12 @@ def show @suite = Teaspoon::Suite.new(params) end + def js + jstype = params.extract!(:jstype).fetch(:jstype, 'vanilla') + @suite = Teaspoon::Suite.new(params) + render "teaspoon/suite/#{jstype}", :content_type => 'application/javascript' + end + def hook hooks = Teaspoon::Suite.new(params).hooks[params[:hook].to_s] diff --git a/app/views/teaspoon/suite/_boot.html.erb b/app/views/teaspoon/suite/_boot.html.erb index 2cd60f4d..94df70a8 100644 --- a/app/views/teaspoon/suite/_boot.html.erb +++ b/app/views/teaspoon/suite/_boot.html.erb @@ -1,4 +1,2 @@ <%= javascript_include_tag *@suite.spec_assets, debug: @suite.config.expand_assets, allow_non_precompiled: true %> - +<%= javascript_include_tag "#{Teaspoon.configuration.mount_at}/js/#{@suite.name}.vanilla.js" %> diff --git a/app/views/teaspoon/suite/_boot_require_js.html.erb b/app/views/teaspoon/suite/_boot_require_js.html.erb index 02b0f435..f924a902 100644 --- a/app/views/teaspoon/suite/_boot_require_js.html.erb +++ b/app/views/teaspoon/suite/_boot_require_js.html.erb @@ -1,20 +1,2 @@ -<% -rails_config = Rails.application.config -require_options = {baseUrl: rails_config.assets.prefix} -require_options.merge!(urlArgs: "instrument=1", waitSeconds: 0) if Teaspoon.configuration.use_coverage -require_options.merge!(rails_config.requirejs.user_config) if rails_config.respond_to?(:requirejs) -specs = @suite.spec_assets(false).map{ |s| "#{s.gsub(/\.js.*$/, "")}" } -%> - <%= javascript_include_tag @suite.helper %> - +<%= javascript_include_tag "#{Teaspoon.configuration.mount_at}/js/#{@suite.name}.require.js" %> diff --git a/app/views/teaspoon/suite/config.js.erb b/app/views/teaspoon/suite/config.js.erb new file mode 100644 index 00000000..012cc576 --- /dev/null +++ b/app/views/teaspoon/suite/config.js.erb @@ -0,0 +1,2 @@ +Teaspoon.version = <%= Teaspoon::VERSION.to_json.html_safe %>; +Teaspoon.suites = <%= {all: Teaspoon.configuration.suite_configs.keys, active: @suite.name}.to_json.html_safe %>; diff --git a/app/views/teaspoon/suite/require.js.erb b/app/views/teaspoon/suite/require.js.erb new file mode 100644 index 00000000..5c11081a --- /dev/null +++ b/app/views/teaspoon/suite/require.js.erb @@ -0,0 +1,17 @@ +<% +rails_config = Rails.application.config +require_options = {baseUrl: rails_config.assets.prefix} +require_options.merge!(urlArgs: "instrument=1", waitSeconds: 0) if Teaspoon.configuration.use_coverage +require_options.merge!(rails_config.requirejs.user_config) if rails_config.respond_to?(:requirejs) +specs = @suite.spec_assets(false).map{ |s| "#{s.gsub(/\.js.*$/, "")}" } +%> + +Teaspoon.onWindowLoad(function () { + // setup the Teaspoon path prefix to load /assets + require.config(<%= require_options.to_json.html_safe %>); + + // require specs by striping off the .js file extension + require(<%= specs.to_json.html_safe %>, function() { + Teaspoon.execute(); + }); +}); diff --git a/app/views/teaspoon/suite/show.html.erb b/app/views/teaspoon/suite/show.html.erb index 35425326..2084e2f6 100644 --- a/app/views/teaspoon/suite/show.html.erb +++ b/app/views/teaspoon/suite/show.html.erb @@ -7,10 +7,7 @@ <%= stylesheet_link_tag *@suite.stylesheets %> <%= javascript_include_tag *@suite.javascripts %> - + <%= javascript_include_tag "#{Teaspoon.configuration.mount_at}/js/#{@suite.name}.config.js" %> <%= render @suite.boot_partial %> diff --git a/app/views/teaspoon/suite/vanilla.js.erb b/app/views/teaspoon/suite/vanilla.js.erb new file mode 100644 index 00000000..c5d4ee43 --- /dev/null +++ b/app/views/teaspoon/suite/vanilla.js.erb @@ -0,0 +1 @@ +Teaspoon.onWindowLoad(Teaspoon.execute); diff --git a/lib/teaspoon/engine.rb b/lib/teaspoon/engine.rb index e2ca28c2..e7304674 100644 --- a/lib/teaspoon/engine.rb +++ b/lib/teaspoon/engine.rb @@ -9,6 +9,7 @@ class Engine < ::Rails::Engine routes do root to: "suite#index" match "/fixtures/*filename", to: "suite#fixtures", via: :get, as: "fixture" + match "/js/:suite.:jstype.js", to: "suite#js", via: :get, defaults: { suite: "default", jstype: "vanilla" } match "/:suite", to: "suite#show", via: :get, as: "suite", defaults: { suite: "default" } match "/:suite/:hook", to: "suite#hook", via: :post, defaults: { suite: "default", hook: "default" } end