alchemy_cms 7.3.3 → 7.3.5
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.
Potentially problematic release.
This version of alchemy_cms might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile +9 -0
- data/README.md +25 -4
- data/Rakefile +22 -0
- data/app/assets/builds/alchemy/admin.css +1 -1
- data/app/assets/builds/alchemy/admin.css.map +1 -1
- data/app/assets/builds/alchemy/welcome.css +1 -17
- data/app/assets/builds/alchemy/welcome.css.map +1 -1
- data/app/assets/stylesheets/alchemy/admin/elements.scss +1 -1
- data/app/assets/stylesheets/alchemy/admin/image_library.scss +40 -26
- data/app/controllers/alchemy/admin/base_controller.rb +27 -3
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -5
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/models/concerns/alchemy/picture_thumbnails.rb +4 -5
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/lib/alchemy/resource.rb +14 -4
- data/lib/alchemy/version.rb +1 -1
- data/vendor/javascript/tinymce.min.js +1 -1
- metadata +3 -5
@@ -1,8 +1,3 @@
|
|
1
|
-
$picture-overlay-handle-width: 24px;
|
2
|
-
$image-overlay-form-width: 350px - $picture-overlay-handle-width;
|
3
|
-
$image-overlay-transition-duration: $transition-duration;
|
4
|
-
$image-overlay-transition-easing: ease-in;
|
5
|
-
|
6
1
|
.alchemy-image-overlay {
|
7
2
|
&.open {
|
8
3
|
background-color: rgba(0, 0, 0, 0.6);
|
@@ -17,10 +12,21 @@ $image-overlay-transition-easing: ease-in;
|
|
17
12
|
max-width: 100%;
|
18
13
|
}
|
19
14
|
|
15
|
+
.alchemy-image-overlay-container {
|
16
|
+
--picture-overlay-handle-width: 24px;
|
17
|
+
--image-overlay-form-width: calc(350px - var(--picture-overlay-handle-width));
|
18
|
+
--image-overlay-transition-duration: 250ms;
|
19
|
+
--image-overlay-transition-easing: ease-in;
|
20
|
+
|
21
|
+
&.open {
|
22
|
+
overflow: hidden;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
20
26
|
.alchemy-image-overlay-dialog {
|
21
27
|
&.hide-form {
|
22
28
|
.picture-details-overlay {
|
23
|
-
right:
|
29
|
+
right: calc(-1 * var(--image-overlay-form-width));
|
24
30
|
}
|
25
31
|
|
26
32
|
.zoomed-picture-background {
|
@@ -28,11 +34,11 @@ $image-overlay-transition-easing: ease-in;
|
|
28
34
|
}
|
29
35
|
|
30
36
|
.alchemy-image-overlay-close {
|
31
|
-
right:
|
37
|
+
right: calc(var(--picture-overlay-handle-width) + var(--spacing-2));
|
32
38
|
}
|
33
39
|
|
34
40
|
.next-picture {
|
35
|
-
right:
|
41
|
+
right: var(--picture-overlay-handle-width);
|
36
42
|
}
|
37
43
|
|
38
44
|
.picture-overlay-handle {
|
@@ -64,17 +70,18 @@ $image-overlay-transition-easing: ease-in;
|
|
64
70
|
height: 32px;
|
65
71
|
top: var(--spacing-2);
|
66
72
|
right: calc(
|
67
|
-
var(--spacing-2) +
|
73
|
+
var(--spacing-2) + var(--picture-overlay-handle-width) +
|
74
|
+
var(--image-overlay-form-width)
|
68
75
|
);
|
69
76
|
cursor: pointer;
|
70
|
-
transition: right
|
71
|
-
|
77
|
+
transition: right var(--image-overlay-transition-duration)
|
78
|
+
var(--image-overlay-transition-easing);
|
72
79
|
|
73
80
|
.icon {
|
74
81
|
font-size: 2em;
|
75
82
|
color: var(--color-grey_light);
|
76
83
|
text-shadow: 0 0 4px var(--color-text);
|
77
|
-
transition: color
|
84
|
+
transition: color var(--image-overlay-transition-duration) linear;
|
78
85
|
|
79
86
|
&:hover {
|
80
87
|
color: var(--color-white);
|
@@ -88,13 +95,13 @@ $image-overlay-transition-easing: ease-in;
|
|
88
95
|
top: 0;
|
89
96
|
background-color: var(--color-grey_light);
|
90
97
|
box-shadow: -2px 0 4px -2px var(--color-text);
|
91
|
-
transition: right
|
92
|
-
|
98
|
+
transition: right var(--image-overlay-transition-duration)
|
99
|
+
var(--image-overlay-transition-easing);
|
93
100
|
}
|
94
101
|
|
95
102
|
.picture-details-overlay {
|
96
103
|
right: 0;
|
97
|
-
width:
|
104
|
+
width: var(--image-overlay-form-width);
|
98
105
|
height: 100%;
|
99
106
|
padding: var(--spacing-2) var(--spacing-4) var(--spacing-2) var(--spacing-1);
|
100
107
|
overflow: auto;
|
@@ -117,9 +124,9 @@ $image-overlay-transition-easing: ease-in;
|
|
117
124
|
}
|
118
125
|
|
119
126
|
.picture-overlay-handle {
|
120
|
-
width:
|
127
|
+
width: var(--picture-overlay-handle-width);
|
121
128
|
height: 100%;
|
122
|
-
right:
|
129
|
+
right: var(--image-overlay-form-width);
|
123
130
|
cursor: pointer;
|
124
131
|
|
125
132
|
.icon {
|
@@ -129,8 +136,8 @@ $image-overlay-transition-easing: ease-in;
|
|
129
136
|
transform: translate(-50%, -50%);
|
130
137
|
font-size: 1.2em;
|
131
138
|
color: var(--color-icon);
|
132
|
-
transition: transform
|
133
|
-
|
139
|
+
transition: transform var(--image-overlay-transition-duration)
|
140
|
+
var(--image-overlay-transition-easing);
|
134
141
|
}
|
135
142
|
|
136
143
|
&:hover {
|
@@ -143,15 +150,16 @@ $image-overlay-transition-easing: ease-in;
|
|
143
150
|
height: 100%;
|
144
151
|
padding-top: var(--spacing-2);
|
145
152
|
padding-right: calc(
|
146
|
-
|
153
|
+
var(--image-overlay-form-width) + var(--spacing-2) +
|
154
|
+
var(--picture-overlay-handle-width)
|
147
155
|
);
|
148
156
|
padding-bottom: var(--spacing-2);
|
149
157
|
padding-left: var(--spacing-2);
|
150
158
|
margin: 0 auto;
|
151
159
|
text-align: center;
|
152
160
|
cursor: pointer;
|
153
|
-
transition: padding-right
|
154
|
-
|
161
|
+
transition: padding-right var(--image-overlay-transition-duration)
|
162
|
+
var(--image-overlay-transition-easing);
|
155
163
|
|
156
164
|
&:before {
|
157
165
|
content: "";
|
@@ -233,7 +241,7 @@ $image-overlay-transition-easing: ease-in;
|
|
233
241
|
justify-content: center;
|
234
242
|
align-items: center;
|
235
243
|
text-decoration: none;
|
236
|
-
transition: background-color
|
244
|
+
transition: background-color var(--image-overlay-transition-duration) linear;
|
237
245
|
|
238
246
|
.icon {
|
239
247
|
width: 32px;
|
@@ -246,16 +254,20 @@ $image-overlay-transition-easing: ease-in;
|
|
246
254
|
background-color: rgba(0, 0, 0, 0.3);
|
247
255
|
|
248
256
|
.icon {
|
249
|
-
transition: fill
|
257
|
+
transition: fill var(--image-overlay-transition-duration) linear;
|
250
258
|
}
|
251
259
|
}
|
252
260
|
}
|
253
261
|
|
262
|
+
.next-picture {
|
263
|
+
transition-property: background-color, right;
|
264
|
+
}
|
265
|
+
|
254
266
|
.icon {
|
255
267
|
--icon-size: 4em;
|
256
268
|
fill: var(--color-grey_light);
|
257
269
|
filter: drop-shadow(0 0 4px var(--color-icon));
|
258
|
-
transition: all
|
270
|
+
transition: all var(--image-overlay-transition-duration) linear;
|
259
271
|
vertical-align: middle;
|
260
272
|
}
|
261
273
|
|
@@ -265,7 +277,9 @@ $image-overlay-transition-easing: ease-in;
|
|
265
277
|
}
|
266
278
|
|
267
279
|
.next-picture {
|
268
|
-
right:
|
280
|
+
right: calc(
|
281
|
+
var(--image-overlay-form-width) + var(--picture-overlay-handle-width)
|
282
|
+
);
|
269
283
|
@include border-left-radius($default-border-radius);
|
270
284
|
}
|
271
285
|
}
|
@@ -31,6 +31,27 @@ module Alchemy
|
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
+
def safe_redirect_path(path = params[:redirect_to], fallback: admin_path)
|
35
|
+
if is_safe_redirect_path?(path)
|
36
|
+
path
|
37
|
+
elsif is_safe_redirect_path?(fallback)
|
38
|
+
fallback
|
39
|
+
else
|
40
|
+
admin_path
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_safe_redirect_path?(path)
|
45
|
+
mount_path = alchemy.root_path
|
46
|
+
path.to_s.match? %r{^#{mount_path}admin/}
|
47
|
+
end
|
48
|
+
|
49
|
+
def relative_referer_path(referer = request.referer)
|
50
|
+
return unless referer
|
51
|
+
|
52
|
+
URI(referer).path
|
53
|
+
end
|
54
|
+
|
34
55
|
# Disable layout rendering for xhr requests.
|
35
56
|
def set_layout
|
36
57
|
(request.xhr? || turbo_frame_request?) ? false : "alchemy/admin"
|
@@ -105,15 +126,18 @@ module Alchemy
|
|
105
126
|
end
|
106
127
|
end
|
107
128
|
|
108
|
-
# Does redirects for html and js requests
|
129
|
+
# Does redirects for html, turbo_stream and js requests
|
130
|
+
#
|
131
|
+
# Makes sure that the redirect path is safe.
|
109
132
|
#
|
110
133
|
def do_redirect_to(url_or_path)
|
134
|
+
redirect_path = safe_redirect_path(url_or_path)
|
111
135
|
respond_to do |format|
|
112
136
|
format.js {
|
113
|
-
@redirect_url =
|
137
|
+
@redirect_url = redirect_path
|
114
138
|
render :redirect
|
115
139
|
}
|
116
|
-
format.html { redirect_to
|
140
|
+
format.html { redirect_to redirect_path }
|
117
141
|
end
|
118
142
|
end
|
119
143
|
|
@@ -40,7 +40,7 @@ module Alchemy
|
|
40
40
|
def switch
|
41
41
|
@language = set_alchemy_language(params[:language_id])
|
42
42
|
session[:alchemy_language_id] = @language.id
|
43
|
-
do_redirect_to
|
43
|
+
do_redirect_to relative_referer_path || alchemy.admin_dashboard_path
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
@@ -189,11 +189,7 @@ module Alchemy
|
|
189
189
|
end
|
190
190
|
|
191
191
|
def unlock_redirect_path
|
192
|
-
|
193
|
-
params[:redirect_to]
|
194
|
-
else
|
195
|
-
admin_pages_path
|
196
|
-
end
|
192
|
+
safe_redirect_path(fallback: admin_pages_path)
|
197
193
|
end
|
198
194
|
|
199
195
|
# Sets the page public and updates the published_at attribute that is used as cache_key
|
@@ -78,7 +78,7 @@ module Alchemy
|
|
78
78
|
flash[:error] = resource_instance_variable.errors.full_messages.join(", ")
|
79
79
|
end
|
80
80
|
flash_notice_for_resource_action
|
81
|
-
do_redirect_to resource_url_proxy.url_for(search_filter_params.merge(action: "index"))
|
81
|
+
do_redirect_to resource_url_proxy.url_for(search_filter_params.merge(action: "index", only_path: true))
|
82
82
|
end
|
83
83
|
|
84
84
|
def resource_handler
|
@@ -102,11 +102,10 @@ module Alchemy
|
|
102
102
|
|
103
103
|
# Show image cropping link for ingredient
|
104
104
|
def allow_image_cropping?
|
105
|
-
settings[:crop] && picture
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
) && !!picture.image_file
|
105
|
+
settings[:crop] && picture&.can_be_cropped_to?(
|
106
|
+
settings[:size],
|
107
|
+
settings[:upsample]
|
108
|
+
) && !!picture.image_file
|
110
109
|
end
|
111
110
|
|
112
111
|
private
|
data/lib/alchemy/resource.rb
CHANGED
@@ -188,11 +188,21 @@ module Alchemy
|
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
191
|
+
# Returns a sorted array of attributes.
|
192
|
+
#
|
193
|
+
# Attribute called "name" comes first.
|
194
|
+
# Attribute called "updated_at" comes last.
|
195
|
+
# Boolean type attributes come after non-boolean attributes but before "updated_at".
|
196
|
+
#
|
191
197
|
def sorted_attributes
|
192
|
-
@_sorted_attributes ||= attributes
|
193
|
-
|
194
|
-
|
195
|
-
|
198
|
+
@_sorted_attributes ||= attributes.sort_by! do |attr|
|
199
|
+
[
|
200
|
+
(attr[:name] == "name") ? 0 : 1,
|
201
|
+
(attr[:name] == "updated_at") ? 3 : 2,
|
202
|
+
(attr[:type] == :boolean) ? 2 : 1,
|
203
|
+
attr[:name]
|
204
|
+
]
|
205
|
+
end
|
196
206
|
end
|
197
207
|
|
198
208
|
def editable_attributes
|