diff --git a/Gemfile b/Gemfile index 8b29154be..95ddcbb4d 100644 --- a/Gemfile +++ b/Gemfile @@ -47,6 +47,7 @@ gem 'redcarpet', '~> 3.5' gem 'simple_form' gem 'tinymce-rails' gem 'image_processing', '~> 1.2' +gem 'puppeteer-ruby' gem 'react-rails' gem 'webpacker' diff --git a/Gemfile.lock b/Gemfile.lock index 93db6869f..95bdc765a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -345,6 +345,10 @@ GEM nio4r (~> 2.0) pundit (2.1.1) activesupport (>= 3.0.0) + puppeteer-ruby (0.40.7) + concurrent-ruby (~> 1.1.0) + mime-types (>= 3.0) + websocket-driver (>= 0.6.0) racc (1.6.0) rack (2.2.3.1) rack-mini-profiler (2.3.3) @@ -556,6 +560,7 @@ DEPENDENCIES pry-rescue puma pundit + puppeteer-ruby rack-mini-profiler rack-timeout (~> 0.5) rails (~> 6.1.4) diff --git a/app/controllers/staff/pages_controller.rb b/app/controllers/staff/pages_controller.rb index 8a463009d..809e69b2d 100644 --- a/app/controllers/staff/pages_controller.rb +++ b/app/controllers/staff/pages_controller.rb @@ -11,6 +11,7 @@ def index def show @body = params[:preview] || @page.unpublished_body || "" + @include_tailwind = true render template: 'pages/show', layout: "themes/#{current_website.theme}" end @@ -39,6 +40,8 @@ def update def preview; end def publish + save_tailwind_page_content + @page.update(published_body: @page.unpublished_body, body_published_at: Time.current) flash[:success] = "#{@page.name} Page was successfully published." @@ -67,6 +70,24 @@ def set_page end end + def save_tailwind_page_content + Puppeteer.launch(args: ['--no-sandbox', '--disable-setuid-sandbox']) do |browser| + page = browser.pages.first || browser.new_page + page.goto(root_url) + cookies.each do |name, value| + page.set_cookie(name: name, value: value) + end + page.goto(event_staff_page_url(current_event, @page), wait_until: 'domcontentloaded') + css = page.query_selector_all('style').map do |style| + style.evaluate('(el) => el.textContent') + end.detect { |text| text.match("tailwindcss") } + html = "" + + content = @page.contents.find_or_initialize_by(name: Page::TAILWIND) + content.update!(placement: Website::Content::HEAD, html: html) + end + end + def build_page if template = params[:page] && page_params[:template].presence Page.from_template( diff --git a/app/helpers/page_helper.rb b/app/helpers/page_helper.rb index bdbf126c3..c6443275b 100644 --- a/app/helpers/page_helper.rb +++ b/app/helpers/page_helper.rb @@ -36,4 +36,10 @@ def background_style def logo_image(args) resize_image_tag(current_website.logo, **args) end + + def tailwind_content + return false if @include_tailwind + + @page&.tailwind_css&.html_safe + end end diff --git a/app/javascript/packs/default_theme.js b/app/javascript/packs/default_theme.js new file mode 100644 index 000000000..72ef077f8 --- /dev/null +++ b/app/javascript/packs/default_theme.js @@ -0,0 +1 @@ +import "controllers" diff --git a/app/models/page.rb b/app/models/page.rb index e77807361..f5edd5adc 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -4,9 +4,13 @@ class Page < ApplicationRecord 'home' => { }, } + TAILWIND = 'tailwind'.freeze + belongs_to :website after_save_commit :purge_website_cache + has_many :contents, class_name: 'Website::Content', as: :contentable, dependent: :destroy + scope :published, -> { where.not(published_body: nil).where(hide_page: false) } scope :in_footer, -> { published.where.not(footer_category: [nil, ""]) } @@ -39,6 +43,10 @@ def unpublished_changes? published_body != unpublished_body end + def tailwind_css + contents.where(name: TAILWIND).pluck(:html).first + end + private def purge_website_cache diff --git a/app/models/website.rb b/app/models/website.rb index e355fc7dd..a5ca3eaa4 100644 --- a/app/models/website.rb +++ b/app/models/website.rb @@ -4,7 +4,7 @@ class Website < ApplicationRecord belongs_to :event has_many :pages, dependent: :destroy has_many :fonts, class_name: 'Website::Font', dependent: :destroy - has_many :contents, class_name: 'Website::Content', dependent: :destroy + has_many :contents, class_name: 'Website::Content', as: :contentable, dependent: :destroy has_one :meta_data, class_name: 'Website::MetaData', dependent: :destroy has_many :session_formats, through: :event diff --git a/app/models/website/content.rb b/app/models/website/content.rb index fe61a5df4..ab7551ba6 100644 --- a/app/models/website/content.rb +++ b/app/models/website/content.rb @@ -4,9 +4,10 @@ class Website::Content < ApplicationRecord FOOTER = "footer", ].freeze - belongs_to :website + belongs_to :contentable, polymorphic: true scope :for, -> (placement) { where(placement: placement) } + scope :for_page, -> (slug) { where(name: slug) } end # == Schema Information diff --git a/app/views/layouts/themes/default.html.haml b/app/views/layouts/themes/default.html.haml index 95a18ac72..cc7716dfa 100644 --- a/app/views/layouts/themes/default.html.haml +++ b/app/views/layouts/themes/default.html.haml @@ -21,11 +21,11 @@ %meta{property: "twitter:image", content: current_website.meta_image_url} = stylesheet_link_tag current_website.theme, media: 'all' - = javascript_pack_tag "application" + = javascript_pack_tag "default_theme" :css #{current_website.font_faces_css} #{current_website.font_root_css} - = javascript_pack_tag "tailwind" + = tailwind_content || javascript_pack_tag("tailwind") = current_website.head_content %body @@ -58,4 +58,4 @@ }) = current_website.footer_content - = yield :javascript \ No newline at end of file + = yield :javascript diff --git a/db/migrate/20220609140626_convert_website_contents_to_polymorphic.rb b/db/migrate/20220609140626_convert_website_contents_to_polymorphic.rb new file mode 100644 index 000000000..e402ebbf2 --- /dev/null +++ b/db/migrate/20220609140626_convert_website_contents_to_polymorphic.rb @@ -0,0 +1,10 @@ +class ConvertWebsiteContentsToPolymorphic < ActiveRecord::Migration[6.1] + def change + change_table :website_contents, bulk: true do |t| + t.rename :website_id, :contentable_id + t.string :contentable_type, default: 'Website', null: false + t.index [:contentable_id, :contentable_type] + t.remove_index :contentable_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 910c0c409..c26da9691 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_05_23_185412) do +ActiveRecord::Schema.define(version: 2022_06_09_140626) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -344,10 +344,11 @@ t.text "html" t.string "placement", default: "head", null: false t.string "name" - t.bigint "website_id" + t.bigint "contentable_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false - t.index ["website_id"], name: "index_website_contents_on_website_id" + t.string "contentable_type", default: "Website", null: false + t.index ["contentable_id", "contentable_type"], name: "index_website_contents_on_contentable_id_and_contentable_type" end create_table "website_fonts", force: :cascade do |t| diff --git a/spec/features/website/configuration_spec.rb b/spec/features/website/configuration_spec.rb index 0b9f10d97..608b2a2e6 100644 --- a/spec/features/website/configuration_spec.rb +++ b/spec/features/website/configuration_spec.rb @@ -71,7 +71,7 @@ website = create(:website, event: event) home_page = create(:page, website: website) - login_as(organizer) + signin_as(organizer) visit edit_event_staff_website_path(event) click_on("Add Content") fill_in_codemirror(<<~HTML @@ -111,7 +111,7 @@ visit page_path(event, home_page) expect(response_headers["Cache-Control"]).to eq("max-age=0, private, s-maxage=0") - login_as(organizer) + signin_as(organizer) visit edit_event_staff_website_path(event) select("automatic", from: "Caching") @@ -126,7 +126,6 @@ expect(response_headers["Last-Modified"]).to eq(last_modified) RSpec::Mocks.space.proxy_for(fastly_service).reset - sleep 1 visit event_staff_pages_path(event) click_on("Publish") expect(fastly_service).to have_received(:purge_by_key).with(event.slug) @@ -145,7 +144,6 @@ last_modified = response_headers["Last-Modified"] RSpec::Mocks.space.proxy_for(fastly_service).reset - sleep 1 visit event_staff_pages_path(event) click_on("Publish") expect(fastly_service).not_to have_received(:purge_by_key).with(event.slug) diff --git a/spec/features/website/page_management_spec.rb b/spec/features/website/page_management_spec.rb index ac2076510..f65477e0b 100644 --- a/spec/features/website/page_management_spec.rb +++ b/spec/features/website/page_management_spec.rb @@ -60,7 +60,7 @@ scenario "Organizer publishes a website page", :js do home_page = create(:page, unpublished_body: 'Home Content', published_body: nil) - login_as(organizer) + signin_as(organizer) visit page_path(slug: event.slug, page: home_page.slug) expect(page).to have_content("Page Not Found") @@ -91,7 +91,7 @@ end scenario "Organizer creates and publishes a splash page from a template", :js do - login_as(organizer) + signin_as(organizer) visit new_event_staff_page_path(event) select("splash", from: "template") diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 692c78f28..a43f3ee59 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -93,3 +93,4 @@ def save_timestamped_screenshot(page) page.save_screenshot(screenshot_path) end +Capybara.default_max_wait_time = 3.seconds diff --git a/spec/support/helpers/session_helpers.rb b/spec/support/helpers/session_helpers.rb index 98b9250c9..b86a2d578 100644 --- a/spec/support/helpers/session_helpers.rb +++ b/spec/support/helpers/session_helpers.rb @@ -22,5 +22,8 @@ def forgot_password(email) click_button 'Send me reset password instructions' end + def signin_as(user) + signin(user.email, user.password) + end end end