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
@@ -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 {
|
@@ -6,8 +6,8 @@
|
|
6
6
|
//=require ./slideshow/scroll_indicator
|
7
7
|
//=require ./slideshow/scroll_indicator_widget
|
8
8
|
//=require ./slideshow/hidden_text_indicator_widget
|
9
|
-
//=require ./slideshow/
|
10
|
-
//=require ./slideshow/
|
9
|
+
//=require ./slideshow/adjacent_preloader
|
10
|
+
//=require ./slideshow/successor_preparer
|
11
11
|
//=require ./slideshow/swipe_gesture
|
12
12
|
//=require ./slideshow/hide_text
|
13
13
|
//=require ./slideshow/hide_text_on_swipe
|
@@ -16,7 +16,6 @@
|
|
16
16
|
|
17
17
|
pageflow.Slideshow = function($el, configurations) {
|
18
18
|
var transitioning = false,
|
19
|
-
preload = new pageflow.ProgressivePreload(),
|
20
19
|
currentPage = $(),
|
21
20
|
pages = $(),
|
22
21
|
that = this,
|
@@ -127,7 +126,7 @@ pageflow.Slideshow = function($el, configurations) {
|
|
127
126
|
transition: transition
|
128
127
|
});
|
129
128
|
|
130
|
-
|
129
|
+
currentPage.page('preload');
|
131
130
|
$el.trigger('slideshowchangepage', [options]);
|
132
131
|
|
133
132
|
return Math.max(outDuration, inDuration);
|
@@ -176,16 +175,17 @@ pageflow.Slideshow = function($el, configurations) {
|
|
176
175
|
currentPageIndex = currentPage.index();
|
177
176
|
|
178
177
|
currentPage.page('activateAsLandingPage');
|
179
|
-
|
178
|
+
currentPage.page('preload');
|
180
179
|
}
|
181
180
|
}
|
182
181
|
|
183
182
|
function findNewCurrentPage(options) {
|
184
183
|
if (!currentPage.length) {
|
185
184
|
var permaId = options && options.landingPagePermaId;
|
185
|
+
var landingPage = permaId ? getPageByPermaId(permaId) : $();
|
186
186
|
|
187
|
-
return
|
188
|
-
|
187
|
+
return landingPage.length ?
|
188
|
+
landingPage :
|
189
189
|
that.scrollNavigator.getLandingPage(pages);
|
190
190
|
}
|
191
191
|
else if (!currentPage.parent().length) {
|
@@ -236,7 +236,14 @@ pageflow.Slideshow = function($el, configurations) {
|
|
236
236
|
$el.find('.scroll_indicator').scrollIndicator({parent: this});
|
237
237
|
|
238
238
|
this.scrollNavigator = new pageflow.DomOrderScrollNavigator(this, pageflow.entryData);
|
239
|
-
|
239
|
+
|
240
|
+
pageflow.AdjacentPreloader
|
241
|
+
.create(function() { return pages; }, this.scrollNavigator)
|
242
|
+
.attach(pageflow.events);
|
243
|
+
|
244
|
+
pageflow.SuccessorPreparer
|
245
|
+
.create(function() { return pages; }, this.scrollNavigator)
|
246
|
+
.attach(pageflow.events);
|
240
247
|
};
|
241
248
|
|
242
249
|
pageflow.Slideshow.setup = function(options) {
|
@@ -7,10 +7,10 @@ pageflow.AdjacentPages = pageflow.Object.extend({
|
|
7
7
|
of: function(page) {
|
8
8
|
var result = [];
|
9
9
|
var pages = this.pages();
|
10
|
-
var nextPage = this.
|
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) {
|
@@ -22,5 +22,10 @@ pageflow.AdjacentPages = pageflow.Object.extend({
|
|
22
22
|
}, this);
|
23
23
|
|
24
24
|
return result;
|
25
|
+
},
|
26
|
+
|
27
|
+
nextPage: function(page) {
|
28
|
+
var nextPage = this.scrollNavigator.getNextPage(page.element, this.pages());
|
29
|
+
return nextPage.length && nextPage.page('instance');
|
25
30
|
}
|
26
|
-
});
|
31
|
+
});
|
@@ -0,0 +1,26 @@
|
|
1
|
+
//= require ./adjacent_pages
|
2
|
+
|
3
|
+
pageflow.AdjacentPreloader = pageflow.Object.extend({
|
4
|
+
initialize: function(adjacentPages) {
|
5
|
+
this.adjacentPages = adjacentPages;
|
6
|
+
},
|
7
|
+
|
8
|
+
attach: function(events) {
|
9
|
+
this.listenTo(events, 'page:change', this.preloadAdjacent);
|
10
|
+
},
|
11
|
+
|
12
|
+
preloadAdjacent: function(page) {
|
13
|
+
_(this.adjacentPages.of(page)).each(function(page) {
|
14
|
+
page.preload();
|
15
|
+
});
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
pageflow.AdjacentPreloader.create = function(pages, scrollNavigator) {
|
20
|
+
return new pageflow.AdjacentPreloader(
|
21
|
+
new pageflow.AdjacentPages(
|
22
|
+
pages,
|
23
|
+
scrollNavigator
|
24
|
+
)
|
25
|
+
);
|
26
|
+
};
|
@@ -1,10 +1,10 @@
|
|
1
1
|
(function($) {
|
2
2
|
var creatingMethods = [
|
3
|
-
'reinit', 'reactivate', 'activate', 'activateAsLandingPage', 'prepare', 'linkedPages'
|
3
|
+
'reinit', 'reactivate', 'activate', 'activateAsLandingPage', 'preload', 'prepare', 'linkedPages'
|
4
4
|
];
|
5
5
|
|
6
6
|
var ignoredMethods = [
|
7
|
-
'cleanup', 'refreshScroller', 'resize', '
|
7
|
+
'cleanup', 'refreshScroller', 'resize', 'deactivate', 'unprepare',
|
8
8
|
'isPageChangeAllowed'
|
9
9
|
];
|
10
10
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
//= require ./adjacent_pages
|
2
|
+
|
3
|
+
pageflow.SuccessorPreparer = pageflow.Object.extend({
|
4
|
+
initialize: function(adjacentPages) {
|
5
|
+
this.adjacentPages = adjacentPages;
|
6
|
+
},
|
7
|
+
|
8
|
+
attach: function(events) {
|
9
|
+
this.listenTo(events, 'page:change', this.schedule);
|
10
|
+
},
|
11
|
+
|
12
|
+
schedule: function(page) {
|
13
|
+
clearTimeout(this.scheduleTimeout);
|
14
|
+
|
15
|
+
var prepare = _.bind(this.prepareSuccessor, this, page);
|
16
|
+
this.scheduleTimeout = setTimeout(prepare, page.prepareNextPageTimeout());
|
17
|
+
},
|
18
|
+
|
19
|
+
prepareSuccessor: function(page) {
|
20
|
+
var preparedPages = _.compact([
|
21
|
+
page,
|
22
|
+
this.adjacentPages.nextPage(page)
|
23
|
+
]);
|
24
|
+
|
25
|
+
var noLongerPreparedPages = _.difference(this.lastPreparedPages, preparedPages);
|
26
|
+
var newAdjacentPages = _.difference(preparedPages, this.lastPreparedPages);
|
27
|
+
|
28
|
+
_(noLongerPreparedPages).each(function(page) {
|
29
|
+
if (!page.isDestroyed) {
|
30
|
+
page.unprepare();
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
_(newAdjacentPages).each(function(adjacentPage) {
|
35
|
+
adjacentPage.prepare();
|
36
|
+
});
|
37
|
+
|
38
|
+
this.lastPreparedPages = preparedPages;
|
39
|
+
}
|
40
|
+
});
|
41
|
+
|
42
|
+
pageflow.SuccessorPreparer.create = function(pages, scrollNavigator) {
|
43
|
+
return new pageflow.SuccessorPreparer(
|
44
|
+
new pageflow.AdjacentPages(
|
45
|
+
pages,
|
46
|
+
scrollNavigator
|
47
|
+
)
|
48
|
+
);
|
49
|
+
};
|
@@ -4,6 +4,11 @@
|
|
4
4
|
* @param {boolean} [options.required=false]
|
5
5
|
* Display an error if the input is blank.
|
6
6
|
*
|
7
|
+
* @param {number} [options.maxLength=255]
|
8
|
+
* Maximum length of characters for this input.
|
9
|
+
* To support legacy data which consists of more characters than the specified maxLength,
|
10
|
+
* the option will only take effect for data which is shorter than the specified maxLength.
|
11
|
+
*
|
7
12
|
* @see
|
8
13
|
* {@link module:pageflow/ui.pageflow.inputWithPlaceholderText pageflow.inputWithPlaceholderText}
|
9
14
|
* for placeholder related further options
|
@@ -33,12 +38,15 @@ pageflow.TextInputView = Backbone.Marionette.ItemView.extend({
|
|
33
38
|
},
|
34
39
|
|
35
40
|
onChange: function() {
|
36
|
-
this.validate()
|
37
|
-
|
41
|
+
if(this.validate()) {
|
42
|
+
this.save();
|
43
|
+
}
|
38
44
|
},
|
39
45
|
|
40
46
|
onClose: function() {
|
41
|
-
this.
|
47
|
+
if(this.validate()) {
|
48
|
+
this.save();
|
49
|
+
}
|
42
50
|
},
|
43
51
|
|
44
52
|
save: function() {
|
@@ -46,15 +54,31 @@ pageflow.TextInputView = Backbone.Marionette.ItemView.extend({
|
|
46
54
|
},
|
47
55
|
|
48
56
|
load: function() {
|
49
|
-
this.ui.input
|
57
|
+
var input = this.ui.input;
|
58
|
+
input.val(this.model.get(this.options.propertyName));
|
59
|
+
|
60
|
+
// set mysql varchar length as default for non-legacy data
|
61
|
+
this.options.maxLength = this.options.maxLength || 255;
|
62
|
+
// do not validate legacy data which length exceeds the specified maximum
|
63
|
+
// for new and maxLength-conforming data: add validation
|
64
|
+
this.validateMaxLength = (input.val().length <= this.options.maxLength);
|
50
65
|
},
|
51
66
|
|
52
67
|
validate: function() {
|
53
|
-
|
68
|
+
var input = this.ui.input;
|
69
|
+
if (this.options.required && !input.val()) {
|
54
70
|
this.displayValidationError(I18n.t('pageflow.ui.views.inputs.text_input_view.required_field'));
|
71
|
+
return false;
|
72
|
+
} if (this.validateMaxLength && (input.val().length > this.options.maxLength)) {
|
73
|
+
this.displayValidationError(
|
74
|
+
I18n.t('pageflow.ui.views.inputs.text_input_view.max_characters_exceeded',
|
75
|
+
{max_length: this.options.maxLength})
|
76
|
+
);
|
77
|
+
return false;
|
55
78
|
}
|
56
79
|
else {
|
57
80
|
this.resetValidationError();
|
81
|
+
return true;
|
58
82
|
}
|
59
83
|
},
|
60
84
|
|
@@ -56,7 +56,7 @@
|
|
56
56
|
* ### Inline Help for Disabled Inputs
|
57
57
|
*
|
58
58
|
* For each inline help translation key, a separate key with an
|
59
|
-
* `"
|
59
|
+
* `"_disabled"` suffix can be supplied, which provides a help string
|
60
60
|
* that shall be displayed when the input is disabled. More specific
|
61
61
|
* attribute translation key prefixes take precedence over suffixed
|
62
62
|
* keys:
|
@@ -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));
|
@@ -3,7 +3,7 @@
|
|
3
3
|
background-color: #f4f4f4;
|
4
4
|
@include inset-shadow(0, 1px, 4px, #ddd);
|
5
5
|
|
6
|
-
|
6
|
+
&-tabs {
|
7
7
|
@include gradient(#efefef, #dfe1e2);
|
8
8
|
box-shadow: 0 1px 1px rgba(0,0,0,0.10), 0 1px 0 0 rgba(255,255,255, 0.8) inset;
|
9
9
|
border: solid 1px #c7c7c7;
|
@@ -37,7 +37,7 @@
|
|
37
37
|
}
|
38
38
|
}
|
39
39
|
|
40
|
-
|
40
|
+
&-container {
|
41
41
|
@include clearfix;
|
42
42
|
@extend .panel_contents;
|
43
43
|
|
@@ -48,4 +48,4 @@
|
|
48
48
|
display: block;
|
49
49
|
}
|
50
50
|
}
|
51
|
-
}
|
51
|
+
}
|