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") %>
+
+
+
- <%= 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"