pageflow 12.3.0 → 12.4.0
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 +25 -49
- data/app/assets/javascripts/pageflow/dist/react.js +1021 -930
- 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/adjacent_pages.js +2 -2
- data/app/assets/javascripts/pageflow/widgets/multimedia_alert.js +2 -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/lib/pageflow/configuration.rb +10 -0
- data/lib/pageflow/primary_domain_entry_redirect.rb +25 -0
- data/lib/pageflow/version.rb +1 -1
- metadata +3 -2
@@ -7,6 +7,7 @@ pageflow.mediaPlayer.volumeBinding = function(player, settings, options) {
|
|
7
7
|
var volumeFactor = 'volumeFactor' in options ? options.volumeFactor : 1;
|
8
8
|
|
9
9
|
player.play = function() {
|
10
|
+
player.intendToPlay();
|
10
11
|
player.volume(player.targetVolume());
|
11
12
|
listenToVolumeSetting();
|
12
13
|
|
@@ -71,4 +72,4 @@ pageflow.mediaPlayer.volumeBinding = function(player, settings, options) {
|
|
71
72
|
function onVolumeChange(model, value) {
|
72
73
|
player.fadeVolume(player.targetVolume(), 40);
|
73
74
|
}
|
74
|
-
};
|
75
|
+
};
|
@@ -12,62 +12,84 @@ pageflow.mediaPlayer.volumeFading.webAudio = function(player, audioContext) {
|
|
12
12
|
|
13
13
|
var allowedMinValue = 0.000001;
|
14
14
|
|
15
|
-
var originalPlay = player.play;
|
16
|
-
|
17
15
|
if (audioContext.state === 'suspended') {
|
18
16
|
pageflow.events.on('background_media:unmute', function() {
|
19
|
-
audioContext.resume();
|
20
|
-
});
|
21
|
-
|
22
|
-
audioContext.addEventListener('statechange', function() {
|
23
17
|
player.volume(currentValue);
|
24
18
|
});
|
25
19
|
}
|
26
20
|
|
27
|
-
|
28
|
-
return
|
29
|
-
};
|
30
|
-
|
31
|
-
player.volume = function(value) {
|
32
|
-
if (typeof value !== 'undefined') {
|
21
|
+
function tryResumeIfSuspended() {
|
22
|
+
return new $.Deferred(function(deferred) {
|
33
23
|
if (audioContext.state === 'suspended') {
|
34
|
-
|
35
|
-
|
24
|
+
var maybePromise = audioContext.resume();
|
25
|
+
|
26
|
+
if (maybePromise && maybePromise.then) {
|
27
|
+
maybePromise.then(handleDeferred);
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
setTimeout(handleDeferred, 0);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
else {
|
34
|
+
deferred.resolve();
|
36
35
|
}
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
function handleDeferred() {
|
38
|
+
if (audioContext.state === 'suspended') {
|
39
|
+
deferred.reject();
|
40
|
+
}
|
41
|
+
else {
|
42
|
+
deferred.resolve();
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}).promise();
|
46
|
+
}
|
42
47
|
|
43
|
-
|
44
|
-
|
48
|
+
player.volume = function(value) {
|
49
|
+
if (typeof value !== 'undefined') {
|
50
|
+
tryResumeIfSuspended().then(
|
51
|
+
function() {
|
52
|
+
ensureGainNode();
|
53
|
+
|
54
|
+
cancel();
|
55
|
+
currentValue = ensureInAllowedRange(value);
|
56
|
+
|
57
|
+
gainNode.gain.setValueAtTime(currentValue,
|
58
|
+
audioContext.currentTime);
|
59
|
+
},
|
60
|
+
function() {
|
61
|
+
currentValue = ensureInAllowedRange(value);
|
62
|
+
}
|
63
|
+
);
|
45
64
|
}
|
46
65
|
|
47
66
|
return Math.round(currentValue * 100) / 100;
|
48
67
|
};
|
49
68
|
|
50
69
|
player.fadeVolume = function(value, duration) {
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
}
|
70
|
+
return tryResumeIfSuspended().then(
|
71
|
+
function() {
|
72
|
+
ensureGainNode();
|
55
73
|
|
56
|
-
|
74
|
+
cancel();
|
75
|
+
recordFadeStart(duration);
|
57
76
|
|
58
|
-
|
59
|
-
recordFadeStart(duration);
|
60
|
-
|
61
|
-
currentValue = ensureInAllowedRange(value);
|
77
|
+
currentValue = ensureInAllowedRange(value);
|
62
78
|
|
63
|
-
|
64
|
-
|
65
|
-
|
79
|
+
gainNode.gain.setValueAtTime(lastStartValue, audioContext.currentTime);
|
80
|
+
gainNode.gain.linearRampToValueAtTime(currentValue,
|
81
|
+
audioContext.currentTime + duration / 1000);
|
66
82
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
83
|
+
return new $.Deferred(function(deferred) {
|
84
|
+
currentTimeout = setTimeout(resolve, duration);
|
85
|
+
currentDeferred = deferred;
|
86
|
+
}).promise();
|
87
|
+
},
|
88
|
+
function() {
|
89
|
+
currentValue = ensureInAllowedRange(value);
|
90
|
+
return new $.Deferred().resolve().promise();
|
91
|
+
}
|
92
|
+
);
|
71
93
|
};
|
72
94
|
|
73
95
|
player.one('dispose', cancel);
|
@@ -119,9 +141,10 @@ pageflow.mediaPlayer.volumeFading.webAudio = function(player, audioContext) {
|
|
119
141
|
if (gainNode.gain.value == 1) {
|
120
142
|
var performedDuration = (audioContext.currentTime - lastStartTime) * 1000;
|
121
143
|
var lastDelta = currentValue - lastStartValue;
|
144
|
+
var performedFraction = lastDelta > 0 ? performedDuration / lastDuration : 1;
|
122
145
|
|
123
146
|
currentValue = ensureInAllowedRange(
|
124
|
-
lastStartValue +
|
147
|
+
lastStartValue + performedFraction * lastDelta
|
125
148
|
);
|
126
149
|
}
|
127
150
|
else {
|
@@ -9,8 +9,8 @@ pageflow.AdjacentPages = pageflow.Object.extend({
|
|
9
9
|
var pages = this.pages();
|
10
10
|
var nextPage = this.nextPage(page);
|
11
11
|
|
12
|
-
if (nextPage
|
13
|
-
result.push(nextPage
|
12
|
+
if (nextPage) {
|
13
|
+
result.push(nextPage);
|
14
14
|
}
|
15
15
|
|
16
16
|
_(page.linkedPages()).each(function(permaId) {
|
@@ -23,6 +23,7 @@
|
|
23
23
|
|
24
24
|
widget.element.find('.close').one('click', function() {
|
25
25
|
hide();
|
26
|
+
pageflow.backgroundMedia.unmute();
|
26
27
|
|
27
28
|
pageflow.events.trigger('button:close_multimedia_alert');
|
28
29
|
start();
|
@@ -42,4 +43,4 @@
|
|
42
43
|
pageflow.nativeScrolling.preventScrollBouncing(this.element);
|
43
44
|
}
|
44
45
|
});
|
45
|
-
}(jQuery));
|
46
|
+
}(jQuery));
|
@@ -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
|
+
@include 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_filter :authenticate_user!, except: [:index, :show, :page]
|
7
7
|
|
8
|
-
before_filter :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'
|
@@ -155,6 +155,15 @@ module Pageflow
|
|
155
155
|
# end
|
156
156
|
attr_accessor :public_entry_request_scope
|
157
157
|
|
158
|
+
# Either a lambda or an object with a `call` method taking an
|
159
|
+
# {Entry} record and an {ActionDispatch::Request} object and
|
160
|
+
# returning `nil` or a path to redirect to. Can be used in
|
161
|
+
# conjuction with {PrimaryDomainEntryRedirect} to make sure
|
162
|
+
# entries are accessed via their account's configured cname.
|
163
|
+
#
|
164
|
+
# @since 12.4
|
165
|
+
attr_accessor :public_entry_redirect
|
166
|
+
|
158
167
|
# Either a lambda or an object with a `call` method taking a
|
159
168
|
# {Theming} as paramater and returing a hash of options used to
|
160
169
|
# construct the url of a published entry.
|
@@ -315,6 +324,7 @@ module Pageflow
|
|
315
324
|
|
316
325
|
@theming_request_scope = CnameThemingRequestScope.new
|
317
326
|
@public_entry_request_scope = lambda { |entries, request| entries }
|
327
|
+
@public_entry_redirect = ->(_entry, _request) { nil }
|
318
328
|
@public_entry_url_options = Pageflow::ThemingsHelper::DEFAULT_PUBLIC_ENTRY_OPTIONS
|
319
329
|
@entry_embed_url_options = {protocol: 'https'}
|
320
330
|
|
@@ -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
|
data/lib/pageflow/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pageflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.
|
4
|
+
version: 12.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Codevise Solutions Ltd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -2039,6 +2039,7 @@ files:
|
|
2039
2039
|
- lib/pageflow/page_types.rb
|
2040
2040
|
- lib/pageflow/paperclip_processors/vtt.rb
|
2041
2041
|
- lib/pageflow/plugin.rb
|
2042
|
+
- lib/pageflow/primary_domain_entry_redirect.rb
|
2042
2043
|
- lib/pageflow/quota.rb
|
2043
2044
|
- lib/pageflow/quotas.rb
|
2044
2045
|
- lib/pageflow/react.rb
|