pageflow 17.1.0 → 17.2.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.
Files changed (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +319 -345
  3. data/README.md +3 -4
  4. data/admins/pageflow/accounts.rb +6 -6
  5. data/admins/pageflow/entry.rb +10 -8
  6. data/admins/pageflow/membership.rb +11 -11
  7. data/admins/pageflow/translations.rb +5 -5
  8. data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
  9. data/app/assets/javascripts/pageflow/dist/ui.js +1350 -630
  10. data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
  11. data/app/assets/javascripts/pageflow/ui.js +0 -1
  12. data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
  13. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -1
  14. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  15. data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
  16. data/app/assets/stylesheets/pageflow/animations.scss +1 -0
  17. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +21 -5
  18. data/app/assets/stylesheets/pageflow/editor/base.scss +9 -1
  19. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +13 -1
  20. data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
  21. data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
  22. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +0 -1
  23. data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
  24. data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
  25. data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
  26. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
  27. data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
  28. data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
  29. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
  30. data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
  31. data/app/assets/stylesheets/pageflow/editor/files.scss +230 -50
  32. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +142 -14
  33. data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
  34. data/app/assets/stylesheets/pageflow/editor/info_box.scss +12 -0
  35. data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
  36. data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
  37. data/app/assets/stylesheets/pageflow/editor/list.scss +88 -38
  38. data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
  39. data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
  40. data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
  41. data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
  42. data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
  43. data/app/assets/stylesheets/pageflow/ui/forms.scss +34 -4
  44. data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
  45. data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -16
  46. data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
  47. data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
  48. data/app/assets/stylesheets/pageflow/ui/properties.scss +29 -0
  49. data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
  50. data/app/assets/stylesheets/pageflow/ui.scss +4 -2
  51. data/app/controllers/pageflow/editor/entries_controller.rb +1 -0
  52. data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
  53. data/app/controllers/pageflow/editor/file_import_controller.rb +1 -0
  54. data/app/controllers/pageflow/editor/files_controller.rb +15 -6
  55. data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
  56. data/app/controllers/pageflow/entries_controller.rb +17 -13
  57. data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
  58. data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
  59. data/app/controllers/pageflow/review/comments_controller.rb +53 -0
  60. data/app/controllers/pageflow/revisions_controller.rb +4 -1
  61. data/app/helpers/pageflow/admin/entries_helper.rb +40 -0
  62. data/app/helpers/pageflow/admin/widgets_helper.rb +2 -2
  63. data/app/helpers/pageflow/common_entry_seed_helper.rb +5 -3
  64. data/app/helpers/pageflow/editor/config_helper.rb +3 -1
  65. data/app/helpers/pageflow/entries_helper.rb +24 -42
  66. data/app/helpers/pageflow/entry_json_seed_helper.rb +4 -4
  67. data/app/helpers/pageflow/public_i18n_helper.rb +9 -8
  68. data/app/helpers/pageflow/structured_data_helper.rb +4 -1
  69. data/app/helpers/pageflow/themes_helper.rb +1 -3
  70. data/app/helpers/pageflow/widgets_helper.rb +2 -1
  71. data/app/inputs/pageflow_permalink_input.rb +6 -2
  72. data/app/models/concerns/pageflow/auto_generated_perma_id.rb +11 -4
  73. data/app/models/concerns/pageflow/reusable_file.rb +1 -1
  74. data/app/models/concerns/pageflow/serialization_blacklist.rb +2 -4
  75. data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
  76. data/app/models/concerns/pageflow/uploadable_file.rb +1 -1
  77. data/app/models/pageflow/comment.rb +30 -0
  78. data/app/models/pageflow/comment_thread.rb +65 -0
  79. data/app/models/pageflow/comment_thread_read.rb +22 -0
  80. data/app/models/pageflow/customized_theme.rb +3 -2
  81. data/app/models/pageflow/draft_entry.rb +20 -8
  82. data/app/models/pageflow/entry.rb +2 -0
  83. data/app/models/pageflow/entry_at_revision.rb +9 -1
  84. data/app/models/pageflow/entry_comment_summary.rb +114 -0
  85. data/app/models/pageflow/file_folder.rb +74 -0
  86. data/app/models/pageflow/file_reuse.rb +3 -2
  87. data/app/models/pageflow/file_usage.rb +8 -0
  88. data/app/models/pageflow/image_file.rb +24 -20
  89. data/app/models/pageflow/image_file_url_templates.rb +3 -3
  90. data/app/models/pageflow/legal_info.rb +38 -0
  91. data/app/models/pageflow/nested_revision_component_copy.rb +1 -1
  92. data/app/models/pageflow/permalink.rb +1 -0
  93. data/app/models/pageflow/revision.rb +6 -2
  94. data/app/models/pageflow/site.rb +10 -0
  95. data/app/models/pageflow/used_file.rb +8 -2
  96. data/app/models/pageflow/widget.rb +2 -2
  97. data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
  98. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +4 -2
  99. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
  100. data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
  101. data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
  102. data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
  103. data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
  104. data/app/views/pageflow/editor/files/_file.json.jbuilder +2 -1
  105. data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
  106. data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +3 -0
  107. data/app/views/pageflow/files/_file.json.jbuilder +2 -0
  108. data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
  109. data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
  110. data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
  111. data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
  112. data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
  113. data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
  114. data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
  115. data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
  116. data/config/locales/de.yml +152 -14
  117. data/config/locales/en.yml +150 -14
  118. data/config/routes.rb +14 -0
  119. data/db/migrate/20140418225525_setup_schema.rb +2 -2
  120. data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
  121. data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
  122. data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
  123. data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
  124. data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
  125. data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
  126. data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
  127. data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
  128. data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
  129. data/db/migrate/20260728000000_create_file_folders.rb +17 -0
  130. data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
  131. data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
  132. data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
  133. data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
  134. data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
  135. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +8665 -3890
  136. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +979 -3571
  137. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20199 -28120
  138. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18652 -26584
  139. data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
  140. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +33 -3
  141. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -3
  142. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +21 -1
  143. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
  144. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +7 -5
  145. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +5 -2
  146. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +13 -5
  147. data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
  148. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +26 -11
  149. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +2 -2
  150. data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
  151. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +174 -3
  152. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +49 -7
  153. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
  154. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
  155. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +1 -0
  156. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +13 -12
  157. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +30 -10
  158. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +9 -0
  159. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
  160. data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
  161. data/entry_types/scrolled/config/locales/de.yml +512 -65
  162. data/entry_types/scrolled/config/locales/en.yml +518 -52
  163. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
  164. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +51 -6
  165. data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
  166. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
  167. data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
  168. data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
  169. data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
  170. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +205 -22
  171. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
  172. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +56 -36
  173. data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
  174. data/entry_types/scrolled/lib/pageflow_scrolled.rb +13 -0
  175. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +19 -1
  176. data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
  177. data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
  178. data/entry_types/scrolled/package/config/webpack.js +72 -0
  179. data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -1
  180. data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1181 -915
  181. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
  182. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
  183. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
  184. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
  185. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
  186. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
  187. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +71 -21
  188. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
  189. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
  190. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
  191. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
  192. data/entry_types/scrolled/package/contentElements-editor.js +1915 -1097
  193. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  194. data/entry_types/scrolled/package/contentElements-frontend.js +3093 -1679
  195. data/entry_types/scrolled/package/editor.css +1 -0
  196. data/entry_types/scrolled/package/editor.js +8667 -4077
  197. data/entry_types/scrolled/package/entryState.js +1600 -0
  198. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
  199. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
  200. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9f76033e.js → PhonePlatformContext-035a99fa.js} +7 -12
  201. data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
  202. data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
  203. data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
  204. data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
  205. data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
  206. data/entry_types/scrolled/package/frontend/{ToggleFullscreenCornerButton-788e9cdb.js → ToggleFullscreenCornerButton-30fd1124.js} +6 -6
  207. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
  208. data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
  209. data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
  210. data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
  211. data/entry_types/scrolled/package/frontend/{Viewer-0345ce57.js → Viewer-cc8d4072.js} +84 -92
  212. data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
  213. data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
  214. data/entry_types/scrolled/package/frontend/commenting.css +1 -0
  215. data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
  216. data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
  217. data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
  218. data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
  219. data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
  220. data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
  221. data/entry_types/scrolled/package/frontend/{index-eb670c2f.js → index-2e5546f7.js} +36 -44
  222. data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
  223. data/entry_types/scrolled/package/frontend/index.css +1 -1
  224. data/entry_types/scrolled/package/frontend/index.js +1870 -875
  225. data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
  226. data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
  227. data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
  228. data/entry_types/scrolled/package/frontend/{usePhonePlatform-c2ba875d.js → usePhonePlatform-4ecb96d4.js} +1 -1
  229. data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
  230. data/entry_types/scrolled/package/frontend-server.js +20 -209
  231. data/entry_types/scrolled/package/package.json +5 -3
  232. data/entry_types/scrolled/package/review.css +1 -0
  233. data/entry_types/scrolled/package/review.js +3306 -0
  234. data/entry_types/scrolled/package/testHelpers.js +836 -359
  235. data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
  236. data/entry_types/scrolled/package/widgets/consentBar.js +269 -290
  237. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  238. data/entry_types/scrolled/package/widgets/defaultNavigation.js +911 -352
  239. data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -1
  240. data/entry_types/scrolled/package/widgets/excursionSheet.js +87 -124
  241. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
  242. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -29
  243. data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +32 -13
  244. data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -1
  245. data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +56 -100
  246. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
  247. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +33 -28
  248. data/entry_types/scrolled/package/widgets-server.js +1 -0
  249. data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
  250. data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
  251. data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
  252. data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
  253. data/lib/generators/pageflow/resque/resque_generator.rb +0 -2
  254. data/lib/pageflow/configuration.rb +49 -7
  255. data/lib/pageflow/deprecation.rb +19 -0
  256. data/lib/pageflow/engine.rb +1 -1
  257. data/lib/pageflow/entries_controller_env_helper.rb +32 -2
  258. data/lib/pageflow/entry_export_import/entry_serialization.rb +4 -4
  259. data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
  260. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +10 -0
  261. data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
  262. data/lib/pageflow/entry_structured_data_types.rb +43 -0
  263. data/lib/pageflow/entry_type_configuration.rb +1 -0
  264. data/lib/pageflow/file_type.rb +2 -2
  265. data/lib/pageflow/file_types.rb +1 -1
  266. data/lib/pageflow/oembed_providers.rb +42 -0
  267. data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
  268. data/lib/pageflow/rails_version.rb +13 -2
  269. data/lib/pageflow/themes.rb +41 -0
  270. data/lib/pageflow/user_mixin.rb +12 -0
  271. data/lib/pageflow/version.rb +1 -1
  272. data/lib/pageflow.rb +1 -0
  273. data/package/config/eslint-rules/documented-in-toc.js +125 -0
  274. data/package/config/jest/index.js +0 -1
  275. data/package/config/webpack.js +0 -1
  276. data/package/config/webpack5.js +0 -1
  277. data/package/editor.js +4378 -1897
  278. data/package/frontend.js +647 -886
  279. data/package/package.json +2 -1
  280. data/package/review.js +384 -0
  281. data/package/testHelpers.js +248 -188
  282. data/package/ui.js +1346 -630
  283. data/package/vendor/stubs/wysihtml5.js +2 -0
  284. data/spec/factories/comment_thread_reads.rb +10 -0
  285. data/spec/factories/comment_threads.rb +10 -0
  286. data/spec/factories/comments.rb +9 -0
  287. data/spec/factories/file_folders.rb +8 -0
  288. data/spec/factories/published_entries.rb +2 -0
  289. metadata +188 -67
  290. data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
  291. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
  292. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-51914be7.js +0 -5439
  293. data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +0 -1932
  294. data/entry_types/scrolled/package/frontend/Viewer-cdc549cc.js +0 -147
  295. data/entry_types/scrolled/package/frontend/Wavesurfer-1cdc3925.js +0 -313
  296. data/entry_types/scrolled/package/frontend/components-96660ffd.js +0 -3803
  297. data/entry_types/scrolled/package/frontend/inherits-539844a6.js +0 -99
  298. data/entry_types/scrolled/package/frontend/useContentElementEditorState-77fe6c79.js +0 -51
  299. data/entry_types/scrolled/package/widgets/excursionDialog.css +0 -1
  300. data/entry_types/scrolled/package/widgets/excursionDialog.js +0 -109
  301. data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
  302. data/package/vendor/jquery.minicolors.js +0 -1108
@@ -35,7 +35,7 @@ module Pageflow
35
35
 
36
36
  def with_thumbnail_support
37
37
  select do |file_type|
38
- file_type.model.instance_methods.include?(:thumbnail_url)
38
+ file_type.model.method_defined?(:thumbnail_url)
39
39
  end
40
40
  end
41
41
 
@@ -0,0 +1,42 @@
1
+ module Pageflow
2
+ # Registry for oEmbed providers that can be used to resolve URLs.
3
+ class OembedProviders
4
+ def initialize
5
+ @providers = {}
6
+ end
7
+
8
+ # Register an oEmbed provider.
9
+ #
10
+ # @param name [Symbol] The name of the provider
11
+ # @param endpoint [String] The oEmbed endpoint URL with {format} placeholder
12
+ # @param url_patterns [Array<String>] Array of URL patterns the provider can handle
13
+ #
14
+ # @example
15
+ # config.oembed_providers.register(
16
+ # :bluesky,
17
+ # endpoint: 'https://bsky.app/oembed.{format}',
18
+ # url_patterns: ['https://bsky.app/profile/*/post/*']
19
+ # )
20
+ def register(name, endpoint:, url_patterns:)
21
+ provider = OEmbed::Provider.new(endpoint)
22
+ url_patterns.each { |pattern| provider << pattern }
23
+ @providers[name.to_s] = provider
24
+ end
25
+
26
+ # @api private
27
+ def find_by_name!(name)
28
+ @providers.fetch(name.to_s) do
29
+ raise(OembedProviderNotFoundError, "Unknown oEmbed provider '#{name}'")
30
+ end
31
+ end
32
+
33
+ # @api private
34
+ def names
35
+ @providers.keys
36
+ end
37
+ end
38
+
39
+ # Error raised when an oEmbed provider is not found
40
+ class OembedProviderNotFoundError < StandardError
41
+ end
42
+ end
@@ -4,6 +4,10 @@ module Pageflow
4
4
  #
5
5
  # @since 12.4
6
6
  class PrimaryDomainEntryRedirect
7
+ def initialize(ignore_additional_cnames: false)
8
+ @ignore_additional_cnames = ignore_additional_cnames
9
+ end
10
+
7
11
  def call(entry, request)
8
12
  site = entry.site
9
13
 
@@ -16,6 +20,8 @@ module Pageflow
16
20
  private
17
21
 
18
22
  def known_domains(site)
23
+ return [site.cname] if @ignore_additional_cnames
24
+
19
25
  [
20
26
  site.cname,
21
27
  (site.additional_cnames || '').split(',').map(&:strip)
@@ -3,16 +3,27 @@ module Pageflow
3
3
  module RailsVersion
4
4
  extend self
5
5
 
6
+ SUPPORTED = ['>= 7.2', '< 8.2'].freeze
7
+ DEFAULT = '~> 7.2.0'.freeze
8
+
6
9
  def detect
7
- from_env || '~> 7.1.0'
10
+ from_env || DEFAULT
11
+ end
12
+
13
+ def requirement
14
+ experimental? ? [] : SUPPORTED
8
15
  end
9
16
 
10
17
  def experimental?
11
- detect != '~> 7.1.0'
18
+ !Gem::Requirement.new(SUPPORTED).satisfied_by?(requested_version)
12
19
  end
13
20
 
14
21
  private
15
22
 
23
+ def requested_version
24
+ Gem::Requirement.new(detect).requirements.first.last
25
+ end
26
+
16
27
  def from_env
17
28
  ENV['PAGEFLOW_RAILS_VERSION'] if ENV['PAGEFLOW_RAILS_VERSION'] != ''
18
29
  end
@@ -4,6 +4,47 @@ module Pageflow
4
4
 
5
5
  def initialize
6
6
  @themes = HashWithIndifferentAccess.new
7
+ @default_options = {}
8
+ @options_transforms = []
9
+ end
10
+
11
+ # Register default options that apply to all themes. Can be called
12
+ # multiple times to accumulate defaults from different sources
13
+ # (gem, plugins, host app). Later calls override earlier ones for
14
+ # the same keys. Theme options always take precedence over defaults.
15
+ #
16
+ # @param options [Hash]
17
+ # Default options to deep merge into accumulated defaults.
18
+ #
19
+ # @since 17.2
20
+ def register_default_options(options)
21
+ @default_options = @default_options.deep_merge(options)
22
+ end
23
+
24
+ # Register a transform that can conditionally modify theme options.
25
+ # Transforms run after defaults are merged with theme options, so
26
+ # they can inspect what the theme defines and add conditional defaults.
27
+ #
28
+ # @param callable [#call]
29
+ # Receives merged options hash, returns transformed options.
30
+ # Use for conditional defaults based on what theme defines.
31
+ #
32
+ # @since 17.2
33
+ def register_options_transform(callable)
34
+ @options_transforms << callable
35
+ end
36
+
37
+ # Apply all registered defaults to theme options.
38
+ #
39
+ # @api private
40
+ def apply_default_options(options, entry:)
41
+ # First merge hash defaults under theme options (theme wins)
42
+ result = @default_options.deep_merge(options)
43
+
44
+ # Then apply callable transforms (they can see theme options)
45
+ @options_transforms.reduce(result) do |opts, transform|
46
+ transform.call(opts, entry:)
47
+ end
7
48
  end
8
49
 
9
50
  # Register a theme and supply theme options.
@@ -23,10 +23,22 @@ module Pageflow
23
23
 
24
24
  has_many :revisions, class_name: 'Pageflow::Revision', foreign_key: :creator_id
25
25
 
26
+ has_many :comment_thread_reads,
27
+ dependent: :destroy,
28
+ class_name: 'Pageflow::CommentThreadRead'
29
+
26
30
  validates :first_name, :last_name, presence: true
27
31
  validates_inclusion_of :locale, in: Pageflow.config.available_locales.map(&:to_s)
28
32
 
29
33
  scope :admins, -> { where(admin: true) }
34
+
35
+ before_create :ensure_unread_comments_since_at
36
+ end
37
+
38
+ # Comments predating a user are not new to them. Without a baseline,
39
+ # joining would mean facing every comment ever written as unread.
40
+ def ensure_unread_comments_since_at
41
+ self.unread_comments_since_at ||= Time.current
30
42
  end
31
43
 
32
44
  def admin?
@@ -1,3 +1,3 @@
1
1
  module Pageflow
2
- VERSION = '17.1.0'.freeze
2
+ VERSION = '17.2.0'.freeze
3
3
  end
data/lib/pageflow.rb CHANGED
@@ -2,6 +2,7 @@ require 'pageflow/engine'
2
2
  require 'pageflow/global_config_api'
3
3
  require 'pageflow/news_item_api'
4
4
  require 'pageflow/version'
5
+ require 'pageflow/deprecation'
5
6
 
6
7
  module Pageflow # rubocop:todo Style/Documentation
7
8
  extend GlobalConfigApi
@@ -0,0 +1,125 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const yaml = require('js-yaml');
4
+
5
+ // JSDoc comments on these are either nested under another item or
6
+ // excluded from the generated docs, so they do not need toc entries.
7
+ const skippedTags = /@(private|internal|ignore|memberof)\b/;
8
+
9
+ module.exports = {
10
+ meta: {
11
+ type: 'suggestion',
12
+ docs: {
13
+ description:
14
+ 'Ensure JSDoc documented top level items are listed in the toc ' +
15
+ 'of documentation.yml. Otherwise they render at an arbitrary ' +
16
+ 'spot at the end of the generated docs.'
17
+ },
18
+ schema: []
19
+ },
20
+
21
+ create(context) {
22
+ const config = findTocConfig(path.dirname(context.getFilename()));
23
+
24
+ if (!config) {
25
+ return {};
26
+ }
27
+
28
+ const sourceCode = context.getSourceCode();
29
+
30
+ return {
31
+ Program(program) {
32
+ program.body.forEach(statement => {
33
+ const comment = jsdocCommentBefore(statement);
34
+
35
+ if (!comment || skippedTags.test(comment.value)) {
36
+ return;
37
+ }
38
+
39
+ const name = documentedName(comment, statement);
40
+
41
+ if (name && !config.names.has(name)) {
42
+ context.report({
43
+ loc: comment.loc,
44
+ message:
45
+ `'${name}' has a JSDoc comment, but is not listed in the ` +
46
+ `toc in ${config.relativePath}. Add it to the section ` +
47
+ 'where it should show up in the generated docs.'
48
+ });
49
+ }
50
+ });
51
+ }
52
+ };
53
+
54
+ function jsdocCommentBefore(statement) {
55
+ const comments = sourceCode.getCommentsBefore(statement);
56
+ const comment = comments[comments.length - 1];
57
+
58
+ return comment &&
59
+ comment.type === 'Block' &&
60
+ comment.value.startsWith('*') ? comment : null;
61
+ }
62
+ }
63
+ };
64
+
65
+ function documentedName(comment, statement) {
66
+ const tagMatch = comment.value.match(/@(?:name|alias)\s+([\w.#]+)/);
67
+
68
+ if (tagMatch) {
69
+ return tagMatch[1];
70
+ }
71
+
72
+ return declaredName(statement);
73
+ }
74
+
75
+ function declaredName(statement) {
76
+ switch (statement.type) {
77
+ case 'ExportNamedDeclaration':
78
+ case 'ExportDefaultDeclaration':
79
+ return statement.declaration && declaredName(statement.declaration);
80
+ case 'FunctionDeclaration':
81
+ case 'ClassDeclaration':
82
+ return statement.id && statement.id.name;
83
+ case 'VariableDeclaration':
84
+ return statement.declarations[0].id.type === 'Identifier' ?
85
+ statement.declarations[0].id.name : null;
86
+ default:
87
+ return null;
88
+ }
89
+ }
90
+
91
+ const configCache = new Map();
92
+
93
+ function findTocConfig(directory) {
94
+ if (configCache.has(directory)) {
95
+ return configCache.get(directory);
96
+ }
97
+
98
+ const configPath = path.join(directory, 'documentation.yml');
99
+ let config;
100
+
101
+ if (fs.existsSync(configPath)) {
102
+ config = loadTocConfig(configPath);
103
+ }
104
+ else {
105
+ const parent = path.dirname(directory);
106
+ config = parent === directory ? null : findTocConfig(parent);
107
+ }
108
+
109
+ configCache.set(directory, config);
110
+ return config;
111
+ }
112
+
113
+ function loadTocConfig(configPath) {
114
+ const toc = yaml.safeLoad(fs.readFileSync(configPath, 'utf8')).toc || [];
115
+ const names = new Set();
116
+
117
+ toc.forEach(section =>
118
+ (section.children || []).forEach(child => names.add(child))
119
+ );
120
+
121
+ return {
122
+ names,
123
+ relativePath: path.relative(process.cwd(), configPath)
124
+ };
125
+ }
@@ -13,7 +13,6 @@ module.exports = {
13
13
  moduleNameMapper: {
14
14
  '^jquery$': resolve('../../vendor/jquery'),
15
15
  '^jquery-ui$': resolve('../../vendor/jquery-ui'),
16
- '^jquery.minicolors$': resolve('../../vendor/jquery.minicolors'),
17
16
  '^backbone.marionette$': resolve('../../vendor/backbone.marionette'),
18
17
  '^backbone.babysitter$': resolve('../../vendor/backbone.babysitter'),
19
18
  '^backbone$': resolve('../../vendor/backbone'),
@@ -5,7 +5,6 @@ module.exports = {
5
5
  'cocktail': 'Cocktail',
6
6
  'jquery': 'jQuery',
7
7
  'jquery-ui': 'jQuery',
8
- 'jquery.minicolors': 'jQuery',
9
8
  'underscore': '_',
10
9
  'backbone.marionette': 'Backbone.Marionette',
11
10
  'iscroll': 'IScroll',
@@ -5,7 +5,6 @@ module.exports = {
5
5
  'cocktail': 'Cocktail',
6
6
  'jquery': 'jQuery',
7
7
  'jquery-ui': 'jQuery',
8
- 'jquery.minicolors': 'jQuery',
9
8
  'underscore': '_',
10
9
  'backbone.marionette': 'Backbone.Marionette',
11
10
  'iscroll': 'IScroll',