diff --git a/client/src/entrypoints/admin/draftail.js b/client/src/entrypoints/admin/draftail.js index a1543e252b..5ceb905191 100644 --- a/client/src/entrypoints/admin/draftail.js +++ b/client/src/entrypoints/admin/draftail.js @@ -16,6 +16,9 @@ window.Draftail = Draftail; // Expose module as a global. window.draftail = draftail; +/** @deprecated RemovedInWagtail70 - Ensure that any third party packages that use global.chooserUrls can still append to this global object until support is removed. */ +window.chooserUrls = global.chooserUrls || {}; + // Plugins for the built-in entities. const entityTypes = [ { diff --git a/wagtail/admin/templates/wagtailadmin/pages/_editor_js.html b/wagtail/admin/templates/wagtailadmin/pages/_editor_js.html index a6afd08096..96f108a5f9 100644 --- a/wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +++ b/wagtail/admin/templates/wagtailadmin/pages/_editor_js.html @@ -4,16 +4,6 @@ JavaScript declarations to be included on the 'create page' and 'edit page' views {% endcomment %} - - diff --git a/wagtail/admin/tests/test_rich_text.py b/wagtail/admin/tests/test_rich_text.py index 46f15883f4..dc7cdee9cb 100644 --- a/wagtail/admin/tests/test_rich_text.py +++ b/wagtail/admin/tests/test_rich_text.py @@ -3,7 +3,8 @@ import unittest from django.conf import settings from django.test import SimpleTestCase, TestCase from django.test.utils import override_settings -from django.urls import reverse +from django.urls import reverse, reverse_lazy +from django.utils.html import format_html from wagtail.admin.rich_text import DraftailRichTextArea, get_rich_text_editor_widget from wagtail.admin.rich_text.converters.editor_html import PageLinkHandler @@ -11,6 +12,7 @@ from wagtail.admin.rich_text.editors.draftail.features import Feature from wagtail.blocks import RichTextBlock from wagtail.models import Page, get_page_models from wagtail.rich_text import RichText +from wagtail.rich_text.feature_registry import FeatureRegistry from wagtail.test.testapp.models import SingleEventPage from wagtail.test.testapp.rich_text import CustomRichTextArea, LegacyRichTextArea from wagtail.test.utils import WagtailTestUtils @@ -491,3 +493,103 @@ class TestDraftailFeature(SimpleTestCase): media_html = str(feature.media) self.assertRegex(media_html, r"feature.js\?v=(\w+)") self.assertRegex(media_html, r"feature.css\?v=(\w+)") + + +class TestRichTextChooserUrls(WagtailTestUtils, BaseRichTextEditHandlerTestCase): + def setUp(self): + super().setUp() + + # Find root page + self.root_page = Page.objects.get(id=2) + + self.login() + + @override_settings( + WAGTAILADMIN_RICH_TEXT_EDITORS={ + "default": { + "WIDGET": "wagtail.admin.rich_text.DraftailRichTextArea", + }, + } + ) + def test_chooser_urls_exist(self): + features = FeatureRegistry() + link = features.get_editor_plugin("draftail", "link") + + self.assertIsNotNone(link.data.get("chooserUrls")) + self.assertEqual( + link.data["chooserUrls"]["pageChooser"], + reverse_lazy("wagtailadmin_choose_page"), + ) + self.assertEqual( + link.data["chooserUrls"]["externalLinkChooser"], + reverse_lazy("wagtailadmin_choose_page_external_link"), + ) + self.assertEqual( + link.data["chooserUrls"]["emailLinkChooser"], + reverse_lazy("wagtailadmin_choose_page_email_link"), + ) + self.assertEqual( + link.data["chooserUrls"]["phoneLinkChooser"], + reverse_lazy("wagtailadmin_choose_page_phone_link"), + ) + self.assertEqual( + link.data["chooserUrls"]["anchorLinkChooser"], + reverse_lazy("wagtailadmin_choose_page_anchor_link"), + ) + + def test_lazy_chooser_urls_resolved_correctly(self): + response = self.client.get( + reverse( + "wagtailadmin_pages:add", + args=("tests", "defaultrichtextfieldpage", self.root_page.id), + ) + ) + + self.assertContains( + response, '"chooserUrls": {"imageChooser": "/admin/images/chooser/"}' + ) + self.assertContains( + response, '"chooserUrls": {"embedsChooser": "/admin/embeds/chooser/"}' + ) + self.assertContains( + response, '"chooserUrls": {"documentChooser": "/admin/documents/chooser/"}' + ) + + self.assertContains( + response, + '"chooserUrls": {"pageChooser": "/admin/choose-page/", "externalLinkChooser": "/admin/choose-external-link/", "emailLinkChooser": "/admin/choose-email-link/", "phoneLinkChooser": "/admin/choose-phone-link/", "anchorLinkChooser": "/admin/choose-anchor-link/"}', + ) + + def test_lazy_urls_resolution(self): + widget = DraftailRichTextArea() + + pageChooser = format_html( + "
this link_Chooser link : {page_chooser}
", + page_chooser=reverse_lazy("wagtailadmin_choose_page"), + ) + + imageChooser = format_html( + "this image_chooser link : {image_chooser}
", + image_chooser=reverse_lazy("wagtailimages_chooser:choose"), + ) + + embedsChooser = format_html( + "this embeds_chooser link: {embeds_chooser}
", + embeds_chooser=reverse_lazy("wagtailembeds:chooser"), + ) + + documentChooser = format_html( + "this document_chooser link: {document_chooser}
", + document_chooser=reverse_lazy("wagtaildocs_chooser:choose"), + ) + + rendered_html_link = widget.render("test_chooserUrls", pageChooser, {}) + rendered_html_image = widget.render("test_chooserUrls", imageChooser, {}) + rendered_html_embeds = widget.render("test_chooserUrls", embedsChooser, {}) + rendered_html_document = widget.render("test_chooserUrls", documentChooser, {}) + + # Assert that the lazy URLs has been resolved correctly + self.assertIn("/admin/choose-page/", rendered_html_link) + self.assertIn("/admin/images/chooser/", rendered_html_image) + self.assertIn("/admin/embeds/chooser/", rendered_html_embeds) + self.assertIn("/admin/documents/chooser/", rendered_html_document) diff --git a/wagtail/admin/wagtail_hooks.py b/wagtail/admin/wagtail_hooks.py index 8aa93e4801..003ba8a490 100644 --- a/wagtail/admin/wagtail_hooks.py +++ b/wagtail/admin/wagtail_hooks.py @@ -1,6 +1,6 @@ from django.conf import settings from django.contrib.auth.models import Permission -from django.urls import reverse +from django.urls import reverse, reverse_lazy from django.utils.functional import cached_property from django.utils.http import urlencode from django.utils.translation import gettext @@ -743,6 +743,21 @@ def register_core_features(features): # Keep pasted links with http/https protocol, and not-pasted links (href = undefined). "href": "^(http:|https:|undefined$)", }, + "chooserUrls": { + "pageChooser": reverse_lazy("wagtailadmin_choose_page"), + "externalLinkChooser": reverse_lazy( + "wagtailadmin_choose_page_external_link" + ), + "emailLinkChooser": reverse_lazy( + "wagtailadmin_choose_page_email_link" + ), + "phoneLinkChooser": reverse_lazy( + "wagtailadmin_choose_page_phone_link" + ), + "anchorLinkChooser": reverse_lazy( + "wagtailadmin_choose_page_anchor_link" + ), + }, }, js=[ "wagtailadmin/js/page-chooser-modal.js",