pageflow 13.0.0.beta7 → 13.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pageflow might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +65 -0
- data/Rakefile +1 -1
- data/admins/pageflow/entry.rb +1 -1
- data/admins/pageflow/revisions.rb +3 -4
- data/app/assets/javascripts/pageflow/admin/accounts.js +1 -1
- data/app/assets/javascripts/pageflow/background_media.js +1 -1
- data/app/assets/javascripts/pageflow/base.js +1 -1
- data/app/assets/javascripts/pageflow/dist/react.js +1166 -982
- data/app/assets/javascripts/pageflow/media_player/volume_binding.js +2 -1
- data/app/assets/javascripts/pageflow/media_player/volume_fading/web_audio.js +60 -37
- data/app/assets/javascripts/pageflow/slideshow.js +15 -8
- data/app/assets/javascripts/pageflow/slideshow/adjacent_pages.js +9 -4
- data/app/assets/javascripts/pageflow/slideshow/adjacent_preloader.js +26 -0
- data/app/assets/javascripts/pageflow/slideshow/lazy_page_widget.js +2 -2
- data/app/assets/javascripts/pageflow/slideshow/successor_preparer.js +49 -0
- data/app/assets/javascripts/pageflow/ui/views/inputs/text_input_view.js +29 -5
- data/app/assets/javascripts/pageflow/ui/views/mixins/input_view.js +1 -1
- data/app/assets/javascripts/pageflow/widgets/multimedia_alert.js +2 -1
- data/app/assets/stylesheets/pageflow/admin/tabs_view.scss +3 -3
- data/app/assets/stylesheets/pageflow/navigation_mobile.scss +1 -1
- data/app/assets/stylesheets/pageflow/page_types/background-image.scss +1 -1
- data/app/assets/stylesheets/pageflow/themes/default/anchors.scss +5 -0
- data/app/assets/stylesheets/pageflow/themes/default/background_media_unmute_button.scss +45 -36
- data/app/assets/stylesheets/pageflow/themes/default/overview/icons/icon_font.scss +4 -1
- data/app/assets/stylesheets/pageflow/themes/default/page/anchors.scss +4 -0
- data/app/controllers/concerns/pageflow/public_https_mode.rb +5 -1
- data/app/controllers/pageflow/entries_controller.rb +10 -4
- data/app/jobs/pageflow/upload_file_to_s3_job.rb +1 -1
- data/app/models/concerns/pageflow/hosted_file.rb +0 -25
- data/app/models/pageflow/widget.rb +20 -9
- data/app/views/components/pageflow/admin/revisions_tab.rb +2 -2
- data/app/views/components/pageflow/admin/tabs_view.rb +3 -3
- data/app/views/pageflow/entries/_entry.html.erb +1 -1
- data/app/views/pageflow/entries/show.html.erb +1 -0
- data/config/locales/de.yml +2 -0
- data/config/locales/en.yml +2 -0
- data/lib/pageflow/configuration.rb +10 -0
- data/lib/pageflow/primary_domain_entry_redirect.rb +25 -0
- data/lib/pageflow/react/widget_type.rb +7 -2
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow/widget_type.rb +8 -0
- data/spec/factories/hosted_files.rb +0 -8
- metadata +6 -5
- data/app/assets/javascripts/pageflow/slideshow/adjacent_preparer.js +0 -53
- data/app/assets/javascripts/pageflow/slideshow/progressive_preload.js +0 -42
@@ -1,3 +1,7 @@
|
|
1
|
+
/// Color of the caret icon displayed in front of links. Same as text
|
2
|
+
/// color by default.
|
3
|
+
$anchor-icon-color: null !default;
|
4
|
+
|
1
5
|
%anchor {
|
2
6
|
@include fa-caret-right-icon;
|
3
7
|
|
@@ -25,5 +29,6 @@
|
|
25
29
|
top: 7px;
|
26
30
|
width: 10px;
|
27
31
|
height: 12px;
|
32
|
+
color: $anchor-icon-color;
|
28
33
|
}
|
29
34
|
}
|
@@ -1,14 +1,16 @@
|
|
1
|
-
$background-media-unmute-button-color: rgba(53, 53, 53, 0.9);
|
1
|
+
$background-media-unmute-button-color: rgba(53, 53, 53, 0.9) !default;
|
2
2
|
|
3
|
-
$background-media-unmute-button-shadow-color: #ccc;
|
3
|
+
$background-media-unmute-button-shadow-color: #ccc !default;
|
4
4
|
|
5
|
-
$background-media-unmute-button-icon-color: #ddd;
|
5
|
+
$background-media-unmute-button-icon-color: #ddd !default;
|
6
6
|
|
7
|
-
$background-media-unmute-button-icon-size: 24px;
|
7
|
+
$background-media-unmute-button-icon-size: 24px !default;
|
8
8
|
|
9
|
-
$background-media-unmute-button-size: 34px;
|
9
|
+
$background-media-unmute-button-size: 34px !default;
|
10
10
|
|
11
|
-
$background-media-unmute-button-margin: 10px;
|
11
|
+
$background-media-unmute-button-margin: 10px !default;
|
12
|
+
|
13
|
+
$background-media-unmute-button-custom-image: false !default;
|
12
14
|
|
13
15
|
.background_media_unmute_button {
|
14
16
|
position: absolute;
|
@@ -25,22 +27,20 @@ $background-media-unmute-button-margin: 10px;
|
|
25
27
|
right: 11px;
|
26
28
|
}
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@include box-shadow(0 0 7px $background-media-unmute-button-shadow-color);
|
43
|
-
z-index: 1;
|
30
|
+
@if not $background-media-unmute-button-custom-image {
|
31
|
+
&:after {
|
32
|
+
content: "";
|
33
|
+
display: block;
|
34
|
+
position: absolute;
|
35
|
+
top: 6px;
|
36
|
+
left: 6px;
|
37
|
+
width: $background-media-unmute-button-size;
|
38
|
+
height: $background-media-unmute-button-size;
|
39
|
+
border-radius: $background-media-unmute-button-size / 2;
|
40
|
+
background-color: $background-media-unmute-button-color;
|
41
|
+
box-shadow: 0 0 7px $background-media-unmute-button-shadow-color;
|
42
|
+
z-index: 1;
|
43
|
+
}
|
44
44
|
}
|
45
45
|
|
46
46
|
a {
|
@@ -48,21 +48,30 @@ $background-media-unmute-button-margin: 10px;
|
|
48
48
|
width: 100%;
|
49
49
|
height: 100%;
|
50
50
|
z-index: 2;
|
51
|
-
position: relative;
|
52
|
-
@include background-icon-center($color: $background-media-unmute-button-icon-color,
|
53
|
-
$font-size: $background-media-unmute-button-icon-size);
|
54
|
-
@include fa-volume-down-icon;
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
@if $background-media-unmute-button-custom-image {
|
53
|
+
background-image: image-url("pageflow/themes/#{$theme-name}/background_media_unmute_button.svg");
|
54
|
+
background-size: $background-media-unmute-button-size
|
55
|
+
$background-media-unmute-button-size;
|
56
|
+
background-repeat: no-repeat;
|
57
|
+
background-position: 50% 50%;
|
58
|
+
} @else {
|
59
|
+
position: relative;
|
60
|
+
@include background-icon-center($color: $background-media-unmute-button-icon-color,
|
61
|
+
$font-size: $background-media-unmute-button-icon-size);
|
62
|
+
@include fa-volume-down-icon;
|
63
|
+
|
64
|
+
&:after {
|
65
|
+
content: "";
|
66
|
+
display: block;
|
67
|
+
position: absolute;
|
68
|
+
width: 25px;
|
69
|
+
left: 22px;
|
70
|
+
top: 22px;
|
71
|
+
border-top: solid 2px $background-media-unmute-button-icon-color;
|
72
|
+
border-bottom: solid 1px $background-media-unmute-button-color;
|
73
|
+
@include transform(translate(-50%, -50%) rotate(45deg));
|
74
|
+
}
|
66
75
|
}
|
67
76
|
}
|
68
77
|
}
|
@@ -8,10 +8,14 @@ $page-anchor-color: #fff !default;
|
|
8
8
|
/// Color of links inside the text on inverted pages
|
9
9
|
$page-anchor-inverted-color: #000 !default;
|
10
10
|
|
11
|
+
/// Typography settings of links in page content text
|
12
|
+
$page-anchor-typography: () !default;
|
13
|
+
|
11
14
|
.contentText a {
|
12
15
|
@extend %anchor;
|
13
16
|
color: $page-anchor-color;
|
14
17
|
pointer-events: all;
|
18
|
+
@include typography($page-anchor-typography)
|
15
19
|
}
|
16
20
|
|
17
21
|
.invert .contentText a {
|
@@ -2,12 +2,16 @@ module Pageflow
|
|
2
2
|
module PublicHttpsMode
|
3
3
|
protected
|
4
4
|
|
5
|
-
def
|
5
|
+
def redirect_according_to_public_https_mode
|
6
6
|
if request.ssl? && Pageflow.config.public_https_mode == :prevent
|
7
7
|
redirect_to("http://#{request.host}#{request.fullpath}", status: :moved_permanently)
|
8
|
+
true
|
8
9
|
elsif !request.ssl? && Pageflow.config.public_https_mode == :enforce
|
9
10
|
redirect_to("https://#{request.host}#{request.fullpath}", status: :moved_permanently)
|
11
|
+
true
|
10
12
|
end
|
11
13
|
end
|
14
|
+
|
15
|
+
alias_method :check_public_https_mode, :redirect_according_to_public_https_mode
|
12
16
|
end
|
13
17
|
end
|
@@ -5,10 +5,6 @@ module Pageflow
|
|
5
5
|
|
6
6
|
before_action :authenticate_user!, except: [:index, :show, :page]
|
7
7
|
|
8
|
-
before_action :check_public_https_mode,
|
9
|
-
only: [:index, :show],
|
10
|
-
unless: lambda { |controller| controller.request.format.json? }
|
11
|
-
|
12
8
|
after_action :allow_iframe_for_embed, only: :show
|
13
9
|
|
14
10
|
helper_method :render_to_string
|
@@ -30,6 +26,12 @@ module Pageflow
|
|
30
26
|
@entry = PublishedEntry.find(params[:id], entry_request_scope)
|
31
27
|
I18n.locale = @entry.locale
|
32
28
|
|
29
|
+
if redirect_location = entry_redirect(@entry)
|
30
|
+
return redirect_to(redirect_location, status: :moved_permanently)
|
31
|
+
end
|
32
|
+
|
33
|
+
return if redirect_according_to_public_https_mode
|
34
|
+
|
33
35
|
if !request.format.css?
|
34
36
|
check_entry_password_protection(@entry)
|
35
37
|
end
|
@@ -97,6 +99,10 @@ module Pageflow
|
|
97
99
|
Pageflow.config.public_entry_request_scope.call(Entry, request)
|
98
100
|
end
|
99
101
|
|
102
|
+
def entry_redirect(entry)
|
103
|
+
Pageflow.config.public_entry_redirect.call(entry, request)
|
104
|
+
end
|
105
|
+
|
100
106
|
def allow_iframe_for_embed
|
101
107
|
if params[:embed]
|
102
108
|
response.headers.except! 'X-Frame-Options'
|
@@ -10,7 +10,7 @@ module Pageflow
|
|
10
10
|
file.attachment_on_s3 = file.attachment_on_filesystem
|
11
11
|
file.save!
|
12
12
|
|
13
|
-
file.attachment_on_filesystem.destroy
|
13
|
+
file.attachment_on_filesystem.destroy
|
14
14
|
:ok
|
15
15
|
else
|
16
16
|
logger.info "#{file.class.name} #{file.id} not yet transfered to instance."
|
@@ -47,10 +47,6 @@ module Pageflow
|
|
47
47
|
self.attachment_on_filesystem = value
|
48
48
|
end
|
49
49
|
|
50
|
-
def keep_on_filesystem_after_upload_to_s3?
|
51
|
-
false
|
52
|
-
end
|
53
|
-
|
54
50
|
def retryable?
|
55
51
|
can_retry?
|
56
52
|
end
|
@@ -73,27 +69,6 @@ module Pageflow
|
|
73
69
|
url
|
74
70
|
end
|
75
71
|
|
76
|
-
# @deprecated Write a migration instead
|
77
|
-
def self.columns(t)
|
78
|
-
t.belongs_to(:entry, index: true)
|
79
|
-
t.belongs_to(:uploader, index: true)
|
80
|
-
|
81
|
-
t.string(:state)
|
82
|
-
t.string(:rights)
|
83
|
-
|
84
|
-
t.string(:attachment_on_filesystem_file_name)
|
85
|
-
t.string(:attachment_on_filesystem_content_type)
|
86
|
-
t.integer(:attachment_on_filesystem_file_size, limit: 8)
|
87
|
-
t.datetime(:attachment_on_filesystem_updated_at)
|
88
|
-
|
89
|
-
t.string(:attachment_on_s3_file_name)
|
90
|
-
t.string(:attachment_on_s3_content_type)
|
91
|
-
t.integer(:attachment_on_s3_file_size, limit: 8)
|
92
|
-
t.datetime(:attachment_on_s3_updated_at)
|
93
|
-
|
94
|
-
t.timestamps
|
95
|
-
end
|
96
|
-
|
97
72
|
module ClassMethods
|
98
73
|
def processing_state_machine(&block)
|
99
74
|
state_machine do
|
@@ -14,14 +14,9 @@ module Pageflow
|
|
14
14
|
record.save!
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
elsif options[:scope] == :preview
|
21
|
-
widget_type.enabled_in_preview?
|
22
|
-
else
|
23
|
-
true
|
24
|
-
end
|
17
|
+
def matches?(options)
|
18
|
+
enabled_for_scope?(options[:scope]) &&
|
19
|
+
for_insert_point?(options.fetch(:insert_point, :any))
|
25
20
|
end
|
26
21
|
|
27
22
|
def self.copy_all_to(subject)
|
@@ -40,10 +35,26 @@ module Pageflow
|
|
40
35
|
Resolver.new(config, options).result
|
41
36
|
end
|
42
37
|
|
38
|
+
private
|
39
|
+
|
40
|
+
def enabled_for_scope?(scope)
|
41
|
+
if scope == :editor
|
42
|
+
widget_type.enabled_in_editor?
|
43
|
+
elsif scope == :preview
|
44
|
+
widget_type.enabled_in_preview?
|
45
|
+
else
|
46
|
+
true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def for_insert_point?(insert_point)
|
51
|
+
insert_point == :any || widget_type.insert_point == insert_point
|
52
|
+
end
|
53
|
+
|
43
54
|
Resolver = Struct.new(:config, :options) do
|
44
55
|
def result
|
45
56
|
assign_widget_types(all).select do |widget|
|
46
|
-
widget.
|
57
|
+
widget.matches?(options)
|
47
58
|
end
|
48
59
|
end
|
49
60
|
|
@@ -41,7 +41,7 @@ module Pageflow
|
|
41
41
|
text_node(link_to(t('pageflow.admin.entries.show'), pageflow.revision_path(revision), :class => 'show'))
|
42
42
|
if authorized?(:restore, entry)
|
43
43
|
text_node(link_to(t('pageflow.admin.entries.restore'),
|
44
|
-
restore_admin_revision_path(revision),
|
44
|
+
restore_admin_revision_path(revision, params.permit(:tab)),
|
45
45
|
method: :post,
|
46
46
|
class: 'restore',
|
47
47
|
data: {
|
@@ -58,7 +58,7 @@ module Pageflow
|
|
58
58
|
|
59
59
|
if authorized?(:snapshot, entry)
|
60
60
|
text_node(button_to(t('pageflow.admin.entries.snapshot'),
|
61
|
-
snapshot_admin_entry_path(entry),
|
61
|
+
snapshot_admin_entry_path(entry, params.permit(:tab)),
|
62
62
|
method: :post))
|
63
63
|
end
|
64
64
|
end
|
@@ -26,7 +26,7 @@ module Pageflow
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def build_tab_list
|
29
|
-
ul(class: 'tabs') do
|
29
|
+
ul(class: 'admin_tabs_view-tabs') do
|
30
30
|
tabs.each do |tab|
|
31
31
|
build_tab_item(tab)
|
32
32
|
end
|
@@ -66,8 +66,8 @@ module Pageflow
|
|
66
66
|
|
67
67
|
def tab_container_class(tab_name)
|
68
68
|
[
|
69
|
-
'
|
70
|
-
"
|
69
|
+
'admin_tabs_view-container',
|
70
|
+
"admin_tabs_view-#{tab_name}_container",
|
71
71
|
current_tab?(tab_name) ? 'active' : nil
|
72
72
|
].compact.join(' ')
|
73
73
|
end
|
@@ -17,5 +17,5 @@
|
|
17
17
|
|
18
18
|
<%= render 'pageflow/entries/header', :entry => entry %>
|
19
19
|
<%= render 'pageflow/entries/overview', :entry => entry %>
|
20
|
-
<%= render_widgets(entry, :
|
20
|
+
<%= render_widgets(entry, scope: widget_scope, insert_point: :bottom_of_entry) %>
|
21
21
|
<% end %>
|
@@ -20,6 +20,7 @@
|
|
20
20
|
<%= render 'pageflow/entries/ie8_hint' %>
|
21
21
|
<%= render 'pageflow/entries/loading_spinner' %>
|
22
22
|
<%= render 'pageflow/entries/multimedia_alert' %>
|
23
|
+
<%= render_widgets(@entry, scope: @widget_scope, insert_point: :before_entry) %>
|
23
24
|
<%= render @entry, :widget_scope => @widget_scope %>
|
24
25
|
|
25
26
|
<script>
|
data/config/locales/de.yml
CHANGED
@@ -831,6 +831,7 @@ de:
|
|
831
831
|
users: Benutzer
|
832
832
|
revisions:
|
833
833
|
published_until_hint: Freilassen, um Beitrag unbegrenzt zu veröffentlichen.
|
834
|
+
restored: Revision wiederhergestellt
|
834
835
|
themings:
|
835
836
|
additional_cnames_hint: Kommaseparierte Liste von weiteren CNAMES. Ausschließlich zur Auswahl der Redirect URL genutzt.
|
836
837
|
cname_hint: Wird in Share Links verwendet.
|
@@ -1811,6 +1812,7 @@ de:
|
|
1811
1812
|
none: "(Kein)"
|
1812
1813
|
placeholder: Standard (%{text})
|
1813
1814
|
text_input_view:
|
1815
|
+
max_characters_exceeded: Maximale Zeichenanzahl überschritten (%{max_length})
|
1814
1816
|
required_field: Muss ausgefüllt werden
|
1815
1817
|
url_input_view:
|
1816
1818
|
required_field: Muss ausgefüllt werden
|
data/config/locales/en.yml
CHANGED
@@ -831,6 +831,7 @@ en:
|
|
831
831
|
users: User
|
832
832
|
revisions:
|
833
833
|
published_until_hint: Leave blank to publish indefinitely.
|
834
|
+
restored: Version restored
|
834
835
|
themings:
|
835
836
|
additional_cnames_hint: Comma separated list of additional CNAMES. Used only to select the correct redirect URL.
|
836
837
|
cname_hint: Used in public sharing URLs.
|
@@ -1786,6 +1787,7 @@ en:
|
|
1786
1787
|
none: "(none)"
|
1787
1788
|
placeholder: Default (%{text})
|
1788
1789
|
text_input_view:
|
1790
|
+
max_characters_exceeded: Maximum number of characters exceeded (%{max_length})
|
1789
1791
|
required_field: Required field
|
1790
1792
|
url_input_view:
|
1791
1793
|
required_field: Required field
|
@@ -162,6 +162,15 @@ module Pageflow
|
|
162
162
|
# end
|
163
163
|
attr_accessor :public_entry_request_scope
|
164
164
|
|
165
|
+
# Either a lambda or an object with a `call` method taking an
|
166
|
+
# {Entry} record and an {ActionDispatch::Request} object and
|
167
|
+
# returning `nil` or a path to redirect to. Can be used in
|
168
|
+
# conjuction with {PrimaryDomainEntryRedirect} to make sure
|
169
|
+
# entries are accessed via their account's configured cname.
|
170
|
+
#
|
171
|
+
# @since 12.4
|
172
|
+
attr_accessor :public_entry_redirect
|
173
|
+
|
165
174
|
# Either a lambda or an object with a `call` method taking a
|
166
175
|
# {Theming} as paramater and returing a hash of options used to
|
167
176
|
# construct the url of a published entry.
|
@@ -326,6 +335,7 @@ module Pageflow
|
|
326
335
|
|
327
336
|
@theming_request_scope = CnameThemingRequestScope.new
|
328
337
|
@public_entry_request_scope = lambda { |entries, request| entries }
|
338
|
+
@public_entry_redirect = ->(_entry, _request) { nil }
|
329
339
|
@public_entry_url_options = Pageflow::ThemingsHelper::DEFAULT_PUBLIC_ENTRY_OPTIONS
|
330
340
|
@entry_embed_url_options = {protocol: 'https'}
|
331
341
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Pageflow
|
2
|
+
# Use as {Configuration#public_entry_redirect} to make sure entries
|
3
|
+
# are accessed via their account's configured cname.
|
4
|
+
#
|
5
|
+
# @since 12.4
|
6
|
+
class PrimaryDomainEntryRedirect
|
7
|
+
def call(entry, request)
|
8
|
+
theming = entry.theming
|
9
|
+
|
10
|
+
if theming.cname.present? &&
|
11
|
+
!known_domains(theming).include?(request.host)
|
12
|
+
[request.protocol, theming.cname, request.fullpath].join
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def known_domains(theming)
|
19
|
+
[
|
20
|
+
theming.cname,
|
21
|
+
(theming.additional_cnames || '').split(',').map(&:strip)
|
22
|
+
].flatten
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,17 +1,22 @@
|
|
1
1
|
module Pageflow
|
2
2
|
module React
|
3
3
|
class WidgetType < Pageflow::WidgetType
|
4
|
-
attr_reader :name, :role
|
4
|
+
attr_reader :name, :role, :options
|
5
5
|
|
6
|
-
def initialize(name, role)
|
6
|
+
def initialize(name, role, options = {})
|
7
7
|
@name = name
|
8
8
|
@role = role
|
9
|
+
@options = options
|
9
10
|
end
|
10
11
|
|
11
12
|
def roles
|
12
13
|
[role]
|
13
14
|
end
|
14
15
|
|
16
|
+
def insert_point
|
17
|
+
@options[:insert_point] || super
|
18
|
+
end
|
19
|
+
|
15
20
|
def render(template, _)
|
16
21
|
template.render(File.join('pageflow', 'react', 'widget'), name: name)
|
17
22
|
end
|