From 5bdb95cd95eb518f01e3febd61e162cfcb933a5a Mon Sep 17 00:00:00 2001 From: Sascha Karnatz <122262394+sascha-karnatz@users.noreply.github.com> Date: Fri, 3 Nov 2023 12:44:43 +0100 Subject: [PATCH 1/2] Create menubar web component Create a small Web component wrapper to show the Menubar as a web component, which encapsulate the menubar CSS and the HTML. --- app/assets/config/alchemy_manifest.js | 1 - .../javascripts/alchemy/menubar.js.coffee | 8 ----- app/assets/stylesheets/alchemy/menubar.scss | 13 ++++---- app/javascript/menubar.js | 10 +++++++ app/views/alchemy/_menubar.html.erb | 30 +++++++++++-------- 5 files changed, 34 insertions(+), 28 deletions(-) delete mode 100644 app/assets/javascripts/alchemy/menubar.js.coffee create mode 100644 app/javascript/menubar.js diff --git a/app/assets/config/alchemy_manifest.js b/app/assets/config/alchemy_manifest.js index 6faec0f116..e7f0abeca5 100644 --- a/app/assets/config/alchemy_manifest.js +++ b/app/assets/config/alchemy_manifest.js @@ -2,7 +2,6 @@ //= link alchemy/admin/all.js //= link alchemy/preview.js //= link alchemy/menubar.css -//= link alchemy/menubar.js //= link alchemy/print.css //= link alchemy/welcome.css //= link tinymce/plugins/alchemy_link/plugin.min.js diff --git a/app/assets/javascripts/alchemy/menubar.js.coffee b/app/assets/javascripts/alchemy/menubar.js.coffee deleted file mode 100644 index 5b4694df91..0000000000 --- a/app/assets/javascripts/alchemy/menubar.js.coffee +++ /dev/null @@ -1,8 +0,0 @@ -window.Alchemy = {} if typeof(window.Alchemy) is 'undefined' - -Alchemy.showMenubar = -> - menubar = document.getElementById('alchemy_menubar') - if (typeof(menubar) != 'undefined' && menubar != null) - menubar.style.display = "block" - -Alchemy.showMenubar() diff --git a/app/assets/stylesheets/alchemy/menubar.scss b/app/assets/stylesheets/alchemy/menubar.scss index 85e43e7f7c..0684eefb5a 100644 --- a/app/assets/stylesheets/alchemy/menubar.scss +++ b/app/assets/stylesheets/alchemy/menubar.scss @@ -32,13 +32,13 @@ } &:after { - content: ''; + content: ""; width: 24px; height: 24px; position: absolute; right: 10px; top: 50%; - background: image-url('alchemy/icon-white.svg') 1px 1px no-repeat; + background: image-url("alchemy/icon-white.svg") 1px 1px no-repeat; background-size: 24px 24px; transform: translateY(-50%); } @@ -57,7 +57,8 @@ list-style-type: none; text-align: center; - a, button { + a, + button { @include button-defaults( $background-color: $main-menu-bg-color, $hover-color: $blue, @@ -70,10 +71,10 @@ ); width: 100%; text-decoration: none !important; - text-transform: none; - font-family: $default-font-family; - &:after { display: none } + &:after { + display: none; + } } } } diff --git a/app/javascript/menubar.js b/app/javascript/menubar.js new file mode 100644 index 0000000000..369ec38019 --- /dev/null +++ b/app/javascript/menubar.js @@ -0,0 +1,10 @@ +class Menubar extends HTMLElement { + constructor() { + super() + const template = this.querySelector("template") + const attachedShadowRoot = this.attachShadow({ mode: "open" }) + attachedShadowRoot.appendChild(template.content.cloneNode(true)) + } +} + +customElements.define("alchemy-menubar", Menubar) diff --git a/app/views/alchemy/_menubar.html.erb b/app/views/alchemy/_menubar.html.erb index 272c970730..ce296a2287 100644 --- a/app/views/alchemy/_menubar.html.erb +++ b/app/views/alchemy/_menubar.html.erb @@ -1,16 +1,20 @@ <% if !@preview_mode && @page && can?(:edit_content, @page) %> - + + + - <%= stylesheet_link_tag("alchemy/menubar") %> - <%= javascript_include_tag('alchemy/menubar') %> + <%= javascript_include_tag('menubar', type: "module") %> <% end %> From 34320ee722c7fb1c202e80cc0d18b5495f0d38ee Mon Sep 17 00:00:00 2001 From: Sascha Karnatz <122262394+sascha-karnatz@users.noreply.github.com> Date: Fri, 3 Nov 2023 15:31:26 +0100 Subject: [PATCH 2/2] Add Capybara Shadowdom gem Parts of the page feature are failing because the selector of the menubar isn't available anymore, because that part is in a shadow root of the menubar component. --- alchemy_cms.gemspec | 1 + spec/features/page_feature_spec.rb | 24 +++++++++++++----------- spec/rails_helper.rb | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/alchemy_cms.gemspec b/alchemy_cms.gemspec index 1690e9b3a9..564989321d 100644 --- a/alchemy_cms.gemspec +++ b/alchemy_cms.gemspec @@ -56,6 +56,7 @@ Gem::Specification.new do |gem| gem.add_development_dependency "capybara", ["~> 3.0"] gem.add_development_dependency "capybara-screenshot", ["~> 1.0"] + gem.add_development_dependency "capybara-shadowdom", ["~> 0.3"] gem.add_development_dependency "factory_bot_rails", ["~> 6.0"] gem.add_development_dependency "puma", ["~> 6.0"] gem.add_development_dependency "rails-controller-testing", ["~> 1.0"] diff --git a/spec/features/page_feature_spec.rb b/spec/features/page_feature_spec.rb index 07eedea92c..988403adbb 100644 --- a/spec/features/page_feature_spec.rb +++ b/spec/features/page_feature_spec.rb @@ -68,7 +68,7 @@ context "rendering for guest users" do it "is prohibited" do visit "/#{public_page.urlname}" - within("body") { expect(page).not_to have_selector("#alchemy_menubar") } + within("body") { expect(page).not_to have_selector("alchemy-menubar") } end end @@ -76,7 +76,7 @@ it "is prohibited" do authorize_user(build(:alchemy_dummy_user)) visit "/#{public_page.urlname}" - within("body") { expect(page).not_to have_selector("#alchemy_menubar") } + within("body") { expect(page).not_to have_selector("alchemy-menubar") } end end @@ -84,7 +84,7 @@ it "is allowed" do authorize_user(:as_author) visit "/#{public_page.urlname}" - within("body") { expect(page).to have_selector("#alchemy_menubar") } + within("body") { expect(page).to have_selector("alchemy-menubar") } end end @@ -92,7 +92,7 @@ it "is allowed" do authorize_user(:as_editor) visit "/#{public_page.urlname}" - within("body") { expect(page).to have_selector("#alchemy_menubar") } + within("body") { expect(page).to have_selector("alchemy-menubar") } end end @@ -100,31 +100,33 @@ it "is allowed" do authorize_user(:as_admin) visit "/#{public_page.urlname}" - within("body") { expect(page).to have_selector("#alchemy_menubar") } + within("body") { expect(page).to have_selector("alchemy-menubar") } end end - context "contains" do + context "contains", js: true do + let(:host) { "#{page.server.host}:#{page.server.port}" } + before do authorize_user(:as_admin) visit "/#{public_page.urlname}" end it "a link to the admin area" do - within("#alchemy_menubar") do - expect(page).to have_selector("li a[href='#{alchemy.admin_dashboard_url(host: Capybara.current_host)}']") + within find("alchemy-menubar").shadow_root do + expect(page).to have_selector("li a[href='#{alchemy.admin_dashboard_url(host: host)}']") end end it "a link to edit the current page" do - within("#alchemy_menubar") do + within find("alchemy-menubar").shadow_root do expect(page).to \ - have_selector("li a[href='#{alchemy.edit_admin_page_url(public_page, host: Capybara.current_host)}']") + have_selector("li a[href='#{alchemy.edit_admin_page_url(public_page, host: host)}']") end end it "a form and button to logout of alchemy" do - within("#alchemy_menubar") do + within find("alchemy-menubar").shadow_root do expect(page).to \ have_selector("li form[action='#{Alchemy.logout_path}'][method='post']") expect(page).to \ diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index c1e840a958..ecfc504f0f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -9,6 +9,7 @@ require "capybara/rails" require "capybara-screenshot/rspec" +require "capybara/shadowdom" require "rails-controller-testing" require "rspec-activemodel-mocks" require "rspec/rails"