From 32f6f6e8f226057a3830f42cb485df0b8c1e5f6b Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Sat, 15 Jul 2017 08:27:22 +0200 Subject: [PATCH] Use HalloPlugin media definitions to import JS for our default plugins. To make this work, we need an explicit 'default features' list so that the relevant HalloPlugin objects are available even in the default setup (where no 'features' list is supplied). In this case we special-case HalloRichTextArea to use the global halloPlugins js config rather than building one properly via construct_plugins_list, to ensure that legacy setups that hack halloPlugins will continue to work (for now). --- wagtail/wagtailadmin/rich_text.py | 31 ++++++++++++-------- wagtail/wagtailadmin/tests/test_rich_text.py | 27 +++++++++++++++++ wagtail/wagtailcore/rich_text.py | 16 ++++++++++ wagtail/wagtaildocs/wagtail_hooks.py | 7 +++-- wagtail/wagtailembeds/wagtail_hooks.py | 10 ++++--- wagtail/wagtailimages/wagtail_hooks.py | 7 +++-- 6 files changed, 78 insertions(+), 20 deletions(-) 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')