pageflow 12.2.0 → 12.3.0

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 pageflow might be problematic. Click here for more details.

Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -92
  3. data/admins/pageflow/accounts.rb +1 -0
  4. data/app/assets/audios/pageflow/unmute.mp3 +0 -0
  5. data/app/assets/javascripts/pageflow/asset_urls.js.erb +1 -1
  6. data/app/assets/javascripts/pageflow/audio/multi_player.js +4 -0
  7. data/app/assets/javascripts/pageflow/audio_player.js +1 -1
  8. data/app/assets/javascripts/pageflow/background_media.js +22 -0
  9. data/app/assets/javascripts/pageflow/base.js +2 -0
  10. data/app/assets/javascripts/pageflow/browser/agent.js +92 -78
  11. data/app/assets/javascripts/pageflow/browser/autoplay_support.js +2 -2
  12. data/app/assets/javascripts/pageflow/cookie_notice.js +7 -0
  13. data/app/assets/javascripts/pageflow/dist/react.js +1312 -329
  14. data/app/assets/javascripts/pageflow/editor/models/configuration.js +5 -5
  15. data/app/assets/javascripts/pageflow/editor/templates/background_positioning_sliders.jst.ejs +8 -0
  16. data/app/assets/javascripts/pageflow/editor/views/background_positioning_sliders_view.js +37 -23
  17. data/app/assets/javascripts/pageflow/editor/views/background_positioning_view.js +2 -2
  18. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/video.js +1 -1
  19. data/app/assets/javascripts/pageflow/editor/views/edit_widget_view.js +9 -0
  20. data/app/assets/javascripts/pageflow/editor/views/info_box_view.js +8 -0
  21. data/app/assets/javascripts/pageflow/editor/views/widget_types/cookie_notice_bar.js +15 -0
  22. data/app/assets/javascripts/pageflow/media_player.js +7 -3
  23. data/app/assets/javascripts/pageflow/media_player/handle_failed_play.js +34 -0
  24. data/app/assets/javascripts/pageflow/media_player/volume_fading/web_audio.js +29 -3
  25. data/app/assets/javascripts/pageflow/seed_entry_data.js +3 -3
  26. data/app/assets/javascripts/pageflow/slideshow.js +17 -9
  27. data/app/assets/javascripts/pageflow/slideshow/adjacent_pages.js +7 -2
  28. data/app/assets/javascripts/pageflow/slideshow/adjacent_preloader.js +26 -0
  29. data/app/assets/javascripts/pageflow/slideshow/atmo.js +23 -12
  30. data/app/assets/javascripts/pageflow/slideshow/lazy_page_widget.js +2 -2
  31. data/app/assets/javascripts/pageflow/slideshow/{adjacent_preparer.js → successor_preparer.js} +14 -11
  32. data/app/assets/javascripts/pageflow/ui/views/configuration_editor_view.js +2 -2
  33. data/app/assets/javascripts/pageflow/video_player/lazy.js +1 -1
  34. data/app/assets/javascripts/pageflow/visited.js +2 -0
  35. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +34 -10
  36. data/app/assets/stylesheets/pageflow/page_types/video.scss +1 -4
  37. data/app/assets/stylesheets/pageflow/page_types/video/mobile_poster.scss +15 -0
  38. data/app/assets/stylesheets/pageflow/themes/default/background_media_unmute_button.scss +68 -0
  39. data/app/assets/stylesheets/pageflow/themes/default/base.scss +2 -0
  40. data/app/assets/stylesheets/pageflow/themes/default/cookie_notice_bar.scss +57 -0
  41. data/app/assets/stylesheets/pageflow/themes/default/page.scss +1 -0
  42. data/app/assets/stylesheets/pageflow/themes/default/page/hyphenate.scss +24 -0
  43. data/app/assets/stylesheets/pageflow/themes/default/slideshow.scss +1 -0
  44. data/app/controllers/pageflow/admin/initial_passwords_controller.rb +8 -0
  45. data/app/helpers/pageflow/common_entry_seed_helper.rb +1 -0
  46. data/app/helpers/pageflow/entries_helper.rb +20 -2
  47. data/app/helpers/pageflow/entry_json_seed_helper.rb +1 -1
  48. data/app/helpers/pageflow/public_i18n_helper.rb +6 -1
  49. data/app/views/admin/accounts/_form.html.erb +1 -0
  50. data/app/views/pageflow/admin/initial_passwords/edit.html.erb +16 -0
  51. data/app/views/pageflow/entry_json_seed/_entry.json.jbuilder +1 -1
  52. data/app/views/pageflow/user_mailer/invitation.html.erb +2 -2
  53. data/app/views/pageflow/user_mailer/invitation.text.erb +1 -1
  54. data/config/locales/de.yml +14 -6
  55. data/config/locales/en.yml +16 -8
  56. data/config/routes.rb +6 -0
  57. data/db/migrate/20180528144334_add_privacy_link_url_to_themings.rb +5 -0
  58. data/lib/pageflow/built_in_widget_type.rb +8 -0
  59. data/lib/pageflow/built_in_widget_types_plugin.rb +2 -0
  60. data/lib/pageflow/version.rb +1 -1
  61. data/vendor/assets/javascripts/audio5.min.js +280 -129
  62. metadata +19 -7
  63. data/app/assets/javascripts/pageflow/media_player/catch_play_promise.js +0 -23
  64. data/app/assets/javascripts/pageflow/slideshow/progressive_preload.js +0 -42
@@ -2,14 +2,19 @@
2
2
  var attributeName = 'atmo_audio_file_id';
3
3
 
4
4
  pageflow.Atmo = pageflow.Object.extend({
5
- initialize: function(slideshow, events, multiPlayer) {
6
- this.slideshow = slideshow;
7
- this.multiPlayer = multiPlayer;
5
+ initialize: function(options) {
6
+ this.slideshow = options.slideshow;
7
+ this.multiPlayer = options.multiPlayer;
8
+ this.backgroundMedia = options.backgroundMedia;
8
9
  this.disabled = pageflow.browser.has('mobile platform');
9
10
 
10
- this.listenTo(events, 'page:change page:update', function() {
11
+ this.listenTo(options.events, 'page:change page:update background_media:unmute', function() {
11
12
  this.update();
12
13
  });
14
+
15
+ this.listenTo(options.multiPlayer, 'playfailed', function() {
16
+ options.backgroundMedia.mute();
17
+ });
13
18
  },
14
19
 
15
20
  disable: function() {
@@ -46,7 +51,7 @@
46
51
 
47
52
  resume: function() {
48
53
  if (this.multiPlayer.paused()) {
49
- if (this.disabled) {
54
+ if (this.disabled || this.backgroundMedia.muted) {
50
55
  return new $.Deferred().resolve().promise();
51
56
  }
52
57
  else {
@@ -62,7 +67,12 @@
62
67
  var configuration = this.slideshow.currentPageConfiguration();
63
68
 
64
69
  if (!this.disabled) {
65
- this.multiPlayer.fadeTo(configuration[attributeName]);
70
+ if (this.backgroundMedia.muted) {
71
+ this.multiPlayer.fadeOutAndPause();
72
+ }
73
+ else {
74
+ this.multiPlayer.fadeTo(configuration[attributeName]);
75
+ }
66
76
  }
67
77
  },
68
78
 
@@ -86,11 +96,12 @@
86
96
  }
87
97
  });
88
98
 
89
- pageflow.Atmo.create = function(slideshow, events, audio) {
90
- return new pageflow.Atmo(
91
- slideshow,
92
- events,
93
- audio.createMultiPlayer({
99
+ pageflow.Atmo.create = function(slideshow, events, audio, backgroundMedia) {
100
+ return new pageflow.Atmo({
101
+ slideshow: slideshow,
102
+ events: events,
103
+ backgroundMedia: backgroundMedia,
104
+ multiPlayer: audio.createMultiPlayer({
94
105
  loop: true,
95
106
  fadeDuration: 500,
96
107
  crossFade: true,
@@ -98,7 +109,7 @@
98
109
  rewindOnChange: true,
99
110
  pauseInBackground: true
100
111
  })
101
- );
112
+ });
102
113
  };
103
114
 
104
115
  pageflow.Atmo.duringPlaybackModes = ['play', 'mute', 'turn_down'];
@@ -1,6 +1,6 @@
1
1
  (function($) {
2
- var creatingMethods = ['reinit', 'reactivate', 'activate', 'activateAsLandingPage', 'prepare', 'linkedPages'];
3
- var ignoredMethods = ['cleanup', 'refreshScroller', 'resize', 'preload', 'deactivate', 'unprepare'];
2
+ var creatingMethods = ['reinit', 'reactivate', 'activate', 'activateAsLandingPage', 'prepare', 'preload', 'linkedPages'];
3
+ var ignoredMethods = ['cleanup', 'refreshScroller', 'resize', 'deactivate', 'unprepare'];
4
4
 
5
5
  var prototype = {
6
6
  _create: function() {
@@ -1,6 +1,6 @@
1
1
  //= require ./adjacent_pages
2
2
 
3
- pageflow.AdjacentPreparer = pageflow.Object.extend({
3
+ pageflow.SuccessorPreparer = pageflow.Object.extend({
4
4
  initialize: function(adjacentPages) {
5
5
  this.adjacentPages = adjacentPages;
6
6
  },
@@ -12,14 +12,18 @@ pageflow.AdjacentPreparer = pageflow.Object.extend({
12
12
  schedule: function(page) {
13
13
  clearTimeout(this.scheduleTimeout);
14
14
 
15
- var prepare = _.bind(this.prepareAdjacent, this, page.element.page('instance'));
15
+ var prepare = _.bind(this.prepareSuccessor, this, page);
16
16
  this.scheduleTimeout = setTimeout(prepare, page.prepareNextPageTimeout());
17
17
  },
18
18
 
19
- prepareAdjacent: function(page) {
20
- var adjacentPages = this.adjacentPages.of(page);
21
- var noLongerPreparedPages = _.difference(this.lastPreparedPages, adjacentPages, [page]);
22
- var newAdjacentPages = _.difference(adjacentPages, this.lastPreparedPages);
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);
23
27
 
24
28
  _(noLongerPreparedPages).each(function(page) {
25
29
  if (!page.isDestroyed) {
@@ -29,18 +33,17 @@ pageflow.AdjacentPreparer = pageflow.Object.extend({
29
33
 
30
34
  _(newAdjacentPages).each(function(adjacentPage) {
31
35
  adjacentPage.prepare();
32
- adjacentPage.preload();
33
36
  });
34
37
 
35
- this.lastPreparedPages = adjacentPages.concat([page]);
38
+ this.lastPreparedPages = preparedPages;
36
39
  }
37
40
  });
38
41
 
39
- pageflow.AdjacentPreparer.create = function(pages, scrollNavigator) {
40
- return new pageflow.AdjacentPreparer(
42
+ pageflow.SuccessorPreparer.create = function(pages, scrollNavigator) {
43
+ return new pageflow.SuccessorPreparer(
41
44
  new pageflow.AdjacentPages(
42
45
  pages,
43
46
  scrollNavigator
44
47
  )
45
48
  );
46
- };
49
+ };
@@ -3,7 +3,7 @@ pageflow.ConfigurationEditorView = Backbone.Marionette.View.extend({
3
3
 
4
4
  initialize: function() {
5
5
  this.tabsView = new pageflow.TabsView({
6
- i18n: 'pageflow.ui.configuration_editor.tabs',
6
+ i18n: this.options.tabTranslationKeyPrefix || 'pageflow.ui.configuration_editor.tabs',
7
7
  defaultTab: this.options.tab
8
8
  });
9
9
  this.configure();
@@ -40,4 +40,4 @@ _.extend(pageflow.ConfigurationEditorView, {
40
40
  register: function(pageTypeName, prototype) {
41
41
  this.repository[pageTypeName] = pageflow.ConfigurationEditorView.extend(prototype);
42
42
  }
43
- });
43
+ });
@@ -80,7 +80,7 @@ pageflow.VideoPlayer.Lazy = function(template, options) {
80
80
  return videoPlayer && videoPlayer.posterImage.unlockShowing();
81
81
  };
82
82
 
83
- _.each(['play', 'playAndFadeIn', 'pause', 'fadeOutAndPause', 'prebuffer', 'src', 'on', 'load', 'currentTime'], function(method) {
83
+ _.each(['play', 'playAndFadeIn', 'pause', 'fadeOutAndPause', 'prebuffer', 'src', 'on', 'load', 'currentTime', 'muted'], function(method) {
84
84
  that[method] = function(/* args */) {
85
85
  var args = arguments;
86
86
 
@@ -4,6 +4,8 @@ pageflow.Visited = function(entryId, pages, events, cookies) {
4
4
  var unvisitedPages = [];
5
5
 
6
6
  function init() {
7
+ pageflow.cookieNotice.request();
8
+
7
9
  if (!cookies.hasItem(cookieName)) {
8
10
  storeVisitedPageIds(getAllIds());
9
11
  }
@@ -47,7 +47,7 @@
47
47
 
48
48
  .wrapper {
49
49
  text-align: center;
50
- margin: 20px;
50
+ margin: 35px;
51
51
  }
52
52
 
53
53
  .previews {
@@ -96,6 +96,7 @@
96
96
  .slider {
97
97
  position: absolute;
98
98
  border: none;
99
+ background: #ddd;
99
100
 
100
101
  a {
101
102
  @include background-icon-center($font-size: 20px);
@@ -113,10 +114,10 @@
113
114
  }
114
115
 
115
116
  &.horizontal {
116
- bottom: 0;
117
- left: 40px;
118
- right: 40px;
119
- height: 0;
117
+ bottom: -10px;
118
+ left: 9px;
119
+ right: 11px;
120
+ height: 2px;
120
121
 
121
122
  a {
122
123
  @include transform(rotate(90deg));
@@ -126,10 +127,10 @@
126
127
  }
127
128
 
128
129
  &.vertical {
129
- right: 0;
130
- top: 40px;
131
- bottom: 40px;
132
- width: 0;
130
+ right: -10px;
131
+ top: 12px;
132
+ bottom: 11px;
133
+ width: 2px;
133
134
  height: auto;
134
135
 
135
136
  a {
@@ -139,6 +140,29 @@
139
140
  }
140
141
  }
141
142
 
143
+ .percent {
144
+ position: absolute;
145
+ font-size: 12px;
146
+ white-space: nowrap;
147
+
148
+ input {
149
+ width: 45px;
150
+ height: 25px;
151
+ box-sizing: border-box;
152
+ text-align: right;
153
+ }
154
+
155
+ &.horizontal {
156
+ left: -65px;
157
+ bottom: -26px;
158
+ }
159
+
160
+ &.vertical {
161
+ left: 100%;
162
+ top: -30px;
163
+ }
164
+ }
165
+
142
166
  a.save {
143
167
  @include check-icon;
144
168
  @include icon-button;
@@ -147,4 +171,4 @@
147
171
  a.close {
148
172
  @include icon-button(#888);
149
173
  }
150
- }
174
+ }
@@ -1,4 +1,5 @@
1
1
  @import "./video/content_hiding";
2
+ @import "./video/mobile_poster";
2
3
 
3
4
  .has_native_video_player .page .videoPage .videoWrapper {
4
5
  margin-right: 0;
@@ -114,7 +115,3 @@
114
115
  .js .non_js_video {
115
116
  display: none;
116
117
  }
117
-
118
- .has_no_native_video_player .videoPage .background_image {
119
- display: none;
120
- }
@@ -0,0 +1,15 @@
1
+ .videoPage .background_image {
2
+ display: none;
3
+ }
4
+
5
+ .has_phone_platform {
6
+ // Show mobile poster only on phone platform
7
+ .videoPage .background_image {
8
+ display: block;
9
+ }
10
+
11
+ // But not while playing inline (e.g. on Android)
12
+ &.has_no_native_video_player .videoPage.should_play .background_image {
13
+ display: none;
14
+ }
15
+ }
@@ -0,0 +1,68 @@
1
+ $background-media-unmute-button-color: rgba(53, 53, 53, 0.9);
2
+
3
+ $background-media-unmute-button-shadow-color: #ccc;
4
+
5
+ $background-media-unmute-button-icon-color: #ddd;
6
+
7
+ $background-media-unmute-button-icon-size: 24px;
8
+
9
+ $background-media-unmute-button-size: 34px;
10
+
11
+ $background-media-unmute-button-margin: 10px;
12
+
13
+ .background_media_unmute_button {
14
+ position: absolute;
15
+ top: 26px;
16
+ right: 25px;
17
+ width: $background-media-unmute-button-size + $background-media-unmute-button-margin;
18
+ height: $background-media-unmute-button-size + $background-media-unmute-button-margin;
19
+
20
+ @extend %pageflow_widget_margin_right_max !optional;
21
+ @extend %pageflow_widget_margin_top !optional;
22
+
23
+ @include mobile {
24
+ top: 70px;
25
+ right: 11px;
26
+ }
27
+
28
+ &:before {
29
+ z-index: 2;
30
+ }
31
+
32
+ &:after {
33
+ content: "";
34
+ display: block;
35
+ position: absolute;
36
+ top: 6px;
37
+ left: 6px;
38
+ width: $background-media-unmute-button-size;
39
+ height: $background-media-unmute-button-size;
40
+ border-radius: $background-media-unmute-button-size / 2;
41
+ background-color: $background-media-unmute-button-color;
42
+ @include box-shadow(0 0 7px $background-media-unmute-button-shadow-color);
43
+ z-index: 1;
44
+ }
45
+
46
+ a {
47
+ display: block;
48
+ width: 100%;
49
+ height: 100%;
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
+
56
+ &:after {
57
+ content: "";
58
+ display: block;
59
+ position: absolute;
60
+ width: 25px;
61
+ left: 22px;
62
+ top: 22px;
63
+ border-top: solid 2px $background-media-unmute-button-icon-color;
64
+ border-bottom: solid 1px $background-media-unmute-button-color;
65
+ @include transform(translate(-50%, -50%) rotate(45deg));
66
+ }
67
+ }
68
+ }
@@ -16,12 +16,14 @@
16
16
 
17
17
  @import "./built_in_page_types";
18
18
  @import "./anchors";
19
+ @import "./cookie_notice_bar";
19
20
  @import "./loading_spinner";
20
21
  @import "./logo";
21
22
  @import "./page";
22
23
  @import "./indicators";
23
24
  @import "./navigation";
24
25
  @import "./mobile_navigation";
26
+ @import "./background_media_unmute_button";
25
27
  @import "./multimedia_alert";
26
28
  @import "./overview";
27
29
  @import "./player_controls";
@@ -0,0 +1,57 @@
1
+ /// Color of the cookie notice bar
2
+ $cookie-notice-bar-background-color: rgba(20, 20, 20, 0.9);
3
+
4
+ /// Color of the text inside cookie notice bar
5
+ $cookie-notice-bar-text-color: #fff;
6
+
7
+ $cookie-notice-bar-link-text-color: $main-color;
8
+
9
+ $cookie-notice-bar-typography: ();
10
+
11
+ $cookie-notice-bar-dismiss-button-background-color: $main-color-dark;
12
+
13
+ $cookie-notice-bar-dismiss-button-text-color: #fff;
14
+
15
+ .cookie_notice_bar {
16
+ position: absolute;
17
+ bottom: 0;
18
+ left: 0;
19
+ right: 0;
20
+ background-color: $cookie-notice-bar-background-color;
21
+ color: $cookie-notice-bar-text-color;
22
+ padding: 10px 20px;
23
+ z-index: 2;
24
+
25
+ @include standard-typography(
26
+ $cookie-notice-bar-typography
27
+ );
28
+
29
+ &-content {
30
+ @extend %pageflow_widget_margin_right_max !optional;
31
+ }
32
+
33
+ &-text {
34
+ margin-top: 10px;
35
+ margin-bottom: 10px;
36
+ display: inline-block;
37
+
38
+ a {
39
+ color: $cookie-notice-bar-link-text-color;
40
+ }
41
+ }
42
+
43
+ &-dismiss {
44
+ background-color: $cookie-notice-bar-dismiss-button-background-color;
45
+ color: $cookie-notice-bar-dismiss-button-text-color;
46
+ border-radius: 3px;
47
+ float: right;
48
+ margin-top: 5px;
49
+ padding: 5px 10px;
50
+ }
51
+ }
52
+
53
+ @include pageflow-widget-margin("cookie_notice_bar_visible", "bottom") {
54
+ @include desktop {
55
+ margin-bottom: 60px;
56
+ }
57
+ }
@@ -84,6 +84,7 @@ $page-content-text-font-size: 1.2em !default;
84
84
  $page-content-text-line-height: 1.5em !default;
85
85
 
86
86
  @import "./page/anchors";
87
+ @import "./page/hyphenate";
87
88
  @import "./page/paddings";
88
89
  @import "./page/scroller";
89
90
  @import "./page/shadow";
@@ -0,0 +1,24 @@
1
+ /// Let browser break words in header.
2
+ ///
3
+ /// - `"narrow"`: Only allow hyphenating words when header is narrow,
4
+ /// i.e. in portrait phone layout.
5
+ ///
6
+ /// - `"always"`: Always break words
7
+ ///
8
+ /// - `"never"`: Never break words
9
+ $page-hyphenate-header: "narrow" !default;
10
+
11
+ .page {
12
+ h2 {
13
+ @if $page-hyphenate-header == "always" {
14
+
15
+ hyphens: auto;
16
+
17
+ } @else if $page-hyphenate-header == "narrow" {
18
+
19
+ @include phone_portrait {
20
+ hyphens: auto;
21
+ }
22
+ }
23
+ }
24
+ }