pageflow 17.1.0 → 17.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +319 -345
  3. data/README.md +3 -4
  4. data/admins/pageflow/accounts.rb +6 -6
  5. data/admins/pageflow/entry.rb +10 -8
  6. data/admins/pageflow/membership.rb +11 -11
  7. data/admins/pageflow/translations.rb +5 -5
  8. data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
  9. data/app/assets/javascripts/pageflow/dist/ui.js +1350 -630
  10. data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
  11. data/app/assets/javascripts/pageflow/ui.js +0 -1
  12. data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
  13. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -1
  14. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  15. data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
  16. data/app/assets/stylesheets/pageflow/animations.scss +1 -0
  17. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +21 -5
  18. data/app/assets/stylesheets/pageflow/editor/base.scss +9 -1
  19. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +13 -1
  20. data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
  21. data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
  22. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +0 -1
  23. data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
  24. data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
  25. data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
  26. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
  27. data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
  28. data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
  29. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
  30. data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
  31. data/app/assets/stylesheets/pageflow/editor/files.scss +230 -50
  32. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +142 -14
  33. data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
  34. data/app/assets/stylesheets/pageflow/editor/info_box.scss +12 -0
  35. data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
  36. data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
  37. data/app/assets/stylesheets/pageflow/editor/list.scss +88 -38
  38. data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
  39. data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
  40. data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
  41. data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
  42. data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
  43. data/app/assets/stylesheets/pageflow/ui/forms.scss +34 -4
  44. data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
  45. data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -16
  46. data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
  47. data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
  48. data/app/assets/stylesheets/pageflow/ui/properties.scss +29 -0
  49. data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
  50. data/app/assets/stylesheets/pageflow/ui.scss +4 -2
  51. data/app/controllers/pageflow/editor/entries_controller.rb +1 -0
  52. data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
  53. data/app/controllers/pageflow/editor/file_import_controller.rb +1 -0
  54. data/app/controllers/pageflow/editor/files_controller.rb +15 -6
  55. data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
  56. data/app/controllers/pageflow/entries_controller.rb +17 -13
  57. data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
  58. data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
  59. data/app/controllers/pageflow/review/comments_controller.rb +53 -0
  60. data/app/controllers/pageflow/revisions_controller.rb +4 -1
  61. data/app/helpers/pageflow/admin/entries_helper.rb +40 -0
  62. data/app/helpers/pageflow/admin/widgets_helper.rb +2 -2
  63. data/app/helpers/pageflow/common_entry_seed_helper.rb +5 -3
  64. data/app/helpers/pageflow/editor/config_helper.rb +3 -1
  65. data/app/helpers/pageflow/entries_helper.rb +24 -42
  66. data/app/helpers/pageflow/entry_json_seed_helper.rb +4 -4
  67. data/app/helpers/pageflow/public_i18n_helper.rb +9 -8
  68. data/app/helpers/pageflow/structured_data_helper.rb +4 -1
  69. data/app/helpers/pageflow/themes_helper.rb +1 -3
  70. data/app/helpers/pageflow/widgets_helper.rb +2 -1
  71. data/app/inputs/pageflow_permalink_input.rb +6 -2
  72. data/app/models/concerns/pageflow/auto_generated_perma_id.rb +11 -4
  73. data/app/models/concerns/pageflow/reusable_file.rb +1 -1
  74. data/app/models/concerns/pageflow/serialization_blacklist.rb +2 -4
  75. data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
  76. data/app/models/concerns/pageflow/uploadable_file.rb +1 -1
  77. data/app/models/pageflow/comment.rb +30 -0
  78. data/app/models/pageflow/comment_thread.rb +65 -0
  79. data/app/models/pageflow/comment_thread_read.rb +22 -0
  80. data/app/models/pageflow/customized_theme.rb +3 -2
  81. data/app/models/pageflow/draft_entry.rb +20 -8
  82. data/app/models/pageflow/entry.rb +2 -0
  83. data/app/models/pageflow/entry_at_revision.rb +9 -1
  84. data/app/models/pageflow/entry_comment_summary.rb +114 -0
  85. data/app/models/pageflow/file_folder.rb +74 -0
  86. data/app/models/pageflow/file_reuse.rb +3 -2
  87. data/app/models/pageflow/file_usage.rb +8 -0
  88. data/app/models/pageflow/image_file.rb +24 -20
  89. data/app/models/pageflow/image_file_url_templates.rb +3 -3
  90. data/app/models/pageflow/legal_info.rb +38 -0
  91. data/app/models/pageflow/nested_revision_component_copy.rb +1 -1
  92. data/app/models/pageflow/permalink.rb +1 -0
  93. data/app/models/pageflow/revision.rb +6 -2
  94. data/app/models/pageflow/site.rb +10 -0
  95. data/app/models/pageflow/used_file.rb +8 -2
  96. data/app/models/pageflow/widget.rb +2 -2
  97. data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
  98. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +4 -2
  99. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
  100. data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
  101. data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
  102. data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
  103. data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
  104. data/app/views/pageflow/editor/files/_file.json.jbuilder +2 -1
  105. data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
  106. data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +3 -0
  107. data/app/views/pageflow/files/_file.json.jbuilder +2 -0
  108. data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
  109. data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
  110. data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
  111. data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
  112. data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
  113. data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
  114. data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
  115. data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
  116. data/config/locales/de.yml +152 -14
  117. data/config/locales/en.yml +150 -14
  118. data/config/routes.rb +14 -0
  119. data/db/migrate/20140418225525_setup_schema.rb +2 -2
  120. data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
  121. data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
  122. data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
  123. data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
  124. data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
  125. data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
  126. data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
  127. data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
  128. data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
  129. data/db/migrate/20260728000000_create_file_folders.rb +17 -0
  130. data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
  131. data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
  132. data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
  133. data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
  134. data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
  135. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +8665 -3890
  136. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +979 -3571
  137. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20199 -28120
  138. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18652 -26584
  139. data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
  140. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +33 -3
  141. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -3
  142. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +21 -1
  143. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
  144. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +7 -5
  145. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +5 -2
  146. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +13 -5
  147. data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
  148. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +26 -11
  149. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +2 -2
  150. data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
  151. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +174 -3
  152. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +49 -7
  153. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
  154. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
  155. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +1 -0
  156. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +13 -12
  157. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +30 -10
  158. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +9 -0
  159. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
  160. data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
  161. data/entry_types/scrolled/config/locales/de.yml +512 -65
  162. data/entry_types/scrolled/config/locales/en.yml +518 -52
  163. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
  164. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +51 -6
  165. data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
  166. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
  167. data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
  168. data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
  169. data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
  170. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +205 -22
  171. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
  172. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +56 -36
  173. data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
  174. data/entry_types/scrolled/lib/pageflow_scrolled.rb +13 -0
  175. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +19 -1
  176. data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
  177. data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
  178. data/entry_types/scrolled/package/config/webpack.js +72 -0
  179. data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -1
  180. data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1181 -915
  181. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
  182. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
  183. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
  184. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
  185. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
  186. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
  187. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +71 -21
  188. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
  189. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
  190. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
  191. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
  192. data/entry_types/scrolled/package/contentElements-editor.js +1915 -1097
  193. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  194. data/entry_types/scrolled/package/contentElements-frontend.js +3093 -1679
  195. data/entry_types/scrolled/package/editor.css +1 -0
  196. data/entry_types/scrolled/package/editor.js +8667 -4077
  197. data/entry_types/scrolled/package/entryState.js +1600 -0
  198. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
  199. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
  200. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9f76033e.js → PhonePlatformContext-035a99fa.js} +7 -12
  201. data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
  202. data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
  203. data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
  204. data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
  205. data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
  206. data/entry_types/scrolled/package/frontend/{ToggleFullscreenCornerButton-788e9cdb.js → ToggleFullscreenCornerButton-30fd1124.js} +6 -6
  207. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
  208. data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
  209. data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
  210. data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
  211. data/entry_types/scrolled/package/frontend/{Viewer-0345ce57.js → Viewer-cc8d4072.js} +84 -92
  212. data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
  213. data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
  214. data/entry_types/scrolled/package/frontend/commenting.css +1 -0
  215. data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
  216. data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
  217. data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
  218. data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
  219. data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
  220. data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
  221. data/entry_types/scrolled/package/frontend/{index-eb670c2f.js → index-2e5546f7.js} +36 -44
  222. data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
  223. data/entry_types/scrolled/package/frontend/index.css +1 -1
  224. data/entry_types/scrolled/package/frontend/index.js +1870 -875
  225. data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
  226. data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
  227. data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
  228. data/entry_types/scrolled/package/frontend/{usePhonePlatform-c2ba875d.js → usePhonePlatform-4ecb96d4.js} +1 -1
  229. data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
  230. data/entry_types/scrolled/package/frontend-server.js +20 -209
  231. data/entry_types/scrolled/package/package.json +5 -3
  232. data/entry_types/scrolled/package/review.css +1 -0
  233. data/entry_types/scrolled/package/review.js +3306 -0
  234. data/entry_types/scrolled/package/testHelpers.js +836 -359
  235. data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
  236. data/entry_types/scrolled/package/widgets/consentBar.js +269 -290
  237. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  238. data/entry_types/scrolled/package/widgets/defaultNavigation.js +911 -352
  239. data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -1
  240. data/entry_types/scrolled/package/widgets/excursionSheet.js +87 -124
  241. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
  242. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -29
  243. data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +32 -13
  244. data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -1
  245. data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +56 -100
  246. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
  247. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +33 -28
  248. data/entry_types/scrolled/package/widgets-server.js +1 -0
  249. data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
  250. data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
  251. data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
  252. data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
  253. data/lib/generators/pageflow/resque/resque_generator.rb +0 -2
  254. data/lib/pageflow/configuration.rb +49 -7
  255. data/lib/pageflow/deprecation.rb +19 -0
  256. data/lib/pageflow/engine.rb +1 -1
  257. data/lib/pageflow/entries_controller_env_helper.rb +32 -2
  258. data/lib/pageflow/entry_export_import/entry_serialization.rb +4 -4
  259. data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
  260. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +10 -0
  261. data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
  262. data/lib/pageflow/entry_structured_data_types.rb +43 -0
  263. data/lib/pageflow/entry_type_configuration.rb +1 -0
  264. data/lib/pageflow/file_type.rb +2 -2
  265. data/lib/pageflow/file_types.rb +1 -1
  266. data/lib/pageflow/oembed_providers.rb +42 -0
  267. data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
  268. data/lib/pageflow/rails_version.rb +13 -2
  269. data/lib/pageflow/themes.rb +41 -0
  270. data/lib/pageflow/user_mixin.rb +12 -0
  271. data/lib/pageflow/version.rb +1 -1
  272. data/lib/pageflow.rb +1 -0
  273. data/package/config/eslint-rules/documented-in-toc.js +125 -0
  274. data/package/config/jest/index.js +0 -1
  275. data/package/config/webpack.js +0 -1
  276. data/package/config/webpack5.js +0 -1
  277. data/package/editor.js +4378 -1897
  278. data/package/frontend.js +647 -886
  279. data/package/package.json +2 -1
  280. data/package/review.js +384 -0
  281. data/package/testHelpers.js +248 -188
  282. data/package/ui.js +1346 -630
  283. data/package/vendor/stubs/wysihtml5.js +2 -0
  284. data/spec/factories/comment_thread_reads.rb +10 -0
  285. data/spec/factories/comment_threads.rb +10 -0
  286. data/spec/factories/comments.rb +9 -0
  287. data/spec/factories/file_folders.rb +8 -0
  288. data/spec/factories/published_entries.rb +2 -0
  289. metadata +188 -67
  290. data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
  291. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
  292. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-51914be7.js +0 -5439
  293. data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +0 -1932
  294. data/entry_types/scrolled/package/frontend/Viewer-cdc549cc.js +0 -147
  295. data/entry_types/scrolled/package/frontend/Wavesurfer-1cdc3925.js +0 -313
  296. data/entry_types/scrolled/package/frontend/components-96660ffd.js +0 -3803
  297. data/entry_types/scrolled/package/frontend/inherits-539844a6.js +0 -99
  298. data/entry_types/scrolled/package/frontend/useContentElementEditorState-77fe6c79.js +0 -51
  299. data/entry_types/scrolled/package/widgets/excursionDialog.css +0 -1
  300. data/entry_types/scrolled/package/widgets/excursionDialog.js +0 -109
  301. data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
  302. data/package/vendor/jquery.minicolors.js +0 -1108
@@ -0,0 +1,1982 @@
1
+ import React, { createContext, useContext, useCallback, useState, useMemo, useRef, useEffect } from 'react';
2
+ import { flushSync } from 'react-dom';
3
+ import classNames from 'classnames';
4
+ import { a as useActiveExcursion, o as useFloatingPortalRoot, d as api, w as widths, g as useContentElementAttributes, U as PlainEditableText, N as renderLeaf, V as textStyles, T as Text, R as renderElement } from './FloatingPortalRootProvider-58189220.js';
5
+ import './useDelayedBoolean-a387d85b.js';
6
+ import 'backbone-events-standalone';
7
+ import { useEntryMetadata } from 'pageflow-scrolled/entryState';
8
+ import 'i18n-js';
9
+ import { u as useI18n } from './i18n-e06cac14.js';
10
+ import 'react-measure';
11
+ import 'prop-types';
12
+ import { review, useCommentDisplayFilter, useLocatedCommentThreads, ActivityList, useUnreadThreadCount, useStoredCommentDisplayFilter, ReviewStateProvider, LocatedCommentThreadsProvider, CommentDisplayFilterProvider, ReviewMessageHandler, ThreadsBadge, ThreadList, useLocatedCommentThreadsForSubject, useAnchoredFloating, useRangeAnchors, useCommentThreads, useCommentHighlights, decorateCommentHighlights, RangeAnchor, commentHighlightStyles } from 'pageflow-scrolled/review';
13
+ import { useFloating, offset, shift, size, autoUpdate, FloatingPortal, flip } from '@floating-ui/react';
14
+ import { Node, Point, createEditor, Editor } from 'slate';
15
+ import { ReactEditor, withReact, Slate, Editable } from 'slate-react';
16
+ import { createReviewSession } from 'pageflow/review';
17
+
18
+ // Headings carry no ranged comments since EditableInlineText has no
19
+ // commenting alternative, so every comment refers to the header as a whole
20
+ // and the quote covers all three of its texts.
21
+ review.contentElementTypes.register('heading', {
22
+ extractQuote(configuration) {
23
+ const parts = [inlineText(configuration.tagline), mainText(configuration), inlineText(configuration.subtitle)];
24
+ return parts.map(part => part.trim()).filter(Boolean).join('\n') || null;
25
+ }
26
+ });
27
+
28
+ // Mirrors how EditableInlineText picks the legacy string value, so the quote
29
+ // never contains text the heading does not display.
30
+ function mainText(configuration) {
31
+ return configuration.value ? inlineText(configuration.value) : configuration.children || '';
32
+ }
33
+ function inlineText(value) {
34
+ return value ? value.map(node => Node.string(node)).join(' ') : '';
35
+ }
36
+
37
+ review.contentElementTypes.register('textBlock', {
38
+ compareRanges(a, b) {
39
+ if (!a && !b) return 0;
40
+ if (!a) return 1;
41
+ if (!b) return -1;
42
+ return Point.compare(rangeStart(a), rangeStart(b));
43
+ },
44
+ // Element wide comments stay unquoted: the whole text is too long to serve
45
+ // as a point of reference, and any edit anywhere in it would mark the quote
46
+ // outdated.
47
+ extractQuote(configuration, range) {
48
+ if (!range) return null;
49
+ const root = {
50
+ children: configuration.value || []
51
+ };
52
+ if (!Node.has(root, range.anchor.path) || !Node.has(root, range.focus.path)) {
53
+ return null;
54
+ }
55
+ const text = Node.fragment(root, range).map(node => Node.string(node)).join('\n').trim();
56
+ return text || null;
57
+ }
58
+ });
59
+ function rangeStart(range) {
60
+ return Point.isBefore(range.anchor, range.focus) ? range.anchor : range.focus;
61
+ }
62
+
63
+ var _jsxFileName = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/SelectedSubjectProvider.js";
64
+ const SelectedSubjectContext = createContext({
65
+ selectedSubject: null,
66
+ setSelectedSubject: () => {},
67
+ clearSelection: () => {}
68
+ });
69
+ const CommentNavigationContext = createContext({
70
+ count: 0,
71
+ position: 0,
72
+ goToNext: () => {},
73
+ goToPrevious: () => {},
74
+ goToThread: () => {}
75
+ });
76
+ function SelectedSubjectProvider({
77
+ children
78
+ }) {
79
+ const {
80
+ resolution
81
+ } = useCommentDisplayFilter();
82
+ const {
83
+ chapters
84
+ } = useLocatedCommentThreads();
85
+ const {
86
+ activateExcursionOfSection,
87
+ returnFromExcursion
88
+ } = useActiveExcursion();
89
+ const [selectedSubject, setSelectedSubject] = useState(null);
90
+ const allTargets = useMemo(() => navigableTargets(chapters), [chapters]);
91
+ const targets = useMemo(() => allTargets.filter(target => matchesResolution(target, resolution)), [allTargets, resolution]);
92
+ const clearSelection = useCallback(() => {
93
+ setSelectedSubject(null);
94
+ }, []);
95
+ const selectTarget = useCallback((target, options) => {
96
+ if (movesToDifferentSubject(selectedSubject, target)) {
97
+ if (target.excursion) {
98
+ activateExcursionOfSection({
99
+ id: target.sectionId
100
+ });
101
+ } else {
102
+ returnFromExcursion();
103
+ }
104
+ }
105
+ setSelectedSubject({
106
+ subjectType: target.subjectType,
107
+ subjectId: target.subjectId,
108
+ subjectRange: target.subjectRange,
109
+ highlightedThreadId: target.threadId,
110
+ ...options
111
+ });
112
+ }, [selectedSubject, activateExcursionOfSection, returnFromExcursion]);
113
+ const goTo = useCallback(step => {
114
+ if (targets.length === 0) {
115
+ return;
116
+ }
117
+ const current = currentTargetIndex(targets, selectedSubject);
118
+ const next = current < 0 ? step > 0 ? 0 : targets.length - 1 : (current + step + targets.length) % targets.length;
119
+ selectTarget(targets[next]);
120
+ }, [targets, selectedSubject, selectTarget]);
121
+ const goToThread = useCallback((threadId, options) => {
122
+ const target = allTargets.find(target => target.threadId === threadId);
123
+ if (target) {
124
+ selectTarget(target, options);
125
+ }
126
+ }, [allTargets, selectTarget]);
127
+ const position = useMemo(() => currentTargetIndex(targets, selectedSubject) + 1, [targets, selectedSubject]);
128
+ const selection = useMemo(() => ({
129
+ selectedSubject,
130
+ setSelectedSubject,
131
+ clearSelection
132
+ }), [selectedSubject, clearSelection]);
133
+ const navigation = useMemo(() => {
134
+ var _selectedSubject$high;
135
+ return {
136
+ count: targets.length,
137
+ position,
138
+ highlightedThreadId: (_selectedSubject$high = selectedSubject === null || selectedSubject === void 0 ? void 0 : selectedSubject.highlightedThreadId) !== null && _selectedSubject$high !== void 0 ? _selectedSubject$high : null,
139
+ goToNext: () => goTo(1),
140
+ goToPrevious: () => goTo(-1),
141
+ goToThread
142
+ };
143
+ }, [targets.length, position, selectedSubject, goTo, goToThread]);
144
+ return /*#__PURE__*/React.createElement(SelectedSubjectContext.Provider, {
145
+ value: selection,
146
+ __self: this,
147
+ __source: {
148
+ fileName: _jsxFileName,
149
+ lineNumber: 99,
150
+ columnNumber: 5
151
+ }
152
+ }, /*#__PURE__*/React.createElement(CommentNavigationContext.Provider, {
153
+ value: navigation,
154
+ __self: this,
155
+ __source: {
156
+ fileName: _jsxFileName,
157
+ lineNumber: 100,
158
+ columnNumber: 7
159
+ }
160
+ }, children));
161
+ }
162
+ function useCommentNavigation() {
163
+ return useContext(CommentNavigationContext);
164
+ }
165
+ function useSelectedSubject(subjectType, subjectId, subjectRange) {
166
+ var _selectedSubject$high2;
167
+ const {
168
+ selectedSubject,
169
+ setSelectedSubject,
170
+ clearSelection
171
+ } = useContext(SelectedSubjectContext);
172
+ const isSelected = selectedSubject && selectedSubject.subjectType === subjectType && selectedSubject.subjectId === subjectId && (!subjectRange || JSON.stringify(selectedSubject.subjectRange) === JSON.stringify(subjectRange));
173
+ const select = useCallback(options => {
174
+ setSelectedSubject({
175
+ subjectType,
176
+ subjectId,
177
+ subjectRange,
178
+ ...options
179
+ });
180
+ }, [setSelectedSubject, subjectType, subjectId, subjectRange]);
181
+ return {
182
+ isSelected,
183
+ hasSelection: !!selectedSubject,
184
+ select,
185
+ clearSelection,
186
+ revealOnly: !!(isSelected && selectedSubject.revealOnly),
187
+ showNewForm: isSelected && selectedSubject.showNewForm,
188
+ subjectRange: isSelected ? selectedSubject.subjectRange : undefined,
189
+ highlightedThreadId: isSelected ? (_selectedSubject$high2 = selectedSubject.highlightedThreadId) !== null && _selectedSubject$high2 !== void 0 ? _selectedSubject$high2 : null : null
190
+ };
191
+ }
192
+ function movesToDifferentSubject(selectedSubject, target) {
193
+ return !selectedSubject || subjectKey(selectedSubject) !== target.key;
194
+ }
195
+ function currentTargetIndex(targets, selectedSubject) {
196
+ if (!selectedSubject) {
197
+ return -1;
198
+ }
199
+ if (selectedSubject.highlightedThreadId != null) {
200
+ return targets.findIndex(target => target.threadId === selectedSubject.highlightedThreadId);
201
+ }
202
+ const key = subjectKey(selectedSubject);
203
+ return targets.findIndex(target => target.key === key);
204
+ }
205
+ function navigableTargets(chapters) {
206
+ const targets = [];
207
+ chapters.forEach(chapter => {
208
+ chapter.sections.forEach(section => {
209
+ const location = {
210
+ sectionId: section.id,
211
+ excursion: chapter.isExcursion
212
+ };
213
+ section.threads.forEach(thread => targets.push({
214
+ key: subjectKey({
215
+ subjectType: 'Section',
216
+ subjectId: section.permaId
217
+ }),
218
+ subjectType: 'Section',
219
+ subjectId: section.permaId,
220
+ threadId: thread.id,
221
+ resolved: !!thread.resolvedAt,
222
+ ...location
223
+ }));
224
+ section.contentElements.forEach(contentElement => {
225
+ pushTargets(targets, contentElement.threads, location);
226
+ });
227
+ });
228
+ });
229
+ return targets;
230
+ }
231
+ function pushTargets(targets, threads, location) {
232
+ threads.forEach(thread => targets.push({
233
+ key: subjectKey(thread),
234
+ subjectType: thread.subjectType,
235
+ subjectId: thread.subjectId,
236
+ subjectRange: thread.subjectRange,
237
+ threadId: thread.id,
238
+ resolved: !!thread.resolvedAt,
239
+ ...location
240
+ }));
241
+ }
242
+ function matchesResolution(target, resolution) {
243
+ return resolution === 'all' || resolution === 'unresolved' && !target.resolved || resolution === 'resolved' && target.resolved;
244
+ }
245
+ function subjectKey({
246
+ subjectType,
247
+ subjectId,
248
+ subjectRange
249
+ }) {
250
+ return `${subjectType}:${subjectId}:${subjectRange ? JSON.stringify(subjectRange) : ''}`;
251
+ }
252
+
253
+ var _jsxFileName$1 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/AddCommentModeProvider.js";
254
+ const AddCommentModeContext = createContext({
255
+ active: false,
256
+ toggle: () => {},
257
+ deactivate: () => {},
258
+ preselect: () => {},
259
+ clearPreselection: () => {}
260
+ });
261
+ function AddCommentModeProvider({
262
+ children
263
+ }) {
264
+ const [active, setActive] = useState(false);
265
+ const preselectionRef = useRef(null);
266
+ const {
267
+ select
268
+ } = useSelectedSubject();
269
+ const toggle = useCallback(() => {
270
+ if (!active && preselectionRef.current) {
271
+ select(preselectionRef.current);
272
+ preselectionRef.current = null;
273
+ return;
274
+ }
275
+ setActive(prev => !prev);
276
+ }, [active, select]);
277
+ const deactivate = useCallback(() => {
278
+ setActive(false);
279
+ }, []);
280
+ const preselect = useCallback(subject => {
281
+ preselectionRef.current = subject;
282
+ }, []);
283
+ const clearPreselection = useCallback(subjectId => {
284
+ var _preselectionRef$curr;
285
+ if (((_preselectionRef$curr = preselectionRef.current) === null || _preselectionRef$curr === void 0 ? void 0 : _preselectionRef$curr.subjectId) === subjectId) {
286
+ preselectionRef.current = null;
287
+ }
288
+ }, []);
289
+ useEffect(() => {
290
+ if (!active) return;
291
+ function handleMouseDown(event) {
292
+ if (!event.target.closest('[data-add-comment-overlay]') && !event.target.closest('[data-add-comment-toggle]')) {
293
+ setActive(false);
294
+ }
295
+ }
296
+ document.addEventListener('mousedown', handleMouseDown);
297
+ return () => {
298
+ document.removeEventListener('mousedown', handleMouseDown);
299
+ };
300
+ }, [active]);
301
+ const value = useMemo(() => ({
302
+ active,
303
+ toggle,
304
+ deactivate,
305
+ preselect,
306
+ clearPreselection
307
+ }), [active, toggle, deactivate, preselect, clearPreselection]);
308
+ return /*#__PURE__*/React.createElement(AddCommentModeContext.Provider, {
309
+ value: value,
310
+ __self: this,
311
+ __source: {
312
+ fileName: _jsxFileName$1,
313
+ lineNumber: 66,
314
+ columnNumber: 5
315
+ }
316
+ }, children);
317
+ }
318
+ function useAddCommentMode() {
319
+ return useContext(AddCommentModeContext);
320
+ }
321
+
322
+ var _jsxFileName$2 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/CommentingVisibilityProvider.js";
323
+ const storageKey = 'pageflow.scrolled.commentingVisible';
324
+ const CommentingVisibilityContext = createContext({
325
+ visible: true,
326
+ toggle: () => {}
327
+ });
328
+ function CommentingVisibilityProvider({
329
+ children
330
+ }) {
331
+ const [visible, setVisible] = useState(readStoredVisibility);
332
+ const toggle = useCallback(() => {
333
+ const next = !visible;
334
+ const flip = () => setVisible(next);
335
+
336
+ // Without flushSync the transition captures the pre-toggle DOM.
337
+ if (document.startViewTransition) {
338
+ document.startViewTransition(() => flushSync(flip));
339
+ } else {
340
+ flip();
341
+ }
342
+ storeVisibility(next);
343
+ }, [visible]);
344
+ const value = useMemo(() => ({
345
+ visible,
346
+ toggle
347
+ }), [visible, toggle]);
348
+ return /*#__PURE__*/React.createElement(CommentingVisibilityContext.Provider, {
349
+ value: value,
350
+ __self: this,
351
+ __source: {
352
+ fileName: _jsxFileName$2,
353
+ lineNumber: 32,
354
+ columnNumber: 5
355
+ }
356
+ }, children);
357
+ }
358
+ function useCommentingVisibility() {
359
+ return useContext(CommentingVisibilityContext);
360
+ }
361
+ function readStoredVisibility() {
362
+ var _getLocalStorage;
363
+ return ((_getLocalStorage = getLocalStorage()) === null || _getLocalStorage === void 0 ? void 0 : _getLocalStorage[storageKey]) !== 'false';
364
+ }
365
+ function storeVisibility(visible) {
366
+ const storage = getLocalStorage();
367
+ if (storage) {
368
+ storage[storageKey] = visible;
369
+ }
370
+ }
371
+ function getLocalStorage() {
372
+ try {
373
+ return typeof window === 'undefined' ? null : window.localStorage;
374
+ } catch (e) {
375
+ // Safari throws SecurityError when accessing window.localStorage
376
+ // if cookies/website data are disabled.
377
+ return null;
378
+ }
379
+ }
380
+
381
+ function _extends() {
382
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
383
+ for (var i = 1; i < arguments.length; i++) {
384
+ var source = arguments[i];
385
+ for (var key in source) {
386
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
387
+ target[key] = source[key];
388
+ }
389
+ }
390
+ }
391
+ return target;
392
+ };
393
+ return _extends.apply(this, arguments);
394
+ }
395
+ var ActivityIcon = (({
396
+ styles = {},
397
+ ...props
398
+ }) => /*#__PURE__*/React.createElement("svg", _extends({
399
+ xmlns: "http://www.w3.org/2000/svg",
400
+ viewBox: "0 0 24 24",
401
+ fill: "none",
402
+ stroke: "currentColor",
403
+ strokeWidth: "2",
404
+ strokeLinecap: "round",
405
+ strokeLinejoin: "round",
406
+ width: "16",
407
+ height: "16"
408
+ }, props), /*#__PURE__*/React.createElement("path", {
409
+ d: "M3 12a9 9 0 109-9 9.75 9.75 0 00-6.74 2.74L3 8"
410
+ }), /*#__PURE__*/React.createElement("path", {
411
+ d: "M3 3v5h5m4-1v5l4 2"
412
+ })));
413
+
414
+ var styles = {"toolbar":"FloatingToolbar-module_toolbar__3iLrb","toggleIcon":"FloatingToolbar-module_toggleIcon__tzwy_","puck":"FloatingToolbar-module_puck__1N8t9","puckIdle":"FloatingToolbar-module_puckIdle__25dov","unreadDot":"FloatingToolbar-module_unreadDot__3Ykgi","navigation":"FloatingToolbar-module_navigation__2oEYm","button":"FloatingToolbar-module_button__2_Q49","count":"FloatingToolbar-module_count__37jUH","segmented":"FloatingToolbar-module_segmented__34nUI","chevronUp":"FloatingToolbar-module_chevronUp__tCL4E","chevronDown":"FloatingToolbar-module_chevronDown__2NELa","segment":"FloatingToolbar-module_segment__q3hcg","segmentCount":"FloatingToolbar-module_segmentCount__2Nsqk","addButton":"FloatingToolbar-module_addButton__2tgNA"};
415
+
416
+ var styles$1 = {"button":"ActivityButton-module_button__3BNt8","unseenDot":"ActivityButton-module_unseenDot__1w8QA","panel":"ActivityButton-module_panel__1tcQU","scroller":"ActivityButton-module_scroller__2RTTE"};
417
+
418
+ var _jsxFileName$3 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/ActivityButton.js";
419
+
420
+ // Clears the default navigation: a 50px bar with an 8px progress bar.
421
+ const viewportPadding = {
422
+ top: 74,
423
+ right: 16,
424
+ bottom: 16,
425
+ left: 16
426
+ };
427
+ function ActivityButton() {
428
+ const {
429
+ t
430
+ } = useI18n({
431
+ locale: 'ui'
432
+ });
433
+ const [open, setOpen] = useState(false);
434
+ const unreadCount = useUnreadThreadCount();
435
+ const label = t('pageflow_scrolled.review.activity.toggle');
436
+ const {
437
+ clearSelection
438
+ } = useSelectedSubject();
439
+ const portalRoot = useFloatingPortalRoot();
440
+ const {
441
+ refs,
442
+ floatingStyles
443
+ } = useFloating({
444
+ open,
445
+ strategy: 'fixed',
446
+ placement: 'top-end',
447
+ middleware: [offset(8), shift({
448
+ padding: viewportPadding
449
+ }), size({
450
+ padding: viewportPadding,
451
+ apply({
452
+ availableHeight,
453
+ elements
454
+ }) {
455
+ elements.floating.style.maxHeight = `${availableHeight}px`;
456
+ }
457
+ })],
458
+ whileElementsMounted: autoUpdate
459
+ });
460
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
461
+ ref: refs.setReference,
462
+ className: classNames(styles.button, styles$1.button),
463
+ onClick: () => {
464
+ if (!open) {
465
+ clearSelection();
466
+ }
467
+ setOpen(!open);
468
+ },
469
+ "aria-expanded": open,
470
+ "aria-label": label,
471
+ title: label,
472
+ __self: this,
473
+ __source: {
474
+ fileName: _jsxFileName$3,
475
+ lineNumber: 47,
476
+ columnNumber: 7
477
+ }
478
+ }, /*#__PURE__*/React.createElement(ActivityIcon, {
479
+ __self: this,
480
+ __source: {
481
+ fileName: _jsxFileName$3,
482
+ lineNumber: 59,
483
+ columnNumber: 9
484
+ }
485
+ }), unreadCount > 0 && /*#__PURE__*/React.createElement("span", {
486
+ className: styles$1.unseenDot,
487
+ __self: this,
488
+ __source: {
489
+ fileName: _jsxFileName$3,
490
+ lineNumber: 60,
491
+ columnNumber: 29
492
+ }
493
+ })), open && /*#__PURE__*/React.createElement(FloatingPortal, {
494
+ id: "floating-ui-above-navigation-widgets",
495
+ root: portalRoot,
496
+ __self: this,
497
+ __source: {
498
+ fileName: _jsxFileName$3,
499
+ lineNumber: 67,
500
+ columnNumber: 9
501
+ }
502
+ }, /*#__PURE__*/React.createElement(ActivityPanel, {
503
+ ref: refs.setFloating,
504
+ style: floatingStyles,
505
+ onClose: () => setOpen(false),
506
+ __self: this,
507
+ __source: {
508
+ fileName: _jsxFileName$3,
509
+ lineNumber: 68,
510
+ columnNumber: 11
511
+ }
512
+ })));
513
+ }
514
+ const ActivityPanel = React.forwardRef(function ActivityPanel({
515
+ style,
516
+ onClose
517
+ }, ref) {
518
+ const {
519
+ t
520
+ } = useI18n({
521
+ locale: 'ui'
522
+ });
523
+ const {
524
+ goToThread,
525
+ highlightedThreadId
526
+ } = useCommentNavigation();
527
+ const panelRef = useRef();
528
+ const setRefs = useCallback(node => {
529
+ panelRef.current = node;
530
+ ref(node);
531
+ }, [ref]);
532
+ useEffect(() => {
533
+ function handleClick(event) {
534
+ var _panelRef$current;
535
+ if ((_panelRef$current = panelRef.current) === null || _panelRef$current === void 0 ? void 0 : _panelRef$current.contains(event.target)) return;
536
+ if (event.target.closest('[data-comment-toolbar]')) return;
537
+ onClose();
538
+ }
539
+
540
+ // An open popover would otherwise close itself on the same key.
541
+ function handleKeyDown(event) {
542
+ if (event.key === 'Escape') {
543
+ event.stopPropagation();
544
+ onClose();
545
+ }
546
+ }
547
+ document.addEventListener('mousedown', handleClick);
548
+ document.addEventListener('keydown', handleKeyDown, true);
549
+ return () => {
550
+ document.removeEventListener('mousedown', handleClick);
551
+ document.removeEventListener('keydown', handleKeyDown, true);
552
+ };
553
+ }, [onClose]);
554
+ return /*#__PURE__*/React.createElement("div", {
555
+ ref: setRefs,
556
+ className: styles$1.panel,
557
+ style: style,
558
+ role: "dialog",
559
+ "aria-label": t('pageflow_scrolled.review.activity.toggle'),
560
+ "data-comment-activity": true,
561
+ __self: this,
562
+ __source: {
563
+ fileName: _jsxFileName$3,
564
+ lineNumber: 113,
565
+ columnNumber: 5
566
+ }
567
+ }, /*#__PURE__*/React.createElement("div", {
568
+ className: styles$1.scroller,
569
+ __self: this,
570
+ __source: {
571
+ fileName: _jsxFileName$3,
572
+ lineNumber: 119,
573
+ columnNumber: 7
574
+ }
575
+ }, /*#__PURE__*/React.createElement(ActivityList, {
576
+ highlightedThreadId: highlightedThreadId,
577
+ onEntryClick: entry => goToThread(entry.threadId, {
578
+ revealOnly: true
579
+ }),
580
+ __self: this,
581
+ __source: {
582
+ fileName: _jsxFileName$3,
583
+ lineNumber: 120,
584
+ columnNumber: 9
585
+ }
586
+ })));
587
+ });
588
+
589
+ function _extends$1() {
590
+ _extends$1 = Object.assign ? Object.assign.bind() : function (target) {
591
+ for (var i = 1; i < arguments.length; i++) {
592
+ var source = arguments[i];
593
+ for (var key in source) {
594
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
595
+ target[key] = source[key];
596
+ }
597
+ }
598
+ }
599
+ return target;
600
+ };
601
+ return _extends$1.apply(this, arguments);
602
+ }
603
+ var AddCommentIcon = (({
604
+ styles = {},
605
+ ...props
606
+ }) => /*#__PURE__*/React.createElement("svg", _extends$1({
607
+ xmlns: "http://www.w3.org/2000/svg",
608
+ width: "24",
609
+ height: "24",
610
+ fill: "none",
611
+ stroke: "currentColor",
612
+ strokeWidth: "2",
613
+ strokeLinecap: "round",
614
+ strokeLinejoin: "round"
615
+ }, props), /*#__PURE__*/React.createElement("path", {
616
+ d: "M22 17a2 2 0 01-2 2H6.828a2 2 0 00-1.414.586l-2.202 2.202A.71.71 0 012 21.286V5a2 2 0 012-2h16a2 2 0 012 2zM12 8v6m-3-3h6"
617
+ })));
618
+
619
+ function _extends$2() {
620
+ _extends$2 = Object.assign ? Object.assign.bind() : function (target) {
621
+ for (var i = 1; i < arguments.length; i++) {
622
+ var source = arguments[i];
623
+ for (var key in source) {
624
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
625
+ target[key] = source[key];
626
+ }
627
+ }
628
+ }
629
+ return target;
630
+ };
631
+ return _extends$2.apply(this, arguments);
632
+ }
633
+ var CancelCommentIcon = (({
634
+ styles = {},
635
+ ...props
636
+ }) => /*#__PURE__*/React.createElement("svg", _extends$2({
637
+ xmlns: "http://www.w3.org/2000/svg",
638
+ width: "24",
639
+ height: "24",
640
+ fill: "none",
641
+ stroke: "currentColor",
642
+ strokeWidth: "2",
643
+ strokeLinecap: "round",
644
+ strokeLinejoin: "round"
645
+ }, props), /*#__PURE__*/React.createElement("path", {
646
+ d: "M22 17a2 2 0 01-2 2H6.828a2 2 0 00-1.414.586l-2.202 2.202A.71.71 0 012 21.286V5a2 2 0 012-2h16a2 2 0 012 2zm-7.5-8.5l-5 5m0-5l5 5"
647
+ })));
648
+
649
+ function _extends$3() {
650
+ _extends$3 = Object.assign ? Object.assign.bind() : function (target) {
651
+ for (var i = 1; i < arguments.length; i++) {
652
+ var source = arguments[i];
653
+ for (var key in source) {
654
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
655
+ target[key] = source[key];
656
+ }
657
+ }
658
+ }
659
+ return target;
660
+ };
661
+ return _extends$3.apply(this, arguments);
662
+ }
663
+ var ChevronIcon = (({
664
+ styles = {},
665
+ ...props
666
+ }) => /*#__PURE__*/React.createElement("svg", _extends$3({
667
+ xmlns: "http://www.w3.org/2000/svg",
668
+ viewBox: "0 0 24 24",
669
+ fill: "none",
670
+ stroke: "currentColor",
671
+ strokeWidth: "2",
672
+ strokeLinecap: "round",
673
+ strokeLinejoin: "round",
674
+ width: "16",
675
+ height: "16"
676
+ }, props), /*#__PURE__*/React.createElement("path", {
677
+ d: "M6 9l6 6 6-6"
678
+ })));
679
+
680
+ function _extends$4() {
681
+ _extends$4 = Object.assign ? Object.assign.bind() : function (target) {
682
+ for (var i = 1; i < arguments.length; i++) {
683
+ var source = arguments[i];
684
+ for (var key in source) {
685
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
686
+ target[key] = source[key];
687
+ }
688
+ }
689
+ }
690
+ return target;
691
+ };
692
+ return _extends$4.apply(this, arguments);
693
+ }
694
+ var HideCommentsIcon = (({
695
+ styles = {},
696
+ ...props
697
+ }) => /*#__PURE__*/React.createElement("svg", _extends$4({
698
+ xmlns: "http://www.w3.org/2000/svg",
699
+ viewBox: "0 0 24 24",
700
+ fill: "none",
701
+ stroke: "currentColor",
702
+ strokeWidth: "2",
703
+ strokeLinecap: "round",
704
+ strokeLinejoin: "round",
705
+ width: "16",
706
+ height: "16"
707
+ }, props), /*#__PURE__*/React.createElement("path", {
708
+ d: "M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24M1 1l22 22"
709
+ })));
710
+
711
+ function _extends$5() {
712
+ _extends$5 = Object.assign ? Object.assign.bind() : function (target) {
713
+ for (var i = 1; i < arguments.length; i++) {
714
+ var source = arguments[i];
715
+ for (var key in source) {
716
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
717
+ target[key] = source[key];
718
+ }
719
+ }
720
+ }
721
+ return target;
722
+ };
723
+ return _extends$5.apply(this, arguments);
724
+ }
725
+ var ShowCommentsIcon = (({
726
+ styles = {},
727
+ ...props
728
+ }) => /*#__PURE__*/React.createElement("svg", _extends$5({
729
+ xmlns: "http://www.w3.org/2000/svg",
730
+ viewBox: "0 0 24 24",
731
+ fill: "none",
732
+ stroke: "currentColor",
733
+ strokeWidth: "2",
734
+ strokeLinecap: "round",
735
+ strokeLinejoin: "round",
736
+ width: "16",
737
+ height: "16"
738
+ }, props), /*#__PURE__*/React.createElement("path", {
739
+ d: "M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z"
740
+ })));
741
+
742
+ var _jsxFileName$4 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/FloatingToolbar.js";
743
+ function FloatingToolbar() {
744
+ const {
745
+ t
746
+ } = useI18n({
747
+ locale: 'ui'
748
+ });
749
+ const {
750
+ visible
751
+ } = useCommentingVisibility();
752
+ const {
753
+ active,
754
+ deactivate
755
+ } = useAddCommentMode();
756
+ useEffect(() => {
757
+ if (!visible && active) {
758
+ deactivate();
759
+ }
760
+ }, [visible, active, deactivate]);
761
+ if (!visible) {
762
+ return /*#__PURE__*/React.createElement(ShowCommentsButton, {
763
+ __self: this,
764
+ __source: {
765
+ fileName: _jsxFileName$4,
766
+ lineNumber: 32,
767
+ columnNumber: 12
768
+ }
769
+ });
770
+ }
771
+ return /*#__PURE__*/React.createElement("div", {
772
+ className: styles.toolbar,
773
+ role: "group",
774
+ "aria-label": t('pageflow_scrolled.review.comment_toolbar'),
775
+ "data-comment-toolbar": true,
776
+ __self: this,
777
+ __source: {
778
+ fileName: _jsxFileName$4,
779
+ lineNumber: 36,
780
+ columnNumber: 5
781
+ }
782
+ }, /*#__PURE__*/React.createElement(PositionIndicator, {
783
+ __self: this,
784
+ __source: {
785
+ fileName: _jsxFileName$4,
786
+ lineNumber: 40,
787
+ columnNumber: 7
788
+ }
789
+ }), /*#__PURE__*/React.createElement(ResolutionToggleButton, {
790
+ __self: this,
791
+ __source: {
792
+ fileName: _jsxFileName$4,
793
+ lineNumber: 41,
794
+ columnNumber: 7
795
+ }
796
+ }), /*#__PURE__*/React.createElement(NavigationArrows, {
797
+ __self: this,
798
+ __source: {
799
+ fileName: _jsxFileName$4,
800
+ lineNumber: 42,
801
+ columnNumber: 7
802
+ }
803
+ }), /*#__PURE__*/React.createElement(ActivityButton, {
804
+ __self: this,
805
+ __source: {
806
+ fileName: _jsxFileName$4,
807
+ lineNumber: 43,
808
+ columnNumber: 7
809
+ }
810
+ }), /*#__PURE__*/React.createElement(HideCommentsButton, {
811
+ __self: this,
812
+ __source: {
813
+ fileName: _jsxFileName$4,
814
+ lineNumber: 44,
815
+ columnNumber: 7
816
+ }
817
+ }), /*#__PURE__*/React.createElement(AddCommentButton, {
818
+ __self: this,
819
+ __source: {
820
+ fileName: _jsxFileName$4,
821
+ lineNumber: 45,
822
+ columnNumber: 7
823
+ }
824
+ }));
825
+ }
826
+ function HideCommentsButton() {
827
+ const {
828
+ t
829
+ } = useI18n({
830
+ locale: 'ui'
831
+ });
832
+ const {
833
+ toggle
834
+ } = useCommentingVisibility();
835
+ const label = t('pageflow_scrolled.review.hide_comments');
836
+ return /*#__PURE__*/React.createElement("button", {
837
+ className: styles.button,
838
+ onClick: toggle,
839
+ "aria-label": label,
840
+ title: label,
841
+ __self: this,
842
+ __source: {
843
+ fileName: _jsxFileName$4,
844
+ lineNumber: 56,
845
+ columnNumber: 5
846
+ }
847
+ }, /*#__PURE__*/React.createElement(HideCommentsIcon, {
848
+ className: styles.toggleIcon,
849
+ __self: this,
850
+ __source: {
851
+ fileName: _jsxFileName$4,
852
+ lineNumber: 60,
853
+ columnNumber: 7
854
+ }
855
+ }));
856
+ }
857
+ function ShowCommentsButton() {
858
+ const {
859
+ t
860
+ } = useI18n({
861
+ locale: 'ui'
862
+ });
863
+ const {
864
+ toggle
865
+ } = useCommentingVisibility();
866
+ const unreadCount = useUnreadThreadCount();
867
+ const unread = unreadCount > 0;
868
+ const label = unread ? t('pageflow_scrolled.review.show_comments_with_unread', {
869
+ count: unreadCount
870
+ }) : t('pageflow_scrolled.review.show_comments');
871
+ return /*#__PURE__*/React.createElement("button", {
872
+ className: styles.puck,
873
+ onClick: toggle,
874
+ "aria-label": label,
875
+ title: label,
876
+ __self: this,
877
+ __source: {
878
+ fileName: _jsxFileName$4,
879
+ lineNumber: 78,
880
+ columnNumber: 5
881
+ }
882
+ }, /*#__PURE__*/React.createElement(ShowCommentsIcon, {
883
+ className: styles.toggleIcon,
884
+ __self: this,
885
+ __source: {
886
+ fileName: _jsxFileName$4,
887
+ lineNumber: 82,
888
+ columnNumber: 7
889
+ }
890
+ }), unread && /*#__PURE__*/React.createElement("span", {
891
+ className: styles.unreadDot,
892
+ __self: this,
893
+ __source: {
894
+ fileName: _jsxFileName$4,
895
+ lineNumber: 83,
896
+ columnNumber: 18
897
+ }
898
+ }));
899
+ }
900
+ function PositionIndicator() {
901
+ const {
902
+ t
903
+ } = useI18n({
904
+ locale: 'ui'
905
+ });
906
+ const {
907
+ count,
908
+ position
909
+ } = useCommentNavigation();
910
+ return /*#__PURE__*/React.createElement("span", {
911
+ className: styles.count,
912
+ title: t('pageflow_scrolled.review.comment_count', {
913
+ count
914
+ }),
915
+ __self: this,
916
+ __source: {
917
+ fileName: _jsxFileName$4,
918
+ lineNumber: 93,
919
+ columnNumber: 5
920
+ }
921
+ }, position || '–', " /");
922
+ }
923
+ function NavigationArrows() {
924
+ const {
925
+ t
926
+ } = useI18n({
927
+ locale: 'ui'
928
+ });
929
+ const {
930
+ count,
931
+ goToPrevious,
932
+ goToNext
933
+ } = useCommentNavigation();
934
+ return /*#__PURE__*/React.createElement("div", {
935
+ className: styles.navigation,
936
+ __self: this,
937
+ __source: {
938
+ fileName: _jsxFileName$4,
939
+ lineNumber: 105,
940
+ columnNumber: 5
941
+ }
942
+ }, /*#__PURE__*/React.createElement("button", {
943
+ className: styles.button,
944
+ onClick: goToPrevious,
945
+ disabled: count === 0,
946
+ "aria-label": t('pageflow_scrolled.review.previous_comment'),
947
+ title: t('pageflow_scrolled.review.previous_comment'),
948
+ __self: this,
949
+ __source: {
950
+ fileName: _jsxFileName$4,
951
+ lineNumber: 106,
952
+ columnNumber: 7
953
+ }
954
+ }, /*#__PURE__*/React.createElement(ChevronIcon, {
955
+ className: styles.chevronUp,
956
+ __self: this,
957
+ __source: {
958
+ fileName: _jsxFileName$4,
959
+ lineNumber: 111,
960
+ columnNumber: 9
961
+ }
962
+ })), /*#__PURE__*/React.createElement("button", {
963
+ className: styles.button,
964
+ onClick: goToNext,
965
+ disabled: count === 0,
966
+ "aria-label": t('pageflow_scrolled.review.next_comment'),
967
+ title: t('pageflow_scrolled.review.next_comment'),
968
+ __self: this,
969
+ __source: {
970
+ fileName: _jsxFileName$4,
971
+ lineNumber: 113,
972
+ columnNumber: 7
973
+ }
974
+ }, /*#__PURE__*/React.createElement(ChevronIcon, {
975
+ className: styles.chevronDown,
976
+ __self: this,
977
+ __source: {
978
+ fileName: _jsxFileName$4,
979
+ lineNumber: 118,
980
+ columnNumber: 9
981
+ }
982
+ })));
983
+ }
984
+ const resolutions = ['unresolved', 'all'];
985
+ function ResolutionToggleButton() {
986
+ const {
987
+ t
988
+ } = useI18n({
989
+ locale: 'ui'
990
+ });
991
+ const {
992
+ resolution,
993
+ setResolution
994
+ } = useCommentDisplayFilter();
995
+ const {
996
+ threads
997
+ } = useLocatedCommentThreads();
998
+ const counts = {
999
+ unresolved: threads.filter(thread => !thread.resolvedAt).length,
1000
+ all: threads.length
1001
+ };
1002
+ return /*#__PURE__*/React.createElement("div", {
1003
+ className: styles.segmented,
1004
+ role: "group",
1005
+ "aria-label": t('pageflow_scrolled.review.filter.label'),
1006
+ __self: this,
1007
+ __source: {
1008
+ fileName: _jsxFileName$4,
1009
+ lineNumber: 137,
1010
+ columnNumber: 5
1011
+ }
1012
+ }, resolutions.map(value => /*#__PURE__*/React.createElement("button", {
1013
+ key: value,
1014
+ type: "button",
1015
+ className: styles.segment,
1016
+ "aria-pressed": resolution === value,
1017
+ onClick: () => setResolution(value),
1018
+ __self: this,
1019
+ __source: {
1020
+ fileName: _jsxFileName$4,
1021
+ lineNumber: 141,
1022
+ columnNumber: 9
1023
+ }
1024
+ }, t(`pageflow_scrolled.review.filter.${value}`), /*#__PURE__*/React.createElement("span", {
1025
+ className: styles.segmentCount,
1026
+ "aria-hidden": "true",
1027
+ __self: this,
1028
+ __source: {
1029
+ fileName: _jsxFileName$4,
1030
+ lineNumber: 147,
1031
+ columnNumber: 11
1032
+ }
1033
+ }, counts[value]))));
1034
+ }
1035
+ function AddCommentButton() {
1036
+ const {
1037
+ t
1038
+ } = useI18n({
1039
+ locale: 'ui'
1040
+ });
1041
+ const {
1042
+ active,
1043
+ toggle
1044
+ } = useAddCommentMode();
1045
+ const Icon = active ? CancelCommentIcon : AddCommentIcon;
1046
+ const label = t(active ? 'pageflow_scrolled.review.cancel_add_comment' : 'pageflow_scrolled.review.add_comment');
1047
+ return /*#__PURE__*/React.createElement("button", {
1048
+ className: classNames(styles.button, styles.addButton),
1049
+ onClick: toggle,
1050
+ "data-add-comment-toggle": true,
1051
+ "aria-label": label,
1052
+ title: label,
1053
+ __self: this,
1054
+ __source: {
1055
+ fileName: _jsxFileName$4,
1056
+ lineNumber: 166,
1057
+ columnNumber: 5
1058
+ }
1059
+ }, /*#__PURE__*/React.createElement(Icon, {
1060
+ __self: this,
1061
+ __source: {
1062
+ fileName: _jsxFileName$4,
1063
+ lineNumber: 171,
1064
+ columnNumber: 7
1065
+ }
1066
+ }));
1067
+ }
1068
+
1069
+ var _jsxFileName$5 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/EntryDecorator.js";
1070
+ const resolutionStorageKey = 'pageflow.scrolled.commentsResolution';
1071
+ function EntryDecorator({
1072
+ commentingInitialState,
1073
+ children
1074
+ }) {
1075
+ const commentDisplayFilter = useStoredCommentDisplayFilter(resolutionStorageKey);
1076
+ return /*#__PURE__*/React.createElement(ReviewStateProvider, {
1077
+ initialState: commentingInitialState,
1078
+ __self: this,
1079
+ __source: {
1080
+ fileName: _jsxFileName$5,
1081
+ lineNumber: 23,
1082
+ columnNumber: 5
1083
+ }
1084
+ }, /*#__PURE__*/React.createElement(ReviewSessionSetup, {
1085
+ initialState: commentingInitialState,
1086
+ __self: this,
1087
+ __source: {
1088
+ fileName: _jsxFileName$5,
1089
+ lineNumber: 24,
1090
+ columnNumber: 7
1091
+ }
1092
+ }), /*#__PURE__*/React.createElement(LocatedCommentThreadsProvider, {
1093
+ __self: this,
1094
+ __source: {
1095
+ fileName: _jsxFileName$5,
1096
+ lineNumber: 25,
1097
+ columnNumber: 7
1098
+ }
1099
+ }, /*#__PURE__*/React.createElement(CommentingVisibilityProvider, {
1100
+ __self: this,
1101
+ __source: {
1102
+ fileName: _jsxFileName$5,
1103
+ lineNumber: 26,
1104
+ columnNumber: 9
1105
+ }
1106
+ }, /*#__PURE__*/React.createElement(CommentDisplayFilterProvider, Object.assign({}, commentDisplayFilter, {
1107
+ __self: this,
1108
+ __source: {
1109
+ fileName: _jsxFileName$5,
1110
+ lineNumber: 27,
1111
+ columnNumber: 11
1112
+ }
1113
+ }), /*#__PURE__*/React.createElement(SelectedSubjectProvider, {
1114
+ __self: this,
1115
+ __source: {
1116
+ fileName: _jsxFileName$5,
1117
+ lineNumber: 28,
1118
+ columnNumber: 13
1119
+ }
1120
+ }, /*#__PURE__*/React.createElement(AddCommentModeProvider, {
1121
+ __self: this,
1122
+ __source: {
1123
+ fileName: _jsxFileName$5,
1124
+ lineNumber: 29,
1125
+ columnNumber: 15
1126
+ }
1127
+ }, children, /*#__PURE__*/React.createElement(FloatingToolbar, {
1128
+ __self: this,
1129
+ __source: {
1130
+ fileName: _jsxFileName$5,
1131
+ lineNumber: 31,
1132
+ columnNumber: 17
1133
+ }
1134
+ })))))));
1135
+ }
1136
+ function ReviewSessionSetup({
1137
+ initialState
1138
+ }) {
1139
+ const entryMetadata = useEntryMetadata();
1140
+ const entryId = entryMetadata === null || entryMetadata === void 0 ? void 0 : entryMetadata.id;
1141
+ useEffect(() => {
1142
+ if (!entryId) return;
1143
+ const session = createReviewSession({
1144
+ entryId,
1145
+ initialState
1146
+ });
1147
+ const handler = ReviewMessageHandler.create({
1148
+ session,
1149
+ targetWindow: window
1150
+ });
1151
+ if (!initialState) {
1152
+ session.fetch();
1153
+ }
1154
+ return () => handler.dispose();
1155
+ }, [entryId, initialState]);
1156
+ return null;
1157
+ }
1158
+
1159
+ var styles$2 = {"badge":"Popover-module_badge__16NvD","threadList":"Popover-module_threadList__2nA5p"};
1160
+
1161
+ var _jsxFileName$6 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/Popover.js";
1162
+ function Popover({
1163
+ subjectType,
1164
+ subjectId,
1165
+ subjectRange,
1166
+ placement = 'bottom-start',
1167
+ strategy = 'absolute',
1168
+ hideNewTopicButton
1169
+ }) {
1170
+ const {
1171
+ isSelected,
1172
+ revealOnly,
1173
+ showNewForm,
1174
+ select,
1175
+ clearSelection,
1176
+ highlightedThreadId
1177
+ } = useSelectedSubject(subjectType, subjectId, subjectRange);
1178
+ const {
1179
+ resolution
1180
+ } = useCommentDisplayFilter();
1181
+ const [reference, setReference] = useState(null);
1182
+ useEffect(() => {
1183
+ if (isSelected && highlightedThreadId != null) {
1184
+ reference === null || reference === void 0 ? void 0 : reference.scrollIntoView({
1185
+ block: 'center',
1186
+ behavior: 'smooth'
1187
+ });
1188
+ }
1189
+ }, [isSelected, highlightedThreadId, reference]);
1190
+ function handleBadgeClick() {
1191
+ if (isSelected && !revealOnly) {
1192
+ clearSelection();
1193
+ } else {
1194
+ select(revealOnly ? {
1195
+ highlightedThreadId
1196
+ } : undefined);
1197
+ }
1198
+ }
1199
+ return /*#__PURE__*/React.createElement("span", {
1200
+ ref: setReference,
1201
+ className: styles$2.badge,
1202
+ __self: this,
1203
+ __source: {
1204
+ fileName: _jsxFileName$6,
1205
+ lineNumber: 38,
1206
+ columnNumber: 5
1207
+ }
1208
+ }, /*#__PURE__*/React.createElement(ThreadsBadge, {
1209
+ subjectType: subjectType,
1210
+ subjectId: subjectId,
1211
+ subjectRange: subjectRange,
1212
+ resolution: resolution,
1213
+ revealedThreadId: highlightedThreadId,
1214
+ mode: isSelected ? 'active' : undefined,
1215
+ onClick: handleBadgeClick,
1216
+ __self: this,
1217
+ __source: {
1218
+ fileName: _jsxFileName$6,
1219
+ lineNumber: 39,
1220
+ columnNumber: 7
1221
+ }
1222
+ }), isSelected && !revealOnly && /*#__PURE__*/React.createElement(OpenThreadList, {
1223
+ reference: reference,
1224
+ subjectType: subjectType,
1225
+ subjectId: subjectId,
1226
+ subjectRange: subjectRange,
1227
+ placement: placement,
1228
+ strategy: strategy,
1229
+ showNewForm: showNewForm,
1230
+ hideNewTopicButton: hideNewTopicButton,
1231
+ highlightedThreadId: highlightedThreadId,
1232
+ expandResolved: resolution === 'all',
1233
+ onDismiss: clearSelection,
1234
+ __self: this,
1235
+ __source: {
1236
+ fileName: _jsxFileName$6,
1237
+ lineNumber: 48,
1238
+ columnNumber: 9
1239
+ }
1240
+ }));
1241
+ }
1242
+ function OpenThreadList({
1243
+ reference,
1244
+ subjectType,
1245
+ subjectId,
1246
+ subjectRange,
1247
+ placement,
1248
+ strategy,
1249
+ showNewForm,
1250
+ hideNewTopicButton,
1251
+ highlightedThreadId,
1252
+ expandResolved,
1253
+ onDismiss
1254
+ }) {
1255
+ const portalRoot = useFloatingPortalRoot();
1256
+ const {
1257
+ refs,
1258
+ floatingStyles
1259
+ } = useFloating({
1260
+ open: true,
1261
+ elements: {
1262
+ reference
1263
+ },
1264
+ placement,
1265
+ strategy,
1266
+ middleware: [offset(8), flip({
1267
+ fallbackPlacements: [placement.startsWith('top') ? 'bottom-start' : 'top-start'],
1268
+ rootBoundary: 'document'
1269
+ }), shift({
1270
+ padding: 8
1271
+ })],
1272
+ whileElementsMounted: autoUpdate
1273
+ });
1274
+ useEffect(() => {
1275
+ function handleClick(event) {
1276
+ var _refs$floating$curren;
1277
+ if (reference === null || reference === void 0 ? void 0 : reference.contains(event.target)) return;
1278
+ if ((_refs$floating$curren = refs.floating.current) === null || _refs$floating$curren === void 0 ? void 0 : _refs$floating$curren.contains(event.target)) return;
1279
+ if (event.target.closest('[data-comment-highlight]')) return;
1280
+ if (event.target.closest('[data-comment-toolbar]')) return;
1281
+ if (event.target.closest('[data-comment-menu]')) return;
1282
+ onDismiss();
1283
+ }
1284
+ function handleKeyDown(event) {
1285
+ if (event.key === 'Escape') {
1286
+ onDismiss();
1287
+ }
1288
+ }
1289
+ document.addEventListener('mousedown', handleClick);
1290
+ document.addEventListener('keydown', handleKeyDown);
1291
+ return () => {
1292
+ document.removeEventListener('mousedown', handleClick);
1293
+ document.removeEventListener('keydown', handleKeyDown);
1294
+ };
1295
+ }, [reference, refs.floating, onDismiss]);
1296
+ return /*#__PURE__*/React.createElement(FloatingPortal, {
1297
+ root: portalRoot,
1298
+ __self: this,
1299
+ __source: {
1300
+ fileName: _jsxFileName$6,
1301
+ lineNumber: 112,
1302
+ columnNumber: 5
1303
+ }
1304
+ }, /*#__PURE__*/React.createElement("div", {
1305
+ ref: refs.setFloating,
1306
+ "data-floating-raised": true,
1307
+ className: styles$2.threadList,
1308
+ style: floatingStyles,
1309
+ __self: this,
1310
+ __source: {
1311
+ fileName: _jsxFileName$6,
1312
+ lineNumber: 113,
1313
+ columnNumber: 7
1314
+ }
1315
+ }, /*#__PURE__*/React.createElement(ThreadList, {
1316
+ subjectType: subjectType,
1317
+ subjectId: subjectId,
1318
+ subjectRange: subjectRange,
1319
+ highlightedThreadId: highlightedThreadId,
1320
+ expandResolved: expandResolved,
1321
+ showNewForm: showNewForm,
1322
+ hideNewTopicButton: hideNewTopicButton,
1323
+ __self: this,
1324
+ __source: {
1325
+ fileName: _jsxFileName$6,
1326
+ lineNumber: 117,
1327
+ columnNumber: 9
1328
+ }
1329
+ })));
1330
+ }
1331
+
1332
+ var styles$3 = {"wrapper":"SectionDecorator-module_wrapper__3oQuz","commentBadge":"SectionDecorator-module_commentBadge__2MYch","sticky":"SectionDecorator-module_sticky__M1Elo","addButton":"SectionDecorator-module_addButton__3-FuB","pill":"SectionDecorator-module_pill__1wMMW AddCommentOverlay-module_pill__K6tzV"};
1333
+
1334
+ var _jsxFileName$7 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/SectionDecorator.js";
1335
+ function SectionDecorator({
1336
+ section,
1337
+ children
1338
+ }) {
1339
+ const {
1340
+ visible
1341
+ } = useCommentingVisibility();
1342
+ const {
1343
+ active
1344
+ } = useAddCommentMode();
1345
+ const {
1346
+ isSelected,
1347
+ highlightedThreadId
1348
+ } = useSelectedSubject('Section', section.permaId);
1349
+ const {
1350
+ resolution
1351
+ } = useCommentDisplayFilter();
1352
+ const threads = useLocatedCommentThreadsForSubject({
1353
+ subjectType: 'Section',
1354
+ subjectId: section.permaId,
1355
+ resolution,
1356
+ revealedThreadId: highlightedThreadId
1357
+ });
1358
+ const hasThreads = threads.length > 0;
1359
+ if (!visible) {
1360
+ return children;
1361
+ }
1362
+ return /*#__PURE__*/React.createElement("div", {
1363
+ className: styles$3.wrapper,
1364
+ __self: this,
1365
+ __source: {
1366
+ fileName: _jsxFileName$7,
1367
+ lineNumber: 34,
1368
+ columnNumber: 5
1369
+ }
1370
+ }, children, /*#__PURE__*/React.createElement("div", {
1371
+ className: classNames(styles$3.commentBadge, {
1372
+ [styles$3.sticky]: hasThreads || active || isSelected
1373
+ }),
1374
+ __self: this,
1375
+ __source: {
1376
+ fileName: _jsxFileName$7,
1377
+ lineNumber: 36,
1378
+ columnNumber: 7
1379
+ }
1380
+ }, active ? /*#__PURE__*/React.createElement(AddCommentButton$1, {
1381
+ permaId: section.permaId,
1382
+ __self: this,
1383
+ __source: {
1384
+ fileName: _jsxFileName$7,
1385
+ lineNumber: 39,
1386
+ columnNumber: 10
1387
+ }
1388
+ }) : /*#__PURE__*/React.createElement(Popover, {
1389
+ subjectType: "Section",
1390
+ subjectId: section.permaId,
1391
+ placement: "top-start",
1392
+ strategy: "fixed",
1393
+ __self: this,
1394
+ __source: {
1395
+ fileName: _jsxFileName$7,
1396
+ lineNumber: 40,
1397
+ columnNumber: 10
1398
+ }
1399
+ })));
1400
+ }
1401
+ function AddCommentButton$1({
1402
+ permaId
1403
+ }) {
1404
+ const {
1405
+ t
1406
+ } = useI18n({
1407
+ locale: 'ui'
1408
+ });
1409
+ const {
1410
+ deactivate
1411
+ } = useAddCommentMode();
1412
+ const {
1413
+ select
1414
+ } = useSelectedSubject('Section', permaId);
1415
+ function handleClick() {
1416
+ select({
1417
+ showNewForm: true
1418
+ });
1419
+ deactivate();
1420
+ }
1421
+ return /*#__PURE__*/React.createElement("button", {
1422
+ "data-add-comment-overlay": true,
1423
+ onClick: handleClick,
1424
+ className: styles$3.addButton,
1425
+ "aria-label": t('pageflow_scrolled.review.select_section'),
1426
+ __self: this,
1427
+ __source: {
1428
+ fileName: _jsxFileName$7,
1429
+ lineNumber: 60,
1430
+ columnNumber: 5
1431
+ }
1432
+ }, /*#__PURE__*/React.createElement("span", {
1433
+ className: styles$3.pill,
1434
+ __self: this,
1435
+ __source: {
1436
+ fileName: _jsxFileName$7,
1437
+ lineNumber: 64,
1438
+ columnNumber: 7
1439
+ }
1440
+ }, /*#__PURE__*/React.createElement(AddCommentIcon, {
1441
+ __self: this,
1442
+ __source: {
1443
+ fileName: _jsxFileName$7,
1444
+ lineNumber: 65,
1445
+ columnNumber: 9
1446
+ }
1447
+ })));
1448
+ }
1449
+
1450
+ var styles$4 = {"highlight":"AddCommentOverlay-module_highlight__1VAyf","pill":"AddCommentOverlay-module_pill__K6tzV"};
1451
+
1452
+ var _jsxFileName$8 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/AddCommentOverlay.js";
1453
+ function AddCommentOverlay({
1454
+ permaId
1455
+ }) {
1456
+ const {
1457
+ t
1458
+ } = useI18n({
1459
+ locale: 'ui'
1460
+ });
1461
+ const {
1462
+ active,
1463
+ deactivate
1464
+ } = useAddCommentMode();
1465
+ const {
1466
+ select
1467
+ } = useSelectedSubject('ContentElement', permaId);
1468
+ if (!active) return null;
1469
+ function handleClick() {
1470
+ select({
1471
+ showNewForm: true
1472
+ });
1473
+ deactivate();
1474
+ }
1475
+ return /*#__PURE__*/React.createElement("button", {
1476
+ onClick: handleClick,
1477
+ "data-add-comment-overlay": true,
1478
+ className: styles$4.highlight,
1479
+ "aria-label": t('pageflow_scrolled.review.select_content_element'),
1480
+ title: t('pageflow_scrolled.review.select_content_element'),
1481
+ __self: this,
1482
+ __source: {
1483
+ fileName: _jsxFileName$8,
1484
+ lineNumber: 23,
1485
+ columnNumber: 5
1486
+ }
1487
+ }, /*#__PURE__*/React.createElement("span", {
1488
+ className: styles$4.pill,
1489
+ __self: this,
1490
+ __source: {
1491
+ fileName: _jsxFileName$8,
1492
+ lineNumber: 28,
1493
+ columnNumber: 7
1494
+ }
1495
+ }, /*#__PURE__*/React.createElement(AddCommentIcon, {
1496
+ __self: this,
1497
+ __source: {
1498
+ fileName: _jsxFileName$8,
1499
+ lineNumber: 29,
1500
+ columnNumber: 9
1501
+ }
1502
+ })));
1503
+ }
1504
+
1505
+ var styles$5 = {"wrapper":"ContentElementDecorator-module_wrapper__omtl-","selected":"ContentElementDecorator-module_selected__1xIK9","badge":"ContentElementDecorator-module_badge__3RBr6","badgeFlush":"ContentElementDecorator-module_badgeFlush__1lR32"};
1506
+
1507
+ var _jsxFileName$9 = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/ContentElementDecorator.js";
1508
+ function ContentElementDecorator({
1509
+ type,
1510
+ width,
1511
+ customMargin,
1512
+ permaId,
1513
+ children
1514
+ }) {
1515
+ const {
1516
+ inlineComments
1517
+ } = api.contentElementTypes.getOptions(type) || {};
1518
+ if (inlineComments) {
1519
+ return children;
1520
+ }
1521
+ return /*#__PURE__*/React.createElement(DefaultCommentDecorator, {
1522
+ permaId: permaId,
1523
+ flush: width === widths.full || customMargin,
1524
+ __self: this,
1525
+ __source: {
1526
+ fileName: _jsxFileName$9,
1527
+ lineNumber: 22,
1528
+ columnNumber: 5
1529
+ }
1530
+ }, children);
1531
+ }
1532
+ function DefaultCommentDecorator({
1533
+ permaId,
1534
+ flush,
1535
+ children
1536
+ }) {
1537
+ const {
1538
+ visible
1539
+ } = useCommentingVisibility();
1540
+ const {
1541
+ active
1542
+ } = useAddCommentMode();
1543
+ const {
1544
+ isSelected
1545
+ } = useSelectedSubject('ContentElement', permaId);
1546
+ if (!visible) {
1547
+ return children;
1548
+ }
1549
+ return /*#__PURE__*/React.createElement("div", {
1550
+ className: classNames(styles$5.wrapper, {
1551
+ [styles$5.selected]: isSelected
1552
+ }),
1553
+ __self: this,
1554
+ __source: {
1555
+ fileName: _jsxFileName$9,
1556
+ lineNumber: 39,
1557
+ columnNumber: 5
1558
+ }
1559
+ }, /*#__PURE__*/React.createElement("div", {
1560
+ inert: active ? '' : undefined,
1561
+ __self: this,
1562
+ __source: {
1563
+ fileName: _jsxFileName$9,
1564
+ lineNumber: 40,
1565
+ columnNumber: 7
1566
+ }
1567
+ }, children), /*#__PURE__*/React.createElement(AddCommentOverlay, {
1568
+ permaId: permaId,
1569
+ __self: this,
1570
+ __source: {
1571
+ fileName: _jsxFileName$9,
1572
+ lineNumber: 41,
1573
+ columnNumber: 7
1574
+ }
1575
+ }), /*#__PURE__*/React.createElement("div", {
1576
+ className: classNames(styles$5.badge, {
1577
+ [styles$5.badgeFlush]: flush
1578
+ }),
1579
+ __self: this,
1580
+ __source: {
1581
+ fileName: _jsxFileName$9,
1582
+ lineNumber: 42,
1583
+ columnNumber: 7
1584
+ }
1585
+ }, /*#__PURE__*/React.createElement(Popover, {
1586
+ subjectType: "ContentElement",
1587
+ subjectId: permaId,
1588
+ __self: this,
1589
+ __source: {
1590
+ fileName: _jsxFileName$9,
1591
+ lineNumber: 43,
1592
+ columnNumber: 9
1593
+ }
1594
+ })));
1595
+ }
1596
+
1597
+ var styles$6 = {"hint":"AddCommentHint-module_hint__1tsMa","tooltip":"AddCommentHint-module_tooltip__28laa"};
1598
+
1599
+ var _jsxFileName$a = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/AddCommentHint.js";
1600
+ function AddCommentHint() {
1601
+ const {
1602
+ t
1603
+ } = useI18n({
1604
+ locale: 'ui'
1605
+ });
1606
+ return /*#__PURE__*/React.createElement("div", {
1607
+ className: styles$6.hint,
1608
+ __self: this,
1609
+ __source: {
1610
+ fileName: _jsxFileName$a,
1611
+ lineNumber: 11,
1612
+ columnNumber: 5
1613
+ }
1614
+ }, /*#__PURE__*/React.createElement("span", {
1615
+ className: styles$6.tooltip,
1616
+ __self: this,
1617
+ __source: {
1618
+ fileName: _jsxFileName$a,
1619
+ lineNumber: 12,
1620
+ columnNumber: 7
1621
+ }
1622
+ }, t('pageflow_scrolled.review.select_text_to_comment')));
1623
+ }
1624
+
1625
+ var styles$7 = {"floating":"PopoversColumn-module_floating__2fpOt"};
1626
+
1627
+ var _jsxFileName$b = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/PopoversColumn.js";
1628
+ function PopoversColumn({
1629
+ highlights,
1630
+ anchors
1631
+ }) {
1632
+ return highlights.map(highlight => /*#__PURE__*/React.createElement(PositionedPopover, {
1633
+ key: highlight.key,
1634
+ rangeKey: highlight.key,
1635
+ subjectRange: highlight.range,
1636
+ anchors: anchors,
1637
+ __self: this,
1638
+ __source: {
1639
+ fileName: _jsxFileName$b,
1640
+ lineNumber: 11,
1641
+ columnNumber: 5
1642
+ }
1643
+ }));
1644
+ }
1645
+ function PositionedPopover({
1646
+ rangeKey,
1647
+ subjectRange,
1648
+ anchors
1649
+ }) {
1650
+ const {
1651
+ contentElementPermaId
1652
+ } = useContentElementAttributes();
1653
+ const {
1654
+ refs,
1655
+ floatingStyles,
1656
+ hasAnchor
1657
+ } = useAnchoredFloating(rangeKey, anchors, {
1658
+ placement: 'left-end'
1659
+ });
1660
+ if (!hasAnchor) return null;
1661
+ return /*#__PURE__*/React.createElement("div", {
1662
+ ref: refs.setFloating,
1663
+ className: styles$7.floating,
1664
+ style: floatingStyles,
1665
+ __self: this,
1666
+ __source: {
1667
+ fileName: _jsxFileName$b,
1668
+ lineNumber: 27,
1669
+ columnNumber: 5
1670
+ }
1671
+ }, /*#__PURE__*/React.createElement(Popover, {
1672
+ subjectType: "ContentElement",
1673
+ subjectId: contentElementPermaId,
1674
+ subjectRange: subjectRange,
1675
+ hideNewTopicButton: true,
1676
+ __self: this,
1677
+ __source: {
1678
+ fileName: _jsxFileName$b,
1679
+ lineNumber: 28,
1680
+ columnNumber: 7
1681
+ }
1682
+ }));
1683
+ }
1684
+
1685
+ const slateSelection = {
1686
+ inEditor(editor) {
1687
+ const domSelection = window.getSelection();
1688
+ if (!domSelection || !domSelection.anchorNode || !domSelection.focusNode || domSelection.isCollapsed) return null;
1689
+ if (!ReactEditor.hasDOMNode(editor, domSelection.anchorNode) || !ReactEditor.hasDOMNode(editor, domSelection.focusNode)) return null;
1690
+ try {
1691
+ return ReactEditor.toSlateRange(editor, domSelection);
1692
+ } catch (e) {
1693
+ return null;
1694
+ }
1695
+ }
1696
+ };
1697
+
1698
+ var commentingStyles = {"activeOverlay":"EditableTextHighlight-module_activeOverlay__6krun","clickable":"EditableTextHighlight-module_clickable__1nF8U"};
1699
+
1700
+ var _jsxFileName$c = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/frontend/commenting/EditableText.js";
1701
+ const defaultValue = [{
1702
+ type: 'paragraph',
1703
+ children: [{
1704
+ text: ''
1705
+ }]
1706
+ }];
1707
+ const EditableText = React.memo(function EditableText(props) {
1708
+ const {
1709
+ inlineComments
1710
+ } = useContentElementAttributes();
1711
+ const {
1712
+ visible
1713
+ } = useCommentingVisibility();
1714
+ if (inlineComments && visible) {
1715
+ return /*#__PURE__*/React.createElement(CommentingEditableText, Object.assign({}, props, {
1716
+ __self: this,
1717
+ __source: {
1718
+ fileName: _jsxFileName$c,
1719
+ lineNumber: 31,
1720
+ columnNumber: 12
1721
+ }
1722
+ }));
1723
+ }
1724
+ return /*#__PURE__*/React.createElement(PlainEditableText, Object.assign({}, props, {
1725
+ __self: this,
1726
+ __source: {
1727
+ fileName: _jsxFileName$c,
1728
+ lineNumber: 34,
1729
+ columnNumber: 10
1730
+ }
1731
+ }));
1732
+ });
1733
+ function CommentingEditableText({
1734
+ value,
1735
+ className,
1736
+ scaleCategory = 'body',
1737
+ typographyVariant,
1738
+ typographySize
1739
+ }) {
1740
+ const editor = useMemo(() => withLinks(withReact(createEditor())), []);
1741
+ const {
1742
+ anchors,
1743
+ registerAnchor
1744
+ } = useRangeAnchors();
1745
+ const {
1746
+ contentElementPermaId
1747
+ } = useContentElementAttributes();
1748
+ const {
1749
+ active,
1750
+ deactivate,
1751
+ preselect,
1752
+ clearPreselection
1753
+ } = useAddCommentMode();
1754
+ const {
1755
+ subjectRange,
1756
+ select,
1757
+ highlightedThreadId
1758
+ } = useSelectedSubject('ContentElement', contentElementPermaId);
1759
+ const {
1760
+ resolution
1761
+ } = useCommentDisplayFilter();
1762
+ const threads = useCommentThreads({
1763
+ subjectType: 'ContentElement',
1764
+ subjectId: contentElementPermaId,
1765
+ resolution,
1766
+ revealedThreadId: highlightedThreadId
1767
+ });
1768
+ const highlights = useCommentHighlights(threads, subjectRange);
1769
+ usePreselection(editor, contentElementPermaId, threads, active, preselect, clearPreselection);
1770
+ const handleMouseUp = useSelectTextOnMouseUp(active, editor, threads, deactivate, select);
1771
+ const decorate = useMemo(() => decorateCommentHighlights(editor, highlights), [editor, highlights]);
1772
+ const renderLeafCb = useCallback(({
1773
+ attributes,
1774
+ children,
1775
+ leaf
1776
+ }) => {
1777
+ if (leaf.commentHighlight) {
1778
+ children = /*#__PURE__*/React.createElement(ClickableHighlight, {
1779
+ subjectRange: leaf.subjectRange,
1780
+ __self: this,
1781
+ __source: {
1782
+ fileName: _jsxFileName$c,
1783
+ lineNumber: 67,
1784
+ columnNumber: 9
1785
+ }
1786
+ }, children);
1787
+ }
1788
+ if (leaf.lastInRange) {
1789
+ children = /*#__PURE__*/React.createElement(RangeAnchor, {
1790
+ rangeKey: leaf.rangeKey,
1791
+ onRegister: registerAnchor,
1792
+ __self: this,
1793
+ __source: {
1794
+ fileName: _jsxFileName$c,
1795
+ lineNumber: 75,
1796
+ columnNumber: 9
1797
+ }
1798
+ }, children);
1799
+ }
1800
+ return renderLeaf({
1801
+ attributes,
1802
+ children,
1803
+ leaf
1804
+ });
1805
+ }, [registerAnchor]);
1806
+ return /*#__PURE__*/React.createElement("div", {
1807
+ ref: anchors.containerRef,
1808
+ className: classNames(textStyles.root, className, {
1809
+ [commentingStyles.activeOverlay]: active && !subjectRange
1810
+ }),
1811
+ "data-add-comment-overlay": true,
1812
+ style: {
1813
+ position: 'relative'
1814
+ },
1815
+ __self: this,
1816
+ __source: {
1817
+ fileName: _jsxFileName$c,
1818
+ lineNumber: 85,
1819
+ columnNumber: 5
1820
+ }
1821
+ }, /*#__PURE__*/React.createElement(Text, {
1822
+ scaleCategory: scaleCategory,
1823
+ typographyVariant: typographyVariant,
1824
+ typographySize: typographySize,
1825
+ __self: this,
1826
+ __source: {
1827
+ fileName: _jsxFileName$c,
1828
+ lineNumber: 90,
1829
+ columnNumber: 7
1830
+ }
1831
+ }, /*#__PURE__*/React.createElement(Slate, {
1832
+ editor: editor,
1833
+ value: value || defaultValue,
1834
+ onChange: () => {},
1835
+ __self: this,
1836
+ __source: {
1837
+ fileName: _jsxFileName$c,
1838
+ lineNumber: 93,
1839
+ columnNumber: 9
1840
+ }
1841
+ }, /*#__PURE__*/React.createElement(Editable, {
1842
+ key: (subjectRange ? 'highlighted' : 'plain') + threads.length,
1843
+ onMouseUp: handleMouseUp,
1844
+ readOnly: true,
1845
+ decorate: decorate,
1846
+ renderElement: renderElement,
1847
+ renderLeaf: renderLeafCb,
1848
+ __self: this,
1849
+ __source: {
1850
+ fileName: _jsxFileName$c,
1851
+ lineNumber: 96,
1852
+ columnNumber: 11
1853
+ }
1854
+ }))), active && !subjectRange && /*#__PURE__*/React.createElement(AddCommentHint, {
1855
+ __self: this,
1856
+ __source: {
1857
+ fileName: _jsxFileName$c,
1858
+ lineNumber: 104,
1859
+ columnNumber: 35
1860
+ }
1861
+ }), /*#__PURE__*/React.createElement(PopoversColumn, {
1862
+ highlights: highlights,
1863
+ anchors: anchors,
1864
+ __self: this,
1865
+ __source: {
1866
+ fileName: _jsxFileName$c,
1867
+ lineNumber: 105,
1868
+ columnNumber: 7
1869
+ }
1870
+ }));
1871
+ }
1872
+ function ClickableHighlight({
1873
+ subjectRange,
1874
+ children
1875
+ }) {
1876
+ const {
1877
+ contentElementPermaId
1878
+ } = useContentElementAttributes();
1879
+ const {
1880
+ deactivate
1881
+ } = useAddCommentMode();
1882
+ const {
1883
+ isSelected,
1884
+ revealOnly,
1885
+ select,
1886
+ highlightedThreadId
1887
+ } = useSelectedSubject('ContentElement', contentElementPermaId, subjectRange);
1888
+ function handleClick(event) {
1889
+ if (event.target.closest('a')) return;
1890
+ if (isSelected && !revealOnly) return;
1891
+ deactivate();
1892
+ select(revealOnly ? {
1893
+ highlightedThreadId
1894
+ } : undefined);
1895
+ }
1896
+ return /*#__PURE__*/React.createElement("span", {
1897
+ className: classNames(commentHighlightStyles.highlight, {
1898
+ [commentHighlightStyles.selected]: isSelected,
1899
+ [commentingStyles.clickable]: !isSelected || revealOnly
1900
+ }),
1901
+ "data-comment-highlight": true,
1902
+ onClick: handleClick,
1903
+ __self: this,
1904
+ __source: {
1905
+ fileName: _jsxFileName$c,
1906
+ lineNumber: 126,
1907
+ columnNumber: 5
1908
+ }
1909
+ }, children);
1910
+ }
1911
+ function useSelectTextOnMouseUp(active, editor, threads, deactivate, select) {
1912
+ return useCallback(event => {
1913
+ if (!active) return;
1914
+ const slateRange = slateSelection.inEditor(editor) || topLevelRangeFromEvent(editor, event);
1915
+ if (!slateRange) return;
1916
+ const matchingThread = findMatchingThread(threads, slateRange);
1917
+ deactivate();
1918
+ select({
1919
+ subjectRange: (matchingThread === null || matchingThread === void 0 ? void 0 : matchingThread.subjectRange) || slateRange,
1920
+ showNewForm: !matchingThread
1921
+ });
1922
+ }, [active, editor, threads, deactivate, select]);
1923
+ }
1924
+ function topLevelRangeFromEvent(editor, event) {
1925
+ if (event.target.closest('a')) return null;
1926
+ if (event.target.closest('[data-comment-highlight]')) return null;
1927
+ try {
1928
+ const node = ReactEditor.toSlateNode(editor, event.target);
1929
+ const path = ReactEditor.findPath(editor, node);
1930
+ if (!path.length) return null;
1931
+ return Editor.range(editor, [path[0]]);
1932
+ } catch (e) {
1933
+ return null;
1934
+ }
1935
+ }
1936
+ function usePreselection(editor, contentElementPermaId, threads, active, preselect, clearPreselection) {
1937
+ useEffect(() => {
1938
+ function handleSelectionChange() {
1939
+ if (active) return;
1940
+ const slateRange = slateSelection.inEditor(editor);
1941
+ if (slateRange) {
1942
+ const matchingThread = findMatchingThread(threads, slateRange);
1943
+ preselect({
1944
+ subjectType: 'ContentElement',
1945
+ subjectId: contentElementPermaId,
1946
+ subjectRange: (matchingThread === null || matchingThread === void 0 ? void 0 : matchingThread.subjectRange) || slateRange,
1947
+ showNewForm: !matchingThread
1948
+ });
1949
+ } else {
1950
+ clearPreselection(contentElementPermaId);
1951
+ }
1952
+ }
1953
+ document.addEventListener('selectionchange', handleSelectionChange);
1954
+ return () => document.removeEventListener('selectionchange', handleSelectionChange);
1955
+ }, [editor, contentElementPermaId, threads, active, preselect, clearPreselection]);
1956
+ }
1957
+ function findMatchingThread(threads, slateRange) {
1958
+ const key = JSON.stringify(slateRange);
1959
+ return threads.find(t => JSON.stringify(t.subjectRange) === key);
1960
+ }
1961
+ function withLinks(editor) {
1962
+ const {
1963
+ isInline
1964
+ } = editor;
1965
+ editor.isInline = element => {
1966
+ return element.type === 'link' ? true : isInline(element);
1967
+ };
1968
+ return editor;
1969
+ }
1970
+
1971
+ const extensions = {
1972
+ decorators: {
1973
+ Entry: EntryDecorator,
1974
+ Section: SectionDecorator,
1975
+ ContentElement: ContentElementDecorator
1976
+ },
1977
+ alternatives: {
1978
+ EditableText
1979
+ }
1980
+ };
1981
+
1982
+ export { extensions };