diff --git a/wagtail/wagtailadmin/rich_text.py b/wagtail/wagtailadmin/rich_text.py index 4873d90ed3..394ae4e5a1 100644 --- a/wagtail/wagtailadmin/rich_text.py +++ b/wagtail/wagtailadmin/rich_text.py @@ -24,14 +24,19 @@ class HalloRichTextArea(WidgetWithScript, widgets.Textarea): self.features = kwargs.pop('features', None) if self.features is None: - self.plugins = None + self.features = features.get_default_features() + + # RemovedInWagtail114Warning + self.use_legacy_plugin_config = True else: - # construct a list of plugin objects, by querying the feature registry - # and keeping the non-null responses from get_editor_plugin - self.plugins = list(filter(None, [ - features.get_editor_plugin('hallo', feature_name) - for feature_name in self.features - ])) + self.use_legacy_plugin_config = False + + # construct a list of plugin objects, by querying the feature registry + # and keeping the non-null responses from get_editor_plugin + self.plugins = list(filter(None, [ + features.get_editor_plugin('hallo', feature_name) + for feature_name in self.features + ])) super(HalloRichTextArea, self).__init__(*args, **kwargs) @@ -44,15 +49,17 @@ class HalloRichTextArea(WidgetWithScript, widgets.Textarea): def render_js_init(self, id_, name, value): if self.options is not None and 'plugins' in self.options: + # explicit 'plugins' config passed in options, so use that plugin_data = self.options['plugins'] - elif self.plugins is not None: + elif self.use_legacy_plugin_config: + # RemovedInWagtail114Warning + # no feature list specified, so initialise without a plugins arg + # (so that it'll pick up the globally-defined halloPlugins list instead) + return "makeHalloRichTextEditable({0});".format(json.dumps(id_)) + else: plugin_data = {} for plugin in self.plugins: plugin.construct_plugins_list(plugin_data) - else: - # no plugin list specified, so initialise without a plugins arg - # (so that it'll pick up the globally-defined halloPlugins list instead) - return "makeHalloRichTextEditable({0});".format(json.dumps(id_)) return "makeHalloRichTextEditable({0}, {1});".format( json.dumps(id_), json.dumps(plugin_data) diff --git a/wagtail/wagtailadmin/tests/test_rich_text.py b/wagtail/wagtailadmin/tests/test_rich_text.py index 47026f479d..74f55738dc 100644 --- a/wagtail/wagtailadmin/tests/test_rich_text.py +++ b/wagtail/wagtailadmin/tests/test_rich_text.py @@ -104,6 +104,10 @@ class TestDefaultRichText(BaseRichTextEditHandlerTestCase, WagtailTestUtils): # Check that hallo (default editor by now) self.assertContains(response, 'makeHalloRichTextEditable("id_body");') + # check that media for the default hallo features (but not others) is being imported + self.assertContains(response, 'wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js') + self.assertNotContains(response, 'testapp/js/hallo-blockquote.js') + def test_default_editor_in_rich_text_block(self): response = self.client.get(reverse( 'wagtailadmin_pages:add', args=('tests', 'defaultrichblockfieldpage', self.root_page.id) @@ -115,6 +119,10 @@ class TestDefaultRichText(BaseRichTextEditHandlerTestCase, WagtailTestUtils): # Check that hallo (default editor by now) self.assertContains(response, 'makeHalloRichTextEditable("__PREFIX__-value");') + # check that media for the default hallo features (but not others) is being imported + self.assertContains(response, 'wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js') + self.assertNotContains(response, 'testapp/js/hallo-blockquote.js') + @override_settings(WAGTAILADMIN_RICH_TEXT_EDITORS={ 'default': { @@ -295,6 +303,9 @@ class TestHalloJsWithFeaturesKwarg(BaseRichTextEditHandlerTestCase, WagtailTestU self.assertContains(response, 'testapp/js/hallo-blockquote.js') self.assertContains(response, 'testapp/css/hallo-blockquote.css') + # check that we're NOT importing media for the default features we're not using + self.assertNotContains(response, 'wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js') + def test_features_list_on_rich_text_block(self): block = RichTextBlock(features=['blockquote', 'embed', 'made-up-feature']) @@ -310,6 +321,8 @@ class TestHalloJsWithFeaturesKwarg(BaseRichTextEditHandlerTestCase, WagtailTestU media_html = str(block.media) self.assertIn('testapp/js/hallo-blockquote.js', media_html) self.assertIn('testapp/css/hallo-blockquote.css', media_html) + # check that we're NOT importing media for the default features we're not using + self.assertNotIn('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js', media_html) @override_settings(WAGTAILADMIN_RICH_TEXT_EDITORS={ @@ -361,6 +374,13 @@ class TestHalloJsWithCustomFeatureOptions(BaseRichTextEditHandlerTestCase, Wagta self.assertNotContains(response, '"halloheadings":') self.assertNotContains(response, '"hallowagtailimage":') + # check that media (js/css) from the features is being imported + self.assertContains(response, 'testapp/js/hallo-blockquote.js') + self.assertContains(response, 'testapp/css/hallo-blockquote.css') + + # check that we're NOT importing media for the default features we're not using + self.assertNotContains(response, 'wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js') + def test_custom_features_option_on_rich_text_block(self): block = RichTextBlock(editor='custom') @@ -382,3 +402,10 @@ class TestHalloJsWithCustomFeatureOptions(BaseRichTextEditHandlerTestCase, Wagta self.assertIn('"hallowagtailembeds":', form_html) self.assertNotIn('"hallowagtailimage":', form_html) self.assertNotIn('"halloheadings":', form_html) + + # check that media (js/css) from the features is being imported + media_html = str(block.media) + self.assertIn('testapp/js/hallo-blockquote.js', media_html) + self.assertIn('testapp/css/hallo-blockquote.css', media_html) + # check that we're NOT importing media for the default features we're not using + self.assertNotIn('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js', media_html) diff --git a/wagtail/wagtailcore/rich_text.py b/wagtail/wagtailcore/rich_text.py index bf336ccf8f..605a24d197 100644 --- a/wagtail/wagtailcore/rich_text.py +++ b/wagtail/wagtailcore/rich_text.py @@ -225,6 +225,22 @@ class FeatureRegistry(object): # here, and is specific to each editor. self.plugins_by_editor = {} + # a list of feature names that will be applied on rich text areas that do not specify + # an explicit `feature` list. + # RemovedInWagtail114Warning: Until Wagtail 1.14, features listed here MUST also + # update the legacy global halloPlugins list (typically by calling registerHalloPlugin + # within an insert_editor_js hook). This is because we special-case rich text areas + # without an explicit `feature` list, to use the legacy halloPlugins list instead of + # the one constructed using construct_plugins_list; this ensures that any user code + # that fiddles with halloPlugins will continue to work until Wagtail 1.14. + self.default_features = [] + + def get_default_features(self): + if not self.has_scanned_for_features: + self._scan_for_features() + + return self.default_features + def _scan_for_features(self): for fn in hooks.get_hooks('register_rich_text_features'): fn(self) diff --git a/wagtail/wagtaildocs/wagtail_hooks.py b/wagtail/wagtaildocs/wagtail_hooks.py index f7c27e61c3..0ac98ee0f3 100644 --- a/wagtail/wagtaildocs/wagtail_hooks.py +++ b/wagtail/wagtaildocs/wagtail_hooks.py @@ -57,7 +57,6 @@ def register_documents_menu_item(): @hooks.register('insert_editor_js') def editor_js(): js_files = [ - static('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js'), static('wagtaildocs/js/document-chooser.js'), ] js_includes = format_html_join( @@ -79,8 +78,12 @@ def editor_js(): def register_embed_feature(features): features.register_editor_plugin( 'hallo', 'document-link', - HalloPlugin(name='hallowagtaildoclink') + HalloPlugin( + name='hallowagtaildoclink', + js=[static('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js')], + ) ) + features.default_features.append('document-link') @hooks.register('register_rich_text_link_handler') diff --git a/wagtail/wagtailembeds/wagtail_hooks.py b/wagtail/wagtailembeds/wagtail_hooks.py index 619c021bbf..87d447830b 100644 --- a/wagtail/wagtailembeds/wagtail_hooks.py +++ b/wagtail/wagtailembeds/wagtail_hooks.py @@ -22,13 +22,11 @@ def register_admin_urls(): def editor_js(): return format_html( """ - """, - static('wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.js'), urlresolvers.reverse('wagtailembeds:chooser') ) @@ -37,8 +35,12 @@ def editor_js(): def register_embed_feature(features): features.register_editor_plugin( 'hallo', 'embed', - HalloPlugin(name='hallowagtailembeds') + HalloPlugin( + name='hallowagtailembeds', + js=[static('wagtailembeds/js/hallo-plugins/hallo-wagtailembeds.js')], + ) ) + features.default_features.append('embed') @hooks.register('register_rich_text_embed_handler') diff --git a/wagtail/wagtailimages/wagtail_hooks.py b/wagtail/wagtailimages/wagtail_hooks.py index 7eb18a08a3..b4902b83fc 100644 --- a/wagtail/wagtailimages/wagtail_hooks.py +++ b/wagtail/wagtailimages/wagtail_hooks.py @@ -49,7 +49,6 @@ def register_images_menu_item(): @hooks.register('insert_editor_js') def editor_js(): js_files = [ - static('wagtailimages/js/hallo-plugins/hallo-wagtailimage.js'), static('wagtailimages/js/image-chooser.js'), ] js_includes = format_html_join( @@ -71,8 +70,12 @@ def editor_js(): def register_image_feature(features): features.register_editor_plugin( 'hallo', 'image', - HalloPlugin(name='hallowagtailimage') + HalloPlugin( + name='hallowagtailimage', + js=[static('wagtailimages/js/hallo-plugins/hallo-wagtailimage.js')], + ) ) + features.default_features.append('image') @hooks.register('register_image_operations')