From 81f7fc59687499bdb3ed136a9c4f5a83a2b9cedc Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Mon, 27 Nov 2017 20:57:33 +0000 Subject: [PATCH] Move FeatureRegistry to a submodule wagtail.core.rich_text.feature_registry --- wagtail/core/rich_text/__init__.py | 70 ++-------------------- wagtail/core/rich_text/feature_registry.py | 64 ++++++++++++++++++++ wagtail/core/tests/test_rich_text.py | 3 +- 3 files changed, 70 insertions(+), 67 deletions(-) create mode 100644 wagtail/core/rich_text/feature_registry.py diff --git a/wagtail/core/rich_text/__init__.py b/wagtail/core/rich_text/__init__.py index e3291545b5..2b77692a04 100644 --- a/wagtail/core/rich_text/__init__.py +++ b/wagtail/core/rich_text/__init__.py @@ -4,10 +4,14 @@ from django.utils.functional import cached_property from django.utils.safestring import mark_safe from wagtail.core import hooks +from wagtail.core.rich_text.feature_registry import FeatureRegistry from wagtail.core.rich_text.pages import PageLinkHandler from wagtail.core.whitelist import allow_without_attributes, Whitelister, DEFAULT_ELEMENT_RULES +features = FeatureRegistry() + + # Define a set of 'embed handlers' and 'link handlers'. These handle the translation # of 'special' HTML elements in rich text - ones which we do not want to include # verbatim in the DB representation because they embed information which is stored @@ -195,69 +199,3 @@ class RichText: def __bool__(self): return bool(self.source) __nonzero__ = __bool__ - - -class FeatureRegistry: - """ - A central store of information about optional features that can be enabled in rich text - editors by passing a ``features`` list to the RichTextField, such as how to - whitelist / convert HTML tags, and how to enable the feature on various editors. - - This information may come from diverse sources - for example, wagtailimages might define - an 'images' feature and a hallo.js plugin for it, while a third-party module might - define a TinyMCE plugin for the same feature. The information is therefore collected into - this registry via the 'register_rich_text_features' hook. - """ - def __init__(self): - # Has the register_rich_text_features hook been run for this registry? - self.has_scanned_for_features = False - - # a dict of dicts, one for each editor (hallo.js, TinyMCE etc); each dict is a mapping - # of feature names to 'plugin' objects that define how to implement that feature - # (e.g. paths to JS files to import). The API of that plugin object is not defined - # 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. - self.default_features = [] - - # a mapping of feature names to whitelister element rules that should be merged into - # the whitelister element_rules config when the feature is active - self.whitelister_element_rules = {} - - 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) - self.has_scanned_for_features = True - - def register_editor_plugin(self, editor_name, feature_name, plugin): - plugins = self.plugins_by_editor.setdefault(editor_name, {}) - plugins[feature_name] = plugin - - def get_editor_plugin(self, editor_name, feature_name): - if not self.has_scanned_for_features: - self._scan_for_features() - - try: - return self.plugins_by_editor[editor_name][feature_name] - except KeyError: - return None - - def register_whitelister_element_rules(self, feature_name, ruleset): - self.whitelister_element_rules[feature_name] = ruleset - - def get_whitelister_element_rules(self, feature_name): - if not self.has_scanned_for_features: - self._scan_for_features() - - return self.whitelister_element_rules.get(feature_name, {}) - - -features = FeatureRegistry() diff --git a/wagtail/core/rich_text/feature_registry.py b/wagtail/core/rich_text/feature_registry.py new file mode 100644 index 0000000000..2253679ebb --- /dev/null +++ b/wagtail/core/rich_text/feature_registry.py @@ -0,0 +1,64 @@ +from wagtail.core import hooks + + +class FeatureRegistry: + """ + A central store of information about optional features that can be enabled in rich text + editors by passing a ``features`` list to the RichTextField, such as how to + whitelist / convert HTML tags, and how to enable the feature on various editors. + + This information may come from diverse sources - for example, wagtailimages might define + an 'images' feature and a hallo.js plugin for it, while a third-party module might + define a TinyMCE plugin for the same feature. The information is therefore collected into + this registry via the 'register_rich_text_features' hook. + """ + def __init__(self): + # Has the register_rich_text_features hook been run for this registry? + self.has_scanned_for_features = False + + # a dict of dicts, one for each editor (hallo.js, TinyMCE etc); each dict is a mapping + # of feature names to 'plugin' objects that define how to implement that feature + # (e.g. paths to JS files to import). The API of that plugin object is not defined + # 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. + self.default_features = [] + + # a mapping of feature names to whitelister element rules that should be merged into + # the whitelister element_rules config when the feature is active + self.whitelister_element_rules = {} + + 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) + self.has_scanned_for_features = True + + def register_editor_plugin(self, editor_name, feature_name, plugin): + plugins = self.plugins_by_editor.setdefault(editor_name, {}) + plugins[feature_name] = plugin + + def get_editor_plugin(self, editor_name, feature_name): + if not self.has_scanned_for_features: + self._scan_for_features() + + try: + return self.plugins_by_editor[editor_name][feature_name] + except KeyError: + return None + + def register_whitelister_element_rules(self, feature_name, ruleset): + self.whitelister_element_rules[feature_name] = ruleset + + def get_whitelister_element_rules(self, feature_name): + if not self.has_scanned_for_features: + self._scan_for_features() + + return self.whitelister_element_rules.get(feature_name, {}) diff --git a/wagtail/core/tests/test_rich_text.py b/wagtail/core/tests/test_rich_text.py index fa2417bd9b..2cdbe9490a 100644 --- a/wagtail/core/tests/test_rich_text.py +++ b/wagtail/core/tests/test_rich_text.py @@ -4,7 +4,8 @@ from mock import patch from wagtail.core.models import Page from wagtail.core.rich_text import ( - DbWhitelister, FeatureRegistry, RichText, expand_db_html, extract_attrs) + DbWhitelister, RichText, expand_db_html, extract_attrs) +from wagtail.core.rich_text.feature_registry import FeatureRegistry from wagtail.core.rich_text.pages import PageLinkHandler