pageflow 16.0.0 → 16.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -33
  3. data/README.md +6 -6
  4. data/Rakefile +1 -1
  5. data/admins/pageflow/entry.rb +0 -1
  6. data/admins/pageflow/sites.rb +3 -0
  7. data/app/assets/images/pageflow/admin/icons/published_with_noindex.svg +4 -0
  8. data/app/assets/javascripts/pageflow/dist/ui.js +299 -72
  9. data/app/assets/stylesheets/pageflow/admin/active_admin_patches.scss +1 -1
  10. data/app/assets/stylesheets/pageflow/admin/entries.scss +4 -0
  11. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +10 -0
  12. data/app/assets/stylesheets/pageflow/admin/publication_state_indicator.scss +4 -0
  13. data/app/assets/stylesheets/pageflow/editor/base.scss +0 -1
  14. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +61 -7
  15. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +12 -1
  16. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +4 -0
  17. data/app/assets/stylesheets/pageflow/editor/help.scss +3 -3
  18. data/app/assets/stylesheets/pageflow/editor/info_box.scss +7 -0
  19. data/app/assets/stylesheets/pageflow/editor/inputs/file_input.scss +0 -5
  20. data/app/assets/stylesheets/pageflow/ui/forms.scss +4 -4
  21. data/app/assets/stylesheets/pageflow/{editor/wysihtml5.scss → ui/input/text_area_input.scss} +13 -1
  22. data/app/assets/stylesheets/pageflow/ui.scss +1 -0
  23. data/app/controllers/pageflow/chapters_controller.rb +2 -2
  24. data/app/controllers/pageflow/editor/entry_publications_controller.rb +5 -1
  25. data/app/controllers/pageflow/editor/file_import_controller.rb +1 -1
  26. data/app/controllers/pageflow/editor/files_controller.rb +1 -1
  27. data/app/controllers/pageflow/entries_controller.rb +12 -2
  28. data/app/controllers/pageflow/feeds_controller.rb +18 -0
  29. data/app/controllers/pageflow/pages_controller.rb +2 -2
  30. data/app/controllers/pageflow/sitemaps_controller.rb +15 -0
  31. data/app/controllers/pageflow/storylines_controller.rb +2 -2
  32. data/app/helpers/pageflow/entries_helper.rb +4 -1
  33. data/app/helpers/pageflow/feeds_helper.rb +66 -0
  34. data/app/helpers/pageflow/meta_tags_helper.rb +2 -1
  35. data/app/helpers/pageflow/page_types_helper.rb +10 -10
  36. data/app/helpers/pageflow/revision_file_helper.rb +3 -3
  37. data/app/helpers/pageflow/social_share_helper.rb +2 -2
  38. data/app/inputs/pageflow_permalink_input.rb +15 -3
  39. data/app/models/concerns/pageflow/entry_publication_states.rb +9 -0
  40. data/app/models/concerns/pageflow/reusable_file.rb +3 -3
  41. data/app/models/concerns/pageflow/uploadable_file.rb +5 -0
  42. data/app/models/pageflow/account.rb +8 -0
  43. data/app/models/pageflow/audio_file_url_templates.rb +2 -1
  44. data/app/models/pageflow/draft_entry.rb +1 -1
  45. data/app/models/pageflow/entries_feed.rb +32 -0
  46. data/app/models/pageflow/entry.rb +7 -5
  47. data/app/models/pageflow/entry_at_revision.rb +2 -0
  48. data/app/models/pageflow/image_file.rb +34 -8
  49. data/app/models/pageflow/image_file_url_templates.rb +7 -1
  50. data/app/models/pageflow/membership.rb +3 -2
  51. data/app/models/pageflow/other_file.rb +5 -0
  52. data/app/models/pageflow/other_file_url_templates.rb +16 -0
  53. data/app/models/pageflow/published_entry.rb +6 -0
  54. data/app/models/pageflow/revision.rb +6 -0
  55. data/app/models/pageflow/site.rb +8 -0
  56. data/app/models/pageflow/sitemaps.rb +14 -0
  57. data/app/models/pageflow/used_file.rb +10 -2
  58. data/app/models/pageflow/video_file_url_templates.rb +3 -1
  59. data/app/models/pageflow/widget.rb +9 -1
  60. data/app/views/admin/entries/_permalink_inputs.html.erb +1 -2
  61. data/app/views/admin/sites/_attributes_table.html.arb +3 -0
  62. data/app/views/admin/sites/_fields.html.erb +6 -0
  63. data/app/views/components/pageflow/admin/extensible_attributes_table.rb +2 -2
  64. data/app/views/components/pageflow/admin/revisions_tab.rb +8 -0
  65. data/app/views/components/pageflow/admin/sites_tab.rb +3 -0
  66. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +2 -0
  67. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +1 -0
  68. data/app/views/pageflow/editor/entry_publications/check.json.jbuilder +1 -0
  69. data/app/views/pageflow/feeds/index.atom.builder +20 -0
  70. data/app/views/pageflow/image_files/_image_file.json.jbuilder +1 -0
  71. data/app/views/pageflow/meta_tags/_entry.html.erb +1 -0
  72. data/app/views/pageflow/sitemaps/index.xml.builder +9 -0
  73. data/config/initializers/features.rb +3 -0
  74. data/config/initializers/paperclip.rb +8 -0
  75. data/config/locales/de.yml +77 -6
  76. data/config/locales/en.yml +79 -4
  77. data/config/routes.rb +3 -0
  78. data/config/spring.rb +1 -1
  79. data/db/migrate/20230120092923_create_other_files.rb +23 -0
  80. data/db/migrate/20230323115745_add_feeds_enabled_to_sites.rb +5 -0
  81. data/db/migrate/20230323154323_add_sitemap_enabled_to_sites.rb +5 -0
  82. data/db/migrate/20230331103823_add_title_to_sites.rb +5 -0
  83. data/db/migrate/20230405103612_add_custom_feed_url_to_sites.rb +5 -0
  84. data/db/migrate/20231024062501_add_output_presences_to_image_files.rb +5 -0
  85. data/db/migrate/20231128124523_add_noindex_to_revisions.rb +5 -0
  86. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +710 -259
  87. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +34 -5
  88. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +1 -1
  89. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +1 -1
  90. data/entry_types/paged/app/controllers/pageflow_paged/editor/entries_controller.rb +0 -2
  91. data/entry_types/paged/app/controllers/pageflow_paged/entries_controller.rb +2 -1
  92. data/entry_types/paged/app/views/pageflow_paged/entries/show.html.erb +1 -0
  93. data/entry_types/paged/config/initializers/features.rb +0 -1
  94. data/entry_types/paged/lib/pageflow_paged/engine.rb +13 -1
  95. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +2 -2
  96. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +3 -4
  97. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +13 -6
  98. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +11 -3
  99. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +11 -0
  100. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +42 -0
  101. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +8 -5
  102. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +17 -12
  103. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +9 -1
  104. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +1 -1
  105. data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +23 -0
  106. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +1 -1
  107. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_seed.json.jbuilder +1 -5
  108. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/sections/_section_with_content_elements.json.jbuilder +10 -0
  109. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +44 -41
  110. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_consent_vendors.json.jbuilder +16 -0
  111. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +7 -0
  112. data/entry_types/scrolled/config/initializers/features.rb +5 -0
  113. data/entry_types/scrolled/config/locales/consent_widget.de.yml +4 -0
  114. data/entry_types/scrolled/config/locales/consent_widget.en.yml +4 -0
  115. data/entry_types/scrolled/config/locales/de.yml +225 -8
  116. data/entry_types/scrolled/config/locales/en.yml +239 -2
  117. data/entry_types/scrolled/config/routes.rb +4 -0
  118. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +69 -44
  119. data/entry_types/scrolled/lib/pageflow_scrolled/additional_packs.rb +2 -1
  120. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +1 -1
  121. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +96 -0
  122. data/entry_types/scrolled/lib/pageflow_scrolled/content_element_consent_vendors.rb +38 -0
  123. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +13 -1
  124. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +30 -0
  125. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +6 -1
  126. data/entry_types/scrolled/lib/pageflow_scrolled/web_app_manifest.rb +1 -1
  127. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/dummy.rake +1 -1
  128. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +1 -2
  129. data/entry_types/scrolled/package/config/webpack.js +26 -0
  130. data/entry_types/scrolled/package/contentElements-editor.js +330 -32
  131. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  132. data/entry_types/scrolled/package/contentElements-frontend.js +920 -145
  133. data/entry_types/scrolled/package/editor.js +819 -239
  134. data/entry_types/scrolled/package/frontend/{EditableInlineText.module-14c7b097.js → EditableInlineText.module-6ee0e024.js} +1975 -1792
  135. data/entry_types/scrolled/package/frontend/PhonePlatformContext-b28d991a.js +32 -0
  136. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-8242f213.js +107 -0
  137. data/entry_types/scrolled/package/frontend/Viewer-32cd1ac1.js +154 -0
  138. data/entry_types/scrolled/package/frontend/{Viewer-b6becc57.js → Viewer-6e4d14ed.js} +32 -161
  139. data/entry_types/scrolled/package/frontend/arrowRight-e42e6011.js +77 -0
  140. data/entry_types/scrolled/package/frontend/{components-b3160dd7.js → components-24363f97.js} +188 -47
  141. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-f6093cc6.js → i18n-71c39823.js} +191 -111
  142. data/entry_types/scrolled/package/frontend/index-fc4b13e6.js +118 -0
  143. data/entry_types/scrolled/package/frontend/index.css +1 -1
  144. data/entry_types/scrolled/package/frontend/index.js +252 -76
  145. data/entry_types/scrolled/package/frontend/useContentElementEditorState-245f1986.js +52 -0
  146. data/entry_types/scrolled/package/package.json +6 -4
  147. data/entry_types/scrolled/package/testHelpers.js +11 -2
  148. data/entry_types/scrolled/package/values/colors.module.css +15 -0
  149. data/entry_types/scrolled/package/widgets/consentBar.css +1 -0
  150. data/entry_types/scrolled/package/widgets/consentBar.js +426 -0
  151. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  152. data/entry_types/scrolled/package/widgets/defaultNavigation.js +39 -4
  153. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -0
  154. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +49 -0
  155. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -0
  156. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +37 -0
  157. data/lib/generators/pageflow/resque/resque_generator.rb +1 -1
  158. data/lib/generators/pageflow/resque/templates/resque.rake +1 -1
  159. data/lib/generators/pageflow/resque/templates/resque.rb +1 -1
  160. data/lib/generators/pageflow/routes/routes_generator.rb +1 -1
  161. data/lib/pageflow/ability_mixin.rb +5 -5
  162. data/lib/pageflow/active_admin_can_can_fix.rb +2 -2
  163. data/lib/pageflow/built_in_file_type.rb +7 -0
  164. data/lib/pageflow/configuration.rb +29 -1
  165. data/lib/pageflow/engine.rb +18 -40
  166. data/lib/pageflow/entry_export_import/revision_serialization.rb +1 -1
  167. data/lib/pageflow/file_type.rb +2 -2
  168. data/lib/pageflow/global_config_api.rb +2 -2
  169. data/lib/pageflow/nested_revision_component.rb +23 -5
  170. data/lib/pageflow/page_type.rb +1 -1
  171. data/lib/pageflow/paperclip_processors/webp.rb +63 -0
  172. data/lib/pageflow/rails_version.rb +19 -0
  173. data/lib/pageflow/seeds.rb +10 -7
  174. data/lib/pageflow/user_mixin.rb +1 -1
  175. data/lib/pageflow/version.rb +1 -1
  176. data/lib/pageflow/widget_types.rb +4 -0
  177. data/package/config/jest/index.js +3 -1
  178. data/package/config/webpack5.js +14 -0
  179. data/package/editor.js +410 -181
  180. data/package/frontend.js +34 -4
  181. data/package/testHelpers.js +1 -1
  182. data/package/ui.js +297 -71
  183. data/spec/factories/entries.rb +34 -3
  184. data/spec/factories/sites.rb +3 -0
  185. data/vendor/assets/javascripts/iscroll.js +4 -7
  186. metadata +118 -80
  187. data/app/helpers/pageflow/admin/permalinks_helper.rb +0 -15
  188. data/entry_types/scrolled/package/frontend/arrowRight-78a7cee4.js +0 -42
data/package/frontend.js CHANGED
@@ -1240,7 +1240,7 @@ var volumeBinding = function volumeBinding(player, settings, options) {
1240
1240
  };
1241
1241
 
1242
1242
  player.targetVolume = function () {
1243
- return settings.get('volume') * volumeFactor;
1243
+ return (options.ignoreVolumeSetting ? 1 : settings.get('volume')) * volumeFactor;
1244
1244
  };
1245
1245
 
1246
1246
  function listenToVolumeSetting() {
@@ -1615,6 +1615,21 @@ mediaPlayer.loadWaiting = loadWaiting;
1615
1615
  mediaPlayer.hooks = hooks;
1616
1616
  mediaPlayer.asyncPlay = asyncPlay;
1617
1617
 
1618
+ // Replacement for Underscore's throttle, because scrolled entries
1619
+ // don't have Underscore anymore
1620
+ function throttle(func, timeFrame) {
1621
+ var lastTime = 0;
1622
+ return function (options) {
1623
+ var now = new Date();
1624
+ func = func.bind(this);
1625
+
1626
+ if (now - lastTime >= timeFrame) {
1627
+ func(options);
1628
+ lastTime = now;
1629
+ }
1630
+ };
1631
+ }
1632
+
1618
1633
  var mediaEvents = function mediaEvents(player, context) {
1619
1634
  function triggerMediaEvent(name) {
1620
1635
  events.trigger('media:' + name, {
@@ -1633,6 +1648,9 @@ var mediaEvents = function mediaEvents(player, context) {
1633
1648
  player.on('timeupdate', function () {
1634
1649
  triggerMediaEvent('timeupdate');
1635
1650
  });
1651
+ player.on('timeupdate', throttle(function () {
1652
+ triggerMediaEvent('timeupdate_throttled');
1653
+ }, 5000));
1636
1654
  player.on('pause', function () {
1637
1655
  triggerMediaEvent('pause');
1638
1656
  });
@@ -2150,6 +2168,9 @@ var mediaEvents$1 = function mediaEvents(player, context) {
2150
2168
  player.on('timeupdate', function () {
2151
2169
  triggerMediaEvent('timeupdate');
2152
2170
  });
2171
+ player.on('timeupdate', throttle(function () {
2172
+ triggerMediaEvent('timeupdate_throttled');
2173
+ }, 5000));
2153
2174
  player.on('pause', function () {
2154
2175
  triggerMediaEvent('pause');
2155
2176
  });
@@ -2291,11 +2312,13 @@ var createMediaPlayer = function createMediaPlayer(options) {
2291
2312
  nativeCaptions: !isAudio && browser.has('iphone platform'),
2292
2313
  // Only used by pageflow-scrolled
2293
2314
  vhs: {
2294
- useBandwidthFromLocalStorage: true
2315
+ useBandwidthFromLocalStorage: true,
2316
+ usePlayerObjectFit: true
2295
2317
  }
2296
2318
  },
2297
2319
  bufferUnderrunWaiting: true,
2298
2320
  fallbackToMutedAutoplay: !isAudio,
2321
+ ignoreVolumeSetting: true,
2299
2322
  volumeFading: true,
2300
2323
  hooks: {},
2301
2324
  mediaEvents: true,
@@ -2524,13 +2547,16 @@ var MediaPool = /*#__PURE__*/function () {
2524
2547
  tagName: type
2525
2548
  });
2526
2549
  mediaEl.setAttribute('src', blankSources[type].src);
2550
+ player.muted(true);
2527
2551
  this.unAllocatedPlayers[type].push(player);
2528
2552
  return player;
2529
2553
  }
2530
2554
  }, {
2531
2555
  key: "initializeMediaPool_",
2532
2556
  value: function initializeMediaPool_(type, mediaElSeed) {
2533
- while (this.allPlayersForType(type).length < this.playerCount) {
2557
+ var playerCount = typeof this.playerCount === 'function' ? this.playerCount(type) : this.playerCount;
2558
+
2559
+ while (this.allPlayersForType(type).length < playerCount) {
2534
2560
  this.createPlayer_(type, mediaElSeed.cloneNode(true));
2535
2561
  }
2536
2562
  }
@@ -2562,7 +2588,11 @@ function clearTextTracks(player) {
2562
2588
  }
2563
2589
 
2564
2590
  var media = {
2565
- playerPool: new MediaPool(),
2591
+ playerPool: new MediaPool({
2592
+ playerCount: function playerCount() {
2593
+ return features.isEnabled('large_player_pool') ? 10 : 4;
2594
+ }
2595
+ }),
2566
2596
  muteState: true,
2567
2597
 
2568
2598
  get muted() {
@@ -174,7 +174,7 @@ var ConfigurationEditorTab = Base.extend({
174
174
  }).get();
175
175
  },
176
176
  visibleInputPropertyNames: function visibleInputPropertyNames() {
177
- return this.$el.find('.input:not(.input-hidden_via_binding)').map(function () {
177
+ return this.$el.find('.input:not(.hidden_via_binding)').map(function () {
178
178
  return $(this).data('inputPropertyName');
179
179
  }).get();
180
180
  },
data/package/ui.js CHANGED
@@ -7,6 +7,7 @@ import ChildViewContainer from 'backbone.babysitter';
7
7
  import IScroll from 'iscroll';
8
8
  import 'jquery.minicolors';
9
9
  import wysihtml5 from 'wysihtml5';
10
+ import 'jquery-ui';
10
11
  import Cocktail from 'cocktail';
11
12
 
12
13
  /*global JST*/
@@ -1064,6 +1065,107 @@ var TooltipView = Marionette.ItemView.extend({
1064
1065
  }
1065
1066
  });
1066
1067
 
1068
+ function _defineProperty(obj, key, value) {
1069
+ if (key in obj) {
1070
+ Object.defineProperty(obj, key, {
1071
+ value: value,
1072
+ enumerable: true,
1073
+ configurable: true,
1074
+ writable: true
1075
+ });
1076
+ } else {
1077
+ obj[key] = value;
1078
+ }
1079
+
1080
+ return obj;
1081
+ }
1082
+
1083
+ function ownKeys(object, enumerableOnly) {
1084
+ var keys = Object.keys(object);
1085
+
1086
+ if (Object.getOwnPropertySymbols) {
1087
+ var symbols = Object.getOwnPropertySymbols(object);
1088
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
1089
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
1090
+ });
1091
+ keys.push.apply(keys, symbols);
1092
+ }
1093
+
1094
+ return keys;
1095
+ }
1096
+
1097
+ function _objectSpread2(target) {
1098
+ for (var i = 1; i < arguments.length; i++) {
1099
+ var source = arguments[i] != null ? arguments[i] : {};
1100
+
1101
+ if (i % 2) {
1102
+ ownKeys(Object(source), true).forEach(function (key) {
1103
+ _defineProperty(target, key, source[key]);
1104
+ });
1105
+ } else if (Object.getOwnPropertyDescriptors) {
1106
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
1107
+ } else {
1108
+ ownKeys(Object(source)).forEach(function (key) {
1109
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
1110
+ });
1111
+ }
1112
+ }
1113
+
1114
+ return target;
1115
+ }
1116
+
1117
+ var attributeBinding = {
1118
+ setupBooleanAttributeBinding: function setupBooleanAttributeBinding(optionName, updateMethod) {
1119
+ this.setupAttributeBinding(optionName, updateMethod, Boolean);
1120
+ },
1121
+ getBooleanAttributBoundOption: function getBooleanAttributBoundOption(optionName) {
1122
+ return this.getAttributeBoundOption(optionName, Boolean);
1123
+ },
1124
+ setupAttributeBinding: function setupAttributeBinding(optionName, updateMethod) {
1125
+ var _this = this;
1126
+
1127
+ var normalize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (value) {
1128
+ return value;
1129
+ };
1130
+ var binding = this.options["".concat(optionName, "Binding")];
1131
+ var view = this;
1132
+
1133
+ if (binding) {
1134
+ _.flatten([binding]).forEach(function (attribute) {
1135
+ _this.listenTo(_this.model, 'change:' + attribute, update);
1136
+ });
1137
+ }
1138
+
1139
+ update();
1140
+
1141
+ function update() {
1142
+ updateMethod.call(view, view.getAttributeBoundOption(optionName, normalize));
1143
+ }
1144
+ },
1145
+ getAttributeBoundOption: function getAttributeBoundOption(optionName) {
1146
+ var _this2 = this;
1147
+
1148
+ var normalize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (value) {
1149
+ return value;
1150
+ };
1151
+ var binding = this.options["".concat(optionName, "Binding")];
1152
+ var bindingValueOptionName = "".concat(optionName, "BindingValue");
1153
+ var value = Array.isArray(binding) ? binding.map(function (attribute) {
1154
+ return _this2.model.get(attribute);
1155
+ }) : this.model.get(binding);
1156
+
1157
+ if (bindingValueOptionName in this.options) {
1158
+ return value === this.options[bindingValueOptionName];
1159
+ } else if (typeof this.options[optionName] === 'function') {
1160
+ return normalize(this.options[optionName](value));
1161
+ } else if (optionName in this.options) {
1162
+ return normalize(this.options[optionName]);
1163
+ } else if (binding) {
1164
+ return normalize(value);
1165
+ }
1166
+ }
1167
+ };
1168
+
1067
1169
  /**
1068
1170
  * Mixin for input views handling common concerns like labels,
1069
1171
  * inline help, visiblity and disabling.
@@ -1193,7 +1295,7 @@ var TooltipView = Marionette.ItemView.extend({
1193
1295
  * @mixin
1194
1296
  */
1195
1297
 
1196
- var inputView = {
1298
+ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1197
1299
  ui: {
1198
1300
  label: 'label',
1199
1301
  labelText: 'label .name',
@@ -1237,8 +1339,8 @@ var inputView = {
1237
1339
  this.ui.labelText.text(this.labelText());
1238
1340
  this.updateInlineHelp();
1239
1341
  this.setLabelFor();
1240
- this.setupAttributeBinding('disabled', this.updateDisabled);
1241
- this.setupAttributeBinding('visible', this.updateVisible);
1342
+ this.setupBooleanAttributeBinding('disabled', this.updateDisabled);
1343
+ this.setupBooleanAttributeBinding('visible', this.updateVisible);
1242
1344
  },
1243
1345
 
1244
1346
  /**
@@ -1287,7 +1389,7 @@ var inputView = {
1287
1389
  }
1288
1390
  },
1289
1391
  isDisabled: function isDisabled() {
1290
- return this.getAttributeBoundOption('disabled');
1392
+ return this.getBooleanAttributBoundOption('disabled');
1291
1393
  },
1292
1394
  updateDisabled: function updateDisabled() {
1293
1395
  this.$el.toggleClass('input-disabled', !!this.isDisabled());
@@ -1305,46 +1407,9 @@ var inputView = {
1305
1407
  }
1306
1408
  },
1307
1409
  updateVisible: function updateVisible() {
1308
- this.$el.toggleClass('input-hidden_via_binding', this.getAttributeBoundOption('visible') === false);
1309
- },
1310
- setupAttributeBinding: function setupAttributeBinding(optionName, updateMethod) {
1311
- var _this = this;
1312
-
1313
- var binding = this.options["".concat(optionName, "Binding")];
1314
- var view = this;
1315
-
1316
- if (binding) {
1317
- _.flatten([binding]).forEach(function (attribute) {
1318
- _this.listenTo(_this.model, 'change:' + attribute, update);
1319
- });
1320
- }
1321
-
1322
- update();
1323
-
1324
- function update() {
1325
- updateMethod.call(view, view.getAttributeBoundOption(optionName));
1326
- }
1327
- },
1328
- getAttributeBoundOption: function getAttributeBoundOption(optionName) {
1329
- var _this2 = this;
1330
-
1331
- var binding = this.options["".concat(optionName, "Binding")];
1332
- var bindingValueOptionName = "".concat(optionName, "BindingValue");
1333
- var value = Array.isArray(binding) ? binding.map(function (attribute) {
1334
- return _this2.model.get(attribute);
1335
- }) : this.model.get(binding);
1336
-
1337
- if (bindingValueOptionName in this.options) {
1338
- return value === this.options[bindingValueOptionName];
1339
- } else if (typeof this.options[optionName] === 'function') {
1340
- return !!this.options[optionName](value);
1341
- } else if (optionName in this.options) {
1342
- return !!this.options[optionName];
1343
- } else if (binding) {
1344
- return !!value;
1345
- }
1410
+ this.$el.toggleClass('hidden_via_binding', this.getBooleanAttributBoundOption('visible') === false);
1346
1411
  }
1347
- };
1412
+ });
1348
1413
 
1349
1414
  function template$4(data) {
1350
1415
  var __p = '';
@@ -1463,6 +1528,125 @@ var UrlDisplayView = Marionette.ItemView.extend({
1463
1528
  }
1464
1529
  });
1465
1530
 
1531
+ function _classCallCheck(instance, Constructor) {
1532
+ if (!(instance instanceof Constructor)) {
1533
+ throw new TypeError("Cannot call a class as a function");
1534
+ }
1535
+ }
1536
+
1537
+ function _defineProperties(target, props) {
1538
+ for (var i = 0; i < props.length; i++) {
1539
+ var descriptor = props[i];
1540
+ descriptor.enumerable = descriptor.enumerable || false;
1541
+ descriptor.configurable = true;
1542
+ if ("value" in descriptor) descriptor.writable = true;
1543
+ Object.defineProperty(target, descriptor.key, descriptor);
1544
+ }
1545
+ }
1546
+
1547
+ function _createClass(Constructor, protoProps, staticProps) {
1548
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1549
+ if (staticProps) _defineProperties(Constructor, staticProps);
1550
+ return Constructor;
1551
+ }
1552
+
1553
+ /**
1554
+ * Input view for a number.
1555
+ *
1556
+ * See {@link inputView} for further options.
1557
+ *
1558
+ * @param {Object} [options]
1559
+ *
1560
+ * @param {string} [options.locale]
1561
+ * Locale used to fomat and parse numbers.
1562
+ *
1563
+ * @class
1564
+ */
1565
+
1566
+ var NumberInputView = Marionette.ItemView.extend({
1567
+ mixins: [inputView],
1568
+ template: function template() {
1569
+ return "\n <label>\n <span class=\"name\"></span>\n <span class=\"inline_help\"></span>\n </label>\n <input type=\"text\" dir=\"auto\" />\n ";
1570
+ },
1571
+ ui: {
1572
+ input: 'input'
1573
+ },
1574
+ events: {
1575
+ 'change': 'onChange'
1576
+ },
1577
+ initialize: function initialize() {
1578
+ this.parser = new NumberParser(this.options.locale);
1579
+ },
1580
+ onRender: function onRender() {
1581
+ this.load();
1582
+ this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
1583
+ },
1584
+ onChange: function onChange() {
1585
+ this.save();
1586
+ this.load();
1587
+ },
1588
+ onClose: function onClose() {
1589
+ this.save();
1590
+ },
1591
+ save: function save() {
1592
+ var inputValue = this.ui.input.val();
1593
+ this.model.set(this.options.propertyName, this.parser.parse(inputValue) || 0);
1594
+ },
1595
+ load: function load() {
1596
+ var input = this.ui.input;
1597
+ var value = this.model.get(this.options.propertyName) || 0;
1598
+ input.val(value.toLocaleString(this.options.locale, {
1599
+ useGrouping: false
1600
+ }));
1601
+ },
1602
+ displayValidationError: function displayValidationError(message) {
1603
+ this.$el.addClass('invalid');
1604
+ this.ui.input.attr('title', message);
1605
+ },
1606
+ resetValidationError: function resetValidationError(message) {
1607
+ this.$el.removeClass('invalid');
1608
+ this.ui.input.attr('title', '');
1609
+ }
1610
+ });
1611
+
1612
+ var NumberParser = /*#__PURE__*/function () {
1613
+ function NumberParser(locale) {
1614
+ _classCallCheck(this, NumberParser);
1615
+
1616
+ var format = new Intl.NumberFormat(locale);
1617
+ var parts = format.formatToParts(12345.6);
1618
+ var numerals = Array.from({
1619
+ length: 10
1620
+ }).map(function (_, i) {
1621
+ return format.format(i);
1622
+ });
1623
+ var index = new Map(numerals.map(function (d, i) {
1624
+ return [d, i];
1625
+ }));
1626
+ this._group = new RegExp("[".concat(parts.find(function (d) {
1627
+ return d.type === "group";
1628
+ }).value, "]"), "g");
1629
+ this._decimal = new RegExp("[".concat(parts.find(function (d) {
1630
+ return d.type === "decimal";
1631
+ }).value, "]"));
1632
+ this._numeral = new RegExp("[".concat(numerals.join(""), "]"), "g");
1633
+
1634
+ this._index = function (d) {
1635
+ return index.get(d);
1636
+ };
1637
+ }
1638
+
1639
+ _createClass(NumberParser, [{
1640
+ key: "parse",
1641
+ value: function parse(string) {
1642
+ string = string.trim().replace(this._group, "").replace(this._decimal, ".").replace(this._numeral, this._index);
1643
+ return string ? +string : NaN;
1644
+ }
1645
+ }]);
1646
+
1647
+ return NumberParser;
1648
+ }();
1649
+
1466
1650
  /**
1467
1651
  * Text based input view that can display a placeholder.
1468
1652
  *
@@ -1673,11 +1857,15 @@ var ColorInputView = Marionette.ItemView.extend({
1673
1857
  this.ui.input.minicolors({
1674
1858
  changeDelay: 200,
1675
1859
  change: _.bind(function (color) {
1860
+ this._saving = true;
1861
+
1676
1862
  if (color === this.defaultValue()) {
1677
1863
  this.model.unset(this.options.propertyName);
1678
1864
  } else {
1679
1865
  this.model.set(this.options.propertyName, color);
1680
1866
  }
1867
+
1868
+ this._saving = false;
1681
1869
  }, this)
1682
1870
  });
1683
1871
  this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
@@ -1706,7 +1894,10 @@ var ColorInputView = Marionette.ItemView.extend({
1706
1894
  }
1707
1895
  },
1708
1896
  load: function load() {
1709
- this.ui.input.minicolors('value', this.model.get(this.options.propertyName) || this.defaultValue());
1897
+ if (!this._saving) {
1898
+ this.ui.input.minicolors('value', this.model.get(this.options.propertyName) || this.defaultValue());
1899
+ }
1900
+
1710
1901
  this.$el.toggleClass('is_default', !this.model.has(this.options.propertyName));
1711
1902
  },
1712
1903
  refreshPicker: function refreshPicker() {
@@ -2113,6 +2304,7 @@ return __p
2113
2304
  var TextAreaInputView = Marionette.ItemView.extend({
2114
2305
  mixins: [inputView, inputWithPlaceholderText],
2115
2306
  template: template$8,
2307
+ className: 'text_area_input',
2116
2308
  ui: {
2117
2309
  input: 'textarea',
2118
2310
  toolbar: '.toolbar',
@@ -2289,21 +2481,6 @@ var TextAreaInputView = Marionette.ItemView.extend({
2289
2481
  }
2290
2482
  });
2291
2483
 
2292
- function _defineProperty(obj, key, value) {
2293
- if (key in obj) {
2294
- Object.defineProperty(obj, key, {
2295
- value: value,
2296
- enumerable: true,
2297
- configurable: true,
2298
- writable: true
2299
- });
2300
- } else {
2301
- obj[key] = value;
2302
- }
2303
-
2304
- return obj;
2305
- }
2306
-
2307
2484
  function template$9(data) {
2308
2485
  var __p = '';
2309
2486
  __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" />\n<div class="validation"></div>\n';
@@ -2570,6 +2747,25 @@ return __p
2570
2747
  *
2571
2748
  * @param {Object} [options]
2572
2749
  *
2750
+ * @param {number} [options.defaultValue]
2751
+ * Defaults value to display if property is not set.
2752
+ *
2753
+ * @param {number} [options.minValue=0]
2754
+ * Value when dragging slider to the very left.
2755
+ *
2756
+ * @param {number} [options.maxValue=100]
2757
+ * Value when dragging slider to the very right.
2758
+ *
2759
+ * @param {string} [options.unit="%"]
2760
+ * Unit to display after value.
2761
+ *
2762
+ * @param {function} [options.displayText]
2763
+ * Function that receives value and returns custom text to display as value.
2764
+ *
2765
+ * @param {boolean} [options.saveOnSlide]
2766
+ * Already update the model while dragging the handle - not only after
2767
+ * handle has been released.
2768
+ *
2573
2769
  * @class
2574
2770
  */
2575
2771
 
@@ -2582,15 +2778,27 @@ var SliderInputView = Marionette.ItemView.extend({
2582
2778
  value: '.value'
2583
2779
  },
2584
2780
  events: {
2585
- 'slidechange': 'save'
2781
+ 'slidechange': 'save',
2782
+ 'slide': 'handleSlide'
2586
2783
  },
2587
2784
  onRender: function onRender() {
2785
+ var _this = this;
2786
+
2588
2787
  this.ui.widget.slider({
2589
- animate: 'fast',
2590
- min: 'minValue' in this.options ? this.options.minValue : 0,
2591
- max: 'maxValue' in this.options ? this.options.maxValue : 100
2788
+ animate: 'fast'
2789
+ });
2790
+ this.setupAttributeBinding('minValue', function (value) {
2791
+ return _this.updateSliderOption('min', value || 0);
2792
+ });
2793
+ this.setupAttributeBinding('maxValue', function (value) {
2794
+ return _this.updateSliderOption('max', value || 100);
2592
2795
  });
2593
2796
  this.load();
2797
+ this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
2798
+ },
2799
+ updateSliderOption: function updateSliderOption(name, value) {
2800
+ this.ui.widget.slider('option', name, value);
2801
+ this.updateText(this.ui.widget.slider('value'));
2594
2802
  },
2595
2803
  updateDisabled: function updateDisabled(disabled) {
2596
2804
  this.$el.toggleClass('disabled', !!disabled);
@@ -2601,11 +2809,15 @@ var SliderInputView = Marionette.ItemView.extend({
2601
2809
  this.ui.widget.slider('enable');
2602
2810
  }
2603
2811
  },
2604
- save: function save() {
2605
- var value = this.ui.widget.slider('option', 'value');
2606
- var unit = 'unit' in this.options ? this.options.unit : '%';
2607
- this.ui.value.text(value + unit);
2608
- this.model.set(this.options.propertyName, value);
2812
+ handleSlide: function handleSlide(event, ui) {
2813
+ this.updateText(ui.value);
2814
+
2815
+ if (this.options.saveOnSlide) {
2816
+ this.save(event, ui);
2817
+ }
2818
+ },
2819
+ save: function save(event, ui) {
2820
+ this.model.set(this.options.propertyName, ui.value);
2609
2821
  },
2610
2822
  load: function load() {
2611
2823
  var value;
@@ -2616,7 +2828,18 @@ var SliderInputView = Marionette.ItemView.extend({
2616
2828
  value = 'defaultValue' in this.options ? this.options.defaultValue : 0;
2617
2829
  }
2618
2830
 
2619
- this.ui.widget.slider('option', 'value', value);
2831
+ this.ui.widget.slider('option', 'value', this.clampValue(value));
2832
+ this.updateText(value);
2833
+ },
2834
+ clampValue: function clampValue(value) {
2835
+ var min = this.ui.widget.slider('option', 'min');
2836
+ var max = this.ui.widget.slider('option', 'max');
2837
+ return Math.min(max, Math.max(min, value));
2838
+ },
2839
+ updateText: function updateText(value) {
2840
+ var unit = 'unit' in this.options ? this.options.unit : '%';
2841
+ var text = 'displayText' in this.options ? this.options.displayText(value) : value + unit;
2842
+ this.ui.value.text(text);
2620
2843
  }
2621
2844
  });
2622
2845
 
@@ -3010,7 +3233,10 @@ var subviewContainer = {
3010
3233
  return view;
3011
3234
  },
3012
3235
  appendSubview: function appendSubview(view) {
3013
- return this.$el.append(this.subview(view).el);
3236
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
3237
+ to = _ref.to;
3238
+
3239
+ return (to || this.$el).append(this.subview(view).el);
3014
3240
  },
3015
3241
  onClose: function onClose() {
3016
3242
  if (this.subviews) {
@@ -3067,4 +3293,4 @@ var tooltipContainer = {
3067
3293
  }
3068
3294
  };
3069
3295
 
3070
- export { CheckBoxGroupInputView, CheckBoxInputView, CollectionView, ColorInputView, ConfigurationEditorTabView, ConfigurationEditorView, DeleteRowTableCellView, EnumTableCellView, ExtendedSelectInputView, IconTableCellView, JsonInputView, LabelOnlyView, BaseObject as Object, PresenceTableCellView, ProxyUrlInputView, SelectInputView, SeparatorView, SliderInputView, SortableCollectionView, TableCellView, TableHeaderCellView, TableRowView, TableView, TabsView, TextAreaInputView, TextInputView, TextTableCellView, TooltipView, UrlDisplayView, UrlInputView, cssModulesUtils, i18nUtils, inputView, inputWithPlaceholderText, serverSideValidation, subviewContainer, tooltipContainer, viewWithValidationErrorMessages };
3296
+ export { CheckBoxGroupInputView, CheckBoxInputView, CollectionView, ColorInputView, ConfigurationEditorTabView, ConfigurationEditorView, DeleteRowTableCellView, EnumTableCellView, ExtendedSelectInputView, IconTableCellView, JsonInputView, LabelOnlyView, NumberInputView, BaseObject as Object, PresenceTableCellView, ProxyUrlInputView, SelectInputView, SeparatorView, SliderInputView, SortableCollectionView, TableCellView, TableHeaderCellView, TableRowView, TableView, TabsView, TextAreaInputView, TextInputView, TextTableCellView, TooltipView, UrlDisplayView, UrlInputView, attributeBinding, cssModulesUtils, i18nUtils, inputView, inputWithPlaceholderText, serverSideValidation, subviewContainer, tooltipContainer, viewWithValidationErrorMessages };
@@ -70,18 +70,49 @@ module Pageflow
70
70
  end
71
71
 
72
72
  trait :published do
73
+ first_published_at { 1.month.ago }
74
+
73
75
  transient do
74
76
  published_revision_attributes { {} }
75
77
  end
76
78
 
77
79
  after(:create) do |entry, evaluator|
78
- create(:revision, :published, evaluator.published_revision_attributes.merge(entry: entry))
80
+ create(:revision, :published,
81
+ evaluator.published_revision_attributes.merge(entry: entry))
79
82
  end
80
83
  end
81
84
 
82
85
  trait :published_with_password do
83
- after(:create) do |entry, _evaluator|
84
- create(:revision, :published, entry: entry, password_protected: true)
86
+ first_published_at { 1.month.ago }
87
+
88
+ transient do
89
+ published_revision_attributes { {} }
90
+ end
91
+
92
+ after(:create) do |entry, evaluator|
93
+ create(:revision,
94
+ :published,
95
+ evaluator.published_revision_attributes.merge(
96
+ entry: entry,
97
+ password_protected: true
98
+ ))
99
+ end
100
+ end
101
+
102
+ trait :published_with_noindex do
103
+ first_published_at { 1.month.ago }
104
+
105
+ transient do
106
+ published_revision_attributes { {} }
107
+ end
108
+
109
+ after(:create) do |entry, evaluator|
110
+ create(:revision,
111
+ :published,
112
+ evaluator.published_revision_attributes.merge(
113
+ entry: entry,
114
+ noindex: true
115
+ ))
85
116
  end
86
117
  end
87
118
 
@@ -1,6 +1,9 @@
1
1
  module Pageflow
2
2
  FactoryBot.define do
3
3
  factory :site, class: Pageflow::Site do
4
+ feeds_enabled { true }
5
+ sitemap_enabled { true }
6
+
4
7
  after(:build) do |site|
5
8
  site.account ||= build(:account, default_site: site)
6
9
  end
@@ -101,7 +101,6 @@ var utils = (function () {
101
101
  me.extend(me, {
102
102
  hasTransform: _transform !== false,
103
103
  hasPerspective: _prefixStyle('perspective') in _elementStyle,
104
- hasTouch: 'ontouchstart' in window,
105
104
  hasPointer: navigator.msPointerEnabled,
106
105
  hasTransition: _prefixStyle('transition') in _elementStyle
107
106
  });
@@ -862,12 +861,10 @@ IScroll.prototype = {
862
861
  eventType(target, 'MSPointerUp', this);
863
862
  }
864
863
 
865
- if ( utils.hasTouch ) {
866
- eventType(startEventTarget, 'touchstart', this);
867
- eventType(target, 'touchmove', this);
868
- eventType(target, 'touchcancel', this);
869
- eventType(target, 'touchend', this);
870
- }
864
+ eventType(startEventTarget, 'touchstart', this);
865
+ eventType(target, 'touchmove', this);
866
+ eventType(target, 'touchcancel', this);
867
+ eventType(target, 'touchend', this);
871
868
 
872
869
  eventType(this.scroller, 'transitionend', this);
873
870
  eventType(this.scroller, 'webkitTransitionEnd', this);