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
@@ -1,9 +1,8 @@
1
- import { browser } from 'pageflow/frontend';
2
- import React, { useReducer, useMemo, useCallback, createContext as createContext$1, useContext, useState, useEffect } from 'react';
3
- import I18n from 'i18n-js';
1
+ import React, { useReducer, useMemo, useCallback, createContext as createContext$1, useContext } from 'react';
4
2
  import { createContext, useContextSelector } from 'use-context-selector';
5
3
  import { createSelectorCreator, defaultMemoize, createSelector } from 'reselect';
6
4
  import slugify from 'slugify';
5
+ import I18n from 'i18n-js';
7
6
 
8
7
  function _arrayWithHoles(arr) {
9
8
  if (Array.isArray(arr)) return arr;
@@ -112,6 +111,56 @@ function _objectSpread2(target) {
112
111
  return target;
113
112
  }
114
113
 
114
+ function _objectWithoutPropertiesLoose(source, excluded) {
115
+ if (source == null) return {};
116
+ var target = {};
117
+ var sourceKeys = Object.keys(source);
118
+ var key, i;
119
+
120
+ for (i = 0; i < sourceKeys.length; i++) {
121
+ key = sourceKeys[i];
122
+ if (excluded.indexOf(key) >= 0) continue;
123
+ target[key] = source[key];
124
+ }
125
+
126
+ return target;
127
+ }
128
+
129
+ function _objectWithoutProperties(source, excluded) {
130
+ if (source == null) return {};
131
+ var target = _objectWithoutPropertiesLoose(source, excluded);
132
+ var key, i;
133
+
134
+ if (Object.getOwnPropertySymbols) {
135
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
136
+
137
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
138
+ key = sourceSymbolKeys[i];
139
+ if (excluded.indexOf(key) >= 0) continue;
140
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
141
+ target[key] = source[key];
142
+ }
143
+ }
144
+
145
+ return target;
146
+ }
147
+
148
+ function _arrayWithoutHoles(arr) {
149
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
150
+ }
151
+
152
+ function _iterableToArray(iter) {
153
+ if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
154
+ }
155
+
156
+ function _nonIterableSpread() {
157
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
158
+ }
159
+
160
+ function _toConsumableArray(arr) {
161
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
162
+ }
163
+
115
164
  var PREFIX = 'PAGEFLOW_SCROLLED_COLLECTION';
116
165
  var RESET = "".concat(PREFIX, "_RESET");
117
166
  var ADD = "".concat(PREFIX, "_ADD");
@@ -215,6 +264,22 @@ function getItem(state, collectionName, key) {
215
264
  return state[collectionName].items[key];
216
265
  }
217
266
  }
267
+ function createMultipleItemsSelector(collectionNames, filter) {
268
+ return createSelector.apply(void 0, _toConsumableArray(collectionNames.map(function (collectionName) {
269
+ return function (collections) {
270
+ return collections[collectionName];
271
+ };
272
+ })).concat([function () {
273
+ for (var _len = arguments.length, collections = new Array(_len), _key = 0; _key < _len; _key++) {
274
+ collections[_key] = arguments[_key];
275
+ }
276
+
277
+ return collectionNames.reduce(function (result, collectionName, index) {
278
+ result[collectionName] = toOrderedItems(collections[index]);
279
+ return result;
280
+ }, {});
281
+ }]));
282
+ }
218
283
  function createItemsSelector(collectionName, filter) {
219
284
  if (filter) {
220
285
  var itemsSelector = createItemsSelector(collectionName);
@@ -227,17 +292,20 @@ function createItemsSelector(collectionName, filter) {
227
292
 
228
293
  return createSelector(function (collections) {
229
294
  return collections[collectionName];
230
- }, function (collection) {
231
- if (collection) {
232
- var items = collection.items;
233
- return collection.order.map(function (key) {
234
- return items[key];
235
- });
236
- } else {
237
- return [];
238
- }
239
- });
295
+ }, toOrderedItems);
296
+ }
297
+
298
+ function toOrderedItems(collection) {
299
+ if (collection) {
300
+ var items = collection.items;
301
+ return collection.order.map(function (key) {
302
+ return items[key];
303
+ });
304
+ } else {
305
+ return [];
306
+ }
240
307
  }
308
+
241
309
  var createShallowEqualArraysSelector = createSelectorCreator(defaultMemoize, shallowEqualArrays);
242
310
 
243
311
  function shallowEqualArrays(a, b) {
@@ -304,6 +372,14 @@ function useEntryStateCollectionItems(collectionName, filter) {
304
372
  return itemsSelector(entryState.collections);
305
373
  });
306
374
  }
375
+ function useMultipleEntryStateCollectionItems(collectionNames) {
376
+ var multipleItemsSelector = useMemo(function () {
377
+ return createMultipleItemsSelector(collectionNames);
378
+ }, [collectionNames]);
379
+ return useEntryState(function (entryState) {
380
+ return multipleItemsSelector(entryState.collections);
381
+ });
382
+ }
307
383
 
308
384
  /**
309
385
  * Returns data generated by a Ruby lambda registered server
@@ -324,6 +400,15 @@ function useAdditionalSeedData(name) {
324
400
  return config.additionalSeedData[name];
325
401
  }
326
402
 
403
+ function useContentElementConsentVendor(_ref) {
404
+ var contentElementId = _ref.contentElementId;
405
+ var config = useEntryStateConfig();
406
+ var vendorName = config.contentElementConsentVendors[contentElementId];
407
+ return config.consentVendors.find(function (vendor) {
408
+ return vendor.name === vendorName;
409
+ });
410
+ }
411
+
327
412
  /**
328
413
  * Returns a nested data structure representing the metadata of the entry.
329
414
  *
@@ -600,21 +685,53 @@ function sectionData(section) {
600
685
  }
601
686
 
602
687
  function useSectionContentElements(_ref2) {
603
- var sectionId = _ref2.sectionId;
688
+ var sectionId = _ref2.sectionId,
689
+ layout = _ref2.layout;
604
690
  var filterBySectionId = useCallback(function (contentElement) {
605
691
  return contentElement.sectionId === sectionId;
606
692
  }, [sectionId]);
607
693
  var contentElements = useEntryStateCollectionItems('contentElements', filterBySectionId);
608
- return contentElements.map(function (item) {
694
+ return contentElements.map(function (contentElement) {
695
+ var position = getPosition(contentElement, layout);
609
696
  return {
610
- id: item.id,
611
- permaId: item.permaId,
612
- type: item.typeName,
613
- position: item.configuration.position,
614
- props: item.configuration
697
+ id: contentElement.id,
698
+ permaId: contentElement.permaId,
699
+ type: contentElement.typeName,
700
+ position: position,
701
+ width: getWidth(contentElement, position),
702
+ standAlone: contentElement.configuration.position === 'standAlone',
703
+ props: contentElement.configuration
615
704
  };
616
705
  });
617
706
  }
707
+ var supportedPositions = {
708
+ center: ['inline', 'left', 'right'],
709
+ centerRagged: ['inline', 'left', 'right'],
710
+ left: ['inline', 'sticky'],
711
+ right: ['inline', 'sticky']
712
+ };
713
+
714
+ function getPosition(contentElement, layout) {
715
+ var position = contentElement.configuration.position;
716
+ return supportedPositions[layout || 'left'].includes(position) ? position : 'inline';
717
+ }
718
+
719
+ var legacyPositionWidths = {
720
+ wide: 2,
721
+ full: 3
722
+ };
723
+ var clampedWidthPositions = ['sticky', 'left', 'right'];
724
+
725
+ function getWidth(contentElement, position) {
726
+ var width = typeof contentElement.configuration.width === 'number' ? contentElement.configuration.width : legacyPositionWidths[contentElement.configuration.position] || 0;
727
+
728
+ if (clampedWidthPositions.includes(position)) {
729
+ return Math.min(Math.max(width || 0, -2), 2);
730
+ } else {
731
+ return width;
732
+ }
733
+ }
734
+
618
735
  function useChapter(_ref3) {
619
736
  var permaId = _ref3.permaId;
620
737
  var chapters = useChapters();
@@ -686,7 +803,7 @@ function expandUrls(collectionName, file, urlTemplates) {
686
803
  throw new Error("No file url templates found for ".concat(collectionName));
687
804
  }
688
805
 
689
- var variants = file.variants || Object.keys(urlTemplates[collectionName]);
806
+ var variants = file.variants ? ['original'].concat(_toConsumableArray(file.variants)) : Object.keys(urlTemplates[collectionName]);
690
807
  var urls = variants.reduce(function (result, variant) {
691
808
  var url = getFileUrl(collectionName, file, variant, urlTemplates);
692
809
 
@@ -706,7 +823,7 @@ function getFileUrl(collectionName, file, quality, urlTemplates) {
706
823
  var template = templates[quality];
707
824
 
708
825
  if (template) {
709
- return template.replace(':id_partition', idPartition(file.id)).replace(':basename', file.basename).replace(':extension', file.extension).replace(':pageflow_hls_qualities', function () {
826
+ return template.replace(':id_partition', idPartition(file.id)).replace(':basename', file.basename).replace(':extension', file.extension).replace(':processed_extension', file.processedExtension).replace(':pageflow_hls_qualities', function () {
710
827
  return hlsQualities(file);
711
828
  });
712
829
  }
@@ -763,6 +880,21 @@ function useFile(_ref) {
763
880
  return extendFile(collectionName, file, useEntryStateConfig());
764
881
  }
765
882
 
883
+ function useFileWithInlineRights(_ref) {
884
+ var configuration = _ref.configuration,
885
+ collectionName = _ref.collectionName,
886
+ propertyName = _ref.propertyName;
887
+ var file = useFile({
888
+ collectionName: collectionName,
889
+ permaId: configuration[propertyName]
890
+ });
891
+ var config = useEntryStateConfig();
892
+ return file && _objectSpread2(_objectSpread2({}, file), {}, {
893
+ license: file.configuration.license && config.fileLicenses[file.configuration.license],
894
+ inlineRights: file.configuration.rights_display === 'inline' && !configuration[propertyName === 'id' ? 'inlineRightsHidden' : "".concat(propertyName.replace('Id', ''), "InlineRightsHidden")]
895
+ });
896
+ }
897
+
766
898
  function useNestedFiles(_ref) {
767
899
  var collectionName = _ref.collectionName,
768
900
  parent = _ref.parent;
@@ -781,29 +913,54 @@ function getFileUrlTemplateHost(seed, collectionName, variant) {
781
913
  }
782
914
 
783
915
  /**
784
- * Returns a string (comma-separated list) of copyrights of
785
- * all images used in the entry.
786
- * If none of the images has a rights attribute configured,
787
- * it falls back to the default file rights of the entry's account,
788
- * otherwise returns an empty string
916
+ * Returns a collection of rights and source urls of all files
917
+ * used in the entry. If none of the files has a rights attribute
918
+ * configured, it falls back to the default file rights of the
919
+ * entry's site, otherwise returns an empty array.
789
920
  *
790
921
  * @example
791
922
  *
792
923
  * const fileRights = useFileRights();
793
- * fileRights // => "author of image 1, author of image 2"
924
+ * fileRights // => [{text: 'author of image 1', urls: ['https://example.com/source-url']}]
794
925
  */
795
926
 
796
927
  function useFileRights() {
797
928
  var _config$defaultFileRi;
798
929
 
799
930
  var config = useEntryStateConfig();
800
- var imageFiles = useEntryStateCollectionItems('imageFiles');
931
+ var fileCollectionNames = Object.keys(config.fileModelTypes);
932
+ var files = useMultipleEntryStateCollectionItems(fileCollectionNames);
801
933
  var defaultFileRights = (_config$defaultFileRi = config.defaultFileRights) === null || _config$defaultFileRi === void 0 ? void 0 : _config$defaultFileRi.trim();
802
- return Array.from(new Set(imageFiles.map(function (imageFile) {
803
- var _imageFile$rights;
934
+ var items = {};
935
+ Object.keys(files).forEach(function (key) {
936
+ return files[key].filter(function (file) {
937
+ return file.configuration.rights_display !== 'inline';
938
+ }).forEach(function (file) {
939
+ var _file$rights;
940
+
941
+ var text = ((_file$rights = file.rights) === null || _file$rights === void 0 ? void 0 : _file$rights.trim()) || defaultFileRights;
942
+
943
+ if (text) {
944
+ var _file$configuration$s;
804
945
 
805
- return ((_imageFile$rights = imageFile.rights) === null || _imageFile$rights === void 0 ? void 0 : _imageFile$rights.trim()) || defaultFileRights;
806
- }))).filter(Boolean).join(', ');
946
+ items[text] = items[text] || {
947
+ text: text,
948
+ urls: new Set()
949
+ };
950
+
951
+ if ((_file$configuration$s = file.configuration.source_url) === null || _file$configuration$s === void 0 ? void 0 : _file$configuration$s.trim()) {
952
+ items[text].urls.add(file.configuration.source_url);
953
+ }
954
+ }
955
+ });
956
+ });
957
+ return Object.values(items).map(function (item) {
958
+ return _objectSpread2(_objectSpread2({}, item), {}, {
959
+ urls: Array.from(item.urls).sort()
960
+ });
961
+ }).sort(function (a, b) {
962
+ return a.text.localeCompare(b.text);
963
+ });
807
964
  }
808
965
  /**
809
966
  * Returns a nested data structure representing the legal info of the entry.
@@ -854,22 +1011,6 @@ function useCredits() {
854
1011
  return credits;
855
1012
  }
856
1013
 
857
- function _arrayWithoutHoles(arr) {
858
- if (Array.isArray(arr)) return _arrayLikeToArray(arr);
859
- }
860
-
861
- function _iterableToArray(iter) {
862
- if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
863
- }
864
-
865
- function _nonIterableSpread() {
866
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
867
- }
868
-
869
- function _toConsumableArray(arr) {
870
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
871
- }
872
-
873
1014
  var qualities = ['medium', 'fullhd', '4k'];
874
1015
  function useAvailableQualities(file) {
875
1016
  if (!file) {
@@ -985,65 +1126,4 @@ function useI18n() {
985
1126
  };
986
1127
  }
987
1128
 
988
- function _objectWithoutPropertiesLoose(source, excluded) {
989
- if (source == null) return {};
990
- var target = {};
991
- var sourceKeys = Object.keys(source);
992
- var key, i;
993
-
994
- for (i = 0; i < sourceKeys.length; i++) {
995
- key = sourceKeys[i];
996
- if (excluded.indexOf(key) >= 0) continue;
997
- target[key] = source[key];
998
- }
999
-
1000
- return target;
1001
- }
1002
-
1003
- function _objectWithoutProperties(source, excluded) {
1004
- if (source == null) return {};
1005
- var target = _objectWithoutPropertiesLoose(source, excluded);
1006
- var key, i;
1007
-
1008
- if (Object.getOwnPropertySymbols) {
1009
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
1010
-
1011
- for (i = 0; i < sourceSymbolKeys.length; i++) {
1012
- key = sourceSymbolKeys[i];
1013
- if (excluded.indexOf(key) >= 0) continue;
1014
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
1015
- target[key] = source[key];
1016
- }
1017
- }
1018
-
1019
- return target;
1020
- }
1021
-
1022
- var BrowserFeaturesAvailableContext = createContext$1(); // Browser feature detection is not available during server side
1023
- // rendering. To prevent mismatches during hydration, we keep features
1024
- // disabled in the initial render. Since hydration only starts after
1025
- // feature detection has finished, we can immediately re-render once
1026
- // the provider has mounted.
1027
-
1028
- function BrowserFeaturesProvider(_ref) {
1029
- var children = _ref.children;
1030
-
1031
- var _useState = useState(false),
1032
- _useState2 = _slicedToArray(_useState, 2),
1033
- isAvailable = _useState2[0],
1034
- setIsAvailable = _useState2[1];
1035
-
1036
- useEffect(function () {
1037
- return setIsAvailable(true);
1038
- }, []);
1039
- return /*#__PURE__*/React.createElement(BrowserFeaturesAvailableContext.Provider, {
1040
- value: isAvailable
1041
- }, children);
1042
- }
1043
- function useBrowserFeature(name) {
1044
- return useContext(BrowserFeaturesAvailableContext) && browser.has(name);
1045
- }
1046
-
1047
- var PhonePlatformContext = React.createContext(false);
1048
-
1049
- export { useShareProviders as A, BrowserFeaturesProvider as B, useShareUrl as C, updateContentElementConfiguration as D, EntryStateProvider as E, _unsupportedIterableToArray as F, LocaleProvider as L, PhonePlatformContext as P, _objectWithoutProperties as _, _objectSpread2 as a, _defineProperty as b, _slicedToArray as c, useLocale as d, useLegalInfo as e, useTheme as f, useEntryMetadata as g, useNestedFiles as h, useFile as i, _toConsumableArray as j, useSectionContentElements as k, useAdditionalSeedData as l, useSectionsWithChapter as m, useBrowserFeature as n, useEntryStateDispatch as o, useSection as p, useChapter as q, useEntryStructure as r, useWidget as s, getFileUrlTemplateHost as t, useI18n as u, useAvailableQualities as v, setupI18n as w, useChapters as x, useCredits as y, useFileRights as z };
1129
+ export { useShareProviders as A, useShareUrl as B, useLocale as C, updateContentElementConfiguration as D, EntryStateProvider as E, _unsupportedIterableToArray as F, LocaleProvider as L, _slicedToArray as _, _objectSpread2 as a, _defineProperty as b, useEntryMetadata as c, useNestedFiles as d, _objectWithoutProperties as e, useWidget as f, useTheme as g, useFileWithInlineRights as h, useFile as i, useSectionContentElements as j, useAdditionalSeedData as k, useSectionsWithChapter as l, useContentElementConsentVendor as m, _toConsumableArray as n, useChapter as o, useEntryStateDispatch as p, useSection as q, useEntryStructure as r, getFileUrlTemplateHost as s, useAvailableQualities as t, useI18n as u, setupI18n as v, useChapters as w, useCredits as x, useFileRights as y, useLegalInfo as z };
@@ -0,0 +1,118 @@
1
+ import React, { useMemo, useEffect, useState, useCallback } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import { _ as _slicedToArray, b as _defineProperty } from './i18n-71c39823.js';
4
+ import classNames from 'classnames';
5
+ import { u as useDelayedBoolean } from './useContentElementEditorState-245f1986.js';
6
+ import { T as ToggleFullscreenCornerButton } from './ToggleFullscreenCornerButton-8242f213.js';
7
+
8
+ var styles = {"wrapper":"Fullscreen-module_wrapper__2MP7f"};
9
+
10
+ function Fullscreen(_ref) {
11
+ var children = _ref.children;
12
+ var root = useMemo(function () {
13
+ return document.getElementById('fullscreenRoot');
14
+ }, []);
15
+ useEffect(function () {
16
+ var resetScrollbarPadding = adjustScrollbarPadding(function () {
17
+ document.getElementById('root').setAttribute('inert', true);
18
+ document.body.style.overflow = 'hidden';
19
+ });
20
+ return function () {
21
+ resetScrollbarPadding();
22
+ document.getElementById('root').removeAttribute('inert', true);
23
+ document.body.style.overflow = 'initial';
24
+ };
25
+ }, []);
26
+ return ReactDOM.createPortal( /*#__PURE__*/React.createElement("div", {
27
+ className: styles.wrapper
28
+ }, children), root);
29
+ } // Adapted from
30
+ // https://github.com/tailwindlabs/headlessui/blob/9dff5456fa196cdc304e2ed17ef47962a9364ce7/packages/%40headlessui-react/src/hooks/document-overflow/adjust-scrollbar-padding.ts
31
+
32
+ function adjustScrollbarPadding(hideScrollbar) {
33
+ var documentElement = document.documentElement;
34
+ var ownerWindow = document.defaultView || window;
35
+ var scrollbarWidthBefore = ownerWindow.innerWidth - documentElement.clientWidth;
36
+ hideScrollbar();
37
+ var scrollbarWidthAfter = documentElement.clientWidth - documentElement.offsetWidth;
38
+ var scrollbarWidth = scrollbarWidthBefore - scrollbarWidthAfter;
39
+ document.documentElement.style.paddingRight = "".concat(scrollbarWidth, "px");
40
+ return function () {
41
+ return document.documentElement.style.paddingRight = '0';
42
+ };
43
+ }
44
+
45
+ var styles$1 = {"wrapper":"index-module_wrapper__ilo7n","visible":"index-module_visible__6QUDn"};
46
+
47
+ function FullscreenViewer(_ref) {
48
+ var contentElementId = _ref.contentElementId,
49
+ renderChildren = _ref.renderChildren,
50
+ renderFullscreenChildren = _ref.renderFullscreenChildren;
51
+
52
+ var _useState = useState(false),
53
+ _useState2 = _slicedToArray(_useState, 2),
54
+ isFullscreen = _useState2[0],
55
+ setIsFullscreen = _useState2[1];
56
+
57
+ var isRendered = useDelayedBoolean(isFullscreen, {
58
+ fromTrueToFalse: 200
59
+ });
60
+ var isVisible = useDelayedBoolean(isFullscreen, {
61
+ fromFalseToTrue: 1
62
+ });
63
+ useEffect(function () {
64
+ function handlePopState() {
65
+ var _window$history$state;
66
+
67
+ setIsFullscreen(((_window$history$state = window.history.state) === null || _window$history$state === void 0 ? void 0 : _window$history$state.fullscreenContentElementId) === contentElementId);
68
+ }
69
+
70
+ window.addEventListener('popstate', handlePopState);
71
+ return function () {
72
+ return window.removeEventListener('popstate', handlePopState);
73
+ };
74
+ });
75
+ var enterFullscreen = useCallback(function () {
76
+ setIsFullscreen(true);
77
+
78
+ if (window.parent === window) {
79
+ window.history.pushState({
80
+ fullscreenContentElementId: contentElementId
81
+ }, '');
82
+ }
83
+ }, [contentElementId]);
84
+ var exitFullscreen = useCallback(function () {
85
+ var _window$history$state2;
86
+
87
+ setIsFullscreen(false);
88
+
89
+ if (((_window$history$state2 = window.history.state) === null || _window$history$state2 === void 0 ? void 0 : _window$history$state2.fullscreenContentElementId) === contentElementId && window.parent === window) {
90
+ window.history.back();
91
+ }
92
+ }, [contentElementId]);
93
+ useEffect(function () {
94
+ function handleKeyDown(event) {
95
+ if (event.key === 'Escape') {
96
+ exitFullscreen();
97
+ }
98
+ }
99
+
100
+ window.addEventListener('keydown', handleKeyDown);
101
+ return function () {
102
+ return window.removeEventListener('keydown', handleKeyDown);
103
+ };
104
+ }, [exitFullscreen]);
105
+ return /*#__PURE__*/React.createElement(React.Fragment, null, renderChildren({
106
+ enterFullscreen: enterFullscreen,
107
+ isFullscreen: isFullscreen
108
+ }), isRendered && /*#__PURE__*/React.createElement(Fullscreen, null, /*#__PURE__*/React.createElement("div", {
109
+ className: classNames(styles$1.wrapper, _defineProperty({}, styles$1.visible, isVisible))
110
+ }, renderFullscreenChildren({
111
+ exitFullscreen: exitFullscreen
112
+ }), /*#__PURE__*/React.createElement(ToggleFullscreenCornerButton, {
113
+ isFullscreen: true,
114
+ onExit: exitFullscreen
115
+ }))));
116
+ }
117
+
118
+ export { FullscreenViewer as F };