wagtail 7.1.2__py3-none-any.whl → 7.2rc1__py3-none-any.whl

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 (332) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_page.py +1 -1
  3. wagtail/actions/create_alias.py +1 -1
  4. wagtail/actions/delete_page.py +1 -1
  5. wagtail/actions/publish_page_revision.py +1 -1
  6. wagtail/actions/publish_revision.py +1 -1
  7. wagtail/actions/revert_to_page_revision.py +1 -1
  8. wagtail/actions/unpublish.py +1 -1
  9. wagtail/actions/unpublish_page.py +1 -1
  10. wagtail/admin/auth.py +3 -1
  11. wagtail/admin/checks.py +2 -2
  12. wagtail/admin/filters.py +28 -1
  13. wagtail/admin/forms/collections.py +1 -1
  14. wagtail/admin/forms/comments.py +1 -1
  15. wagtail/admin/forms/models.py +1 -1
  16. wagtail/admin/forms/pages.py +1 -1
  17. wagtail/admin/forms/tags.py +1 -1
  18. wagtail/admin/locale/cs/LC_MESSAGES/django.mo +0 -0
  19. wagtail/admin/locale/cs/LC_MESSAGES/django.po +25 -1
  20. wagtail/admin/locale/en/LC_MESSAGES/django.po +278 -192
  21. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +29 -15
  22. wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
  23. wagtail/admin/locale/it/LC_MESSAGES/django.po +3 -2
  24. wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
  25. wagtail/admin/locale/nl/LC_MESSAGES/django.po +57 -3
  26. wagtail/admin/locale/nl/LC_MESSAGES/djangojs.mo +0 -0
  27. wagtail/admin/locale/nl/LC_MESSAGES/djangojs.po +8 -2
  28. wagtail/admin/locale/ru/LC_MESSAGES/django.mo +0 -0
  29. wagtail/admin/locale/ru/LC_MESSAGES/django.po +58 -1
  30. wagtail/admin/locale/tr/LC_MESSAGES/django.mo +0 -0
  31. wagtail/admin/locale/tr/LC_MESSAGES/django.po +3 -2
  32. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  33. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  34. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  37. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  38. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  39. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +2 -2
  40. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  42. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/icons.js +1 -1
  44. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  45. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  46. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  47. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  48. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  49. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  50. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  51. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  52. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  53. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  54. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  55. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  56. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +2 -2
  57. wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-modal.js +1 -1
  58. wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-transition.js +1 -1
  59. wagtail/admin/static/wagtailadmin/js/vendor/jquery-3.6.0.min.js +1 -1
  60. wagtail/admin/static/wagtailadmin/js/vendor/jquery-ui-1.13.2.min.js +1 -1
  61. wagtail/admin/static/wagtailadmin/js/vendor/jquery.datetimepicker.js +1 -1
  62. wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload-process.js +1 -1
  63. wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload.js +1 -1
  64. wagtail/admin/static/wagtailadmin/js/vendor/jquery.iframe-transport.js +1 -1
  65. wagtail/admin/static/wagtailadmin/js/vendor/tag-it.js +1 -1
  66. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  67. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +1 -1
  68. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  69. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  70. wagtail/admin/templates/wagtailadmin/account/account.html +2 -0
  71. wagtail/admin/templates/wagtailadmin/base.html +14 -0
  72. wagtail/admin/templates/wagtailadmin/generic/chooser/chooser.html +2 -1
  73. wagtail/admin/templates/wagtailadmin/generic/chooser/creation_form.html +2 -1
  74. wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
  75. wagtail/admin/templates/wagtailadmin/panels/object_list.html +1 -1
  76. wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +3 -2
  77. wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +1 -1
  78. wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
  79. wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +19 -0
  80. wagtail/admin/templates/wagtailadmin/shared/panel.html +1 -1
  81. wagtail/admin/templates/wagtailadmin/shared/set_privacy.html +15 -0
  82. wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +28 -1
  83. wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +2 -2
  84. wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_header.html → tables/ordering_header.html} +2 -2
  85. wagtail/admin/templates/wagtailadmin/tables/title_cell.html +1 -1
  86. wagtail/admin/templates/wagtailadmin/widgets/{daterange_input.html → range_input.html} +1 -1
  87. wagtail/admin/templates/wagtailadmin/workflows/task_chooser/chooser.html +4 -2
  88. wagtail/admin/templatetags/wagtailadmin_tags.py +41 -22
  89. wagtail/admin/tests/api/test_pages.py +7 -7
  90. wagtail/admin/tests/api/test_renderer_classes.py +16 -0
  91. wagtail/admin/tests/pages/test_create_page.py +34 -2
  92. wagtail/admin/tests/pages/test_edit_page.py +128 -14
  93. wagtail/admin/tests/pages/test_explorer_view.py +34 -7
  94. wagtail/admin/tests/pages/test_reorder_page.py +11 -0
  95. wagtail/admin/tests/test_collections_views.py +12 -0
  96. wagtail/admin/tests/test_edit_handlers.py +3 -3
  97. wagtail/admin/tests/test_filters.py +2 -2
  98. wagtail/admin/tests/test_keyboard_shortcuts.py +52 -2
  99. wagtail/admin/tests/test_menu.py +0 -2
  100. wagtail/admin/tests/test_privacy.py +16 -16
  101. wagtail/admin/tests/test_templatetags.py +137 -0
  102. wagtail/admin/tests/test_workflows.py +34 -0
  103. wagtail/admin/tests/viewsets/test_model_viewset.py +322 -0
  104. wagtail/admin/ui/tables/orderable.py +73 -0
  105. wagtail/admin/ui/tables/pages.py +3 -13
  106. wagtail/admin/views/collection_privacy.py +6 -2
  107. wagtail/admin/views/generic/__init__.py +1 -0
  108. wagtail/admin/views/generic/mixins.py +20 -2
  109. wagtail/admin/views/generic/models.py +67 -1
  110. wagtail/admin/views/generic/ordering.py +79 -0
  111. wagtail/admin/views/home.py +3 -3
  112. wagtail/admin/views/page_privacy.py +5 -2
  113. wagtail/admin/views/pages/create.py +1 -1
  114. wagtail/admin/views/pages/edit.py +2 -2
  115. wagtail/admin/views/pages/listing.py +7 -42
  116. wagtail/admin/views/pages/move.py +1 -1
  117. wagtail/admin/views/pages/ordering.py +1 -1
  118. wagtail/admin/viewsets/base.py +1 -1
  119. wagtail/admin/viewsets/model.py +49 -1
  120. wagtail/admin/wagtail_hooks.py +2 -1
  121. wagtail/admin/widgets/slug.py +10 -10
  122. wagtail/api/v2/serializers.py +1 -1
  123. wagtail/api/v2/tests/test_renderer_classes.py +32 -0
  124. wagtail/apps.py +2 -0
  125. wagtail/bin/wagtail.py +1 -1
  126. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +14 -14
  127. wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.mo +0 -0
  128. wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.po +19 -2
  129. wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.mo +0 -0
  130. wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +18 -1
  131. wagtail/contrib/frontend_cache/tests.py +4 -2
  132. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +4 -4
  133. wagtail/contrib/redirects/tests/test_tmp_storages.py +20 -0
  134. wagtail/contrib/redirects/tmp_storages.py +1 -1
  135. wagtail/contrib/redirects/views.py +3 -3
  136. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +3 -3
  137. wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.mo +0 -0
  138. wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +43 -3
  139. wagtail/contrib/search_promotions/static/wagtailsearchpromotions/js/query-chooser-modal.js +1 -1
  140. wagtail/contrib/search_promotions/views/settings.py +2 -2
  141. wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.mo +0 -0
  142. wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.po +6 -1
  143. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +1 -1
  144. wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.mo +0 -0
  145. wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.po +6 -2
  146. wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.mo +0 -0
  147. wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +6 -1
  148. wagtail/contrib/settings/tests/site_specific/test_admin.py +40 -6
  149. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  150. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
  151. wagtail/contrib/styleguide/templates/wagtailstyleguide/base.html +5 -5
  152. wagtail/contrib/table_block/blocks.py +1 -0
  153. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +5 -1
  154. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  155. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
  156. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  157. wagtail/coreutils.py +5 -5
  158. wagtail/documents/forms.py +18 -1
  159. wagtail/documents/locale/en/LC_MESSAGES/django.po +10 -10
  160. wagtail/documents/locale/nl/LC_MESSAGES/django.mo +0 -0
  161. wagtail/documents/locale/nl/LC_MESSAGES/django.po +9 -0
  162. wagtail/documents/locale/ru/LC_MESSAGES/django.mo +0 -0
  163. wagtail/documents/locale/ru/LC_MESSAGES/django.po +9 -0
  164. wagtail/documents/models.py +1 -1
  165. wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
  166. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  167. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  168. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  169. wagtail/documents/templates/wagtaildocs/documents/add.html +0 -34
  170. wagtail/documents/tests/test_admin_views.py +132 -26
  171. wagtail/documents/tests/test_collection_privacy.py +18 -4
  172. wagtail/documents/tests/test_form_overrides.py +1 -1
  173. wagtail/documents/tests/test_search.py +21 -8
  174. wagtail/documents/views/documents.py +1 -1
  175. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  176. wagtail/embeds/static/wagtailembeds/js/embed-chooser-modal.js +1 -1
  177. wagtail/images/forms.py +16 -1
  178. wagtail/images/locale/cs/LC_MESSAGES/django.mo +0 -0
  179. wagtail/images/locale/cs/LC_MESSAGES/django.po +12 -1
  180. wagtail/images/locale/en/LC_MESSAGES/django.po +57 -46
  181. wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
  182. wagtail/images/locale/nl/LC_MESSAGES/django.po +37 -14
  183. wagtail/images/locale/ru/LC_MESSAGES/django.mo +0 -0
  184. wagtail/images/locale/ru/LC_MESSAGES/django.po +20 -1
  185. wagtail/images/models.py +1 -1
  186. wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
  187. wagtail/images/static/wagtailimages/js/focal-point-chooser.js +1 -1
  188. wagtail/images/static/wagtailimages/js/image-block.js +1 -1
  189. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  190. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  191. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  192. wagtail/images/static/wagtailimages/js/image-url-generator.js +1 -1
  193. wagtail/images/static/wagtailimages/js/vendor/jquery.Jcrop.min.js +1 -1
  194. wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
  195. wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-validate.js +1 -1
  196. wagtail/images/static/wagtailimages/js/vendor/load-image.min.js +1 -1
  197. wagtail/images/templates/wagtailimages/chooser/chooser.html +22 -13
  198. wagtail/images/templates/wagtailimages/chooser/image_preview_column_cell.html +10 -0
  199. wagtail/images/templates/wagtailimages/chooser/results.html +24 -20
  200. wagtail/images/templates/wagtailimages/chooser/title_column_cell.html +15 -0
  201. wagtail/images/templates/wagtailimages/images/add.html +0 -34
  202. wagtail/images/templates/wagtailimages/images/index.html +3 -3
  203. wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
  204. wagtail/images/templates/wagtailimages/images/layout_toggle_button.html +8 -7
  205. wagtail/images/templatetags/wagtailimages_tags.py +2 -2
  206. wagtail/images/tests/test_admin_views.py +87 -0
  207. wagtail/images/tests/test_form_overrides.py +1 -1
  208. wagtail/images/tests/test_models.py +48 -9
  209. wagtail/images/views/chooser.py +66 -2
  210. wagtail/locale/en/LC_MESSAGES/django.po +55 -55
  211. wagtail/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  212. wagtail/locale/is_IS/LC_MESSAGES/django.po +3 -3
  213. wagtail/locale/nl/LC_MESSAGES/django.mo +0 -0
  214. wagtail/locale/nl/LC_MESSAGES/django.po +11 -2
  215. wagtail/locale/ru/LC_MESSAGES/django.mo +0 -0
  216. wagtail/locale/ru/LC_MESSAGES/django.po +11 -1
  217. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  218. wagtail/locales/locale/nl/LC_MESSAGES/django.mo +0 -0
  219. wagtail/locales/locale/nl/LC_MESSAGES/django.po +12 -1
  220. wagtail/locales/locale/ru/LC_MESSAGES/django.mo +0 -0
  221. wagtail/locales/locale/ru/LC_MESSAGES/django.po +10 -1
  222. wagtail/locales/views.py +2 -2
  223. wagtail/models/orderable.py +10 -0
  224. wagtail/models/pages.py +9 -11
  225. wagtail/models/sites.py +1 -1
  226. wagtail/models/workflows.py +8 -5
  227. wagtail/project_template/home/tests.py +6 -7
  228. wagtail/project_template/project_name/settings/base.py +9 -9
  229. wagtail/project_template/requirements.txt +1 -1
  230. wagtail/query.py +7 -2
  231. wagtail/rich_text/rewriters.py +1 -1
  232. wagtail/search/apps.py +4 -49
  233. wagtail/search/backends/__init__.py +1 -113
  234. wagtail/search/backends/base.py +1 -547
  235. wagtail/search/backends/database/__init__.py +1 -50
  236. wagtail/search/backends/database/fallback.py +1 -253
  237. wagtail/search/backends/database/mysql/mysql.py +1 -700
  238. wagtail/search/backends/database/mysql/query.py +1 -258
  239. wagtail/search/backends/database/postgres/postgres.py +1 -749
  240. wagtail/search/backends/database/postgres/query.py +1 -83
  241. wagtail/search/backends/database/postgres/weights.py +1 -63
  242. wagtail/search/backends/database/sqlite/query.py +1 -294
  243. wagtail/search/backends/database/sqlite/sqlite.py +1 -719
  244. wagtail/search/backends/database/sqlite/utils.py +1 -35
  245. wagtail/search/backends/deprecation.py +45 -0
  246. wagtail/search/backends/elasticsearch7.py +18 -1260
  247. wagtail/search/backends/elasticsearch8.py +21 -96
  248. wagtail/search/backends/elasticsearch9.py +35 -0
  249. wagtail/search/backends/opensearch2.py +35 -0
  250. wagtail/search/backends/opensearch3.py +35 -0
  251. wagtail/search/index.py +1 -358
  252. wagtail/search/locale/en/LC_MESSAGES/django.po +2 -10
  253. wagtail/search/management/commands/update_index.py +1 -205
  254. wagtail/search/management/commands/wagtail_update_index.py +1 -4
  255. wagtail/search/models.py +32 -158
  256. wagtail/search/query.py +1 -114
  257. wagtail/search/queryset.py +1 -43
  258. wagtail/search/signal_handlers.py +1 -24
  259. wagtail/search/tasks.py +1 -10
  260. wagtail/search/tests/test_elasticsearch.py +22 -0
  261. wagtail/search/utils.py +1 -206
  262. wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
  263. wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -3
  264. wagtail/snippets/locale/ru/LC_MESSAGES/django.mo +0 -0
  265. wagtail/snippets/locale/ru/LC_MESSAGES/django.po +8 -1
  266. wagtail/snippets/locale/tr/LC_MESSAGES/django.mo +0 -0
  267. wagtail/snippets/locale/tr/LC_MESSAGES/django.po +8 -1
  268. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  269. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  270. wagtail/snippets/tests/test_reordering.py +319 -0
  271. wagtail/snippets/tests/test_snippets.py +65 -12
  272. wagtail/snippets/views/snippets.py +16 -0
  273. wagtail/test/numberformat.py +30 -0
  274. wagtail/test/settings.py +35 -12
  275. wagtail/test/testapp/fields.py +12 -0
  276. wagtail/test/testapp/migrations/0056_commentablejsonpage.py +50 -0
  277. wagtail/test/testapp/migrations/0057_featurecompletetoy_sort_order.py +23 -0
  278. wagtail/test/testapp/migrations/0058_customlocktask.py +31 -0
  279. wagtail/test/testapp/models.py +27 -0
  280. wagtail/test/testapp/views.py +3 -1
  281. wagtail/test/utils/page_tests.py +17 -17
  282. wagtail/test/utils/template_tests.py +4 -6
  283. wagtail/test/utils/wagtail_tests.py +1 -2
  284. wagtail/tests/test_page_model.py +15 -0
  285. wagtail/{search/tests → tests}/test_page_search.py +29 -2
  286. wagtail/tests/test_search_fields.py +69 -0
  287. wagtail/tests/test_tests.py +62 -6
  288. wagtail/tests/test_workflow.py +25 -1
  289. wagtail/users/locale/cs/LC_MESSAGES/django.mo +0 -0
  290. wagtail/users/locale/cs/LC_MESSAGES/django.po +3 -0
  291. wagtail/users/locale/en/LC_MESSAGES/django.po +2 -2
  292. wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
  293. wagtail/users/locale/nl/LC_MESSAGES/django.po +6 -3
  294. wagtail/users/locale/ru/LC_MESSAGES/django.mo +0 -0
  295. wagtail/users/locale/ru/LC_MESSAGES/django.po +5 -1
  296. wagtail/users/locale/tr/LC_MESSAGES/django.mo +0 -0
  297. wagtail/users/locale/tr/LC_MESSAGES/django.po +78 -4
  298. wagtail/users/templates/wagtailusers/users/create.html +2 -0
  299. wagtail/users/templates/wagtailusers/users/edit.html +2 -0
  300. wagtail/users/tests/test_admin_views.py +4 -0
  301. wagtail/users/views/users.py +1 -1
  302. {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/METADATA +7 -6
  303. {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/RECORD +309 -315
  304. wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +0 -13
  305. wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +0 -13
  306. wagtail/search/tests/__init__.py +0 -0
  307. wagtail/search/tests/elasticsearch_common_tests.py +0 -251
  308. wagtail/search/tests/test_backends.py +0 -1215
  309. wagtail/search/tests/test_db_backend.py +0 -62
  310. wagtail/search/tests/test_elasticsearch7_backend.py +0 -1452
  311. wagtail/search/tests/test_elasticsearch8_backend.py +0 -15
  312. wagtail/search/tests/test_index_functions.py +0 -256
  313. wagtail/search/tests/test_indexed_class.py +0 -157
  314. wagtail/search/tests/test_mysql_backend.py +0 -192
  315. wagtail/search/tests/test_postgres_backend.py +0 -210
  316. wagtail/search/tests/test_queries.py +0 -332
  317. wagtail/search/tests/test_related_fields.py +0 -102
  318. wagtail/search/tests/test_sqlite_backend.py +0 -52
  319. wagtail/test/search/__init__.py +0 -0
  320. wagtail/test/search/apps.py +0 -9
  321. wagtail/test/search/fixtures/search.json +0 -545
  322. wagtail/test/search/migrations/0001_initial.py +0 -146
  323. wagtail/test/search/migrations/0002_bookunindexed.py +0 -43
  324. wagtail/test/search/migrations/0003_book_summary.py +0 -18
  325. wagtail/test/search/migrations/__init__.py +0 -0
  326. wagtail/test/search/models.py +0 -137
  327. /wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_cell.html → tables/ordering_cell.html} +0 -0
  328. /wagtail/{search/checks.py → checks.py} +0 -0
  329. {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/WHEEL +0 -0
  330. {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/entry_points.txt +0 -0
  331. {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/licenses/LICENSE +0 -0
  332. {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/top_level.txt +0 -0
@@ -61,7 +61,7 @@ object-assign
61
61
  */
62
62
 
63
63
  /**!
64
- * Sortable 1.15.3
64
+ * Sortable 1.15.6
65
65
  * @author RubaXa <trash@rubaxa.org>
66
66
  * @author owenm <owen23355@gmail.com>
67
67
  * @license MIT
@@ -1 +1 @@
1
- (()=>{"use strict";var e,t={412:(e,t,n)=>{var a=n(2833);var r=n(4072);const l=(e,t=!("true"===e.getAttribute("aria-expanded")))=>{const n=document.querySelector(`#${e.getAttribute("aria-controls")}`);n&&(e.setAttribute("aria-expanded",`${t}`),t?n.removeAttribute("hidden"):"onbeforematch"in document.body?n.setAttribute("hidden","until-found"):n.setAttribute("hidden",""),e.dispatchEvent(new CustomEvent("commentAnchorVisibilityChange",{bubbles:!0})),e.dispatchEvent(new CustomEvent("wagtail:panel-toggle",{bubbles:!0,cancelable:!1,detail:{expanded:t}})))};function i(e){const t=e.closest("[data-panel]"),n=document.querySelector(`#${e.getAttribute("aria-controls")}`);if(!n||!t||t.collapsibleInitialised)return;t.collapsibleInitialised=!0;const a=l.bind(null,e),r=t.classList.contains("collapsed"),i=n.querySelector('[aria-invalid="true"], .error, .w-field--error'),o=r&&!i;o&&a(!1),e.addEventListener("click",a.bind(null,void 0));const s=t.querySelector("[data-panel-heading]");s&&s.addEventListener("click",a.bind(null,void 0)),n.addEventListener("beforematch",a.bind(null,!0)),e.dispatchEvent(new CustomEvent("wagtail:panel-init",{bubbles:!0,cancelable:!1,detail:{expanded:!o}}))}var o=n(2427),s=n.n(o),c=n(6931),d=n.n(c),u=n(8667),m=n(1238);const p=({expanded:e,floating:t,insideMinimap:n,onClick:r})=>s().createElement("button",{type:"button","aria-expanded":e,onClick:r,className:`button button-small button-secondary w-minimap__collapse-all ${t?"w-minimap__collapse-all--floating":""} ${n?"w-minimap__collapse-all--inside":""}`},s().createElement(m.A,{name:e?"collapse-up":"collapse-down"}),e?(0,a.AP)("Collapse all"):(0,a.AP)("Expand all")),g=s().createElement("span",{className:"w-required-mark"},"*"),h=({item:e,intersects:t,expanded:n,onClick:r})=>{const{href:l,label:i,icon:o,required:c,errorCount:d,level:u}=e,p=d>0,h=(0,a.WI)("%(num)s error","%(num)s errors",d).replace("%(num)s",`${d}`),f=i.length>22?`${i.substring(0,22)}…`:i;return s().createElement("a",{href:l,className:`w-minimap-item w-minimap-item--${u} ${t?"w-minimap-item--active":""} ${p?"w-minimap-item--error":""}`,onClick:r.bind(null,e),"aria-current":t,tabIndex:n?void 0:-1,"aria-describedby":n?void 0:"w-minimap-toggle"},p?s().createElement("div",{className:"w-minimap-item__errors","aria-label":h},d):null,s().createElement(m.A,{name:"minus",className:"w-minimap-item__placeholder"}),"h1"!==u&&"h2"!==u?s().createElement(m.A,{name:o,className:"w-minimap-item__icon"}):null,s().createElement("span",{className:"w-minimap-item__label"},s().createElement("span",{className:"w-minimap-item__text"},f),c?g:null))},f={root:null,rootMargin:"-50px 0px -70px 0px",threshold:.1},b=(e,{target:t,isIntersecting:n})=>{const a=t.closest("[data-panel]")?.id;return a?(e[`#${a}`]=n,e):e},v=({container:e,anchorsContainer:t,links:n,onUpdate:r,toggleAllPanels:i})=>{const c=(0,o.useMemo)((()=>(()=>{let e="false";try{e=localStorage.getItem("wagtail:minimap-expanded")||e}catch{}return"true"===e})()),[]),[d,g]=(0,o.useState)(c),v=(0,o.useCallback)(((e=!d)=>{g(e),document.body.classList.toggle("minimap-open",e);try{localStorage.setItem("wagtail:minimap-expanded",e?"true":"false")}catch{}}),[d,g]),[w,y]=(0,o.useState)(!0),[E,S]=(0,o.useState)({}),x=(0,o.useRef)(null),A=(0,o.useRef)({}),q=(0,o.useRef)(null),L=(0,o.useRef)(null),C=(e,t)=>{d||t.preventDefault(),l(e.toggle,!0),v(!0)};return(0,o.useEffect)((()=>{v(c)}),[]),(0,o.useEffect)((()=>{x.current||(x.current=new IntersectionObserver((t=>{A.current=t.reduce(b,{...A.current}),q.current||(q.current=(0,u.s)((e=>{S(e),(e=>{const t=e.querySelectorAll('a[aria-current="true"]');if(0===t.length||e.scrollHeight===e.clientHeight)return;const n=t[0],a=t[t.length-1];let r=e.scrollTop;n&&n.offsetTop<e.scrollTop&&(r=n.offsetTop),a&&a.offsetTop>e.scrollTop+e.offsetHeight&&(r=a.offsetTop-e.offsetHeight+a.offsetHeight),e.scrollTop=r})(L.current)}),100)),q.current(A.current),t.forEach((({target:t})=>{t.closest(".deleted")&&r(e)}))}),f));const t=x.current;return t.disconnect(),n.forEach((({panel:e,toggle:n})=>{const a=e.matches(".w-panel--nested")&&null===e.closest("[data-field]");t.observe(a?n:e)})),()=>{t.disconnect()}}),[n,e]),(0,o.useEffect)((()=>{y(!0)}),[t,y]),s().createElement("div",null,s().createElement(p,{expanded:w,onClick:()=>{y(!w),i(!w)},floating:!0,insideMinimap:d}),s().createElement("div",{className:"w-minimap "+(d?"w-minimap--expanded":"")},s().createElement("div",{className:"w-minimap__header"},s().createElement("button",{id:"w-minimap-toggle",type:"button","aria-expanded":d,onClick:()=>v(!d),className:"w-minimap__toggle","aria-label":(0,a.AP)("Toggle side panel"),"data-controller":"w-kbd","data-w-kbd-key-value":"]"},s().createElement(m.A,{name:"expand-right"}))),s().createElement("ol",{className:"w-minimap__list",ref:L},n.map((e=>s().createElement("li",{key:e.href},s().createElement(h,{item:e,intersects:E[e.href],expanded:d,onClick:C}))))),s().createElement("div",{className:"w-minimap__footer"})))},w=e=>{const t=e.closest("[data-panel]"),n=t?.getAttribute("aria-labelledby"),a=t?.querySelector(`#${n}`),r=t?.querySelector("[data-panel-toggle]"),l=e.closest("[data-inline-panel-child].deleted");if(!t||!a||!r||l)return null;const i=a.querySelector("[data-panel-heading-text]"),o=i?.textContent||a.textContent?.replace(/\s+\*\s+$/g,"").trim(),s=null!==t.querySelector("[data-panel-required]"),c=r.querySelector("use"),d=c?.getAttribute("href")?.replace("#icon-","")||"",u=`h${a.getAttribute("aria-level")||a.tagName[1]||2}`,m=[].slice.call(t.querySelectorAll(".error-message")).filter((e=>e.closest("[data-panel]")===t)).length;return{anchor:e,toggle:r,panel:t,icon:d,label:o||"",href:e.getAttribute("href")||"",required:s,errorCount:m,level:u}},y=e=>{let t=document.body;const n=document.querySelector('[data-controller~="w-tabs"]:not([data-panel] [data-controller~="w-tabs"]):has([data-panel-anchor])');if(n){const e=n.querySelector('[role="tab"][aria-selected="true"]'),a=e?.getAttribute("aria-controls");t=n.querySelector(`#${a}`)||t}const a=t.querySelectorAll("[data-panel-anchor]"),r=[].slice.call(a).map(w).filter(Boolean);d().render(s().createElement(v,{container:e,anchorsContainer:t,links:r,onUpdate:y,toggleAllPanels:e=>{r.forEach(((t,n)=>{0===n&&t.href.includes("title")||l(t.toggle,e)}))}}),e)};document.addEventListener("DOMContentLoaded",(()=>{(function(){const e=document.querySelector("[data-form-side]");if(!e)return;const t="formSideExplorer"in e.dataset,n=document.querySelector("[data-form-side-resize-grip]"),r=document.querySelector("[data-form-side-width-input]"),l=()=>{const t=getComputedStyle(e),n=parseFloat(t.minWidth),a=parseFloat(t.maxWidth),r=parseFloat(t.width),l=a-n;return{minWidth:n,maxWidth:a,width:r,range:l,percentage:(r-n)/l*100}},i=e=>"rtl"===document.documentElement.dir?e:100-e;let o;const s=n=>{clearTimeout(o);const a=document.querySelector("body"),s=document.querySelector(`[data-side-panel="${n}"]`);if((!n||s)&&(""===n?(e.classList.remove("form-side--open"),e.removeAttribute("aria-labelledby")):(e.classList.add("form-side--open"),e.setAttribute("aria-labelledby",`side-panel-${n}-title`)),document.querySelectorAll("[data-side-panel]").forEach((t=>{const r=t.dataset.sidePanel;if(r===n)t.hidden&&(t.hidden=!1,e.classList.add(`form-side--${r}`),a.classList.add("side-panel-open"));else if(!t.hidden){const l=()=>{t.hidden=!0,t.dispatchEvent(new CustomEvent("hide")),e.classList.remove(`form-side--${r}`)};""===n?(a.classList.remove("side-panel-open"),o=setTimeout(l,500)):l()}})),document.querySelectorAll("[data-side-panel-toggle]").forEach((e=>{e.setAttribute("aria-expanded",e.dataset.sidePanelToggle===n?"true":"false")})),s&&s.dispatchEvent(new CustomEvent("show")),!t)){try{localStorage.setItem("wagtail:side-panel-open",n)}catch(e){}setTimeout((()=>{const{percentage:e}=l();r.value=i(e)}),500)}};document.querySelectorAll("[data-side-panel]").forEach((e=>{e.addEventListener("open",(()=>{s(e.dataset.sidePanel)}))})),document.querySelectorAll("[data-side-panel-toggle]").forEach((e=>{e.addEventListener("click",(()=>{(e=>{const t=!document.querySelector(`[data-side-panel="${e}"]`).hasAttribute("hidden");s(t?"":e)})(e.dataset.sidePanelToggle)}))}));const c=document.querySelector("[data-form-side-close-button]");c instanceof HTMLButtonElement&&c.addEventListener("click",(()=>{s("")}));const d=e=>{const{minWidth:n,maxWidth:o,range:s,width:c}=l(),d=parseInt(Math.max(n,Math.min(e,o)),10)||c,u=(0,a.WI)("%(num)s pixel","%(num)s pixels",d).replace("%(num)s",d);document.documentElement.style.setProperty("--side-panel-width",`${d}px`);const m=(d-n)/s*100;if(r.value=i(m),r.setAttribute("aria-valuetext",u),!t)try{localStorage.setItem("wagtail:side-panel-width",d)}catch(e){}};let u,m;const p=e=>{if(!e.screenX||!u||!m)return;const t="rtl"===document.documentElement.dir?-1:1,n=u-e.screenX;d(m+n*t)},g=e=>{n.releasePointerCapture(e.pointerId),n.removeEventListener("pointermove",p),document.removeEventListener("pointerup",g),document.body.classList.remove("side-panel-resizing")};n.addEventListener("pointerdown",(e=>{0===e.button&&(u=e.screenX,m=l().width,document.body.classList.add("side-panel-resizing"),n.setPointerCapture(e.pointerId),n.addEventListener("pointermove",p),document.addEventListener("pointerup",g))})),r.addEventListener("change",(e=>{const{minWidth:t,range:n}=l(),a=parseInt(e.target.value,10),r=i(a);d(t+n*r/100)})),setTimeout((()=>{try{const e=localStorage.getItem("wagtail:side-panel-open");!t&&e&&s(e),d(localStorage.getItem("wagtail:side-panel-width"))}catch(e){}setTimeout((()=>{e.classList.remove("form-side--initial")}))}))})(),function(e=document.querySelectorAll("[data-panel-toggle]")){e.forEach(i)}();const e=document.getElementById("w-edit-handler-data");if(e){const t=JSON.parse(e.textContent);window.wagtail.editHandler=window.telepath.unpack(t)}})),window.addEventListener("load",(()=>{!function(e=(window.location.hash?document.getElementById(window.location.hash.slice(1)):null)){const t=e?.matches("[data-panel]")?e:(0,r.KX)();t&&setTimeout((()=>{t.scrollIntoView({behavior:"smooth"})}),100)}(),((e=document.querySelector("[data-minimap-container]"))=>{if(!e)return;if(!document.body.querySelectorAll("[data-panel-anchor]").length)return;const t=(0,u.s)(y.bind(null,e),100);document.addEventListener("w-tabs:changed",t),document.addEventListener("w-tabs:ready",t),document.addEventListener("wagtail:panel-init",t);const n=()=>e.style.setProperty("--offset-top",`${e.offsetTop}px`),a=(0,u.s)(n,100);window.addEventListener("resize",a),n(),t(e)})()}))}},n={};function a(e){var r=n[e];if(void 0!==r)return r.exports;var l=n[e]={exports:{}};return t[e](l,l.exports,a),l.exports}a.m=t,e=[],a.O=(t,n,r,l)=>{if(!n){var i=1/0;for(d=0;d<e.length;d++){for(var[n,r,l]=e[d],o=!0,s=0;s<n.length;s++)(!1&l||i>=l)&&Object.keys(a.O).every((e=>a.O[e](n[s])))?n.splice(s--,1):(o=!1,l<i&&(i=l));if(o){e.splice(d--,1);var c=r();void 0!==c&&(t=c)}}return t}l=l||0;for(var d=e.length;d>0&&e[d-1][2]>l;d--)e[d]=e[d-1];e[d]=[n,r,l]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.j=445,(()=>{var e={445:0};a.O.j=t=>0===e[t];var t=(t,n)=>{var r,l,[i,o,s]=n,c=0;if(i.some((t=>0!==e[t]))){for(r in o)a.o(o,r)&&(a.m[r]=o[r]);if(s)var d=s(a)}for(t&&t(n);c<i.length;c++)l=i[c],a.o(e,l)&&e[l]&&e[l][0](),e[l]=0;return a.O(d)},n=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})();var r=a.O(void 0,[321],(()=>a(412)));r=a.O(r)})();
1
+ (()=>{"use strict";var e,t={412:(e,t,n)=>{var a=n(2833);var r=n(4072);const l=(e,t=!("true"===e.getAttribute("aria-expanded")))=>{const n=document.querySelector(`#${e.getAttribute("aria-controls")}`);n&&(e.setAttribute("aria-expanded",`${t}`),t?n.removeAttribute("hidden"):"onbeforematch"in document.body?n.setAttribute("hidden","until-found"):n.setAttribute("hidden",""),e.dispatchEvent(new CustomEvent("commentAnchorVisibilityChange",{bubbles:!0})),e.dispatchEvent(new CustomEvent("wagtail:panel-toggle",{bubbles:!0,cancelable:!1,detail:{expanded:t}})))};function i(e){const t=e.closest("[data-panel]"),n=document.querySelector(`#${e.getAttribute("aria-controls")}`);if(!n||!t||t.collapsibleInitialised)return;t.collapsibleInitialised=!0;const a=l.bind(null,e),r=t.classList.contains("collapsed"),i=n.querySelector('[aria-invalid="true"], .error, .w-field--error'),o=r&&!i;o&&a(!1),e.addEventListener("click",a.bind(null,void 0));const s=t.querySelector("[data-panel-heading]");s&&s.addEventListener("click",a.bind(null,void 0)),n.addEventListener("beforematch",a.bind(null,!0)),e.dispatchEvent(new CustomEvent("wagtail:panel-init",{bubbles:!0,cancelable:!1,detail:{expanded:!o}}))}var o=n(2427),s=n.n(o),d=n(6931),c=n.n(d),u=n(8667),m=n(1238);const p=({expanded:e,floating:t,insideMinimap:n,onClick:r})=>s().createElement("button",{type:"button","aria-expanded":e,onClick:r,className:`button button-small button-secondary w-minimap__collapse-all ${t?"w-minimap__collapse-all--floating":""} ${n?"w-minimap__collapse-all--inside":""}`},s().createElement(m.A,{name:e?"collapse-up":"collapse-down"}),e?(0,a.AP)("Collapse all"):(0,a.AP)("Expand all")),g=s().createElement("span",{className:"w-required-mark"},"*"),h=({item:e,intersects:t,expanded:n,onClick:r})=>{const{href:l,label:i,icon:o,required:d,errorCount:c,level:u}=e,p=c>0,h=(0,a.WI)("%(num)s error","%(num)s errors",c).replace("%(num)s",`${c}`),f=i.length>22?`${i.substring(0,22)}…`:i;return s().createElement("a",{href:l,className:`w-minimap-item w-minimap-item--${u} ${t?"w-minimap-item--active":""} ${p?"w-minimap-item--error":""}`,onClick:r.bind(null,e),"aria-current":t,tabIndex:n?void 0:-1,"aria-describedby":n?void 0:"w-minimap-toggle"},p?s().createElement("div",{className:"w-minimap-item__errors","aria-label":h},c):null,s().createElement(m.A,{name:"minus",className:"w-minimap-item__placeholder"}),"h1"!==u&&"h2"!==u?s().createElement(m.A,{name:o,className:"w-minimap-item__icon"}):null,s().createElement("span",{className:"w-minimap-item__label"},s().createElement("span",{className:"w-minimap-item__text"},f),d?g:null))},f={root:null,rootMargin:"-50px 0px -70px 0px",threshold:.1},b=(e,{target:t,isIntersecting:n})=>{const a=t.closest("[data-panel]")?.id;return a?(e[`#${a}`]=n,e):e},v=({container:e,anchorsContainer:t,links:n,onUpdate:r,toggleAllPanels:i})=>{const d=(0,o.useMemo)(()=>(()=>{let e="false";try{e=localStorage.getItem("wagtail:minimap-expanded")||e}catch{}return"true"===e})(),[]),[c,g]=(0,o.useState)(d),v=(0,o.useCallback)((e=!c)=>{g(e),document.body.classList.toggle("minimap-open",e);try{localStorage.setItem("wagtail:minimap-expanded",e?"true":"false")}catch{}},[c,g]),[w,y]=(0,o.useState)(!0),[E,S]=(0,o.useState)({}),x=(0,o.useRef)(null),A=(0,o.useRef)({}),q=(0,o.useRef)(null),L=(0,o.useRef)(null),C=(e,t)=>{c||t.preventDefault(),l(e.toggle,!0),v(!0)};return(0,o.useEffect)(()=>{v(d)},[]),(0,o.useEffect)(()=>{x.current||(x.current=new IntersectionObserver(t=>{A.current=t.reduce(b,{...A.current}),q.current||(q.current=(0,u.s)(e=>{S(e),(e=>{const t=e.querySelectorAll('a[aria-current="true"]');if(0===t.length||e.scrollHeight===e.clientHeight)return;const n=t[0],a=t[t.length-1];let r=e.scrollTop;n&&n.offsetTop<e.scrollTop&&(r=n.offsetTop),a&&a.offsetTop>e.scrollTop+e.offsetHeight&&(r=a.offsetTop-e.offsetHeight+a.offsetHeight),e.scrollTop=r})(L.current)},100)),q.current(A.current),t.forEach(({target:t})=>{t.closest(".deleted")&&r(e)})},f));const t=x.current;return t.disconnect(),n.forEach(({panel:e,toggle:n})=>{const a=e.matches(".w-panel--nested")&&null===e.closest("[data-field]");t.observe(a?n:e)}),()=>{t.disconnect()}},[n,e]),(0,o.useEffect)(()=>{y(!0)},[t,y]),s().createElement("div",null,s().createElement(p,{expanded:w,onClick:()=>{y(!w),i(!w)},floating:!0,insideMinimap:c}),s().createElement("div",{className:"w-minimap "+(c?"w-minimap--expanded":"")},s().createElement("div",{className:"w-minimap__header"},s().createElement("button",{id:"w-minimap-toggle",type:"button","aria-expanded":c,onClick:()=>v(!c),className:"w-minimap__toggle","aria-label":(0,a.AP)("Toggle side panel"),"data-controller":"w-kbd","data-w-kbd-key-value":"]"},s().createElement(m.A,{name:"expand-right"}))),s().createElement("ol",{className:"w-minimap__list",ref:L},n.map(e=>s().createElement("li",{key:e.href},s().createElement(h,{item:e,intersects:E[e.href],expanded:c,onClick:C})))),s().createElement("div",{className:"w-minimap__footer"})))},w=e=>{const t=e.closest("[data-panel]"),n=t?.getAttribute("aria-labelledby"),a=t?.querySelector(`#${n}`),r=t?.querySelector("[data-panel-toggle]"),l=e.closest("[data-inline-panel-child].deleted");if(!t||!a||!r||l)return null;const i=a.querySelector("[data-panel-heading-text]"),o=i?.textContent||a.textContent?.replace(/\s+\*\s+$/g,"").trim(),s=null!==t.querySelector("[data-panel-required]"),d=r.querySelector("use"),c=d?.getAttribute("href")?.replace("#icon-","")||"",u=`h${a.getAttribute("aria-level")||a.tagName[1]||2}`,m=[].slice.call(t.querySelectorAll(":not([hidden]):is(.error-message)")).filter(e=>e.closest("[data-panel]")===t).length;return{anchor:e,toggle:r,panel:t,icon:c,label:o||"",href:e.getAttribute("href")||"",required:s,errorCount:m,level:u}},y=e=>{let t=document.body;const n=document.querySelector('[data-controller~="w-tabs"]:not([data-panel] [data-controller~="w-tabs"]):has([data-panel-anchor])');if(n){const e=n.querySelector('[role="tab"][aria-selected="true"]'),a=e?.getAttribute("aria-controls");t=n.querySelector(`#${a}`)||t}const a=t.querySelectorAll("[data-panel-anchor]"),r=[].slice.call(a).map(w).filter(Boolean);c().render(s().createElement(v,{container:e,anchorsContainer:t,links:r,onUpdate:y,toggleAllPanels:e=>{r.forEach((t,n)=>{0===n&&t.href.includes("title")||l(t.toggle,e)})}}),e)};document.addEventListener("DOMContentLoaded",()=>{(function(){const e=document.querySelector("[data-form-side]");if(!e)return;const t="formSideExplorer"in e.dataset,n=document.querySelector("[data-form-side-resize-grip]"),r=document.querySelector("[data-form-side-width-input]"),l=()=>{const t=getComputedStyle(e),n=parseFloat(t.minWidth),a=parseFloat(t.maxWidth),r=parseFloat(t.width),l=a-n;return{minWidth:n,maxWidth:a,width:r,range:l,percentage:(r-n)/l*100}},i=e=>"rtl"===document.documentElement.dir?e:100-e;let o;const s=n=>{clearTimeout(o);const a=document.querySelector("body"),s=document.querySelector(`[data-side-panel="${n}"]`);if((!n||s)&&(""===n?(e.classList.remove("form-side--open"),e.removeAttribute("aria-labelledby")):(e.classList.add("form-side--open"),e.setAttribute("aria-labelledby",`side-panel-${n}-title`)),document.querySelectorAll("[data-side-panel]").forEach(t=>{const r=t.dataset.sidePanel;if(r===n)t.hidden&&(t.hidden=!1,e.classList.add(`form-side--${r}`),a.classList.add("side-panel-open"));else if(!t.hidden){const l=()=>{t.hidden=!0,t.dispatchEvent(new CustomEvent("hide")),e.classList.remove(`form-side--${r}`)};""===n?(a.classList.remove("side-panel-open"),o=setTimeout(l,500)):l()}}),document.querySelectorAll("[data-side-panel-toggle]").forEach(e=>{e.setAttribute("aria-expanded",e.dataset.sidePanelToggle===n?"true":"false")}),s&&s.dispatchEvent(new CustomEvent("show")),!t)){try{localStorage.setItem("wagtail:side-panel-open",n)}catch(e){}setTimeout(()=>{const{percentage:e}=l();r.value=i(e)},500)}};document.querySelectorAll("[data-side-panel]").forEach(e=>{e.addEventListener("open",()=>{s(e.dataset.sidePanel)})}),document.querySelectorAll("[data-side-panel-toggle]").forEach(e=>{e.addEventListener("click",()=>{(e=>{const t=!document.querySelector(`[data-side-panel="${e}"]`).hasAttribute("hidden");s(t?"":e)})(e.dataset.sidePanelToggle)})});const d=document.querySelector("[data-form-side-close-button]");d instanceof HTMLButtonElement&&d.addEventListener("click",()=>{s("")});const c=e=>{const{minWidth:n,maxWidth:o,range:s,width:d}=l(),c=parseInt(Math.max(n,Math.min(e,o)),10)||d,u=(0,a.WI)("%(num)s pixel","%(num)s pixels",c).replace("%(num)s",c);document.documentElement.style.setProperty("--side-panel-width",`${c}px`);const m=(c-n)/s*100;if(r.value=i(m),r.setAttribute("aria-valuetext",u),!t)try{localStorage.setItem("wagtail:side-panel-width",c)}catch(e){}};let u,m;const p=e=>{if(!e.screenX||!u||!m)return;const t="rtl"===document.documentElement.dir?-1:1,n=u-e.screenX;c(m+n*t)},g=e=>{n.releasePointerCapture(e.pointerId),n.removeEventListener("pointermove",p),document.removeEventListener("pointerup",g),document.body.classList.remove("side-panel-resizing")};n.addEventListener("pointerdown",e=>{0===e.button&&(u=e.screenX,m=l().width,document.body.classList.add("side-panel-resizing"),n.setPointerCapture(e.pointerId),n.addEventListener("pointermove",p),document.addEventListener("pointerup",g))}),r.addEventListener("change",e=>{const{minWidth:t,range:n}=l(),a=parseInt(e.target.value,10),r=i(a);c(t+n*r/100)}),setTimeout(()=>{try{const e=localStorage.getItem("wagtail:side-panel-open");!t&&e&&s(e),c(localStorage.getItem("wagtail:side-panel-width"))}catch(e){}setTimeout(()=>{e.classList.remove("form-side--initial")})})})(),function(e=document.querySelectorAll("[data-panel-toggle]")){e.forEach(i)}();const e=document.getElementById("w-edit-handler-data");if(e){const t=JSON.parse(e.textContent);window.wagtail.editHandler=window.telepath.unpack(t)}}),window.addEventListener("load",()=>{!function(e=(window.location.hash?document.getElementById(window.location.hash.slice(1)):null)){const t=e?.matches("[data-panel]")?e:(0,r.KX)();t&&setTimeout(()=>{t.scrollIntoView({behavior:"smooth"})},100)}(),((e=document.querySelector("[data-minimap-container]"))=>{if(!e)return;if(!document.body.querySelectorAll("[data-panel-anchor]").length)return;const t=(0,u.s)(y.bind(null,e),100);document.addEventListener("w-tabs:changed",t),document.addEventListener("w-tabs:ready",t),document.addEventListener("wagtail:panel-init",t);const n=()=>e.style.setProperty("--offset-top",`${e.offsetTop}px`),a=(0,u.s)(n,100);window.addEventListener("resize",a),n(),t(e)})()})}},n={};function a(e){var r=n[e];if(void 0!==r)return r.exports;var l=n[e]={exports:{}};return t[e](l,l.exports,a),l.exports}a.m=t,e=[],a.O=(t,n,r,l)=>{if(!n){var i=1/0;for(c=0;c<e.length;c++){for(var[n,r,l]=e[c],o=!0,s=0;s<n.length;s++)(!1&l||i>=l)&&Object.keys(a.O).every(e=>a.O[e](n[s]))?n.splice(s--,1):(o=!1,l<i&&(i=l));if(o){e.splice(c--,1);var d=r();void 0!==d&&(t=d)}}return t}l=l||0;for(var c=e.length;c>0&&e[c-1][2]>l;c--)e[c]=e[c-1];e[c]=[n,r,l]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.j=445,(()=>{var e={445:0};a.O.j=t=>0===e[t];var t=(t,n)=>{var r,l,[i,o,s]=n,d=0;if(i.some(t=>0!==e[t])){for(r in o)a.o(o,r)&&(a.m[r]=o[r]);if(s)var c=s(a)}for(t&&t(n);d<i.length;d++)l=i[d],a.o(e,l)&&e[l]&&e[l][0](),e[l]=0;return a.O(c)},n=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})();var r=a.O(void 0,[321],()=>a(412));r=a.O(r)})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e,o={8080:(e,o,t)=>{var a=t(1669),n=t.n(a),r=t(2898);function i(e,o,t){const a=document.createElement("input");a.type="hidden",a.name=o,a.value=t,e.appendChild(a)}window._addHiddenInput=i;const l=document.currentScript,c=l.dataset.activate,d=l.dataset.confirmCancellationUrl;document.addEventListener("DOMContentLoaded",(()=>{if("dashboard"===c?function(){const e=document.querySelectorAll("[data-workflow-action-url]"),o=r.HE.CSRF_TOKEN;e.forEach((e=>{e.addEventListener("click",(t=>{if(t.preventDefault(),"launchModal"in e.dataset)ModalWorkflow({url:e.dataset.workflowActionUrl,onload:{action(e){const o=document.createElement("input");o.type="hidden",o.name="next",o.value=window.location,n()("form",e.body).append(o),e.ajaxifyForm(n()("form",e.body))},success(e,o){window.location.href=o.redirect}}});else{const t=document.createElement("form");t.action=e.dataset.workflowActionUrl,t.method="POST",i(t,"csrfmiddlewaretoken",o),i(t,"next",window.location),document.body.appendChild(t),t.submit()}}),{capture:!0})}))}():"editor"===c&&function(e){const o=n()("[data-edit-form]").get(0);document.querySelectorAll("[data-workflow-action-name]").forEach((e=>{e.addEventListener("click",(t=>{"workflowActionModalUrl"in e.dataset?(t.preventDefault(),t.stopPropagation(),ModalWorkflow({url:e.dataset.workflowActionModalUrl,onload:{action(e){e.ajaxifyForm(n()("form",e.body))},success(t,a){i(o,"action-workflow-action","true"),i(o,"workflow-action-name",e.dataset.workflowActionName),i(o,"workflow-action-extra-data",JSON.stringify(a.cleaned_data)),n()(o).submit()}}})):(i(o,"action-workflow-action","true"),i(o,"workflow-action-name",e.dataset.workflowActionName))}),{capture:!0})}))}(),d){let e=!1;n()("[name=action-publish]").click((o=>{e||(o.stopImmediatePropagation(),o.preventDefault(),window.ModalWorkflow({url:d,onload:{confirm(t,a){n()("[data-confirm-cancellation]",t.body).click((a=>{e=!0,t.close(),o.currentTarget.click()})),n()("[data-cancel-dialog]",t.body).click((e=>{t.close()}))},no_confirmation_needed(t,a){t.close(),e=!0,o.currentTarget.click()}},triggerElement:o.currentTarget}))}))}}))},1669:e=>{e.exports=jQuery}},t={};function a(e){var n=t[e];if(void 0!==n)return n.exports;var r=t[e]={exports:{}};return o[e](r,r.exports,a),r.exports}a.m=o,e=[],a.O=(o,t,n,r)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){for(var[t,n,r]=e[u],l=!0,c=0;c<t.length;c++)(!1&r||i>=r)&&Object.keys(a.O).every((e=>a.O[e](t[c])))?t.splice(c--,1):(l=!1,r<i&&(i=r));if(l){e.splice(u--,1);var d=n();void 0!==d&&(o=d)}}return o}r=r||0;for(var u=e.length;u>0&&e[u-1][2]>r;u--)e[u]=e[u-1];e[u]=[t,n,r]},a.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return a.d(o,{a:o}),o},a.d=(e,o)=>{for(var t in o)a.o(o,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.j=327,(()=>{var e={327:0};a.O.j=o=>0===e[o];var o=(o,t)=>{var n,r,[i,l,c]=t,d=0;if(i.some((o=>0!==e[o]))){for(n in l)a.o(l,n)&&(a.m[n]=l[n]);if(c)var u=c(a)}for(o&&o(t);d<i.length;d++)r=i[d],a.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return a.O(u)},t=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})();var n=a.O(void 0,[321],(()=>a(8080)));n=a.O(n)})();
1
+ (()=>{"use strict";var e,o={1669:e=>{e.exports=jQuery},8080:(e,o,t)=>{var a=t(1669),n=t.n(a),r=t(2898);function i(e,o,t){const a=document.createElement("input");a.type="hidden",a.name=o,a.value=t,e.appendChild(a)}window._addHiddenInput=i;const l=document.currentScript,c=l.dataset.activate,d=l.dataset.confirmCancellationUrl;document.addEventListener("DOMContentLoaded",()=>{if("dashboard"===c?function(){const e=document.querySelectorAll("[data-workflow-action-url]"),o=r.HE.CSRF_TOKEN;e.forEach(e=>{e.addEventListener("click",t=>{if(t.preventDefault(),"launchModal"in e.dataset)ModalWorkflow({url:e.dataset.workflowActionUrl,onload:{action(e){const o=document.createElement("input");o.type="hidden",o.name="next",o.value=window.location,n()("form",e.body).append(o),e.ajaxifyForm(n()("form",e.body))},success(e,o){window.location.href=o.redirect}}});else{const t=document.createElement("form");t.action=e.dataset.workflowActionUrl,t.method="POST",i(t,"csrfmiddlewaretoken",o),i(t,"next",window.location),document.body.appendChild(t),t.submit()}},{capture:!0})})}():"editor"===c&&function(){const e=n()("[data-edit-form]").get(0);document.querySelectorAll("[data-workflow-action-name]").forEach(o=>{o.addEventListener("click",t=>{"workflowActionModalUrl"in o.dataset?(t.preventDefault(),t.stopPropagation(),ModalWorkflow({url:o.dataset.workflowActionModalUrl,onload:{action(e){e.ajaxifyForm(n()("form",e.body))},success(t,a){i(e,"action-workflow-action","true"),i(e,"workflow-action-name",o.dataset.workflowActionName),i(e,"workflow-action-extra-data",JSON.stringify(a.cleaned_data)),n()(e).submit()}}})):(i(e,"action-workflow-action","true"),i(e,"workflow-action-name",o.dataset.workflowActionName))},{capture:!0})})}(),d){let e=!1;n()("[name=action-publish]").click(o=>{e||(o.stopImmediatePropagation(),o.preventDefault(),window.ModalWorkflow({url:d,onload:{confirm(t,a){n()("[data-confirm-cancellation]",t.body).click(a=>{e=!0,t.close(),o.currentTarget.click()}),n()("[data-cancel-dialog]",t.body).click(e=>{t.close()})},no_confirmation_needed(t,a){t.close(),e=!0,o.currentTarget.click()}},triggerElement:o.currentTarget}))})}})}},t={};function a(e){var n=t[e];if(void 0!==n)return n.exports;var r=t[e]={exports:{}};return o[e](r,r.exports,a),r.exports}a.m=o,e=[],a.O=(o,t,n,r)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){for(var[t,n,r]=e[u],l=!0,c=0;c<t.length;c++)(!1&r||i>=r)&&Object.keys(a.O).every(e=>a.O[e](t[c]))?t.splice(c--,1):(l=!1,r<i&&(i=r));if(l){e.splice(u--,1);var d=n();void 0!==d&&(o=d)}}return o}r=r||0;for(var u=e.length;u>0&&e[u-1][2]>r;u--)e[u]=e[u-1];e[u]=[t,n,r]},a.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return a.d(o,{a:o}),o},a.d=(e,o)=>{for(var t in o)a.o(o,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.j=327,(()=>{var e={327:0};a.O.j=o=>0===e[o];var o=(o,t)=>{var n,r,[i,l,c]=t,d=0;if(i.some(o=>0!==e[o])){for(n in l)a.o(l,n)&&(a.m[n]=l[n]);if(c)var u=c(a)}for(o&&o(t);d<i.length;d++)r=i[d],a.o(e,r)&&e[r]&&e[r][0](),e[r]=0;return a.O(u)},t=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})();var n=a.O(void 0,[321],()=>a(8080));n=a.O(n)})();
@@ -26,6 +26,7 @@
26
26
  hidden
27
27
  aria-labelledby="tab-label-{{ tab.name|cautious_slugify }}"
28
28
  data-w-tabs-target="panel"
29
+ data-action="w-focus:focus->w-tabs#selectInside"
29
30
  >
30
31
  {% for panel in panels %}
31
32
  {% panel id=panel.name heading=panel.title heading_size="label" %}
@@ -45,6 +46,7 @@
45
46
  hidden
46
47
  aria-labelledby="tab-label-actions"
47
48
  data-w-tabs-target="panel"
49
+ data-action="w-focus:focus->w-tabs#selectInside"
48
50
  >
49
51
  <ul class="listing">
50
52
  {% for item in menu_items %}
@@ -26,6 +26,20 @@
26
26
  {% icon name=level_tag classname="messages-icon" %}
27
27
  {% endif %}
28
28
  {{ message|safe }}
29
+ {% if level_tag == "error" %}
30
+ {# Show a button to focus the first field/response error if available. #}
31
+ <button
32
+ type="button"
33
+ class="button button-small button-secondary w-hidden w-ml-2.5"
34
+ data-controller="w-count w-focus"
35
+ data-action="click->w-focus#focus"
36
+ data-w-count-active-class="!w-inline-block"
37
+ data-w-count-find-value=":not([hidden]):is(.error-message,.help-critical)"
38
+ data-w-focus-target-value=":not([hidden]):is(.error-message,.help-critical)"
39
+ >
40
+ {% trans 'Go to the first error' %}
41
+ </button>
42
+ {% endif %}
29
43
  </li>
30
44
  {% endfor %}
31
45
  {% endif %}
@@ -24,9 +24,10 @@
24
24
  <section
25
25
  id="tab-search"
26
26
  class="w-tabs__panel"
27
- data-w-tabs-target="panel"
28
27
  role="tabpanel"
29
28
  aria-labelledby="tab-label-search"
29
+ data-w-tabs-target="panel"
30
+ data-action="w-focus:focus->w-tabs#selectInside"
30
31
  >
31
32
 
32
33
  {% block filter_form %}
@@ -3,9 +3,10 @@
3
3
  id="tab-{{ view.creation_tab_id }}"
4
4
  class="w-tabs__panel"
5
5
  role="tabpanel"
6
- data-w-tabs-target="panel"
7
6
  hidden
8
7
  aria-labelledby="tab-label-{{ view.creation_tab_id }}"
8
+ data-w-tabs-target="panel"
9
+ data-action="w-focus:focus->w-tabs#selectInside"
9
10
  >
10
11
  {% include "wagtailadmin/shared/non_field_errors.html" with form=creation_form %}
11
12
  <form data-chooser-modal-creation-form action="{{ create_action_url }}" method="POST" {% if creation_form.is_multipart %}enctype="multipart/form-data"{% endif %} novalidate>
@@ -1,5 +1,5 @@
1
1
  {% load wagtailadmin_tags %}
2
- <div class="{% classnames "w-panel__wrapper" child.classes %}" {% include "wagtailadmin/shared/attrs.html" with attrs=child.attrs %}>
2
+ <div class="{% classnames "w-panel__wrapper" child.classes %}"{% include "wagtailadmin/shared/attrs.html" with attrs=child.attrs %}>
3
3
  {% if child.heading %}
4
4
  {% fragment as label_content %}
5
5
  {{ child.heading }}{% if child.is_required %}<span class="w-required-mark">*</span>{% endif %}
@@ -1,6 +1,6 @@
1
1
  {% load wagtailadmin_tags %}
2
2
 
3
- <div class="w-form-width" {% include "wagtailadmin/shared/attrs.html" with attrs=self.attrs %}>
3
+ <div class="w-form-width"{% include "wagtailadmin/shared/attrs.html" with attrs=self.attrs %}>
4
4
  {% if self.help_text %}
5
5
  {% help_block status="info" %}{{ self.help_text }}{% endhelp_block %}
6
6
  {% endif %}
@@ -4,7 +4,7 @@
4
4
  {% help_block status="info" %}{{ self.help_text }}{% endhelp_block %}
5
5
  {% endif %}
6
6
 
7
- <div class="w-tabs" {% include "wagtailadmin/shared/attrs.html" with attrs=self.attrs %}>
7
+ <div class="w-tabs"{% include "wagtailadmin/shared/attrs.html" with attrs=self.attrs %}>
8
8
  <div class="w-tabs__wrapper">
9
9
  <div role="tablist" class="w-tabs__list" data-action="keydown.right->w-tabs#selectNext keydown.left->w-tabs#selectPrevious keydown.home->w-tabs#selectFirst keydown.end->w-tabs#selectLast">
10
10
  {% for child, identifier in self.visible_children_with_identifiers %}
@@ -23,9 +23,10 @@
23
23
  id="tab-{{ identifier }}"
24
24
  class="{% classnames "w-tabs__panel" child.classes %}"
25
25
  role="tabpanel"
26
- data-w-tabs-target="panel"
27
26
  aria-labelledby="tab-label-{{ identifier }}"
28
27
  hidden
28
+ data-w-tabs-target="panel"
29
+ data-action="w-focus:focus->w-tabs#selectInside"
29
30
  >
30
31
  {{ child.render_html }}
31
32
  </section>
@@ -13,7 +13,7 @@
13
13
  A unified template for both use cases is messy, but it guarantees we are keeping form field styles the same everywhere.
14
14
  {% endcomment %}
15
15
 
16
- <div class="w-field__wrapper {{ classname }}"{% if wrapper_id %} id="{{ wrapper_id }}"{% endif %} data-field-wrapper>
16
+ <div class="w-field__wrapper {{ classname }}"{% if wrapper_id %} id="{{ wrapper_id }}"{% endif %}{% if attrs %}{% include "wagtailadmin/shared/attrs.html" with attrs=attrs %}{% endif %}>
17
17
 
18
18
  {# Render custom label attributes if provided, or the bound field’s label attributes otherwise. #}
19
19
  {% if show_label %}
@@ -1,6 +1,6 @@
1
1
  {# Render a single checkbox with text center-aligned. #}
2
2
  {% load l10n %}
3
3
  <label class="w-flex w-items-center {{ label_classname }}">
4
- <input type="checkbox" name="{{ name }}"{% if value %} value="{{ value|unlocalize }}"{% endif %} {% if checked %}checked{% endif %} {% include "wagtailadmin/shared/attrs.html" with attrs=attrs %}>
4
+ <input type="checkbox" name="{{ name }}"{% if value %} value="{{ value|unlocalize }}"{% endif %} {% if checked %}checked{% endif %}{% include "wagtailadmin/shared/attrs.html" with attrs=attrs %}>
5
5
  {{ text }}
6
6
  </label>
@@ -1,5 +1,15 @@
1
1
  {% load wagtailadmin_tags i18n %}
2
+ {% fragment as account_link %}<a class="w-underline" href="{% url 'wagtailadmin_account' %}">{% trans 'account' %}</a>{% endfragment %}
2
3
  {% dialog icon_name="keyboard" classname="w-keyboard-shortcuts" id="keyboard-shortcuts-dialog" title=_("Keyboard shortcuts") %}
4
+ {% if not keyboard_shortcuts_enabled %}
5
+ {% help_block status="warning" %}
6
+ <p>
7
+ {% blocktrans trimmed %}
8
+ Keyboard shortcuts are currently disabled; manage your {{ account_link }} to enable them.
9
+ {% endblocktrans %}
10
+ </p>
11
+ {% endhelp_block %}
12
+ {% endif %}
3
13
  <table class="w-w-full">
4
14
  <caption class="w-sr-only">
5
15
  {% trans "All keyboard shortcuts" %}
@@ -28,4 +38,13 @@
28
38
  {% endfor %}
29
39
  {% endblock %}
30
40
  </table>
41
+ {% if keyboard_shortcuts_enabled %}
42
+ {% help_block status="info" %}
43
+ <p>
44
+ {% blocktrans trimmed %}
45
+ Keyboard shortcuts are currently enabled; manage your {{ account_link }} to disable them.
46
+ {% endblocktrans %}
47
+ </p>
48
+ {% endhelp_block %}
49
+ {% endif %}
31
50
  {% enddialog %}
@@ -22,7 +22,7 @@
22
22
  {% fragment as panel_id %}{{ prefix }}-section{% endfragment %}
23
23
  {% fragment as heading_id %}{{ prefix }}-heading{% endfragment %}
24
24
  {% fragment as content_id %}{{ prefix }}-content{% endfragment %}
25
- <section class="{% classnames "w-panel" classname %}" id="{{ panel_id }}" {% if heading %}aria-labelledby="{{ heading_id }}"{% endif %} data-panel {% include "wagtailadmin/shared/attrs.html" with attrs=attrs %}>
25
+ <section class="{% classnames "w-panel" classname %}" id="{{ panel_id }}" {% if heading %}aria-labelledby="{{ heading_id }}"{% endif %}{% include "wagtailadmin/shared/attrs.html" with attrs=attrs %} data-panel>
26
26
  {# If a panel has no heading nor header controls, we don’t want any of the associated UI. #}
27
27
  {% if heading or header_controls %}
28
28
  <div class="w-panel__header">
@@ -0,0 +1,15 @@
1
+ {% load i18n wagtailadmin_tags %}
2
+
3
+ <form action="{{ action_url }}" method="POST" novalidate data-controller="w-rules" data-action="change->w-rules#resolve">
4
+ {% csrf_token %}
5
+ {% formattedfield field=form.restriction_type show_label=False %}
6
+ {% if form.password is not None %}
7
+ <div {% if form.initial.restriction_type != 'password' %}hidden{% endif %} data-w-rules-target="show" data-w-rules='{"restriction_type": "password"}'>
8
+ {% formattedfield form.password %}
9
+ </div>
10
+ {% endif %}
11
+ <div {% if form.initial.restriction_type != 'groups' %}hidden{% endif %} data-w-rules-target="show" data-w-rules='{"restriction_type": "groups"}'>
12
+ {% formattedfield form.groups %}
13
+ </div>
14
+ <input type="submit" value="{% trans 'Save' %}" class="button" />
15
+ </form>
@@ -28,7 +28,7 @@
28
28
  <h2 class="w-my-5 w-text-16 w-font-bold w-text-text-label">
29
29
  {% trans 'Content metrics' %}
30
30
  </h2>
31
- <div class="w-flex w-flex-wrap w-gap-x-10 w-gap-y-4">
31
+ <div class="w-flex w-flex-wrap w-gap-x-5 w-gap-y-4">
32
32
  {% block metrics %}
33
33
  <div>
34
34
  <h3 class="w-my-2 w-text-14 w-text-text-placeholder">{% trans 'Words' %}</h3>
@@ -38,8 +38,35 @@
38
38
  <h3 class="w-my-2 w-text-14 w-text-text-placeholder">{% trans 'Reading time' %}</h3>
39
39
  <p class="w-font-semibold w-text-text-label" data-content-reading-time>-</p>
40
40
  </div>
41
+ <div>
42
+ <h3 class="w-my-2 w-text-14 w-text-text-placeholder">{% trans 'Readability' %}</h3>
43
+ <p class="w-font-semibold w-text-text-label" data-content-readability-score>-</p>
44
+ </div>
41
45
  {% endblock %}
42
46
  </div>
47
+ <div class="w-mb-5">
48
+ {% fragment as toggle_text %}{% icon name="help" classname="w-w-4 w-h-4 w-mr-1" %} {% trans 'This data explained' %}{% endfragment %}
49
+ {% trans 'Content metrics' as explainer_title %}
50
+ {% trans 'How we calculate our metrics' as explainer_subtitle %}
51
+ {% dialog_toggle classname='w-bg-transparent w-text-14 w-p-0 w-text-text-link-default hover:w-text-text-link-hover w-inline-flex w-justify-center w-transition' dialog_id="metrics-explainer-dialog" text=toggle_text %}
52
+ {% dialog icon_name="help" id="metrics-explainer-dialog" title=explainer_title subtitle=explainer_subtitle %}
53
+ {% block metrics_explainer %}
54
+ <h3 class="w-h3">{% trans 'Words' %}</h3>
55
+ <p>{% trans 'We extract the main content from the page preview, remove all formatting, and calculate the number of words.' %}</p>
56
+ <h3 class="w-h3">{% trans 'Reading time' %}</h3>
57
+ <p>{% trans 'We calculate reading time from word count, using different reading speeds for different languages.' %}</p>
58
+ <h3 class="w-h3">{% trans 'Readability' %}</h3>
59
+ <p>{% trans 'We use a readability formula based on length of words and sentences. Long sentences and words result in a worse readability score.' %}</p>
60
+ <hr>
61
+ {% help_block status="info" %}
62
+ {% fragment as guide_link %}https://guide.wagtail.org/content-checks/{% endfragment %}
63
+ {% blocktrans trimmed %}
64
+ See our <a href="{{ guide_link }}" target="_blank">content checks guide</a> for more information on how content metrics are calculated.
65
+ {% endblocktrans %}
66
+ {% endhelp_block %}
67
+ {% endblock %}
68
+ {% enddialog %}
69
+ </div>
43
70
  </div>
44
71
  {% endblock %}
45
72
  {% block issues_section %}
@@ -27,7 +27,7 @@
27
27
  </div>
28
28
  </div>
29
29
  <div class="tab-content">
30
- <section id="tab-tasks" role="tabpanel" aria-labelledby="tab-label-tasks" data-w-tabs-target="panel" hidden>
30
+ <section id="tab-tasks" role="tabpanel" hidden aria-labelledby="tab-label-tasks" data-w-tabs-target="panel" data-action="w-focus:focus->w-tabs#selectInside">
31
31
  <table class="workflow-progress-table workflow-progress-table--tasks">
32
32
  <colgroup width="20%"></colgroup>
33
33
  {% for task in tasks %}
@@ -87,7 +87,7 @@
87
87
  </table>
88
88
  </section>
89
89
 
90
- <section id="tab-timeline" role="tabpanel" aria-labelledby="tab-label-timeline" data-w-tabs-target="panel" hidden>
90
+ <section id="tab-timeline" role="tabpanel" hidden aria-labelledby="tab-label-timeline" data-w-tabs-target="panel" data-action="w-focus:focus->w-tabs#selectInside">
91
91
  <table class="workflow-progress-table workflow-progress-table--timeline">
92
92
  <colgroup width="20%"></colgroup>
93
93
  <colgroup width="80%"></colgroup>
@@ -1,11 +1,11 @@
1
1
  {% load i18n wagtailadmin_tags %}
2
2
  <th class="ord{% if is_ascending %} ord--active{% endif %}">
3
3
  {% if is_ascending %}
4
- <a href="{{ table.base_url }}{% querystring p=None ordering=None %}" title="{% trans 'Disable ordering of child pages' %}">
4
+ <a href="{{ table.base_url }}{% querystring p=None ordering=None %}" title="{% trans 'Disable custom ordering' %}">
5
5
  {% icon name="order" %}{% trans 'Sort' %}
6
6
  </a>
7
7
  {% else %}
8
- <a href="{{ table.base_url }}{% querystring p=None ordering=column.sort_key %}" title="{% trans 'Enable ordering of child pages' %}">
8
+ <a href="{{ table.base_url }}{% querystring p=None ordering=column.sort_key %}" title="{% trans 'Enable custom ordering' %}">
9
9
  {% icon name="order" %}{% trans 'Sort' %}
10
10
  </a>
11
11
  {% endif %}
@@ -9,7 +9,7 @@
9
9
  {% endfragment %}
10
10
  {% block title %}
11
11
  {% if link_url %}
12
- <a {% include "wagtailadmin/shared/attrs.html" with attrs=link_attrs %}>{{ title }}</a>
12
+ <a{% include "wagtailadmin/shared/attrs.html" with attrs=link_attrs %}>{{ title }}</a>
13
13
  {% elif label_id %}
14
14
  <label for="{{ label_id }}">{{ title }}</label>
15
15
  {% else %}
@@ -1,3 +1,3 @@
1
- <div class="daterange_field">
1
+ <div class="w-flex w-flex-col w-gap-4">
2
2
  {% for widget in widget.subwidgets %}{% include widget.template_name %}{% endfor %}
3
3
  </div>
@@ -16,8 +16,9 @@
16
16
  class="w-tabs__panel"
17
17
  role="tabpanel"
18
18
  aria-labelledby="tab-label-new"
19
- data-w-tabs-target="panel"
20
19
  hidden
20
+ data-w-tabs-target="panel"
21
+ data-action="w-focus:focus->w-tabs#selectInside"
21
22
  >
22
23
  {% include "wagtailadmin/workflows/task_chooser/includes/create_tab.html" %}
23
24
  </section>
@@ -26,8 +27,9 @@
26
27
  class="w-tabs__panel"
27
28
  role="tabpanel"
28
29
  aria-labelledby="tab-label-existing"
29
- data-w-tabs-target="panel"
30
30
  hidden
31
+ data-w-tabs-target="panel"
32
+ data-action="w-focus:focus->w-tabs#selectInside"
31
33
  >
32
34
  <form
33
35
  class="task-search"
@@ -915,9 +915,7 @@ def wagtail_config(context):
915
915
  request = context["request"]
916
916
  config = {
917
917
  "CSRF_TOKEN": get_token(request),
918
- "CSRF_HEADER_NAME": HttpHeaders.parse_header_name(
919
- getattr(settings, "CSRF_HEADER_NAME")
920
- ),
918
+ "CSRF_HEADER_NAME": HttpHeaders.parse_header_name(settings.CSRF_HEADER_NAME),
921
919
  "ADMIN_API": {
922
920
  "PAGES": reverse("wagtailadmin_api:pages:listing"),
923
921
  "DOCUMENTS": reverse("wagtailadmin_api:documents:listing"),
@@ -1190,6 +1188,7 @@ def formattedfield(
1190
1188
  label_text=None,
1191
1189
  error_message_id=None,
1192
1190
  wrapper_id=None,
1191
+ attrs=None,
1193
1192
  ):
1194
1193
  """
1195
1194
  Renders a form field in standard Wagtail admin layout.
@@ -1207,12 +1206,15 @@ def formattedfield(
1207
1206
  - `label_text` - Manually set this if the field’s HTML is hard-coded.
1208
1207
  - `error_message_id` - ID of the error message container element.
1209
1208
  - `wrapper_id` - ID of the overall wrapper element.
1209
+ - `attrs` - Dict of additional HTML attributes to add to the field wrapper element, `data-field-wrapper` will be included by default.
1210
1210
  """
1211
1211
 
1212
1212
  label_for = id_for_label or (field and field.id_for_label) or ""
1213
1213
 
1214
1214
  context = {
1215
1215
  "classname": classname,
1216
+ # Ensure data-field-wrapper is always present
1217
+ "attrs": {**(attrs or {}), "data-field-wrapper": True},
1216
1218
  "show_label": show_label,
1217
1219
  "sr_only_label": sr_only_label,
1218
1220
  "icon": icon,
@@ -1334,15 +1336,42 @@ def keyboard_shortcuts_dialog(context):
1334
1336
  appropriate shortcuts for the user's platform.
1335
1337
  Note: Shortcut keys are intentionally not translated.
1336
1338
  """
1339
+ request = context.get("request")
1340
+ keyboard_shortcuts_enabled = True
1341
+
1342
+ if request and getattr(request, "user", None):
1343
+ profile = getattr(request.user, "wagtail_userprofile", None)
1344
+ if profile is not None:
1345
+ keyboard_shortcuts_enabled = bool(
1346
+ getattr(profile, "keyboard_shortcuts", True)
1347
+ )
1337
1348
 
1338
1349
  comments_enabled = get_comments_enabled()
1339
- user_agent = context["request"].headers.get("User-Agent", "")
1350
+ user_agent = request.headers.get("User-Agent", "") if request else ""
1340
1351
  is_mac = re.search(r"Mac|iPod|iPhone|iPad", user_agent)
1341
- KEYS = get_keyboard_key_labels_from_request(context["request"])
1352
+ KEYS = get_keyboard_key_labels_from_request(request) if request else {}
1342
1353
 
1343
1354
  return {
1355
+ "keyboard_shortcuts_enabled": keyboard_shortcuts_enabled,
1344
1356
  "shortcuts": {
1345
- ("actions-common", _("Common actions")): [
1357
+ # Translators: Shortcuts for admin common shortcuts that are available across the admin
1358
+ ("admin-common", _("Application")): [
1359
+ (_("Show keyboard shortcuts"), "?"),
1360
+ (_("Search"), "/"),
1361
+ (_("Toggle sidebar"), "["),
1362
+ (_("Toggle minimap"), "]"),
1363
+ (_("Close modal dialogs (like this one)"), f"{KEYS.ESC}"),
1364
+ ],
1365
+ # Translators: Shortcuts for admin actions that can be taken while working on core models
1366
+ ("admin-core-models", _("Actions")): [
1367
+ (_("Save changes"), f"{KEYS.MOD} + s"),
1368
+ (_("Preview"), f"{KEYS.MOD} + p"),
1369
+ (_("Add or show comments"), f"{KEYS.CTRL} + {KEYS.ALT} + m")
1370
+ if comments_enabled
1371
+ else None,
1372
+ ],
1373
+ # Translators: Shortcuts for common text editing features available in all fields (even if not a rich text field)
1374
+ ("text-editing-basic", _("Text editing")): [
1346
1375
  (_("Copy"), f"{KEYS.MOD} + c"),
1347
1376
  (_("Cut"), f"{KEYS.MOD} + x"),
1348
1377
  (_("Paste"), f"{KEYS.MOD} + v"),
@@ -1358,27 +1387,17 @@ def keyboard_shortcuts_dialog(context):
1358
1387
  f"{KEYS.MOD} + {KEYS.SHIFT} + z" if is_mac else f"{KEYS.MOD} + y",
1359
1388
  ),
1360
1389
  ],
1361
- ("actions-model", _("Actions")): [
1362
- (_("Save changes"), f"{KEYS.MOD} + s"),
1363
- (_("Preview"), f"{KEYS.MOD} + p"),
1364
- (_("Toggle sidebar"), "["),
1365
- (_("Toggle minimap"), "]"),
1366
- (_("Add or show comments"), f"{KEYS.CTRL} + {KEYS.ALT} + m")
1367
- if comments_enabled
1368
- else None,
1369
- ],
1370
- ("rich-text-content", _("Text content")): [
1371
- (_("Insert or edit a link"), f"{KEYS.MOD} + k")
1372
- ],
1373
- ("rich-text-formatting", _("Text formatting")): [
1390
+ # Translators: Shortcuts for formatting & editing features available in rich text fields
1391
+ ("text-editing-rich-text", _("Text formatting")): [
1392
+ (_("Insert or edit a link"), f"{KEYS.MOD} + k"),
1393
+ (_("Bold"), f"{KEYS.MOD} + b"),
1374
1394
  (_("Italic"), f"{KEYS.MOD} + i"),
1375
- (_("Underline"), f"{KEYS.MOD} + u"),
1376
1395
  (_("Monospace (code)"), f"{KEYS.MOD} + j"),
1377
- (_("Strike-through"), f"{KEYS.MOD} + x"),
1396
+ (_("Strike-through"), f"{KEYS.MOD} + {KEYS.SHIFT} + x"),
1378
1397
  (_("Superscript"), f"{KEYS.MOD} + ."),
1379
1398
  (_("Subscript"), f"{KEYS.MOD} + ,"),
1380
1399
  ],
1381
- }
1400
+ },
1382
1401
  }
1383
1402
 
1384
1403
 
@@ -1378,7 +1378,7 @@ class TestCopyPageAction(AdminAPITestCase, TestCase):
1378
1378
  content,
1379
1379
  {
1380
1380
  "detail": (
1381
- "You do not have permission to publish a page at the destination"
1381
+ "You do not have permission to publish a page at the destination."
1382
1382
  )
1383
1383
  },
1384
1384
  )
@@ -1407,7 +1407,7 @@ class TestCopyPageAction(AdminAPITestCase, TestCase):
1407
1407
  content,
1408
1408
  {
1409
1409
  "slug": [
1410
- "The slug 'events' is already in use within the parent page at '/'"
1410
+ "The slug 'events' is already in use within the parent page at '/'."
1411
1411
  ]
1412
1412
  },
1413
1413
  )
@@ -1517,7 +1517,7 @@ class TestDeletePageAction(AdminAPITestCase, TestCase):
1517
1517
  self.assertEqual(response.status_code, 403)
1518
1518
  content = json.loads(response.content.decode("utf-8"))
1519
1519
  self.assertEqual(
1520
- content, {"detail": "You do not have permission to delete this page"}
1520
+ content, {"detail": "You do not have permission to delete this page."}
1521
1521
  )
1522
1522
 
1523
1523
  # Page is still there
@@ -1565,7 +1565,7 @@ class TestPublishPageAction(AdminAPITestCase, TestCase):
1565
1565
  self.assertEqual(response.status_code, 403)
1566
1566
  content = json.loads(response.content.decode("utf-8"))
1567
1567
  self.assertEqual(
1568
- content, {"detail": "You do not have permission to publish this page"}
1568
+ content, {"detail": "You do not have permission to publish this page."}
1569
1569
  )
1570
1570
 
1571
1571
  def test_publish_alias_page(self):
@@ -1655,7 +1655,7 @@ class TestUnpublishPageAction(AdminAPITestCase, TestCase):
1655
1655
  self.assertEqual(response.status_code, 403)
1656
1656
  content = json.loads(response.content.decode("utf-8"))
1657
1657
  self.assertEqual(
1658
- content, {"detail": "You do not have permission to unpublish this page"}
1658
+ content, {"detail": "You do not have permission to unpublish this page."}
1659
1659
  )
1660
1660
 
1661
1661
 
@@ -1969,7 +1969,7 @@ class TestCreatePageAliasAction(AdminAPITestCase, TestCase):
1969
1969
  content,
1970
1970
  {
1971
1971
  "detail": (
1972
- "You do not have permission to publish a page at the destination"
1972
+ "You do not have permission to publish a page at the destination."
1973
1973
  ),
1974
1974
  },
1975
1975
  )
@@ -2028,7 +2028,7 @@ class TestRevertToPageRevisionAction(AdminAPITestCase, TestCase):
2028
2028
 
2029
2029
  content = json.loads(response.content.decode("utf-8"))
2030
2030
  self.assertEqual(
2031
- content, {"detail": "You do not have permission to edit this page"}
2031
+ content, {"detail": "You do not have permission to edit this page."}
2032
2032
  )
2033
2033
 
2034
2034
  def test_revert_to_page_revision_without_revision_id(self):
@@ -6,6 +6,7 @@ from django.urls import reverse
6
6
  from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer
7
7
 
8
8
  from wagtail.admin.api.views import PagesAdminAPIViewSet
9
+ from wagtail.test.numberformat import ignore_numberformat
9
10
  from wagtail.test.utils import WagtailTestUtils
10
11
 
11
12
 
@@ -59,3 +60,18 @@ class TestPagesAdminAPIRendererClasses(WagtailTestUtils, TestCase):
59
60
  content = json.loads(response.content.decode("UTF-8"))
60
61
  self.assertIn("meta", content)
61
62
  self.assertIn("items", content)
63
+
64
+ def test_api_response_returns_html_with_html_accept_header(self):
65
+ """Test that API returns HTML when HTML is explicitly requested via Accept header."""
66
+ with ignore_numberformat(["rest_framework/base.html"]):
67
+ response = self.client.get(
68
+ reverse("wagtailadmin_api:pages:listing"), HTTP_ACCEPT="text/html"
69
+ )
70
+
71
+ self.assertEqual(response.status_code, 200)
72
+ self.assertEqual(response["Content-Type"], "text/html; charset=utf-8")
73
+
74
+ # Should contain HTML content
75
+ content = response.content.decode("UTF-8")
76
+ self.assertIn("<html", content)
77
+ self.assertIn("</html>", content)