pageflow 17.0.5 → 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 (636) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +342 -41
  3. data/README.md +3 -5
  4. data/admins/pageflow/accounts.rb +22 -20
  5. data/admins/pageflow/entry.rb +76 -26
  6. data/admins/pageflow/entry_templates.rb +10 -9
  7. data/admins/pageflow/folder.rb +1 -1
  8. data/admins/pageflow/membership.rb +15 -15
  9. data/admins/pageflow/revisions.rb +5 -5
  10. data/admins/pageflow/site_root_entry.rb +64 -0
  11. data/admins/pageflow/sites.rb +12 -3
  12. data/admins/pageflow/translations.rb +75 -0
  13. data/admins/pageflow/user.rb +21 -35
  14. data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
  15. data/app/assets/javascripts/pageflow/admin/entries.js +30 -5
  16. data/app/assets/javascripts/pageflow/dist/ui.js +4228 -900
  17. data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
  18. data/app/assets/javascripts/pageflow/ui.js +0 -1
  19. data/app/assets/stylesheets/pageflow/admin/entries/index_table.scss +2 -1
  20. data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
  21. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -0
  22. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  23. data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
  24. data/app/assets/stylesheets/pageflow/animations.scss +1 -0
  25. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +27 -5
  26. data/app/assets/stylesheets/pageflow/editor/base.scss +11 -1
  27. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +20 -2
  28. data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
  29. data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
  30. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +5 -2
  31. data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
  32. data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
  33. data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
  34. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
  35. data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
  36. data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
  37. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
  38. data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
  39. data/app/assets/stylesheets/pageflow/editor/files.scss +242 -50
  40. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +161 -9
  41. data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
  42. data/app/assets/stylesheets/pageflow/editor/info_box.scss +23 -3
  43. data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
  44. data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
  45. data/app/assets/stylesheets/pageflow/editor/list.scss +89 -37
  46. data/app/assets/stylesheets/pageflow/editor/list_search_field.scss +52 -0
  47. data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
  48. data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
  49. data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
  50. data/app/assets/stylesheets/pageflow/editor/outline.scss +0 -13
  51. data/app/assets/stylesheets/pageflow/editor/sortable.scss +12 -0
  52. data/app/assets/stylesheets/pageflow/mixins/buttons.scss +4 -4
  53. data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
  54. data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
  55. data/app/assets/stylesheets/pageflow/ui/forms.scss +38 -4
  56. data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
  57. data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -8
  58. data/app/assets/stylesheets/pageflow/ui/input/file_name_input.scss +37 -0
  59. data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
  60. data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
  61. data/app/assets/stylesheets/pageflow/ui/properties.scss +34 -0
  62. data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
  63. data/app/assets/stylesheets/pageflow/ui.scss +4 -1
  64. data/app/controllers/concerns/pageflow/controller_delegation.rb +1 -1
  65. data/app/controllers/concerns/pageflow/edit_locking.rb +17 -10
  66. data/app/controllers/concerns/pageflow/entry_password_protection.rb +1 -0
  67. data/app/controllers/concerns/pageflow/public_https_mode.rb +2 -1
  68. data/app/controllers/concerns/pageflow/quota_verification.rb +5 -4
  69. data/app/controllers/pageflow/admin/initial_passwords_controller.rb +1 -0
  70. data/app/controllers/pageflow/application_controller.rb +19 -19
  71. data/app/controllers/pageflow/chapters_controller.rb +3 -2
  72. data/app/controllers/pageflow/edit_locks_controller.rb +3 -2
  73. data/app/controllers/pageflow/editor/encoding_confirmations_controller.rb +1 -0
  74. data/app/controllers/pageflow/editor/entries_controller.rb +3 -1
  75. data/app/controllers/pageflow/editor/entry_publications_controller.rb +1 -0
  76. data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
  77. data/app/controllers/pageflow/editor/file_import_controller.rb +4 -3
  78. data/app/controllers/pageflow/editor/files_controller.rb +20 -10
  79. data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
  80. data/app/controllers/pageflow/editor/widgets_controller.rb +1 -0
  81. data/app/controllers/pageflow/entries_controller.rb +85 -21
  82. data/app/controllers/pageflow/feeds_controller.rb +1 -1
  83. data/app/controllers/pageflow/files_controller.rb +1 -0
  84. data/app/controllers/pageflow/pages_controller.rb +4 -2
  85. data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
  86. data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
  87. data/app/controllers/pageflow/review/comments_controller.rb +53 -0
  88. data/app/controllers/pageflow/revisions_controller.rb +5 -1
  89. data/app/controllers/pageflow/sitemaps_controller.rb +1 -1
  90. data/app/controllers/pageflow/storylines_controller.rb +1 -0
  91. data/app/helpers/pageflow/admin/cutoff_modes_helper.rb +12 -0
  92. data/app/helpers/pageflow/admin/entries_helper.rb +41 -1
  93. data/app/helpers/pageflow/admin/entry_translations_helper.rb +18 -0
  94. data/app/helpers/pageflow/admin/features_helper.rb +1 -1
  95. data/app/helpers/pageflow/admin/form_helper.rb +3 -3
  96. data/app/helpers/pageflow/admin/locales_helper.rb +10 -2
  97. data/app/helpers/pageflow/admin/memberships_helper.rb +32 -32
  98. data/app/helpers/pageflow/admin/revisions_helper.rb +1 -1
  99. data/app/helpers/pageflow/admin/sites_helper.rb +22 -0
  100. data/app/helpers/pageflow/admin/users_helper.rb +7 -5
  101. data/app/helpers/pageflow/admin/widgets_helper.rb +5 -5
  102. data/app/helpers/pageflow/asset_urls_helper.rb +1 -1
  103. data/app/helpers/pageflow/audio_files_helper.rb +5 -2
  104. data/app/helpers/pageflow/background_image_helper.rb +7 -6
  105. data/app/helpers/pageflow/common_entry_seed_helper.rb +7 -7
  106. data/app/helpers/pageflow/editor/config_helper.rb +3 -1
  107. data/app/helpers/pageflow/editor/files_helper.rb +1 -1
  108. data/app/helpers/pageflow/embed_code_helper.rb +3 -3
  109. data/app/helpers/pageflow/entries_helper.rb +52 -46
  110. data/app/helpers/pageflow/entry_json_seed_helper.rb +7 -6
  111. data/app/helpers/pageflow/feeds_helper.rb +2 -2
  112. data/app/helpers/pageflow/file_background_images_helper.rb +2 -2
  113. data/app/helpers/pageflow/file_thumbnails_helper.rb +4 -3
  114. data/app/helpers/pageflow/files_helper.rb +5 -4
  115. data/app/helpers/pageflow/folders_helper.rb +8 -5
  116. data/app/helpers/pageflow/help_entries_helper.rb +2 -2
  117. data/app/helpers/pageflow/hreflang_links_helper.rb +37 -0
  118. data/app/helpers/pageflow/info_box_helper.rb +7 -11
  119. data/app/helpers/pageflow/media_query_helper.rb +3 -3
  120. data/app/helpers/pageflow/navigation_bar_helper.rb +1 -1
  121. data/app/helpers/pageflow/overview_helper.rb +1 -1
  122. data/app/helpers/pageflow/page_types_helper.rb +5 -5
  123. data/app/helpers/pageflow/pages_helper.rb +29 -15
  124. data/app/helpers/pageflow/public_i18n_helper.rb +10 -9
  125. data/app/helpers/pageflow/quota_helper.rb +4 -4
  126. data/app/helpers/pageflow/render_json_helper.rb +6 -3
  127. data/app/helpers/pageflow/revision_file_helper.rb +2 -1
  128. data/app/helpers/pageflow/sites_helper.rb +3 -3
  129. data/app/helpers/pageflow/social_share_helper.rb +24 -10
  130. data/app/helpers/pageflow/social_share_links_helper.rb +12 -9
  131. data/app/helpers/pageflow/structured_data_helper.rb +5 -2
  132. data/app/helpers/pageflow/stub_page_configuration.rb +7 -3
  133. data/app/helpers/pageflow/text_direction_helper.rb +1 -1
  134. data/app/helpers/pageflow/themes_helper.rb +2 -4
  135. data/app/helpers/pageflow/video_files_helper.rb +29 -13
  136. data/app/helpers/pageflow/widgets_helper.rb +8 -6
  137. data/app/inputs/pageflow_permalink_input.rb +8 -3
  138. data/app/jobs/pageflow/application_job.rb +1 -0
  139. data/app/jobs/pageflow/entry_export_import/upload_and_publish_file_job.rb +1 -1
  140. data/app/jobs/pageflow/poll_meta_data_from_zencoder_job.rb +1 -0
  141. data/app/jobs/pageflow/poll_zencoder_job.rb +3 -2
  142. data/app/jobs/pageflow/process_image_or_text_track_job.rb +1 -0
  143. data/app/jobs/pageflow/prune_auto_snapshots_job.rb +1 -0
  144. data/app/jobs/pageflow/request_meta_data_from_zencoder_job.rb +1 -0
  145. data/app/jobs/pageflow/submit_file_to_zencoder_job.rb +1 -0
  146. data/app/mailers/pageflow/user_mailer.rb +1 -0
  147. data/app/models/concerns/pageflow/auto_generated_perma_id.rb +20 -1
  148. data/app/models/concerns/pageflow/entry_publication_states.rb +7 -3
  149. data/app/models/concerns/pageflow/feature_target.rb +8 -4
  150. data/app/models/concerns/pageflow/output_source.rb +3 -3
  151. data/app/models/concerns/pageflow/permalinkable.rb +2 -1
  152. data/app/models/concerns/pageflow/reusable_file.rb +24 -24
  153. data/app/models/concerns/pageflow/serialization_blacklist.rb +3 -5
  154. data/app/models/concerns/pageflow/suspendable.rb +5 -3
  155. data/app/models/concerns/pageflow/theme_referencer.rb +1 -1
  156. data/app/models/concerns/pageflow/translatable.rb +62 -0
  157. data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
  158. data/app/models/concerns/pageflow/uploadable_file.rb +6 -6
  159. data/app/models/pageflow/account.rb +6 -5
  160. data/app/models/pageflow/account_member_query.rb +1 -1
  161. data/app/models/pageflow/account_role_query.rb +1 -1
  162. data/app/models/pageflow/application_query.rb +1 -1
  163. data/app/models/pageflow/application_record.rb +1 -1
  164. data/app/models/pageflow/audio_file.rb +4 -4
  165. data/app/models/pageflow/audio_file_url_templates.rb +1 -1
  166. data/app/models/pageflow/authentication_token.rb +2 -2
  167. data/app/models/pageflow/chapter.rb +6 -1
  168. data/app/models/pageflow/chapter_scaffold.rb +2 -4
  169. data/app/models/pageflow/cname_site_request_scope.rb +1 -1
  170. data/app/models/pageflow/comment.rb +30 -0
  171. data/app/models/pageflow/comment_thread.rb +65 -0
  172. data/app/models/pageflow/comment_thread_read.rb +22 -0
  173. data/app/models/pageflow/customized_theme.rb +9 -8
  174. data/app/models/pageflow/draft_entry.rb +49 -9
  175. data/app/models/pageflow/edit_lock.rb +19 -21
  176. data/app/models/pageflow/encoding_confirmation.rb +2 -2
  177. data/app/models/pageflow/entries_feed.rb +2 -2
  178. data/app/models/pageflow/entry.rb +46 -30
  179. data/app/models/pageflow/entry_at_revision.rb +14 -2
  180. data/app/models/pageflow/entry_comment_summary.rb +114 -0
  181. data/app/models/pageflow/entry_duplicate.rb +8 -5
  182. data/app/models/pageflow/entry_publication.rb +2 -2
  183. data/app/models/pageflow/entry_role_query.rb +4 -4
  184. data/app/models/pageflow/entry_template.rb +4 -4
  185. data/app/models/pageflow/entry_title_or_account_name_query.rb +2 -2
  186. data/app/models/pageflow/entry_translation_group.rb +42 -0
  187. data/app/models/pageflow/file_folder.rb +74 -0
  188. data/app/models/pageflow/file_reuse.rb +5 -4
  189. data/app/models/pageflow/file_usage.rb +18 -3
  190. data/app/models/pageflow/folder.rb +2 -2
  191. data/app/models/pageflow/home_button.rb +7 -7
  192. data/app/models/pageflow/image_file.rb +44 -25
  193. data/app/models/pageflow/image_file_url_templates.rb +4 -4
  194. data/app/models/pageflow/invitation_form.rb +2 -1
  195. data/app/models/pageflow/legal_info.rb +38 -0
  196. data/app/models/pageflow/managed_user_query.rb +1 -1
  197. data/app/models/pageflow/membership.rb +5 -5
  198. data/app/models/pageflow/nested_revision_component_copy.rb +263 -0
  199. data/app/models/pageflow/null_user.rb +1 -1
  200. data/app/models/pageflow/overview_button.rb +1 -1
  201. data/app/models/pageflow/page.rb +7 -3
  202. data/app/models/pageflow/permalink.rb +24 -2
  203. data/app/models/pageflow/permalink_directory.rb +7 -0
  204. data/app/models/pageflow/permalink_redirect.rb +7 -0
  205. data/app/models/pageflow/positioned_file.rb +5 -5
  206. data/app/models/pageflow/potential_entry_translations.rb +55 -0
  207. data/app/models/pageflow/potential_memberships.rb +5 -4
  208. data/app/models/pageflow/published_entry.rb +62 -11
  209. data/app/models/pageflow/revision.rb +29 -16
  210. data/app/models/pageflow/roles.rb +14 -18
  211. data/app/models/pageflow/site.rb +46 -3
  212. data/app/models/pageflow/site_root_entry_form.rb +27 -0
  213. data/app/models/pageflow/sitemaps.rb +10 -1
  214. data/app/models/pageflow/storyline.rb +5 -2
  215. data/app/models/pageflow/storyline_scaffold.rb +1 -1
  216. data/app/models/pageflow/text_track_file.rb +1 -1
  217. data/app/models/pageflow/text_track_file_url_templates.rb +1 -1
  218. data/app/models/pageflow/theme_customization_file.rb +3 -2
  219. data/app/models/pageflow/thumbnail_file_resolver.rb +1 -1
  220. data/app/models/pageflow/url_template.rb +1 -1
  221. data/app/models/pageflow/used_file.rb +13 -3
  222. data/app/models/pageflow/user_name_query.rb +2 -2
  223. data/app/models/pageflow/video_file.rb +22 -15
  224. data/app/models/pageflow/video_file_url_templates.rb +6 -4
  225. data/app/models/pageflow/widget.rb +5 -4
  226. data/app/models/pageflow/with_file_usage_extension.rb +1 -1
  227. data/app/models/pageflow/zencoder_attachment.rb +8 -8
  228. data/app/policies/pageflow/account_policy.rb +3 -1
  229. data/app/policies/pageflow/admin/admin_only_tab_policy.rb +1 -0
  230. data/app/policies/pageflow/admin/entry_tab_policy.rb +1 -0
  231. data/app/policies/pageflow/application_policy.rb +2 -0
  232. data/app/policies/pageflow/entry_policy.rb +7 -1
  233. data/app/policies/pageflow/entry_template_policy.rb +2 -1
  234. data/app/policies/pageflow/file_policy.rb +4 -7
  235. data/app/policies/pageflow/folder_policy.rb +18 -8
  236. data/app/policies/pageflow/membership_policy.rb +6 -4
  237. data/app/policies/pageflow/site_policy.rb +10 -3
  238. data/app/policies/pageflow/user_policy.rb +6 -4
  239. data/app/state_machines/pageflow/image_and_text_track_processing_state_machine.rb +3 -2
  240. data/app/state_machines/pageflow/media_encoding_state_machine.rb +5 -4
  241. data/app/views/admin/accounts/_entry_template_details.html.arb +2 -2
  242. data/app/views/admin/entries/_attributes_table.html.arb +6 -5
  243. data/app/views/admin/entries/_form.html.erb +2 -1
  244. data/app/views/admin/entries/_permalink_inputs.html.erb +9 -2
  245. data/app/views/admin/entry_templates/_form.html.erb +1 -3
  246. data/app/views/admin/site_root_entry/choose.html.erb +19 -0
  247. data/app/views/admin/sites/_fields.html.erb +14 -1
  248. data/app/views/admin/translations/_form.html.erb +31 -0
  249. data/app/views/admin/users/_attributes_table.html.arb +13 -0
  250. data/app/views/components/pageflow/admin/add_membership_button.rb +13 -12
  251. data/app/views/components/pageflow/admin/custom_scopes_renderer.rb +1 -0
  252. data/app/views/components/pageflow/admin/embed_code_field.rb +1 -0
  253. data/app/views/components/pageflow/admin/embedded_index_table.rb +9 -10
  254. data/app/views/components/pageflow/admin/entries_tab.rb +1 -0
  255. data/app/views/components/pageflow/admin/entry_publication_state_indicator.rb +6 -5
  256. data/app/views/components/pageflow/admin/entry_templates_tab.rb +2 -1
  257. data/app/views/components/pageflow/admin/entry_translations_tab.rb +102 -0
  258. data/app/views/components/pageflow/admin/entry_user_badge_list.rb +1 -0
  259. data/app/views/components/pageflow/admin/extensible_attributes_table.rb +9 -8
  260. data/app/views/components/pageflow/admin/features_tab.rb +1 -0
  261. data/app/views/components/pageflow/admin/grouped_folder_list.rb +1 -0
  262. data/app/views/components/pageflow/admin/icon_link_to.rb +1 -0
  263. data/app/views/components/pageflow/admin/members_tab.rb +4 -3
  264. data/app/views/components/pageflow/admin/membership_role_with_tooltip.rb +3 -2
  265. data/app/views/components/pageflow/admin/revisions_tab.rb +14 -10
  266. data/app/views/components/pageflow/admin/sites_tab.rb +1 -0
  267. data/app/views/components/pageflow/admin/tabs_view.rb +1 -0
  268. data/app/views/components/pageflow/admin/timestamp.rb +6 -5
  269. data/app/views/components/pageflow/admin/user_account_badge_list.rb +2 -3
  270. data/app/views/components/pageflow/admin/user_accounts_tab.rb +1 -0
  271. data/app/views/components/pageflow/admin/user_entries_tab.rb +1 -0
  272. data/app/views/components/pageflow/admin/users_tab.rb +1 -0
  273. data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
  274. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +5 -3
  275. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
  276. data/app/views/pageflow/editor/entries/index.json.jbuilder +1 -1
  277. data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
  278. data/app/views/pageflow/editor/entries/show.json.jbuilder +1 -1
  279. data/app/views/pageflow/editor/entry_publications/check.json.jbuilder +2 -2
  280. data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
  281. data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
  282. data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
  283. data/app/views/pageflow/editor/files/_file.json.jbuilder +7 -14
  284. data/app/views/pageflow/editor/files/create.json.jbuilder +1 -1
  285. data/app/views/pageflow/editor/files/index.json.jbuilder +1 -1
  286. data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
  287. data/app/views/pageflow/editor/sites/_site.json.jbuilder +1 -0
  288. data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +4 -3
  289. data/app/views/pageflow/entries/share_menu/_bluesky_link.html.erb +8 -0
  290. data/app/views/pageflow/entries/share_menu/_threads_link.html.erb +8 -0
  291. data/app/views/pageflow/files/_file.json.jbuilder +5 -3
  292. data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
  293. data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
  294. data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
  295. data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
  296. data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
  297. data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
  298. data/app/views/pageflow/sitemaps/index.xml.builder +9 -1
  299. data/app/views/pageflow/social_share/_entry_meta_tags.html.erb +1 -1
  300. data/app/views/pageflow/social_share/_page_meta_tags.html.erb +1 -1
  301. data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
  302. data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
  303. data/config/initializers/active_admin_patches.rb +3 -6
  304. data/config/initializers/admin_resource_tabs.rb +3 -0
  305. data/config/initializers/paperclip.rb +1 -0
  306. data/config/initializers/symmetric_encryption.rb +1 -1
  307. data/config/initializers/zencoder.rb +24 -13
  308. data/config/locales/de.yml +256 -12
  309. data/config/locales/en.yml +253 -15
  310. data/config/routes.rb +29 -13
  311. data/config/spring.rb +2 -1
  312. data/db/migrate/20140418225525_setup_schema.rb +2 -2
  313. data/db/migrate/20190306161431_copy_file_attributes_of_failed_uploads.rb +2 -2
  314. data/db/migrate/20190820152900_drop_accounts_themes.rb +2 -1
  315. data/db/migrate/20191202145757_create_pageflow_scrolled_sections.rb +11 -11
  316. data/db/migrate/20191202150657_create_pageflow_scrolled_chapters.rb +1 -1
  317. data/db/migrate/20191202154723_create_pageflow_scrolled_content_elements.rb +9 -9
  318. data/db/migrate/20191219143450_add_position_to_content_elements.rb +2 -1
  319. data/db/migrate/20200117133200_change_revision_appearance_option_default_and_null.rb +2 -1
  320. data/db/migrate/20200122115400_create_pageflow_entry_templates.rb +25 -25
  321. data/db/migrate/20200206134400_convert_legacy_scrolled_content_element_types.rb +3 -3
  322. data/db/migrate/20221215120856_associate_entry_templates_with_sites.rb +2 -2
  323. data/db/migrate/20230120092923_create_other_files.rb +2 -1
  324. data/db/migrate/20230419083307_create_pageflow_entry_translation_group.rb +9 -0
  325. data/db/migrate/20240612110434_add_cutoff_mode_name_to_sites.rb +5 -0
  326. data/db/migrate/20240918084059_create_pageflow_permalink_redirects.rb +14 -0
  327. data/db/migrate/20250508172234_ensure_scrolled_entries_have_main_storyline.rb +14 -0
  328. data/db/migrate/20250617090048_add_custom404_entry_to_sites.rb +5 -0
  329. data/db/migrate/20250617100000_add_perma_id_counter_to_entries.rb +28 -0
  330. data/db/migrate/20250722174123_add_perma_id_to_chapters.rb +10 -0
  331. data/db/migrate/20250725080603_add_perma_id_indexes_to_revision_components.rb +13 -0
  332. data/db/migrate/20250726000000_add_display_name_to_file_usages.rb +5 -0
  333. data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
  334. data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
  335. data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
  336. data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
  337. data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
  338. data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
  339. data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
  340. data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
  341. data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
  342. data/db/migrate/20260728000000_create_file_folders.rb +17 -0
  343. data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
  344. data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
  345. data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
  346. data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
  347. data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
  348. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +12599 -5398
  349. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +1275 -4560
  350. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20204 -22
  351. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18657 -19
  352. data/entry_types/paged/app/controllers/pageflow_paged/entries_controller.rb +1 -0
  353. data/entry_types/paged/app/helpers/pageflow_paged/page_background_asset_helper.rb +1 -1
  354. data/entry_types/paged/app/helpers/pageflow_paged/third_party_embed_consent_helper.rb +7 -7
  355. data/entry_types/paged/app/views/pageflow_paged/editor/entries/_seed.json.jbuilder +1 -0
  356. data/entry_types/paged/app/views/pageflow_paged/entries/show.html.erb +1 -0
  357. data/entry_types/paged/lib/pageflow_paged/plugin.rb +4 -0
  358. data/entry_types/paged/lib/pageflow_paged/react/page_type.rb +1 -1
  359. data/entry_types/paged/lib/pageflow_paged/react/widget_type.rb +3 -3
  360. data/entry_types/paged/lib/pageflow_paged.rb +1 -1
  361. data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
  362. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +5 -3
  363. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +35 -5
  364. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +4 -5
  365. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +23 -2
  366. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
  367. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +8 -5
  368. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +7 -3
  369. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +72 -10
  370. data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
  371. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +41 -12
  372. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +23 -25
  373. data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
  374. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +189 -3
  375. data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +15 -14
  376. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +61 -7
  377. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
  378. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
  379. data/entry_types/scrolled/app/models/pageflow_scrolled/section.rb +12 -1
  380. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +20 -1
  381. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +1 -0
  382. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/sections/_section_with_content_elements.json.jbuilder +2 -2
  383. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +15 -12
  384. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +45 -17
  385. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry_translations.json.jbuilder +14 -0
  386. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +34 -5
  387. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
  388. data/entry_types/scrolled/app/views/pageflow_scrolled/storylines/_storyline.json.jbuilder +7 -0
  389. data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
  390. data/entry_types/scrolled/config/locales/de.yml +1094 -78
  391. data/entry_types/scrolled/config/locales/en.yml +1083 -78
  392. data/entry_types/scrolled/config/routes.rb +18 -8
  393. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +11 -11
  394. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDarkVariantDesktop.svg +56 -0
  395. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDarkVariantMobile.svg +22 -0
  396. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/themes_plugin.rb.tt +26 -11
  397. data/entry_types/scrolled/lib/pageflow_scrolled/additional_packs.rb +27 -8
  398. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
  399. data/entry_types/scrolled/lib/pageflow_scrolled/additional_theme_assets.rb +27 -0
  400. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +67 -10
  401. data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
  402. data/entry_types/scrolled/lib/pageflow_scrolled/content_element_consent_vendors.rb +1 -1
  403. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
  404. data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
  405. data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
  406. data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
  407. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +222 -19
  408. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
  409. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +76 -54
  410. data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
  411. data/entry_types/scrolled/lib/pageflow_scrolled.rb +14 -1
  412. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +24 -5
  413. data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
  414. data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
  415. data/entry_types/scrolled/package/config/webpack.js +94 -0
  416. data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -0
  417. data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1795 -0
  418. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
  419. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
  420. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
  421. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
  422. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
  423. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
  424. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.css +1 -0
  425. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +109 -0
  426. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
  427. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
  428. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
  429. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
  430. data/entry_types/scrolled/package/contentElements-editor.js +3155 -583
  431. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  432. data/entry_types/scrolled/package/contentElements-frontend.js +3375 -1585
  433. data/entry_types/scrolled/package/editor.css +1 -0
  434. data/entry_types/scrolled/package/editor.js +8452 -2867
  435. data/entry_types/scrolled/package/entryState.js +1600 -0
  436. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
  437. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
  438. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-4ec6b2de.js → PhonePlatformContext-035a99fa.js} +9 -15
  439. data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
  440. data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
  441. data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
  442. data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
  443. data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
  444. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-30fd1124.js +39 -0
  445. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
  446. data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
  447. data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
  448. data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
  449. data/entry_types/scrolled/package/frontend/{Viewer-1bb5597c.js → Viewer-cc8d4072.js} +100 -135
  450. data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
  451. data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
  452. data/entry_types/scrolled/package/frontend/commenting.css +1 -0
  453. data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
  454. data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
  455. data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
  456. data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
  457. data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
  458. data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
  459. data/entry_types/scrolled/package/frontend/{index-11f32f10.js → index-2e5546f7.js} +39 -54
  460. data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
  461. data/entry_types/scrolled/package/frontend/index.css +1 -1
  462. data/entry_types/scrolled/package/frontend/index.js +1976 -1367
  463. data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
  464. data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
  465. data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
  466. data/entry_types/scrolled/package/frontend/usePhonePlatform-4ecb96d4.js +8 -0
  467. data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
  468. data/entry_types/scrolled/package/frontend-server.js +20 -210
  469. data/entry_types/scrolled/package/package.json +22 -12
  470. data/entry_types/scrolled/package/review.css +1 -0
  471. data/entry_types/scrolled/package/review.js +3306 -0
  472. data/entry_types/scrolled/package/testHelpers.js +952 -239
  473. data/entry_types/scrolled/package/values/widgets.module.css +18 -0
  474. data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
  475. data/entry_types/scrolled/package/widgets/consentBar.js +275 -315
  476. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  477. data/entry_types/scrolled/package/widgets/defaultNavigation.js +961 -432
  478. data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -0
  479. data/entry_types/scrolled/package/widgets/excursionSheet.js +225 -0
  480. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
  481. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -32
  482. data/entry_types/scrolled/package/widgets/iconScrollIndicator.css +1 -0
  483. data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +67 -0
  484. data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -0
  485. data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +100 -0
  486. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
  487. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +48 -26
  488. data/entry_types/scrolled/package/widgets-server.js +2 -0
  489. data/entry_types/scrolled/spec/factories/chapters.rb +14 -1
  490. data/entry_types/scrolled/spec/factories/content_elements.rb +1 -1
  491. data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
  492. data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
  493. data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
  494. data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
  495. data/lib/generators/pageflow/active_admin_initializer/active_admin_initializer_generator.rb +5 -3
  496. data/lib/generators/pageflow/assets/assets_generator.rb +7 -5
  497. data/lib/generators/pageflow/cancan/cancan_generator.rb +2 -1
  498. data/lib/generators/pageflow/cancan/templates/ability.rb +1 -1
  499. data/lib/generators/pageflow/error_pages/error_pages_generator.rb +2 -1
  500. data/lib/generators/pageflow/initializer/initializer_generator.rb +3 -2
  501. data/lib/generators/pageflow/install/install_generator.rb +2 -2
  502. data/lib/generators/pageflow/procfile/procfile_generator.rb +2 -1
  503. data/lib/generators/pageflow/resque/resque_generator.rb +4 -4
  504. data/lib/generators/pageflow/resque/templates/resque.rake +1 -1
  505. data/lib/generators/pageflow/routes/routes_generator.rb +4 -2
  506. data/lib/generators/pageflow/seeds/seeds_generator.rb +3 -2
  507. data/lib/generators/pageflow/seeds/templates/seeds.rb +6 -6
  508. data/lib/generators/pageflow/theme/theme_generator.rb +2 -1
  509. data/lib/generators/pageflow/user/user_generator.rb +2 -1
  510. data/lib/pageflow/ability_mixin.rb +25 -15
  511. data/lib/pageflow/active_admin_patches/views/attributes_table.rb +1 -0
  512. data/lib/pageflow/active_admin_patches/views/pages/base.rb +3 -2
  513. data/lib/pageflow/active_admin_patches/views/table_for.rb +1 -0
  514. data/lib/pageflow/additional_headers.rb +27 -0
  515. data/lib/pageflow/admin/attributes_table_rows.rb +3 -3
  516. data/lib/pageflow/admin/tabs.rb +1 -1
  517. data/lib/pageflow/built_in_file_type.rb +1 -1
  518. data/lib/pageflow/built_in_page_types_plugin.rb +1 -1
  519. data/lib/pageflow/built_in_widget_type.rb +2 -2
  520. data/lib/pageflow/built_in_widget_types_plugin.rb +2 -1
  521. data/lib/pageflow/configuration.rb +183 -18
  522. data/lib/pageflow/cutoff_modes.rb +39 -0
  523. data/lib/pageflow/deprecation.rb +19 -0
  524. data/lib/pageflow/editor_controller.rb +6 -10
  525. data/lib/pageflow/engine.rb +5 -6
  526. data/lib/pageflow/entries_controller_env_helper.rb +32 -2
  527. data/lib/pageflow/entry_export_import/attachment_files.rb +1 -1
  528. data/lib/pageflow/entry_export_import/entry_serialization.rb +9 -8
  529. data/lib/pageflow/entry_export_import/file_mappings.rb +1 -0
  530. data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
  531. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +11 -1
  532. data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
  533. data/lib/pageflow/entry_export_import.rb +3 -3
  534. data/lib/pageflow/entry_structured_data_types.rb +43 -0
  535. data/lib/pageflow/entry_type_configuration.rb +1 -0
  536. data/lib/pageflow/entry_types.rb +2 -2
  537. data/lib/pageflow/feature.rb +1 -1
  538. data/lib/pageflow/features.rb +4 -6
  539. data/lib/pageflow/file_importers.rb +4 -4
  540. data/lib/pageflow/file_type.rb +5 -5
  541. data/lib/pageflow/file_types.rb +4 -4
  542. data/lib/pageflow/global_config_api.rb +5 -6
  543. data/lib/pageflow/help_entries.rb +7 -7
  544. data/lib/pageflow/help_entry.rb +1 -1
  545. data/lib/pageflow/hooks.rb +1 -1
  546. data/lib/pageflow/nested_revision_component.rb +9 -27
  547. data/lib/pageflow/news_item_api.rb +1 -1
  548. data/lib/pageflow/oembed_providers.rb +42 -0
  549. data/lib/pageflow/page_type.rb +2 -3
  550. data/lib/pageflow/page_types.rb +3 -3
  551. data/lib/pageflow/paperclip_interpolations/support.rb +1 -1
  552. data/lib/pageflow/paperclip_processors/vtt.rb +1 -0
  553. data/lib/pageflow/paperclip_processors/webp.rb +2 -2
  554. data/lib/pageflow/partial_editor_fragment_renderer.rb +2 -2
  555. data/lib/pageflow/plugin.rb +1 -2
  556. data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
  557. data/lib/pageflow/quota.rb +9 -5
  558. data/lib/pageflow/quotas.rb +1 -1
  559. data/lib/pageflow/rails_version.rb +14 -2
  560. data/lib/pageflow/react.rb +1 -1
  561. data/lib/pageflow/revision_component.rb +8 -40
  562. data/lib/pageflow/revision_components.rb +16 -6
  563. data/lib/pageflow/seeds.rb +12 -16
  564. data/lib/pageflow/theme.rb +1 -1
  565. data/lib/pageflow/theme_customizations.rb +10 -10
  566. data/lib/pageflow/themes.rb +44 -3
  567. data/lib/pageflow/user_mixin.rb +18 -6
  568. data/lib/pageflow/version.rb +1 -1
  569. data/lib/pageflow/widget_type.rb +4 -4
  570. data/lib/pageflow/widget_types.rb +9 -9
  571. data/lib/pageflow/zencoder_api.rb +32 -42
  572. data/lib/pageflow/zencoder_audio_output_definition.rb +14 -13
  573. data/lib/pageflow/zencoder_meta_data_output_definition.rb +3 -2
  574. data/lib/pageflow/zencoder_output_definition.rb +16 -14
  575. data/lib/pageflow/zencoder_video_output_definition.rb +140 -88
  576. data/lib/pageflow.rb +8 -2
  577. data/lib/tasks/pageflow_tasks.rake +1 -1
  578. data/package/config/eslint-rules/documented-in-toc.js +125 -0
  579. data/package/config/jest/index.js +0 -1
  580. data/package/config/webpack.js +0 -1
  581. data/package/config/webpack5.js +0 -1
  582. data/package/editor.js +4880 -2313
  583. data/package/frontend.js +710 -1223
  584. data/package/package.json +3 -1
  585. data/package/review.js +384 -0
  586. data/package/testHelpers.js +257 -243
  587. data/package/ui.js +1487 -813
  588. data/package/vendor/stubs/wysihtml5.js +2 -0
  589. data/spec/factories/accounts.rb +37 -22
  590. data/spec/factories/audio_files.rb +2 -2
  591. data/spec/factories/authentication_tokens.rb +4 -4
  592. data/spec/factories/chapters.rb +4 -4
  593. data/spec/factories/comment_thread_reads.rb +10 -0
  594. data/spec/factories/comment_threads.rb +10 -0
  595. data/spec/factories/comments.rb +9 -0
  596. data/spec/factories/draft_entries.rb +14 -6
  597. data/spec/factories/edit_locks.rb +1 -1
  598. data/spec/factories/entries.rb +28 -19
  599. data/spec/factories/entry_translation_groups.rb +6 -0
  600. data/spec/factories/file_folders.rb +8 -0
  601. data/spec/factories/file_usages.rb +2 -1
  602. data/spec/factories/folders.rb +1 -1
  603. data/spec/factories/image_files.rb +2 -2
  604. data/spec/factories/pages.rb +3 -3
  605. data/spec/factories/published_entries.rb +28 -8
  606. data/spec/factories/revisions.rb +1 -1
  607. data/spec/factories/sites.rb +6 -0
  608. data/spec/factories/test_multi_attachment_files.rb +1 -1
  609. data/spec/factories/text_track_files.rb +1 -1
  610. data/spec/factories/uploadable_files.rb +1 -1
  611. data/spec/factories/users.rb +6 -6
  612. data/spec/factories/video_files.rb +2 -2
  613. data/spec/factories/widgets.rb +1 -1
  614. data/spec/fixtures/7x15_rotated.jpg +0 -0
  615. data/vendor/assets/javascripts/wysihtml-toolbar.js +19288 -0
  616. metadata +266 -92
  617. data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
  618. data/config/initializers/revision_components.rb +0 -5
  619. data/config/locales/twitter_to_x.de.yml +0 -6
  620. data/config/locales/twitter_to_x.en.yml +0 -6
  621. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
  622. data/entry_types/scrolled/config/locales/twitter_to_x.de.yml +0 -12
  623. data/entry_types/scrolled/config/locales/twitter_to_x.en.yml +0 -12
  624. data/entry_types/scrolled/config/locales/vr_image_projection.de.yml +0 -24
  625. data/entry_types/scrolled/config/locales/vr_image_projection.en.yml +0 -24
  626. data/entry_types/scrolled/package/frontend/EditableInlineText.module-ebd22921.js +0 -5497
  627. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-b79159cc.js +0 -107
  628. data/entry_types/scrolled/package/frontend/Viewer-1ecf3375.js +0 -154
  629. data/entry_types/scrolled/package/frontend/Wavesurfer-7d9cf1b7.js +0 -333
  630. data/entry_types/scrolled/package/frontend/arrowRight-62998af9.js +0 -77
  631. data/entry_types/scrolled/package/frontend/components-024a9893.js +0 -2853
  632. data/entry_types/scrolled/package/frontend/createSuper-d0f30da3.js +0 -115
  633. data/entry_types/scrolled/package/frontend/i18n-ce13a8bf.js +0 -1129
  634. data/entry_types/scrolled/package/frontend/useContentElementEditorState-4f4c3cf6.js +0 -52
  635. data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
  636. data/package/vendor/jquery.minicolors.js +0 -1108
@@ -0,0 +1,1795 @@
1
+ import { useI18n, ThemeIcon, useTheme, paletteColor, useContentElementLifecycle, useFile, Image, useContentElementConfigurationUpdate, useContentElementEditorState, useStorylineActivity, useDelayedBoolean, useDarkBackground, useFileWithInlineRights, useFloatingPortalRoot, utils, InlineFileRights, Text, EditableInlineText, EditableText, LinkButton, usePortraitOrientation, usePhonePlatform, useContentElementEditorCommandSubscription, useIsomorphicLayoutEffect, FullscreenViewer, contentElementWidths, ContentElementBox, ContentElementFigure, FitViewport, FilePlaceholder, ToggleFullscreenCornerButton, frontend } from 'pageflow-scrolled/frontend';
2
+ import React, { useRef, useMemo, useState, useCallback, useEffect } from 'react';
3
+ import { FloatingPortal, useTransitionStyles, useFloating, offset, shift, flip, arrow, autoUpdate, useRole, useDismiss, useInteractions, CompositeItem, FloatingFocusManager, FloatingArrow, Composite } from '@floating-ui/react';
4
+ import classNames from 'classnames';
5
+
6
+ var styles = {"button":"PagerButton-module_button__1WPOu","icon":"PagerButton-module_icon__346kq","disabled":"PagerButton-module_disabled__1SbjV","visuallyHidden":"PagerButton-module_visuallyHidden__1Hrir"};
7
+
8
+ var _jsxFileName = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/PagerButton.js";
9
+ const size = 40;
10
+ function PagerButton({
11
+ direction,
12
+ disabled,
13
+ onClick
14
+ }) {
15
+ const {
16
+ t
17
+ } = useI18n();
18
+ return /*#__PURE__*/React.createElement("button", {
19
+ className: classNames(styles.button, {
20
+ [styles.disabled]: disabled
21
+ }),
22
+ tabIndex: "-1",
23
+ onClick: onClick,
24
+ __self: this,
25
+ __source: {
26
+ fileName: _jsxFileName,
27
+ lineNumber: 13,
28
+ columnNumber: 5
29
+ }
30
+ }, /*#__PURE__*/React.createElement("div", {
31
+ className: styles.icon,
32
+ __self: this,
33
+ __source: {
34
+ fileName: _jsxFileName,
35
+ lineNumber: 17,
36
+ columnNumber: 7
37
+ }
38
+ }, /*#__PURE__*/React.createElement(ThemeIcon, {
39
+ name: direction === 'left' ? 'arrowLeft' : 'arrowRight',
40
+ width: size,
41
+ height: size,
42
+ __self: this,
43
+ __source: {
44
+ fileName: _jsxFileName,
45
+ lineNumber: 18,
46
+ columnNumber: 9
47
+ }
48
+ }), /*#__PURE__*/React.createElement("span", {
49
+ className: styles.visuallyHidden,
50
+ __self: this,
51
+ __source: {
52
+ fileName: _jsxFileName,
53
+ lineNumber: 21,
54
+ columnNumber: 9
55
+ }
56
+ }, t(direction === 'left' ? 'pageflow_scrolled.public.previous' : 'pageflow_scrolled.public.next'))));
57
+ }
58
+ function insidePagerButton(element) {
59
+ return !!element.closest(`.${styles.button}`);
60
+ }
61
+
62
+ var styles$1 = {"outer":"Pager-module_outer__2CrMo","customMargin":"Pager-module_customMargin__1qTs3","left":"Pager-module_left__2UmsW","right":"Pager-module_right__2Qn5W","center":"Pager-module_center__1nzq4"};
63
+
64
+ var _jsxFileName$1 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/Pager.js";
65
+ function Pager({
66
+ areas,
67
+ customMargin,
68
+ panZoomEnabled,
69
+ hideButtons,
70
+ activeIndex,
71
+ activateArea,
72
+ children
73
+ }) {
74
+ const theme = useTheme();
75
+ return /*#__PURE__*/React.createElement("div", {
76
+ className: classNames(styles$1.outer, {
77
+ [styles$1.customMargin]: customMargin
78
+ }),
79
+ __self: this,
80
+ __source: {
81
+ fileName: _jsxFileName$1,
82
+ lineNumber: 17,
83
+ columnNumber: 5
84
+ }
85
+ }, renderScrollButtons(), /*#__PURE__*/React.createElement("div", {
86
+ className: styles$1.center,
87
+ __self: this,
88
+ __source: {
89
+ fileName: _jsxFileName$1,
90
+ lineNumber: 19,
91
+ columnNumber: 7
92
+ }
93
+ }, children));
94
+ function renderScrollButtons() {
95
+ if (!panZoomEnabled || theme.options.hotspotsPagerButtonsHidden) {
96
+ return null;
97
+ }
98
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
99
+ className: styles$1.left,
100
+ __self: this,
101
+ __source: {
102
+ fileName: _jsxFileName$1,
103
+ lineNumber: 32,
104
+ columnNumber: 9
105
+ }
106
+ }, /*#__PURE__*/React.createElement(PagerButton, {
107
+ direction: "left",
108
+ disabled: activeIndex === -1 || hideButtons,
109
+ onClick: () => {
110
+ if (activeIndex >= 0) {
111
+ activateArea(activeIndex - 1);
112
+ }
113
+ },
114
+ __self: this,
115
+ __source: {
116
+ fileName: _jsxFileName$1,
117
+ lineNumber: 33,
118
+ columnNumber: 11
119
+ }
120
+ })), /*#__PURE__*/React.createElement("div", {
121
+ className: styles$1.right,
122
+ __self: this,
123
+ __source: {
124
+ fileName: _jsxFileName$1,
125
+ lineNumber: 41,
126
+ columnNumber: 9
127
+ }
128
+ }, /*#__PURE__*/React.createElement(PagerButton, {
129
+ direction: "right",
130
+ disabled: activeIndex >= areas.length || hideButtons,
131
+ onClick: () => {
132
+ if (activeIndex < areas.length) {
133
+ activateArea(activeIndex + 1);
134
+ }
135
+ },
136
+ __self: this,
137
+ __source: {
138
+ fileName: _jsxFileName$1,
139
+ lineNumber: 42,
140
+ columnNumber: 11
141
+ }
142
+ })));
143
+ }
144
+ }
145
+
146
+ var styles$2 = {"scroller":"Scroller-module_scroller__b_jkV","sticky":"Scroller-module_sticky__1nSEO","inner":"Scroller-module_inner__XTNms","step":"Scroller-module_step__1ar7Q"};
147
+
148
+ var _jsxFileName$2 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/Scroller.js";
149
+ const Scroller = React.forwardRef(function Scroller({
150
+ areas,
151
+ disabled,
152
+ setStepRef,
153
+ children
154
+ }, ref) {
155
+ if (disabled) {
156
+ return children;
157
+ }
158
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
159
+ ref: ref,
160
+ className: styles$2.scroller,
161
+ __self: this,
162
+ __source: {
163
+ fileName: _jsxFileName$2,
164
+ lineNumber: 14,
165
+ columnNumber: 7
166
+ }
167
+ }, Array.from({
168
+ length: areas.length + 2
169
+ }, (_, index) => /*#__PURE__*/React.createElement("div", {
170
+ key: index,
171
+ ref: setStepRef(index),
172
+ className: styles$2.step,
173
+ __self: this,
174
+ __source: {
175
+ fileName: _jsxFileName$2,
176
+ lineNumber: 17,
177
+ columnNumber: 11
178
+ }
179
+ })), /*#__PURE__*/React.createElement("div", {
180
+ className: styles$2.sticky,
181
+ __self: this,
182
+ __source: {
183
+ fileName: _jsxFileName$2,
184
+ lineNumber: 21,
185
+ columnNumber: 9
186
+ }
187
+ }, /*#__PURE__*/React.createElement("div", {
188
+ className: styles$2.inner,
189
+ __self: this,
190
+ __source: {
191
+ fileName: _jsxFileName$2,
192
+ lineNumber: 22,
193
+ columnNumber: 11
194
+ }
195
+ }, children))));
196
+ });
197
+
198
+ var styles$3 = {"area":"Area-module_area__2uQD0","clip":"Area-module_clip__TgtiP","outline":"Area-module_outline__bRQqm","noPointerEvents":"Area-module_noPointerEvents__kLM1Z","hidden":"Area-module_hidden__2SAnU","highlighted":"Area-module_highlighted__2hdr1"};
199
+
200
+ var _jsxFileName$3 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/Area.js";
201
+ function Area({
202
+ area,
203
+ noPointerEvents,
204
+ highlighted,
205
+ outlined,
206
+ outlineHidden,
207
+ className,
208
+ children,
209
+ onMouseEnter,
210
+ onMouseLeave,
211
+ onClick
212
+ }) {
213
+ return /*#__PURE__*/React.createElement("div", {
214
+ className: classNames(styles$3.area, className, {
215
+ [styles$3.highlighted]: highlighted,
216
+ [styles$3.noPointerEvents]: noPointerEvents
217
+ }),
218
+ __self: this,
219
+ __source: {
220
+ fileName: _jsxFileName$3,
221
+ lineNumber: 15,
222
+ columnNumber: 5
223
+ }
224
+ }, /*#__PURE__*/React.createElement("div", {
225
+ className: styles$3.clip,
226
+ style: {
227
+ clipPath: polygon(area.outline)
228
+ },
229
+ tabIndex: "-1",
230
+ onClick: onClick,
231
+ onMouseEnter: onMouseEnter,
232
+ onMouseLeave: onMouseLeave,
233
+ __self: this,
234
+ __source: {
235
+ fileName: _jsxFileName$3,
236
+ lineNumber: 19,
237
+ columnNumber: 7
238
+ }
239
+ }), children, outlined && /*#__PURE__*/React.createElement(Outline, {
240
+ points: area.outline,
241
+ color: areaColor(area),
242
+ hidden: outlineHidden,
243
+ __self: this,
244
+ __source: {
245
+ fileName: _jsxFileName$3,
246
+ lineNumber: 26,
247
+ columnNumber: 20
248
+ }
249
+ }));
250
+ }
251
+ function areaColor(area) {
252
+ return paletteColor(area.color);
253
+ }
254
+ function Outline({
255
+ points,
256
+ color,
257
+ hidden
258
+ }) {
259
+ return /*#__PURE__*/React.createElement("svg", {
260
+ className: classNames(styles$3.outline, {
261
+ [styles$3.hidden]: hidden
262
+ }),
263
+ xmlns: "http://www.w3.org/2000/svg",
264
+ viewBox: "0 0 100 100",
265
+ preserveAspectRatio: "none",
266
+ __self: this,
267
+ __source: {
268
+ fileName: _jsxFileName$3,
269
+ lineNumber: 39,
270
+ columnNumber: 5
271
+ }
272
+ }, /*#__PURE__*/React.createElement("polygon", {
273
+ points: points.map(coords => coords.map(coord => coord).join(',')).join(' '),
274
+ style: {
275
+ stroke: color
276
+ },
277
+ __self: this,
278
+ __source: {
279
+ fileName: _jsxFileName$3,
280
+ lineNumber: 44,
281
+ columnNumber: 7
282
+ }
283
+ }));
284
+ }
285
+ function polygon(points) {
286
+ return `polygon(${points.map(coords => coords.map(coord => `${coord}%`).join(' ')).join(', ')})`;
287
+ }
288
+
289
+ var styles$4 = {"area":"ImageArea-module_area__3rqgC","activeImageVisible":"ImageArea-module_activeImageVisible__oYKOK"};
290
+
291
+ var _jsxFileName$4 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/ImageArea.js";
292
+ function ImageArea({
293
+ panZoomEnabled,
294
+ activeImageVisible,
295
+ ...props
296
+ }) {
297
+ const {
298
+ shouldLoad
299
+ } = useContentElementLifecycle();
300
+ const activeImageFile = useFile({
301
+ collectionName: 'imageFiles',
302
+ permaId: props.area.activeImage
303
+ });
304
+ const fallbackActiveImageFile = useFile({
305
+ collectionName: 'imageFiles',
306
+ permaId: props.area.fallbackActiveImage
307
+ });
308
+ return /*#__PURE__*/React.createElement(Area, Object.assign({}, props, {
309
+ className: classNames(styles$4.area, {
310
+ [styles$4.activeImageVisible]: activeImageVisible
311
+ }),
312
+ __self: this,
313
+ __source: {
314
+ fileName: _jsxFileName$4,
315
+ lineNumber: 29,
316
+ columnNumber: 5
317
+ }
318
+ }), /*#__PURE__*/React.createElement(Image, {
319
+ imageFile: activeImageFile || fallbackActiveImageFile,
320
+ load: shouldLoad,
321
+ variant: panZoomEnabled ? 'ultra' : 'large',
322
+ preferSvg: true,
323
+ __self: this,
324
+ __source: {
325
+ fileName: _jsxFileName$4,
326
+ lineNumber: 32,
327
+ columnNumber: 7
328
+ }
329
+ }));
330
+ }
331
+
332
+ var styles$5 = {"wrapper":"Indicator-module_wrapper__2b1Mj","indicator":"Indicator-module_indicator__2A3-l","inner":"Indicator-module_inner__2BgbL","hidden":"Indicator-module_hidden__3j1Re","outer":"Indicator-module_outer__36JWr"};
333
+
334
+ var _jsxFileName$5 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/Indicator.js";
335
+ function Indicator({
336
+ area,
337
+ hidden,
338
+ panZoomTransform,
339
+ outerRef
340
+ }) {
341
+ return /*#__PURE__*/React.createElement("div", {
342
+ className: styles$5.wrapper,
343
+ ref: outerRef,
344
+ style: {
345
+ transform: panZoomTransform
346
+ },
347
+ __self: this,
348
+ __source: {
349
+ fileName: _jsxFileName$5,
350
+ lineNumber: 10,
351
+ columnNumber: 5
352
+ }
353
+ }, /*#__PURE__*/React.createElement("div", {
354
+ className: classNames(styles$5.indicator, {
355
+ [styles$5.hidden]: hidden
356
+ }),
357
+ style: {
358
+ '--color': areaColor(area),
359
+ left: `${area.indicatorPosition[0]}%`,
360
+ top: `${area.indicatorPosition[1]}%`
361
+ },
362
+ __self: this,
363
+ __source: {
364
+ fileName: _jsxFileName$5,
365
+ lineNumber: 11,
366
+ columnNumber: 7
367
+ }
368
+ }));
369
+ }
370
+
371
+ const TooltipPortal = FloatingPortal;
372
+
373
+ const useTooltipTransitionStyles = useTransitionStyles;
374
+
375
+ function getBoundingRect(area) {
376
+ const xCoords = area.map(point => point[0]);
377
+ const yCoords = area.map(point => point[1]);
378
+ const minX = Math.min(...xCoords);
379
+ const maxX = Math.max(...xCoords);
380
+ const minY = Math.min(...yCoords);
381
+ const maxY = Math.max(...yCoords);
382
+ return {
383
+ left: minX,
384
+ top: minY,
385
+ width: maxX - minX,
386
+ height: maxY - minY
387
+ };
388
+ }
389
+
390
+ function getTooltipInlineStyles({
391
+ area,
392
+ panZoomTransform
393
+ }) {
394
+ const referencePositionInPercent = getReferencePositionInPercent({
395
+ area
396
+ });
397
+ return {
398
+ reference: {
399
+ left: `${referencePositionInPercent.left}%`,
400
+ top: `${referencePositionInPercent.top}%`,
401
+ height: `${referencePositionInPercent.height}%`
402
+ },
403
+ wrapper: {
404
+ transform: panZoomTransform
405
+ }
406
+ };
407
+ }
408
+ function getReferencePositionInPercent({
409
+ area
410
+ }) {
411
+ const referenceType = area.tooltipReference;
412
+ const indicatorRect = getIndicatorRect(area.indicatorPosition);
413
+ if (referenceType === 'area') {
414
+ const boundingRect = getBoundingRect(area.outline);
415
+ return {
416
+ top: boundingRect.top,
417
+ height: boundingRect.height,
418
+ left: indicatorRect.left
419
+ };
420
+ } else {
421
+ return indicatorRect;
422
+ }
423
+ }
424
+ function getIndicatorRect(indicatorPosition) {
425
+ return {
426
+ left: indicatorPosition[0],
427
+ top: indicatorPosition[1],
428
+ height: 0
429
+ };
430
+ }
431
+
432
+ var styles$6 = {"darkContentSurfaceColor":"var(--theme-dark-content-surface-color, #101010)","lightContentSurfaceColor":"var(--theme-light-content-surface-color, #fff)","darkContentTextColor":"var(--theme-dark-content-text-color, #222)","lightContentTextColor":"var(--theme-light-content-text-color, #fff)","darkContentLinkColor":"var(--theme-dark-content-link-color, var(--theme-content-link-color, currentColor))","lightContentLinkColor":"var(--theme-light-content-link-color, var(--theme-content-link-color, currentColor))","compositeItem":"Tooltip-module_compositeItem__3QnpM","wrapper":"Tooltip-module_wrapper__3J6qG","reference":"Tooltip-module_reference__1qjnL","box":"Tooltip-module_box__2MGMl","paddingForScrollButtons":"Tooltip-module_paddingForScrollButtons__3wFKp","light":"Tooltip-module_light__3H6Ii scope-darkContent","dark":"Tooltip-module_dark__2nDMy scope-lightContent","maxWidth-wide":"Tooltip-module_maxWidth-wide__3Vik_","maxWidth-narrow":"Tooltip-module_maxWidth-narrow__foMG0","maxWidth-veryNarrow":"Tooltip-module_maxWidth-veryNarrow__1yS6L","align-center":"Tooltip-module_align-center__jRtdN","align-right":"Tooltip-module_align-right__2ezWZ","minWidth":"Tooltip-module_minWidth__2iAip","imageWrapper":"Tooltip-module_imageWrapper__1BCEJ","link":"Tooltip-module_link__1xE5O","textWrapper":"Tooltip-module_textWrapper__Hc0qY"};
433
+
434
+ var _jsxFileName$6 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/Tooltip.js";
435
+ const arrowKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
436
+ function Tooltip({
437
+ area,
438
+ panZoomTransform,
439
+ contentElementId,
440
+ configuration,
441
+ visible,
442
+ active,
443
+ imageFile,
444
+ containerRect,
445
+ keepInViewport,
446
+ floatingStrategy,
447
+ aboveNavigationWidgets,
448
+ wrapperRef,
449
+ onMouseEnter,
450
+ onMouseLeave,
451
+ onClick,
452
+ onDismiss,
453
+ onLinkClick
454
+ }) {
455
+ var _tooltipTexts$area$id6, _tooltipTexts$area$id7, _tooltipLinks$area$id, _tooltipLinks$area$id2, _tooltipTexts$area$id8;
456
+ const {
457
+ t: translateWithEntryLocale
458
+ } = useI18n();
459
+ const {
460
+ t
461
+ } = useI18n({
462
+ locale: 'ui'
463
+ });
464
+ const updateConfiguration = useContentElementConfigurationUpdate();
465
+ const {
466
+ isEditable
467
+ } = useContentElementEditorState();
468
+ const storylineMode = useStorylineActivity();
469
+ const inBackground = useDelayedBoolean(storylineMode !== 'active', {
470
+ fromTrueToFalse: 200
471
+ });
472
+ const darkBackground = useDarkBackground();
473
+ const light = configuration.invertTooltips ? !darkBackground : darkBackground;
474
+ const tooltipImageFile = useFileWithInlineRights({
475
+ configuration: area,
476
+ collectionName: 'imageFiles',
477
+ propertyName: 'tooltipImage'
478
+ });
479
+ const inlineStyles = getTooltipInlineStyles({
480
+ area,
481
+ panZoomTransform
482
+ });
483
+ const tooltipTexts = configuration.tooltipTexts || {};
484
+ const tooltipLinks = configuration.tooltipLinks || {};
485
+ const referenceType = area.tooltipReference;
486
+ const position = area.tooltipPosition;
487
+ const maxWidth = area.tooltipMaxWidth;
488
+ const arrowRef = useRef();
489
+ const {
490
+ refs,
491
+ floatingStyles,
492
+ context
493
+ } = useFloating({
494
+ open: containerRect.width > 0 && visible && !inBackground,
495
+ onOpenChange: open => !open && onDismiss(),
496
+ strategy: floatingStrategy || 'absolute',
497
+ placement: position === 'above' ? 'top' : 'bottom',
498
+ middleware: [offset(referenceType === 'area' ? 7 : 20), shift(keepInViewport ? {
499
+ crossAxis: true,
500
+ padding: {
501
+ left: 40,
502
+ right: 40
503
+ }
504
+ } : {
505
+ padding: {
506
+ left: -5,
507
+ right: -5
508
+ },
509
+ boundary: wrapperRef.current
510
+ }), keepInViewport && flip(), arrow({
511
+ element: arrowRef,
512
+ padding: 5
513
+ })],
514
+ whileElementsMounted: autoUpdate
515
+ });
516
+ const role = useRole(context, {
517
+ role: 'label'
518
+ });
519
+ const dismiss = useDismiss(context, {
520
+ outsidePressEvent: 'mousedown',
521
+ outsidePress: event => !insidePagerButton(event.target),
522
+ capture: {
523
+ outsidePress: false
524
+ }
525
+ });
526
+ const {
527
+ getReferenceProps,
528
+ getFloatingProps
529
+ } = useInteractions([role, dismiss]);
530
+ const {
531
+ isMounted,
532
+ styles: transitionStyles
533
+ } = useTooltipTransitionStyles(context);
534
+ const floatingPortalRoot = useFloatingPortalRoot();
535
+ function handleTextChange(propertyName, value) {
536
+ updateConfiguration({
537
+ tooltipTexts: {
538
+ ...tooltipTexts,
539
+ [area.id]: {
540
+ ...tooltipTexts[area.id],
541
+ [propertyName]: value
542
+ }
543
+ }
544
+ });
545
+ }
546
+ function handleLinkChange(value) {
547
+ if (value) {
548
+ var _tooltipTexts$area$id;
549
+ if (utils.isBlankEditableTextValue((_tooltipTexts$area$id = tooltipTexts[area.id]) === null || _tooltipTexts$area$id === void 0 ? void 0 : _tooltipTexts$area$id.link)) {
550
+ handleTextChange('link', [{
551
+ type: 'heading',
552
+ children: [{
553
+ text: translateWithEntryLocale('pageflow_scrolled.public.more')
554
+ }]
555
+ }]);
556
+ }
557
+ } else {
558
+ handleTextChange('link', [{
559
+ type: 'heading',
560
+ children: [{
561
+ text: ''
562
+ }]
563
+ }]);
564
+ }
565
+ updateConfiguration({
566
+ tooltipLinks: {
567
+ ...tooltipLinks,
568
+ [area.id]: value
569
+ }
570
+ });
571
+ }
572
+ function handleKeyDown(event) {
573
+ if (arrowKeys.includes(event.key) && isEditable) {
574
+ event.stopPropagation();
575
+ event.preventDefault();
576
+ }
577
+ }
578
+ function presentOrEditing(propertyName) {
579
+ var _tooltipTexts$area$id2, _tooltipTexts$area$id3, _tooltipTexts$area$id4, _tooltipTexts$area$id5;
580
+ return !utils.isBlankEditableTextValue((_tooltipTexts$area$id2 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id2 === void 0 ? void 0 : _tooltipTexts$area$id2[propertyName]) || isEditable && active || isEditable && utils.isBlankEditableTextValue((_tooltipTexts$area$id3 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id3 === void 0 ? void 0 : _tooltipTexts$area$id3.title) && utils.isBlankEditableTextValue((_tooltipTexts$area$id4 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id4 === void 0 ? void 0 : _tooltipTexts$area$id4.description) && utils.isBlankEditableTextValue((_tooltipTexts$area$id5 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id5 === void 0 ? void 0 : _tooltipTexts$area$id5.link);
581
+ }
582
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CompositeItem, {
583
+ render: /*#__PURE__*/React.createElement("div", {
584
+ className: styles$6.compositeItem,
585
+ __self: this,
586
+ __source: {
587
+ fileName: _jsxFileName$6,
588
+ lineNumber: 181,
589
+ columnNumber: 30
590
+ }
591
+ }),
592
+ __self: this,
593
+ __source: {
594
+ fileName: _jsxFileName$6,
595
+ lineNumber: 181,
596
+ columnNumber: 7
597
+ }
598
+ }, /*#__PURE__*/React.createElement("div", {
599
+ className: styles$6.wrapper,
600
+ style: inlineStyles.wrapper,
601
+ __self: this,
602
+ __source: {
603
+ fileName: _jsxFileName$6,
604
+ lineNumber: 182,
605
+ columnNumber: 9
606
+ }
607
+ }, /*#__PURE__*/React.createElement("div", Object.assign({
608
+ ref: refs.setReference,
609
+ className: styles$6.reference,
610
+ style: inlineStyles.reference
611
+ }, getReferenceProps(), {
612
+ __self: this,
613
+ __source: {
614
+ fileName: _jsxFileName$6,
615
+ lineNumber: 183,
616
+ columnNumber: 11
617
+ }
618
+ })))), isMounted && /*#__PURE__*/React.createElement(TooltipPortal, {
619
+ id: aboveNavigationWidgets && 'floating-ui-above-navigation-widgets',
620
+ root: floatingPortalRoot,
621
+ __self: this,
622
+ __source: {
623
+ fileName: _jsxFileName$6,
624
+ lineNumber: 190,
625
+ columnNumber: 8
626
+ }
627
+ }, /*#__PURE__*/React.createElement(FloatingFocusManager, {
628
+ context: context,
629
+ modal: false,
630
+ initialFocus: -1,
631
+ returnFocus: false,
632
+ __self: this,
633
+ __source: {
634
+ fileName: _jsxFileName$6,
635
+ lineNumber: 192,
636
+ columnNumber: 10
637
+ }
638
+ }, /*#__PURE__*/React.createElement("div", {
639
+ style: transitionStyles,
640
+ __self: this,
641
+ __source: {
642
+ fileName: _jsxFileName$6,
643
+ lineNumber: 193,
644
+ columnNumber: 12
645
+ }
646
+ }, /*#__PURE__*/React.createElement("div", Object.assign({
647
+ ref: refs.setFloating,
648
+ style: floatingStyles,
649
+ className: classNames(styles$6.box, styles$6[`maxWidth-${maxWidth}`], styles$6[`align-${area.tooltipTextAlign}`], configuration.linkButtonVariant && `scope-linkButton-${configuration.linkButtonVariant}`, light ? styles$6.light : styles$6.dark, {
650
+ [styles$6.paddingForScrollButtons]: keepInViewport,
651
+ [styles$6.minWidth]: presentOrEditing('link')
652
+ }),
653
+ onMouseEnter: () => storylineMode === 'active' && onMouseEnter(),
654
+ onMouseLeave: onMouseLeave,
655
+ onClick: onClick
656
+ }, getFloatingProps(), {
657
+ __self: this,
658
+ __source: {
659
+ fileName: _jsxFileName$6,
660
+ lineNumber: 194,
661
+ columnNumber: 14
662
+ }
663
+ }), /*#__PURE__*/React.createElement(FloatingArrow, {
664
+ ref: arrowRef,
665
+ context: context,
666
+ strokeWidth: 1,
667
+ __self: this,
668
+ __source: {
669
+ fileName: _jsxFileName$6,
670
+ lineNumber: 208,
671
+ columnNumber: 16
672
+ }
673
+ }), tooltipImageFile && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
674
+ className: styles$6.imageWrapper,
675
+ __self: this,
676
+ __source: {
677
+ fileName: _jsxFileName$6,
678
+ lineNumber: 211,
679
+ columnNumber: 19
680
+ }
681
+ }, /*#__PURE__*/React.createElement(Image, {
682
+ imageFile: tooltipImageFile,
683
+ variant: 'medium',
684
+ fill: false,
685
+ width: tooltipImageFile.width,
686
+ height: tooltipImageFile.height,
687
+ preferSvg: true,
688
+ __self: this,
689
+ __source: {
690
+ fileName: _jsxFileName$6,
691
+ lineNumber: 212,
692
+ columnNumber: 21
693
+ }
694
+ }), /*#__PURE__*/React.createElement(InlineFileRights, {
695
+ context: "insideElement",
696
+ items: [{
697
+ file: tooltipImageFile,
698
+ label: 'image'
699
+ }],
700
+ __self: this,
701
+ __source: {
702
+ fileName: _jsxFileName$6,
703
+ lineNumber: 218,
704
+ columnNumber: 21
705
+ }
706
+ }), /*#__PURE__*/React.createElement(InlineFileRights, {
707
+ context: "afterElement",
708
+ items: [{
709
+ file: tooltipImageFile,
710
+ label: 'image'
711
+ }],
712
+ __self: this,
713
+ __source: {
714
+ fileName: _jsxFileName$6,
715
+ lineNumber: 219,
716
+ columnNumber: 21
717
+ }
718
+ }))), /*#__PURE__*/React.createElement("div", {
719
+ className: styles$6.textWrapper,
720
+ onKeyDown: handleKeyDown,
721
+ __self: this,
722
+ __source: {
723
+ fileName: _jsxFileName$6,
724
+ lineNumber: 222,
725
+ columnNumber: 16
726
+ }
727
+ }, presentOrEditing('title') && /*#__PURE__*/React.createElement("h3", {
728
+ id: `hotspots-tooltip-title-${contentElementId}-${area.id}`,
729
+ __self: this,
730
+ __source: {
731
+ fileName: _jsxFileName$6,
732
+ lineNumber: 225,
733
+ columnNumber: 19
734
+ }
735
+ }, /*#__PURE__*/React.createElement(Text, {
736
+ inline: true,
737
+ scaleCategory: "hotspotsTooltipTitle",
738
+ __self: this,
739
+ __source: {
740
+ fileName: _jsxFileName$6,
741
+ lineNumber: 226,
742
+ columnNumber: 21
743
+ }
744
+ }, /*#__PURE__*/React.createElement(EditableInlineText, {
745
+ value: (_tooltipTexts$area$id6 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id6 === void 0 ? void 0 : _tooltipTexts$area$id6.title,
746
+ onChange: value => handleTextChange('title', value),
747
+ placeholder: t('pageflow_scrolled.inline_editing.type_heading'),
748
+ __self: this,
749
+ __source: {
750
+ fileName: _jsxFileName$6,
751
+ lineNumber: 227,
752
+ columnNumber: 23
753
+ }
754
+ }))), presentOrEditing('description') && /*#__PURE__*/React.createElement(EditableText, {
755
+ value: (_tooltipTexts$area$id7 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id7 === void 0 ? void 0 : _tooltipTexts$area$id7.description,
756
+ onChange: value => handleTextChange('description', value),
757
+ scaleCategory: "hotspotsTooltipDescription",
758
+ placeholder: t('pageflow_scrolled.inline_editing.type_text'),
759
+ __self: this,
760
+ __source: {
761
+ fileName: _jsxFileName$6,
762
+ lineNumber: 233,
763
+ columnNumber: 19
764
+ }
765
+ }), presentOrEditing('link') && /*#__PURE__*/React.createElement(LinkButton, {
766
+ className: styles$6.link,
767
+ scaleCategory: "hotspotsTooltipLink",
768
+ href: (_tooltipLinks$area$id = tooltipLinks[area.id]) === null || _tooltipLinks$area$id === void 0 ? void 0 : _tooltipLinks$area$id.href,
769
+ openInNewTab: (_tooltipLinks$area$id2 = tooltipLinks[area.id]) === null || _tooltipLinks$area$id2 === void 0 ? void 0 : _tooltipLinks$area$id2.openInNewTab,
770
+ value: (_tooltipTexts$area$id8 = tooltipTexts[area.id]) === null || _tooltipTexts$area$id8 === void 0 ? void 0 : _tooltipTexts$area$id8.link,
771
+ allowRemove: true,
772
+ onTextChange: value => handleTextChange('link', value),
773
+ onLinkChange: value => handleLinkChange(value),
774
+ onClick: onLinkClick,
775
+ __self: this,
776
+ __source: {
777
+ fileName: _jsxFileName$6,
778
+ lineNumber: 238,
779
+ columnNumber: 19
780
+ }
781
+ })))))));
782
+ }
783
+
784
+ function useHotspotsConfiguration(configuration) {
785
+ const defaultImageFile = useFileWithInlineRights({
786
+ configuration,
787
+ collectionName: 'imageFiles',
788
+ propertyName: 'image'
789
+ });
790
+ const portraitImageFile = useFileWithInlineRights({
791
+ configuration,
792
+ collectionName: 'imageFiles',
793
+ propertyName: 'portraitImage'
794
+ });
795
+ const portraitOrientation = usePortraitOrientation();
796
+ const portraitMode = !!(portraitOrientation && portraitImageFile);
797
+ const imageFile = portraitMode ? portraitImageFile : defaultImageFile;
798
+ return {
799
+ panZoomEnabled: usePanZoomEnabled(configuration),
800
+ areas: useAreas(configuration, portraitMode),
801
+ imageFile,
802
+ portraitMode
803
+ };
804
+ }
805
+ function useAreas(configuration, portraitMode) {
806
+ return useMemo(() => {
807
+ return (configuration.areas || []).map(area => {
808
+ if (portraitMode) {
809
+ return applyAreaDefaults({
810
+ ...area,
811
+ outline: area.portraitOutline,
812
+ zoom: area.portraitZoom,
813
+ activeImage: area.portraitActiveImage,
814
+ fallbackActiveImage: area.activeImage,
815
+ indicatorPosition: area.portraitIndicatorPosition,
816
+ color: area.portraitColor || area.color,
817
+ tooltipReference: area.portraitTooltipReference,
818
+ tooltipPosition: area.portraitTooltipPosition,
819
+ tooltipMaxWidth: area.portraitTooltipMaxWidth
820
+ });
821
+ } else {
822
+ return applyAreaDefaults(area);
823
+ }
824
+ });
825
+ }, [configuration.areas, portraitMode]);
826
+ }
827
+ function applyAreaDefaults(area) {
828
+ var _area$outline;
829
+ return {
830
+ ...area,
831
+ outline: ((_area$outline = area.outline) === null || _area$outline === void 0 ? void 0 : _area$outline.length) ? area.outline : [[50, 50]],
832
+ zoom: area.zoom || 0,
833
+ indicatorPosition: area.indicatorPosition || [50, 50]
834
+ };
835
+ }
836
+ function usePanZoomEnabled(configuration) {
837
+ const isPhonePlatform = usePhonePlatform();
838
+ return configuration.enablePanZoom === 'always' || configuration.enablePanZoom === 'phonePlatform' && isPhonePlatform;
839
+ }
840
+
841
+ function useHotspotsEditorCommandSubscriptions({
842
+ setHighlightedIndex,
843
+ activateArea
844
+ }) {
845
+ useContentElementEditorCommandSubscription(command => {
846
+ if (command.type === 'HIGHLIGHT_AREA') {
847
+ setHighlightedIndex(command.index);
848
+ } else if (command.type === 'RESET_AREA_HIGHLIGHT') {
849
+ setHighlightedIndex(-1);
850
+ } else if (command.type === 'SET_ACTIVE_AREA') {
851
+ activateArea(command.index);
852
+ }
853
+ });
854
+ }
855
+
856
+ function useHotspotsState({
857
+ areas,
858
+ initialActiveArea
859
+ }) {
860
+ const {
861
+ setTransientState,
862
+ select,
863
+ isSelected
864
+ } = useContentElementEditorState();
865
+ const [activeIndex, setActiveIndexState] = useState(typeof initialActiveArea === 'undefined' ? -1 : initialActiveArea);
866
+ const [hoveredIndex, setHoveredIndex] = useState(-1);
867
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
868
+ const setActiveIndex = useCallback(index => {
869
+ var _areas$index;
870
+ setTransientState({
871
+ activeAreaId: (_areas$index = areas[index]) === null || _areas$index === void 0 ? void 0 : _areas$index.id
872
+ });
873
+ setActiveIndexState(activeIndex => {
874
+ if (activeIndex !== index && index >= 0 && isSelected) {
875
+ select();
876
+ }
877
+ return index;
878
+ });
879
+ }, [setActiveIndexState, setTransientState, areas, select, isSelected]);
880
+ return {
881
+ activeIndex,
882
+ hoveredIndex,
883
+ highlightedIndex,
884
+ setActiveIndex,
885
+ setHoveredIndex,
886
+ setHighlightedIndex
887
+ };
888
+ }
889
+
890
+ function useContentRect({
891
+ enabled
892
+ }) {
893
+ const [contentRect, setContentRect] = useState({
894
+ width: 0,
895
+ height: 0
896
+ });
897
+ const ref = useRef();
898
+ useEffect(() => {
899
+ if (!enabled) {
900
+ return;
901
+ }
902
+ const current = ref.current;
903
+ const resizeObserver = new ResizeObserver(entries => {
904
+ requestAnimationFrame(() => {
905
+ setContentRect(entries[entries.length - 1].contentRect);
906
+ });
907
+ });
908
+ resizeObserver.observe(current);
909
+ return () => {
910
+ resizeObserver.unobserve(current);
911
+ };
912
+ }, [enabled]);
913
+ return [contentRect, ref];
914
+ }
915
+
916
+ const fullRect = {
917
+ left: 0,
918
+ top: 0,
919
+ width: 100,
920
+ height: 100
921
+ };
922
+ function getInitialTransform({
923
+ containerWidth,
924
+ containerHeight,
925
+ imageFileWidth,
926
+ imageFileHeight,
927
+ areasBoundingRect,
928
+ indicatorPositions = [],
929
+ containerSafeAreaMargin = 0
930
+ }) {
931
+ const baseImageWidth = imageFileWidth * containerHeight / imageFileHeight;
932
+ const baseImageHeight = containerHeight;
933
+ const scaleCover = getScaleToCoverContainerWithRect({
934
+ baseImageWidth,
935
+ baseImageHeight,
936
+ containerWidth,
937
+ containerHeight,
938
+ rect: fullRect
939
+ });
940
+ const scaleContainMotif = getScaleToContainRectInContainer({
941
+ baseImageWidth,
942
+ baseImageHeight,
943
+ containerWidth: containerWidth * (1 - 2 * containerSafeAreaMargin / 100),
944
+ containerHeight,
945
+ rect: areasBoundingRect
946
+ });
947
+ const scale = Math.min(scaleCover, scaleContainMotif);
948
+ const [translateX, translateY] = center({
949
+ baseImageWidth,
950
+ baseImageHeight,
951
+ containerWidth,
952
+ containerHeight,
953
+ scale,
954
+ unbounded: scaleContainMotif < scaleCover,
955
+ rect: areasBoundingRect
956
+ });
957
+ return {
958
+ wrapper: {
959
+ x: translateX,
960
+ y: translateY,
961
+ scale
962
+ },
963
+ indicators: transformIndicators({
964
+ indicatorPositions,
965
+ baseImageWidth,
966
+ baseImageHeight,
967
+ translateX,
968
+ translateY,
969
+ scale
970
+ })
971
+ };
972
+ }
973
+ function getPanZoomStepTransform({
974
+ containerWidth,
975
+ containerHeight,
976
+ imageFileWidth,
977
+ imageFileHeight,
978
+ areaOutline,
979
+ areaZoom,
980
+ indicatorPositions = [],
981
+ initialScale
982
+ }) {
983
+ const areaRect = getBoundingRect(areaOutline);
984
+ const baseImageWidth = imageFileWidth * containerHeight / imageFileHeight;
985
+ const baseImageHeight = containerHeight;
986
+ const scale = getAreaScale({
987
+ baseImageWidth,
988
+ baseImageHeight,
989
+ containerWidth,
990
+ containerHeight,
991
+ areaRect,
992
+ areaZoom,
993
+ initialScale
994
+ });
995
+ const [translateX, translateY] = center({
996
+ baseImageWidth,
997
+ baseImageHeight,
998
+ containerWidth,
999
+ containerHeight,
1000
+ rect: areaRect,
1001
+ scale
1002
+ });
1003
+ return {
1004
+ wrapper: {
1005
+ x: translateX,
1006
+ y: translateY,
1007
+ scale
1008
+ },
1009
+ indicators: transformIndicators({
1010
+ indicatorPositions,
1011
+ baseImageWidth,
1012
+ baseImageHeight,
1013
+ translateX,
1014
+ translateY,
1015
+ scale
1016
+ })
1017
+ };
1018
+ }
1019
+ function transformIndicators({
1020
+ indicatorPositions,
1021
+ baseImageWidth,
1022
+ baseImageHeight,
1023
+ translateX,
1024
+ translateY,
1025
+ scale
1026
+ }) {
1027
+ return indicatorPositions.map(indicatorPosition => ({
1028
+ x: translateX + baseImageWidth * indicatorPosition[0] / 100 * (scale - 1),
1029
+ y: translateY + baseImageHeight * indicatorPosition[1] / 100 * (scale - 1)
1030
+ }));
1031
+ }
1032
+ function getAreaScale({
1033
+ containerWidth,
1034
+ containerHeight,
1035
+ baseImageWidth,
1036
+ baseImageHeight,
1037
+ areaRect,
1038
+ areaZoom,
1039
+ initialScale = 1
1040
+ }) {
1041
+ const scale = getScaleToContainRectInContainer({
1042
+ containerWidth,
1043
+ containerHeight,
1044
+ baseImageWidth,
1045
+ baseImageHeight,
1046
+ rect: areaRect
1047
+ });
1048
+ return (100 - areaZoom) / 100 * initialScale + areaZoom / 100 * scale;
1049
+ }
1050
+ function getScaleToCoverContainerWithRect({
1051
+ containerWidth,
1052
+ containerHeight,
1053
+ baseImageWidth,
1054
+ baseImageHeight,
1055
+ rect
1056
+ }) {
1057
+ const [scaleX, scaleY] = getScalesToFit({
1058
+ containerWidth,
1059
+ containerHeight,
1060
+ baseImageWidth,
1061
+ baseImageHeight,
1062
+ rect
1063
+ });
1064
+ return Math.max(scaleX, scaleY);
1065
+ }
1066
+ function getScaleToContainRectInContainer({
1067
+ containerWidth,
1068
+ containerHeight,
1069
+ baseImageWidth,
1070
+ baseImageHeight,
1071
+ rect
1072
+ }) {
1073
+ const [scaleX, scaleY] = getScalesToFit({
1074
+ containerWidth,
1075
+ containerHeight,
1076
+ baseImageWidth,
1077
+ baseImageHeight,
1078
+ rect
1079
+ });
1080
+ return Math.min(scaleX, scaleY);
1081
+ }
1082
+ function getScalesToFit({
1083
+ containerWidth,
1084
+ containerHeight,
1085
+ baseImageWidth,
1086
+ baseImageHeight,
1087
+ rect
1088
+ }) {
1089
+ const baseRectWidth = rect.width / 100 * baseImageWidth;
1090
+ const baseRectHeight = rect.height / 100 * baseImageHeight;
1091
+ return [containerWidth / baseRectWidth, containerHeight / baseRectHeight];
1092
+ }
1093
+ function center({
1094
+ baseImageWidth,
1095
+ baseImageHeight,
1096
+ containerWidth,
1097
+ containerHeight,
1098
+ unbounded,
1099
+ rect,
1100
+ scale
1101
+ }) {
1102
+ const displayImageWidth = baseImageWidth * scale;
1103
+ const displayImageHeight = baseImageHeight * scale;
1104
+ const displayRectWidth = rect.width / 100 * displayImageWidth;
1105
+ const displayRectLeft = rect.left / 100 * displayImageWidth;
1106
+ const displayRectHeight = rect.height / 100 * displayImageHeight;
1107
+ const displayRectTop = rect.top / 100 * displayImageHeight;
1108
+ let translateX;
1109
+ let translateY;
1110
+ if (displayImageWidth < containerWidth) {
1111
+ translateX = (containerWidth - displayImageWidth) / 2;
1112
+ } else {
1113
+ translateX = (containerWidth - displayRectWidth) / 2 - displayRectLeft;
1114
+ if (!unbounded) {
1115
+ translateX = Math.min(0, Math.max(containerWidth - displayImageWidth, translateX));
1116
+ }
1117
+ }
1118
+ if (displayImageHeight < containerHeight) {
1119
+ translateY = (containerHeight - displayImageHeight) / 2;
1120
+ } else {
1121
+ translateY = (containerHeight - displayRectHeight) / 2 - displayRectTop;
1122
+ if (!unbounded) {
1123
+ translateY = Math.min(0, Math.max(containerHeight - displayImageHeight, translateY));
1124
+ }
1125
+ }
1126
+ return [translateX, translateY];
1127
+ }
1128
+
1129
+ function usePanZoomTransforms({
1130
+ containerRect,
1131
+ imageFile,
1132
+ areas,
1133
+ initialTransformEnabled,
1134
+ panZoomEnabled
1135
+ }) {
1136
+ const imageFileWidth = imageFile === null || imageFile === void 0 ? void 0 : imageFile.width;
1137
+ const imageFileHeight = imageFile === null || imageFile === void 0 ? void 0 : imageFile.height;
1138
+ const containerWidth = containerRect.width;
1139
+ const containerHeight = containerRect.height;
1140
+ return useMemo(() => {
1141
+ if (!panZoomEnabled && !initialTransformEnabled || !containerWidth || !containerHeight || !imageFileWidth || !imageFileHeight) {
1142
+ return nullTransforms;
1143
+ }
1144
+ const indicatorPositions = areas.map(area => area.indicatorPosition);
1145
+ const areasBoundingRect = getBoundingRect(areas.flatMap(area => area.outline));
1146
+ const initialTransform = initialTransformEnabled ? getInitialTransform({
1147
+ areasBoundingRect,
1148
+ imageFileWidth,
1149
+ imageFileHeight,
1150
+ containerWidth,
1151
+ containerHeight,
1152
+ indicatorPositions,
1153
+ containerSafeAreaMargin: getContainerSafeAreaMargin({
1154
+ panZoomEnabled,
1155
+ areasBoundingRect
1156
+ })
1157
+ }) : nullTransform;
1158
+ const initialTransformString = toString(initialTransform.wrapper);
1159
+ const areaTransformStrings = [];
1160
+ const tooltipTransformStrings = [];
1161
+ areas.forEach((area, index) => {
1162
+ if (panZoomEnabled) {
1163
+ var _initialTransform$wra;
1164
+ const transform = getPanZoomStepTransform({
1165
+ areaOutline: area.outline,
1166
+ areaZoom: area.zoom,
1167
+ initialScale: ((_initialTransform$wra = initialTransform.wrapper) === null || _initialTransform$wra === void 0 ? void 0 : _initialTransform$wra.scale) || 1,
1168
+ imageFileWidth,
1169
+ imageFileHeight,
1170
+ containerWidth,
1171
+ containerHeight,
1172
+ indicatorPositions
1173
+ });
1174
+ const transformString = toString(transform.wrapper);
1175
+ areaTransformStrings.push({
1176
+ wrapper: transformString,
1177
+ indicators: transform.indicators.map(toString)
1178
+ });
1179
+ tooltipTransformStrings.push(transformString);
1180
+ } else {
1181
+ tooltipTransformStrings.push(initialTransformString);
1182
+ }
1183
+ });
1184
+ return {
1185
+ initial: {
1186
+ wrapper: initialTransformString,
1187
+ indicators: initialTransform.indicators.map(toString),
1188
+ tooltips: tooltipTransformStrings
1189
+ },
1190
+ areas: areaTransformStrings
1191
+ };
1192
+ }, [panZoomEnabled, initialTransformEnabled, containerWidth, containerHeight, imageFileWidth, imageFileHeight, areas]);
1193
+ }
1194
+ const pagerButtonsMargin = 8;
1195
+ function getContainerSafeAreaMargin({
1196
+ panZoomEnabled,
1197
+ areasBoundingRect
1198
+ }) {
1199
+ return panZoomEnabled && insideSafeArea(areasBoundingRect) ? pagerButtonsMargin : 0;
1200
+ }
1201
+ function insideSafeArea(rect) {
1202
+ return rect.left >= pagerButtonsMargin && rect.left + rect.width <= 100 - pagerButtonsMargin;
1203
+ }
1204
+ function toString(transform) {
1205
+ return transform && `translate(${transform.x}px, ${transform.y}px) scale(${transform.scale || 1})`;
1206
+ }
1207
+ const nullTransforms = {
1208
+ initial: {
1209
+ indicators: [],
1210
+ tooltips: []
1211
+ },
1212
+ areas: []
1213
+ };
1214
+ const nullTransform = {
1215
+ indicators: []
1216
+ };
1217
+
1218
+ function useIntersectionObserver({
1219
+ threshold,
1220
+ onVisibleIndexChange,
1221
+ enabled
1222
+ }) {
1223
+ const containerRef = useRef();
1224
+ const childRefs = useRef([]);
1225
+ const observerRef = useRef();
1226
+ useEffect(() => {
1227
+ if (!enabled) {
1228
+ return;
1229
+ }
1230
+ const observer = observerRef.current = new IntersectionObserver(entries => {
1231
+ const containerElement = containerRef.current;
1232
+ if (!containerElement) {
1233
+ return;
1234
+ }
1235
+ let found = false;
1236
+ entries.forEach(entry => {
1237
+ const entryIndex = Array.from(containerElement.children).findIndex(child => child === entry.target);
1238
+ if (entry.isIntersecting && entry.intersectionRatio >= threshold) {
1239
+ found = true;
1240
+ onVisibleIndexChange(entryIndex);
1241
+ }
1242
+ });
1243
+ if (!found) {
1244
+ onVisibleIndexChange(-1);
1245
+ }
1246
+ }, {
1247
+ root: containerRef.current,
1248
+ threshold
1249
+ });
1250
+ childRefs.current.forEach(child => {
1251
+ if (child) {
1252
+ observer.observe(child);
1253
+ }
1254
+ });
1255
+ return () => {
1256
+ observer.disconnect();
1257
+ };
1258
+ }, [enabled, threshold, onVisibleIndexChange]);
1259
+ const setChildRef = index => ref => {
1260
+ if (observerRef.current) {
1261
+ if (ref) {
1262
+ observerRef.current.observe(ref);
1263
+ } else {
1264
+ observerRef.current.unobserve(childRefs.current[index]);
1265
+ }
1266
+ }
1267
+ childRefs.current[index] = ref;
1268
+ };
1269
+ return [containerRef, setChildRef];
1270
+ }
1271
+
1272
+ function useScrollPanZoom({
1273
+ panZoomTransforms,
1274
+ enabled,
1275
+ onChange
1276
+ }) {
1277
+ const wrapperRef = useRef();
1278
+ const scrollerAreasRef = useRef();
1279
+ const indicatorRefs = useRef([]);
1280
+ const onVisibleIndexChange = useCallback(index => onChange(index - 1), [onChange]);
1281
+ const [scrollerRef, setStepRef] = useIntersectionObserver({
1282
+ enabled,
1283
+ threshold: 0.7,
1284
+ onVisibleIndexChange
1285
+ });
1286
+ const steps = useMemo(() => {
1287
+ if (!enabled || !panZoomTransforms.areas.length) {
1288
+ return;
1289
+ }
1290
+ return [panZoomTransforms.initial, ...panZoomTransforms.areas, panZoomTransforms.initial];
1291
+ }, [panZoomTransforms, enabled]);
1292
+ const scrollFromToArea = useCallback((from, to) => {
1293
+ const scroller = scrollerRef.current;
1294
+ const step = scroller.children[to + 1];
1295
+ scroller.scrollTo(Math.abs(scroller.offsetLeft - step.offsetLeft), 0);
1296
+ if (!steps) {
1297
+ return;
1298
+ }
1299
+ wrapperRef.current.animate([keyframe(steps[from + 1].wrapper), keyframe(steps[to + 1].wrapper)], {
1300
+ duration: 200
1301
+ });
1302
+ panZoomTransforms.areas.forEach((_, index) => {
1303
+ indicatorRefs.current[index].animate([keyframe(steps[from + 1].indicators[index]), keyframe(steps[to + 1].indicators[index])], {
1304
+ duration: 200
1305
+ });
1306
+ });
1307
+ }, [scrollerRef, steps, panZoomTransforms]);
1308
+ useIsomorphicLayoutEffect(() => {
1309
+ if (!steps) {
1310
+ return;
1311
+ }
1312
+ const scrollTimeline = new window.ScrollTimeline({
1313
+ source: scrollerRef.current,
1314
+ axis: 'inline'
1315
+ });
1316
+ const animations = [];
1317
+ [wrapperRef.current, scrollerAreasRef.current].forEach(element => animations.push(element.animate(steps.map(step => keyframe(step.wrapper)), {
1318
+ fill: 'both',
1319
+ timeline: scrollTimeline
1320
+ })));
1321
+ panZoomTransforms.areas.forEach((_, index) => {
1322
+ animations.push(indicatorRefs.current[index].animate(steps.map(step => keyframe(step.indicators[index])), {
1323
+ fill: 'both',
1324
+ timeline: scrollTimeline
1325
+ }));
1326
+ });
1327
+ return () => animations.forEach(animation => animation.cancel());
1328
+ }, [panZoomTransforms, steps]);
1329
+ const setIndicatorRef = index => ref => {
1330
+ indicatorRefs.current[index] = ref;
1331
+ };
1332
+ return {
1333
+ panZoomRefs: {
1334
+ wrapper: wrapperRef,
1335
+ scroller: scrollerRef,
1336
+ scrollerAreas: scrollerAreasRef,
1337
+ setStep: setStepRef,
1338
+ setIndicator: setIndicatorRef
1339
+ },
1340
+ scrollFromToArea
1341
+ };
1342
+ }
1343
+ function keyframe(transform) {
1344
+ return {
1345
+ transform: transform || 'translate(0px, 0px)',
1346
+ easing: 'ease'
1347
+ };
1348
+ }
1349
+
1350
+ var styles$7 = {"tooltipsWrapper":"Hotspots-module_tooltipsWrapper__3EEZA","clip":"Hotspots-module_clip__2wfxm","stack":"Hotspots-module_stack__3Vpw6","letterboxBackground":"Hotspots-module_letterboxBackground__3GNSI","wrapper":"Hotspots-module_wrapper__1TvVX","compositeItem":"Hotspots-module_compositeItem__BZtU-"};
1351
+
1352
+ var _jsxFileName$7 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/Hotspots.js";
1353
+ function Hotspots({
1354
+ contentElementId,
1355
+ contentElementWidth,
1356
+ customMargin,
1357
+ configuration,
1358
+ sectionProps = {}
1359
+ }) {
1360
+ return /*#__PURE__*/React.createElement(FullscreenViewer, {
1361
+ contentElementId: contentElementId,
1362
+ renderChildren: ({
1363
+ enterFullscreen
1364
+ }) => /*#__PURE__*/React.createElement(HotspotsImage, {
1365
+ contentElementId: contentElementId,
1366
+ contentElementWidth: contentElementWidth,
1367
+ customMargin: customMargin,
1368
+ configuration: configuration,
1369
+ isIntersecting: sectionProps.isIntersecting,
1370
+ displayFullscreenToggle: contentElementWidth !== contentElementWidths.full && configuration.enableFullscreen,
1371
+ keepTooltipsInViewport: configuration.position === 'backdrop',
1372
+ onFullscreenEnter: enterFullscreen,
1373
+ floatingStrategy: configuration.position === 'standAlone' || configuration.position === 'backdrop' ? 'fixed' : 'absolute',
1374
+ __self: this,
1375
+ __source: {
1376
+ fileName: _jsxFileName$7,
1377
+ lineNumber: 41,
1378
+ columnNumber: 9
1379
+ }
1380
+ }, children => /*#__PURE__*/React.createElement(ContentElementBox, {
1381
+ configuration: configuration,
1382
+ __self: this,
1383
+ __source: {
1384
+ fileName: _jsxFileName$7,
1385
+ lineNumber: 54,
1386
+ columnNumber: 13
1387
+ }
1388
+ }, /*#__PURE__*/React.createElement(ContentElementFigure, {
1389
+ configuration: configuration,
1390
+ __self: this,
1391
+ __source: {
1392
+ fileName: _jsxFileName$7,
1393
+ lineNumber: 55,
1394
+ columnNumber: 15
1395
+ }
1396
+ }, /*#__PURE__*/React.createElement("div", {
1397
+ className: styles$7.clip,
1398
+ __self: this,
1399
+ __source: {
1400
+ fileName: _jsxFileName$7,
1401
+ lineNumber: 56,
1402
+ columnNumber: 17
1403
+ }
1404
+ }, children)))),
1405
+ renderFullscreenChildren: () => /*#__PURE__*/React.createElement(HotspotsImage, {
1406
+ contentElementId: contentElementId,
1407
+ contentElementWidth: contentElementWidth,
1408
+ configuration: configuration,
1409
+ displayFullscreenToggle: false,
1410
+ keepTooltipsInViewport: true,
1411
+ tooltipsAboveNavigationWidgets: true,
1412
+ __self: this,
1413
+ __source: {
1414
+ fileName: _jsxFileName$7,
1415
+ lineNumber: 65,
1416
+ columnNumber: 9
1417
+ }
1418
+ }),
1419
+ __self: this,
1420
+ __source: {
1421
+ fileName: _jsxFileName$7,
1422
+ lineNumber: 38,
1423
+ columnNumber: 5
1424
+ }
1425
+ });
1426
+ }
1427
+ function HotspotsImage({
1428
+ contentElementId,
1429
+ contentElementWidth,
1430
+ customMargin,
1431
+ configuration,
1432
+ keepTooltipsInViewport,
1433
+ floatingStrategy,
1434
+ tooltipsAboveNavigationWidgets,
1435
+ isIntersecting,
1436
+ displayFullscreenToggle,
1437
+ onFullscreenEnter,
1438
+ children = children => children
1439
+ }) {
1440
+ const {
1441
+ imageFile,
1442
+ areas,
1443
+ panZoomEnabled
1444
+ } = useHotspotsConfiguration(configuration);
1445
+ const {
1446
+ activeIndex,
1447
+ hoveredIndex,
1448
+ highlightedIndex,
1449
+ setActiveIndex,
1450
+ setHoveredIndex,
1451
+ setHighlightedIndex
1452
+ } = useHotspotsState({
1453
+ areas,
1454
+ initialActiveArea: configuration.initialActiveArea
1455
+ });
1456
+ const {
1457
+ shouldLoad
1458
+ } = useContentElementLifecycle();
1459
+ const {
1460
+ isEditable,
1461
+ isSelected
1462
+ } = useContentElementEditorState();
1463
+ const aspectRatio = imageFile ? `${imageFile.width} / ${imageFile.height}` : '4 / 3';
1464
+ const [containerRect, containerRef] = useContentRect({
1465
+ enabled: shouldLoad
1466
+ });
1467
+ const panZoomTransforms = usePanZoomTransforms({
1468
+ containerRect,
1469
+ imageFile,
1470
+ areas,
1471
+ initialTransformEnabled: configuration.position === 'backdrop',
1472
+ panZoomEnabled
1473
+ });
1474
+ const {
1475
+ panZoomRefs,
1476
+ scrollFromToArea
1477
+ } = useScrollPanZoom({
1478
+ panZoomTransforms,
1479
+ enabled: shouldLoad,
1480
+ onChange: setActiveIndex
1481
+ });
1482
+ const scrollToArea = useCallback(index => {
1483
+ scrollFromToArea(activeIndex, index);
1484
+ }, [scrollFromToArea, activeIndex]);
1485
+ const activateArea = panZoomEnabled ? scrollToArea : setActiveIndex;
1486
+ useHotspotsEditorCommandSubscriptions({
1487
+ setHighlightedIndex,
1488
+ activateArea
1489
+ });
1490
+ function renderVisibleAreas() {
1491
+ return areas.map((area, index) => /*#__PURE__*/React.createElement(ImageArea, {
1492
+ key: index,
1493
+ area: area,
1494
+ panZoomEnabled: panZoomEnabled,
1495
+ activeImageVisible: activeIndex === index || !panZoomEnabled && activeIndex < 0 && hoveredIndex === index,
1496
+ outlined: isEditable && isSelected,
1497
+ outlineHidden: isIntersecting,
1498
+ highlighted: hoveredIndex === index || highlightedIndex === index || activeIndex === index,
1499
+ __self: this,
1500
+ __source: {
1501
+ fileName: _jsxFileName$7,
1502
+ lineNumber: 131,
1503
+ columnNumber: 7
1504
+ }
1505
+ }));
1506
+ }
1507
+ function renderClickableAreas() {
1508
+ return areas.map((area, index) => /*#__PURE__*/React.createElement(Area, {
1509
+ key: index,
1510
+ area: area,
1511
+ noPointerEvents: panZoomEnabled && activeIndex >= 0 && activeIndex < areas.length,
1512
+ onMouseEnter: () => setHoveredIndex(index),
1513
+ onMouseLeave: () => setHoveredIndex(-1),
1514
+ onClick: () => {
1515
+ if (!isEditable || isSelected) {
1516
+ activateArea(index);
1517
+ }
1518
+ },
1519
+ __self: this,
1520
+ __source: {
1521
+ fileName: _jsxFileName$7,
1522
+ lineNumber: 148,
1523
+ columnNumber: 7
1524
+ }
1525
+ }));
1526
+ }
1527
+ function renderIndicators() {
1528
+ return areas.map((area, index) => /*#__PURE__*/React.createElement(Indicator, {
1529
+ key: index,
1530
+ area: area,
1531
+ hidden: isIntersecting || panZoomEnabled && activeIndex >= 0 && activeIndex < areas.length && activeIndex !== index,
1532
+ panZoomTransform: panZoomTransforms.initial.indicators[index],
1533
+ outerRef: panZoomRefs.setIndicator(index),
1534
+ __self: this,
1535
+ __source: {
1536
+ fileName: _jsxFileName$7,
1537
+ lineNumber: 165,
1538
+ columnNumber: 7
1539
+ }
1540
+ }));
1541
+ }
1542
+ function renderTooltips() {
1543
+ return areas.map((area, index) => /*#__PURE__*/React.createElement(Tooltip, {
1544
+ key: index,
1545
+ area: area,
1546
+ contentElementId: contentElementId,
1547
+ containerRect: containerRect,
1548
+ imageFile: imageFile,
1549
+ panZoomTransform: panZoomTransforms.initial.tooltips[index],
1550
+ configuration: configuration,
1551
+ visible: !isIntersecting && (activeIndex === index || !panZoomEnabled && activeIndex < 0 && hoveredIndex === index),
1552
+ active: activeIndex === index,
1553
+ keepInViewport: keepTooltipsInViewport,
1554
+ aboveNavigationWidgets: tooltipsAboveNavigationWidgets,
1555
+ wrapperRef: containerRef,
1556
+ floatingStrategy: floatingStrategy,
1557
+ onMouseEnter: () => setHoveredIndex(index),
1558
+ onMouseLeave: () => setHoveredIndex(-1),
1559
+ onClick: () => setActiveIndex(index),
1560
+ onLinkClick: event => {
1561
+ activateArea(-1);
1562
+ setHoveredIndex(-1);
1563
+ event.stopPropagation();
1564
+ },
1565
+ onDismiss: () => activateArea(-1),
1566
+ __self: this,
1567
+ __source: {
1568
+ fileName: _jsxFileName$7,
1569
+ lineNumber: 179,
1570
+ columnNumber: 7
1571
+ }
1572
+ }));
1573
+ }
1574
+ function renderFullscreenToggle() {
1575
+ if (!displayFullscreenToggle) {
1576
+ return null;
1577
+ }
1578
+ return /*#__PURE__*/React.createElement(ToggleFullscreenCornerButton, {
1579
+ isFullscreen: false,
1580
+ onEnter: onFullscreenEnter,
1581
+ __self: this,
1582
+ __source: {
1583
+ fileName: _jsxFileName$7,
1584
+ lineNumber: 212,
1585
+ columnNumber: 7
1586
+ }
1587
+ });
1588
+ }
1589
+ function renderLetterboxBackground() {
1590
+ if (configuration.position !== 'backdrop') {
1591
+ return null;
1592
+ }
1593
+ return /*#__PURE__*/React.createElement("div", {
1594
+ className: styles$7.letterboxBackground,
1595
+ __self: this,
1596
+ __source: {
1597
+ fileName: _jsxFileName$7,
1598
+ lineNumber: 223,
1599
+ columnNumber: 7
1600
+ }
1601
+ }, /*#__PURE__*/React.createElement(Image, {
1602
+ imageFile: imageFile,
1603
+ load: shouldLoad,
1604
+ variant: 'medium',
1605
+ __self: this,
1606
+ __source: {
1607
+ fileName: _jsxFileName$7,
1608
+ lineNumber: 224,
1609
+ columnNumber: 9
1610
+ }
1611
+ }));
1612
+ }
1613
+ return /*#__PURE__*/React.createElement(Pager, {
1614
+ areas: areas,
1615
+ customMargin: customMargin,
1616
+ panZoomEnabled: panZoomEnabled,
1617
+ hideButtons: isIntersecting,
1618
+ activeIndex: activeIndex,
1619
+ activateArea: activateArea,
1620
+ __self: this,
1621
+ __source: {
1622
+ fileName: _jsxFileName$7,
1623
+ lineNumber: 232,
1624
+ columnNumber: 5
1625
+ }
1626
+ }, /*#__PURE__*/React.createElement(FitViewport, {
1627
+ file: imageFile,
1628
+ fallbackAspectRatio: 0.75,
1629
+ fill: configuration.position === 'backdrop',
1630
+ __self: this,
1631
+ __source: {
1632
+ fileName: _jsxFileName$7,
1633
+ lineNumber: 238,
1634
+ columnNumber: 7
1635
+ }
1636
+ }, /*#__PURE__*/React.createElement(Composite, {
1637
+ activeIndex: activeIndex + 1,
1638
+ loop: false,
1639
+ onNavigate: index => activateArea(index - 1),
1640
+ __self: this,
1641
+ __source: {
1642
+ fileName: _jsxFileName$7,
1643
+ lineNumber: 241,
1644
+ columnNumber: 9
1645
+ }
1646
+ }, /*#__PURE__*/React.createElement("div", {
1647
+ className: styles$7.tooltipsWrapper,
1648
+ style: {
1649
+ '--hotspots-image-aspect-ratio': aspectRatio,
1650
+ '--hotspots-container-height': `${containerRect.height}px`
1651
+ },
1652
+ __self: this,
1653
+ __source: {
1654
+ fileName: _jsxFileName$7,
1655
+ lineNumber: 244,
1656
+ columnNumber: 11
1657
+ }
1658
+ }, children( /*#__PURE__*/React.createElement(FitViewport.Content, {
1659
+ __self: this,
1660
+ __source: {
1661
+ fileName: _jsxFileName$7,
1662
+ lineNumber: 248,
1663
+ columnNumber: 15
1664
+ }
1665
+ }, /*#__PURE__*/React.createElement("div", {
1666
+ className: styles$7.stack,
1667
+ ref: containerRef,
1668
+ __self: this,
1669
+ __source: {
1670
+ fileName: _jsxFileName$7,
1671
+ lineNumber: 249,
1672
+ columnNumber: 17
1673
+ }
1674
+ }, /*#__PURE__*/React.createElement(FilePlaceholder, {
1675
+ file: imageFile,
1676
+ __self: this,
1677
+ __source: {
1678
+ fileName: _jsxFileName$7,
1679
+ lineNumber: 251,
1680
+ columnNumber: 19
1681
+ }
1682
+ }), renderLetterboxBackground(), /*#__PURE__*/React.createElement("div", {
1683
+ className: styles$7.wrapper,
1684
+ ref: panZoomRefs.wrapper,
1685
+ style: {
1686
+ transform: panZoomTransforms.initial.wrapper
1687
+ },
1688
+ __self: this,
1689
+ __source: {
1690
+ fileName: _jsxFileName$7,
1691
+ lineNumber: 253,
1692
+ columnNumber: 19
1693
+ }
1694
+ }, /*#__PURE__*/React.createElement(Image, {
1695
+ imageFile: imageFile,
1696
+ load: shouldLoad,
1697
+ fill: false,
1698
+ structuredData: true,
1699
+ variant: panZoomEnabled ? 'ultra' : 'large',
1700
+ preferSvg: true,
1701
+ __self: this,
1702
+ __source: {
1703
+ fileName: _jsxFileName$7,
1704
+ lineNumber: 256,
1705
+ columnNumber: 21
1706
+ }
1707
+ }), renderVisibleAreas()), /*#__PURE__*/React.createElement(Scroller, {
1708
+ disabled: !panZoomEnabled,
1709
+ areas: areas,
1710
+ ref: panZoomRefs.scroller,
1711
+ setStepRef: panZoomRefs.setStep,
1712
+ __self: this,
1713
+ __source: {
1714
+ fileName: _jsxFileName$7,
1715
+ lineNumber: 264,
1716
+ columnNumber: 19
1717
+ }
1718
+ }, /*#__PURE__*/React.createElement("div", {
1719
+ className: styles$7.wrapper,
1720
+ ref: panZoomRefs.scrollerAreas,
1721
+ style: {
1722
+ transform: panZoomTransforms.initial.wrapper
1723
+ },
1724
+ __self: this,
1725
+ __source: {
1726
+ fileName: _jsxFileName$7,
1727
+ lineNumber: 268,
1728
+ columnNumber: 21
1729
+ }
1730
+ }, renderClickableAreas())), renderIndicators()), renderFullscreenToggle(), /*#__PURE__*/React.createElement(InlineFileRights, {
1731
+ configuration: configuration,
1732
+ context: "insideElement",
1733
+ items: [{
1734
+ file: imageFile,
1735
+ label: 'image'
1736
+ }],
1737
+ __self: this,
1738
+ __source: {
1739
+ fileName: _jsxFileName$7,
1740
+ lineNumber: 277,
1741
+ columnNumber: 17
1742
+ }
1743
+ }))), /*#__PURE__*/React.createElement(CompositeItem, {
1744
+ render: /*#__PURE__*/React.createElement("div", {
1745
+ className: styles$7.compositeItem,
1746
+ __self: this,
1747
+ __source: {
1748
+ fileName: _jsxFileName$7,
1749
+ lineNumber: 282,
1750
+ columnNumber: 36
1751
+ }
1752
+ }),
1753
+ __self: this,
1754
+ __source: {
1755
+ fileName: _jsxFileName$7,
1756
+ lineNumber: 282,
1757
+ columnNumber: 13
1758
+ }
1759
+ }), renderTooltips(), /*#__PURE__*/React.createElement(CompositeItem, {
1760
+ render: /*#__PURE__*/React.createElement("div", {
1761
+ className: styles$7.compositeItem,
1762
+ __self: this,
1763
+ __source: {
1764
+ fileName: _jsxFileName$7,
1765
+ lineNumber: 284,
1766
+ columnNumber: 36
1767
+ }
1768
+ }),
1769
+ __self: this,
1770
+ __source: {
1771
+ fileName: _jsxFileName$7,
1772
+ lineNumber: 284,
1773
+ columnNumber: 13
1774
+ }
1775
+ }))), /*#__PURE__*/React.createElement(InlineFileRights, {
1776
+ configuration: configuration,
1777
+ context: "afterElement",
1778
+ items: [{
1779
+ file: imageFile,
1780
+ label: 'image'
1781
+ }],
1782
+ __self: this,
1783
+ __source: {
1784
+ fileName: _jsxFileName$7,
1785
+ lineNumber: 287,
1786
+ columnNumber: 9
1787
+ }
1788
+ })));
1789
+ }
1790
+
1791
+ frontend.contentElementTypes.register('hotspots', {
1792
+ component: Hotspots,
1793
+ lifecycle: true,
1794
+ customMargin: true
1795
+ });