alchemy_cms 8.0.12 → 8.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- window.Alchemy=Alchemy||{},Object.assign(Alchemy,{ElementSelector:{styles:{reset:{outline:"","outline-offset":"",cursor:""},hover:{outline:"2px dashed #f0b437","outline-offset":"4px",cursor:"pointer"},selected:{outline:"2px dashed #90b9d0","outline-offset":"4px"}},init(){window.addEventListener("message",(e=>{switch(e.data.message){case"Alchemy.blurElements":this.blurElements();break;case"Alchemy.focusElement":this.focusElement(e.data);break;default:console.info("Received unknown message!",e.data)}})),this.elements=Array.from(document.querySelectorAll("[data-alchemy-element]")),this.elements.forEach((e=>{e.addEventListener("mouseover",(()=>{e.classList.contains("selected")||Object.assign(e.style,this.getStyle("hover"))})),e.addEventListener("mouseout",(()=>{e.classList.contains("selected")||Object.assign(e.style,this.getStyle("reset"))})),e.addEventListener("click",(t=>{t.stopPropagation(),t.preventDefault(),this.selectElement(e),this.focusElementEditor(e)}))}))},selectElement(e){this.blurElements(e),e.classList.add("selected"),Object.assign(e.style,this.getStyle("selected")),e.scrollIntoView({behavior:"smooth",block:"start"})},blurElements(e){this.elements.forEach((t=>{t!==e&&(t.classList.remove("selected"),Object.assign(t.style,this.getStyle("reset")))}))},focusElement(e){const t=this.getElement(e.element_id);return t?this.selectElement(t):console.warn("Could not focus element with id",e.element_id)},getElement(e){return this.elements.find((t=>t.dataset.alchemyElement===e.toString()))},focusElementEditor(e){const t=e.dataset.alchemyElement;window.parent.postMessage({message:"Alchemy.focusElementEditor",element_id:t},window.location.origin)},getStyle(e){return"reset"===e?this.styles.reset:this.styles[e]}}}),Alchemy.ElementSelector.init();
1
+ window.Alchemy=Alchemy||{},Object.assign(Alchemy,{ElementSelector:{styles:{reset:{outline:"","outline-offset":"",cursor:""},hover:{outline:"2px dashed #f0b437","outline-offset":"4px",cursor:"pointer"},selected:{outline:"2px dashed #90b9d0","outline-offset":"4px"}},init(){window.addEventListener("message",(e=>{switch(e.data.message){case"Alchemy.blurElements":this.blurElements();break;case"Alchemy.focusElement":this.focusElement(e.data);break;default:console.info("Received unknown message!",e.data)}})),this.elements=Array.from(document.querySelectorAll("[data-alchemy-element]")),this.elements.forEach((e=>{e.addEventListener("mouseover",(()=>{e.classList.contains("selected")||Object.assign(e.style,this.getStyle("hover"))})),e.addEventListener("mouseout",(()=>{e.classList.contains("selected")||Object.assign(e.style,this.getStyle("reset"))})),e.addEventListener("click",(t=>{t.stopPropagation(),t.preventDefault(),this.selectElement(e),this.focusElementEditor(e)}))}))},selectElement(e){this.blurElements(e),e.classList.add("selected"),Object.assign(e.style,this.getStyle("selected")),e.scrollIntoView({behavior:"smooth",block:"start"})},blurElements(e){this.elements.forEach((t=>{t!==e&&(t.classList.remove("selected"),Object.assign(t.style,this.getStyle("reset")))}))},focusElement(e){const t=this.getElement(e.element_id);return t?this.selectElement(t):console.warn("Could not focus element with id",e.element_id)},getElement(e){return this.elements.find((t=>t.dataset.alchemyElement===e.toString()))},focusElementEditor(e){const t=e.dataset.alchemyElement;window.parent.postMessage({message:"Alchemy.focusElementEditor",element_id:t},window.location.origin)},getStyle(e){return"reset"===e?this.styles.reset:this.styles[e]}}}),Alchemy.ElementSelector.init(),window.parent.postMessage({message:"Alchemy.previewReady"},window.location.origin);
@@ -14,6 +14,12 @@ export class RemoteSelect extends AlchemyHTMLElement {
14
14
  url: { default: "" }
15
15
  }
16
16
 
17
+ // Select2 manages its own DOM after initialization, so attribute changes
18
+ // must not trigger the default re-render which would destroy the widget.
19
+ static get observedAttributes() {
20
+ return []
21
+ }
22
+
17
23
  async connected() {
18
24
  await setupSelectLocale()
19
25
 
@@ -34,6 +40,11 @@ export class RemoteSelect extends AlchemyHTMLElement {
34
40
  * @param {Event} event
35
41
  */
36
42
  onChange(event) {
43
+ // Update selection attribute so re-attaching the select2 component to
44
+ // the same input (e.g. after dragndrop) does not reset the selection.
45
+ if (event.added) {
46
+ this.setAttribute("selection", JSON.stringify(event.added))
47
+ }
37
48
  this.dispatchCustomEvent("RemoteSelect.Change", {
38
49
  removed: event.removed,
39
50
  added: event.added
@@ -47,24 +47,16 @@ module Alchemy
47
47
  # not tracked via the polymorphic +related_object+ association, so the
48
48
  # base scope cannot see them.
49
49
  #
50
- # Uses a correlated +NOT EXISTS+ subquery that builds the per-row LIKE
51
- # pattern with +Arel::Nodes::Concat+, which compiles to +||+ on
52
- # SQLite/PostgreSQL and +CONCAT()+ on MySQL.
50
+ # Extracts referenced attachment IDs from ingredient values via Ruby
51
+ # regex to stay database-agnostic.
53
52
  scope :deletable, -> do
54
- ingredients = Alchemy::Ingredient.arel_table
55
- pattern = Arel::Nodes::Concat.new(
56
- Arel::Nodes::Concat.new(
57
- Arel::Nodes.build_quoted("%/attachment/"),
58
- arel_table[:id]
59
- ),
60
- Arel::Nodes.build_quoted("/download%")
61
- )
62
- referenced = ingredients
63
- .project(1)
64
- .where(ingredients[:value].matches(pattern))
65
-
66
- where("#{table_name}.id NOT IN (#{RelatableResource::RELATED_INGREDIENTS_SUBQUERY})", type: name)
67
- .where.not(referenced.exists)
53
+ referenced_ids = Alchemy::Ingredient
54
+ .where("value LIKE '%/attachment/%/download%'")
55
+ .pluck(:value)
56
+ .flat_map { |v| v.scan(%r{/attachment/(\d+)/download}).flatten.map(&:to_i) }
57
+
58
+ scope = where("#{table_name}.id NOT IN (#{RelatableResource::RELATED_INGREDIENTS_SUBQUERY})", type: name)
59
+ referenced_ids.any? ? scope.where.not(id: referenced_ids) : scope
68
60
  end
69
61
 
70
62
  # We need to define this method here to have it available in the validations below.
@@ -74,6 +74,15 @@ alchemy-message {
74
74
  margin-top: 0;
75
75
  }
76
76
 
77
+ h1,
78
+ h2,
79
+ h3,
80
+ p {
81
+ &:last-child {
82
+ margin-bottom: 0;
83
+ }
84
+ }
85
+
77
86
  a[href] {
78
87
  text-decoration-color: inherit;
79
88
  text-decoration-thickness: 1px;
@@ -6,7 +6,7 @@
6
6
  <%= render_icon "file-edit", size: "xl" %>
7
7
  </sl-tooltip>
8
8
  <% else %>
9
- <%= render_icon "file-edit", size: "xl" %>
9
+ <%= render_icon "file", size: "xl" %>
10
10
  <% end %>
11
11
  <% else %>
12
12
  <sl-tooltip class="like-hint-tooltip" content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" placement="bottom-start">
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "8.0.12"
4
+ VERSION = "8.0.14"
5
5
 
6
6
  def self.version
7
7
  VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.12
4
+ version: 8.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -646,6 +646,8 @@ files:
646
646
  - app/assets/builds/alchemy/admin.css
647
647
  - app/assets/builds/alchemy/admin/page-select.css
648
648
  - app/assets/builds/alchemy/admin/print.css
649
+ - app/assets/builds/alchemy/alchemy_admin.min.js
650
+ - app/assets/builds/alchemy/alchemy_admin.min.js.map
649
651
  - app/assets/builds/alchemy/dark-theme.css
650
652
  - app/assets/builds/alchemy/light-theme.css
651
653
  - app/assets/builds/alchemy/preview.min.js
@@ -1436,7 +1438,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1436
1438
  version: '0'
1437
1439
  requirements:
1438
1440
  - ImageMagick (libmagick), v6.6 or greater.
1439
- rubygems_version: 4.0.6
1441
+ rubygems_version: 4.0.10
1440
1442
  specification_version: 4
1441
1443
  summary: A powerful, userfriendly and flexible CMS for Rails
1442
1444
  test_files: []