We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
The TinyMCE pattern loads HTML as CSS and slows edit forms
## The TinyMCE pattern loads HTML as CSS and slows edit forms

### What I did:

Open an `@@edit` form with the browser's network inspector open.

### What I expect to happen:

It should load quickly and with the correct resources.

### What actually happened:

For every field using the TinyMCE pattern, there was a network request for the portal root rendered at HTML but loaded as CSS.  This takes a lot of time and greatly slows the page load time.

### What version of Plone/ Addons I am using:

Products.CMFPlone==5.1.5
plone.app.theming==2.0.5

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/patterns/tinymce.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from lxml import html
3 from plone.app.layout.navigation.root import getNavigationRootObject
4 from plone.app.theming.utils import theming_policy
5 from plone.registry.interfaces import IRegistry
6 from Products.CMFCore.utils import getToolByName
7 from Products.CMFPlone.interfaces import IFilterSchema
8 from Products.CMFPlone.interfaces import ITinyMCESchema
9 from Products.CMFPlone.utils import get_portal
10 from zope.component import getUtility
11 
12 import json
13 
14 
15 class TinyMCESettingsGenerator(object):
16 
17     def __init__(self, context, request):
18         self.context = context
19         self.request = request
20         self.settings = getUtility(IRegistry).forInterface(
21             ITinyMCESchema,
22             prefix="plone",
23             check=False
24         )
25         self.filter_settings = getUtility(IRegistry).forInterface(
26             IFilterSchema,
27             prefix="plone",
28             check=False
29         )
30         self.nav_root = getNavigationRootObject(
31             self.context,
32             get_portal(),
33         )
34         self.nav_root_url = self.nav_root.absolute_url()
35 
36     def get_theme(self):
37         return theming_policy().get_theme()
38 
39     def get_content_css(self, style_css=''):
40         files = [
41             '{0}/++plone++static/plone-compiled.css'.format(self.nav_root_url)
42         ]
43         if style_css:
44             files.extend(style_css.split(','))
45         content_css = self.settings.content_css or []
46         for url in content_css:
47             if url and url.strip():
48                 files.append('/'.join([self.nav_root_url, url.strip()]))
49         theme = self.get_theme()
50         tinymce_content_css = getattr(theme, 'tinymce_content_css', None)
51         if tinymce_content_css is not None:
52             for path in theme.tinymce_content_css.split(','):
53                 if path.startswith('http://') or path.startswith('https://'):
54                     files.append(path)
55                 else:
56                     files.append(self.nav_root_url + path)
57 
58         return ','.join(files)
59 
60     def get_style_format(self, txt, _type='format', base=None):
61         parts = txt.strip().split('|')
62         if len(parts) < 2:
63             return
64         if base is None:
65             val = {}
66         else:
67             val = base.copy()
68         val.update({
69             'title': parts[0],
70             _type: parts[1]
71         })
72         if len(parts) > 2:
73             val['icon'] = parts[2]
74         return val
75 
76     def get_styles(self, styles, _type='format', base=None):
77         result = []
78         for style in styles:
79             style = self.get_style_format(style, _type, base)
80             if not style:
81                 continue
82             result.append(style)
83         return result
84 
85     def get_all_style_formats(self):
86         header_styles = self.settings.header_styles or []
87         block_styles = self.settings.block_styles or []
88         inline_styles = self.settings.inline_styles or []
89         alignment_styles = self.settings.alignment_styles or []
90         table_styles = self.settings.table_styles or []
91         return [{
92             'title': 'Headers',
93             'items': self.get_styles(header_styles)
94         }, {
95             'title': 'Block',
96             'items': self.get_styles(block_styles)
97         }, {
98             'title': 'Inline',
99             'items': self.get_styles(inline_styles)
100         }, {
101             'title': 'Alignment',
102             'items': self.get_styles(alignment_styles)
103         }, {
104             'title': 'Tables',
105             'items': self.get_styles(
106                 table_styles, 'classes', {'selector': 'table'})
107         }]
108 
109     def get_tiny_config(self):
110         settings = self.settings
111         importcss_file_filter = '%s/++plone++static/tinymce-styles.css' % (
112             self.nav_root_url
113         )
114 
115         theme = self.get_theme()
116         if theme and getattr(theme, 'tinymce_styles_css', None):
117             importcss_file_filter += ',%s/%s' % (
118                 self.nav_root_url,
119                 theme.tinymce_styles_css.lstrip('/'))
120 
121         tiny_config = {
122             'resize': 'both' if settings.resizing else False,
123             'content_css': self.get_content_css(importcss_file_filter),
124             'plugins': [
125                 'plonelink',
126                 'ploneimage',
127                 'importcss'
128             ] + settings.plugins,
129             'external_plugins': {},
130             'toolbar': settings.toolbar,
131             'entity_encoding': settings.entity_encoding,
132             'importcss_append': True,
133             'importcss_file_filter': importcss_file_filter,
134             'browser_spellcheck': True
135         }
136         toolbar_additions = settings.custom_buttons or []
137 
138         if settings.editor_height:
139             tiny_config['height'] = settings.editor_height
140         if settings.autoresize:
141             tiny_config['plugins'].append('autoresize')
142             tiny_config['autoresize_max_height'] = 1000  # hard coded?
143         if settings.editor_width:
144             tiny_config['width'] = settings.editor_width
145 
146         # specific plugin options
147         if 'contextmenu' in settings.plugins:
148             tiny_config['contextmenu'] = "plonelink ploneimage inserttable |"\
149                 " cell row column deletetable"
150 
151         if settings.libraries_spellchecker_choice == 'AtD':
152             mtool = getToolByName(self.context, 'portal_membership')
153             member = mtool.getAuthenticatedMember()
154             member_id = member.getId()
155             if member_id:
156                 if 'compat3x' not in tiny_config['plugins']:
157                     tiny_config['plugins'].append('compat3x')
158                 tiny_config['external_plugins']['AtD'] = (
159                     '{0}/++plone++static/tinymce-AtD-plugin/'
160                     'editor_plugin.js'.format(self.nav_root_url)
161                 )
162                 # None when Anonymous User
163                 tiny_config['atd_rpc_id'] = 'plone-' + member_id
164                 tiny_config['atd_rpc_url'] = self.nav_root_url
165                 tiny_config['atd_show_types'] = ','.join(
166                     settings.libraries_atd_show_types
167                 )
168                 tiny_config['atd_ignore_strings'] = ','.join(
169                     settings.libraries_atd_ignore_strings
170                 )
171                 toolbar_additions.append('AtD')
172         elif settings.libraries_spellchecker_choice == 'AtD':
173             tiny_config['browser_spellcheck'] = True
174 
175         if toolbar_additions:
176             tiny_config['toolbar'] += ' | {0}'.format(
177                 ' '.join(toolbar_additions)
178             )
179 
180         for plugin in settings.custom_plugins or []:
181             parts = plugin.split('|')
182             if len(parts) != 2:
183                 continue
184             tiny_config['external_plugins'][parts[0]] = parts[1]
185 
186         tiny_config['style_formats'] = self.get_all_style_formats()
187         if settings.formats:
188             try:
189                 tiny_config['formats'] = json.loads(settings.formats)
190             except ValueError:
191                 pass
192 
193         if settings.menubar:
194             tiny_config['menubar'] = settings.menubar
195         if settings.menu:
196             try:
197                 tiny_config['menu'] = json.loads(settings.menu)
198             except ValueError:
199                 pass
200 
201         if hasattr(settings, 'templates') and settings.templates:
202             try:
203                 tiny_config['templates'] = json.loads(settings.templates)
204             except ValueError:
205                 pass
206 
207         # add safe_html settings, which are useed in backend for filtering:
208         if not self.filter_settings.disable_filtering:
209             valid_tags = self.filter_settings.valid_tags
210             nasty_tags = self.filter_settings.nasty_tags
211             custom_attributes = self.filter_settings.custom_attributes
212             safe_attributes = [attr.decode() for attr in html.defs.safe_attrs]
213             valid_attributes = safe_attributes + custom_attributes
214             # valid_elements : 'a[href|target=_blank],strong/b,div[align],br'
215             tiny_valid_elements = []
216             for tag in valid_tags:
217                 tag_str = "%s[%s]" % (tag, "|".join(valid_attributes))
218                 tiny_valid_elements.append(tag_str)
219             # We want to remove the nasty tag including the content in the
220             # backend, so TinyMCE should allow them here.
221             for tag in nasty_tags:
222                 tag_str = "%s[%s]" % (tag, "|".join(valid_attributes))
223                 tiny_valid_elements.append(tag_str)
224             tiny_config['valid_elements'] = ",".join(tiny_valid_elements)
225 
226         if settings.other_settings:
227             try:
228                 tiny_config.update(json.loads(settings.other_settings))
229             except ValueError:
230                 pass
231 
232         return tiny_config
233
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Products/CMFPlone/patterns/tinymce.py b/Products/CMFPlone/patterns/tinymce.py
--- a/Products/CMFPlone/patterns/tinymce.py
+++ b/Products/CMFPlone/patterns/tinymce.py
@@ -48,7 +48,7 @@
                 files.append('/'.join([self.nav_root_url, url.strip()]))
         theme = self.get_theme()
         tinymce_content_css = getattr(theme, 'tinymce_content_css', None)
-        if tinymce_content_css is not None:
+        if tinymce_content_css:
             for path in theme.tinymce_content_css.split(','):
                 if path.startswith('http://') or path.startswith('https://'):
                     files.append(path)

{"golden_diff": "diff --git a/Products/CMFPlone/patterns/tinymce.py b/Products/CMFPlone/patterns/tinymce.py\n--- a/Products/CMFPlone/patterns/tinymce.py\n+++ b/Products/CMFPlone/patterns/tinymce.py\n@@ -48,7 +48,7 @@\n                 files.append('/'.join([self.nav_root_url, url.strip()]))\n         theme = self.get_theme()\n         tinymce_content_css = getattr(theme, 'tinymce_content_css', None)\n-        if tinymce_content_css is not None:\n+        if tinymce_content_css:\n             for path in theme.tinymce_content_css.split(','):\n                 if path.startswith('http://') or path.startswith('https://'):\n                     files.append(path)\n", "issue": "The TinyMCE pattern loads HTML as CSS and slows edit forms\n## The TinyMCE pattern loads HTML as CSS and slows edit forms\r\n\r\n### What I did:\r\n\r\nOpen an `@@edit` form with the browser's network inspector open.\r\n\r\n### What I expect to happen:\r\n\r\nIt should load quickly and with the correct resources.\r\n\r\n### What actually happened:\r\n\r\nFor every field using the TinyMCE pattern, there was a network request for the portal root rendered at HTML but loaded as CSS.  This takes a lot of time and greatly slows the page load time.\r\n\r\n### What version of Plone/ Addons I am using:\r\n\r\nProducts.CMFPlone==5.1.5\r\nplone.app.theming==2.0.5\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom lxml import html\nfrom plone.app.layout.navigation.root import getNavigationRootObject\nfrom plone.app.theming.utils import theming_policy\nfrom plone.registry.interfaces import IRegistry\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone.interfaces import IFilterSchema\nfrom Products.CMFPlone.interfaces import ITinyMCESchema\nfrom Products.CMFPlone.utils import get_portal\nfrom zope.component import getUtility\n\nimport json\n\n\nclass TinyMCESettingsGenerator(object):\n\n    def __init__(self, context, request):\n        self.context = context\n        self.request = request\n        self.settings = getUtility(IRegistry).forInterface(\n            ITinyMCESchema,\n            prefix=\"plone\",\n            check=False\n        )\n        self.filter_settings = getUtility(IRegistry).forInterface(\n            IFilterSchema,\n            prefix=\"plone\",\n            check=False\n        )\n        self.nav_root = getNavigationRootObject(\n            self.context,\n            get_portal(),\n        )\n        self.nav_root_url = self.nav_root.absolute_url()\n\n    def get_theme(self):\n        return theming_policy().get_theme()\n\n    def get_content_css(self, style_css=''):\n        files = [\n            '{0}/++plone++static/plone-compiled.css'.format(self.nav_root_url)\n        ]\n        if style_css:\n            files.extend(style_css.split(','))\n        content_css = self.settings.content_css or []\n        for url in content_css:\n            if url and url.strip():\n                files.append('/'.join([self.nav_root_url, url.strip()]))\n        theme = self.get_theme()\n        tinymce_content_css = getattr(theme, 'tinymce_content_css', None)\n        if tinymce_content_css is not None:\n            for path in theme.tinymce_content_css.split(','):\n                if path.startswith('http://') or path.startswith('https://'):\n                    files.append(path)\n                else:\n                    files.append(self.nav_root_url + path)\n\n        return ','.join(files)\n\n    def get_style_format(self, txt, _type='format', base=None):\n        parts = txt.strip().split('|')\n        if len(parts) < 2:\n            return\n        if base is None:\n            val = {}\n        else:\n            val = base.copy()\n        val.update({\n            'title': parts[0],\n            _type: parts[1]\n        })\n        if len(parts) > 2:\n            val['icon'] = parts[2]\n        return val\n\n    def get_styles(self, styles, _type='format', base=None):\n        result = []\n        for style in styles:\n            style = self.get_style_format(style, _type, base)\n            if not style:\n                continue\n            result.append(style)\n        return result\n\n    def get_all_style_formats(self):\n        header_styles = self.settings.header_styles or []\n        block_styles = self.settings.block_styles or []\n        inline_styles = self.settings.inline_styles or []\n        alignment_styles = self.settings.alignment_styles or []\n        table_styles = self.settings.table_styles or []\n        return [{\n            'title': 'Headers',\n            'items': self.get_styles(header_styles)\n        }, {\n            'title': 'Block',\n            'items': self.get_styles(block_styles)\n        }, {\n            'title': 'Inline',\n            'items': self.get_styles(inline_styles)\n        }, {\n            'title': 'Alignment',\n            'items': self.get_styles(alignment_styles)\n        }, {\n            'title': 'Tables',\n            'items': self.get_styles(\n                table_styles, 'classes', {'selector': 'table'})\n        }]\n\n    def get_tiny_config(self):\n        settings = self.settings\n        importcss_file_filter = '%s/++plone++static/tinymce-styles.css' % (\n            self.nav_root_url\n        )\n\n        theme = self.get_theme()\n        if theme and getattr(theme, 'tinymce_styles_css', None):\n            importcss_file_filter += ',%s/%s' % (\n                self.nav_root_url,\n                theme.tinymce_styles_css.lstrip('/'))\n\n        tiny_config = {\n            'resize': 'both' if settings.resizing else False,\n            'content_css': self.get_content_css(importcss_file_filter),\n            'plugins': [\n                'plonelink',\n                'ploneimage',\n                'importcss'\n            ] + settings.plugins,\n            'external_plugins': {},\n            'toolbar': settings.toolbar,\n            'entity_encoding': settings.entity_encoding,\n            'importcss_append': True,\n            'importcss_file_filter': importcss_file_filter,\n            'browser_spellcheck': True\n        }\n        toolbar_additions = settings.custom_buttons or []\n\n        if settings.editor_height:\n            tiny_config['height'] = settings.editor_height\n        if settings.autoresize:\n            tiny_config['plugins'].append('autoresize')\n            tiny_config['autoresize_max_height'] = 1000  # hard coded?\n        if settings.editor_width:\n            tiny_config['width'] = settings.editor_width\n\n        # specific plugin options\n        if 'contextmenu' in settings.plugins:\n            tiny_config['contextmenu'] = \"plonelink ploneimage inserttable |\"\\\n                \" cell row column deletetable\"\n\n        if settings.libraries_spellchecker_choice == 'AtD':\n            mtool = getToolByName(self.context, 'portal_membership')\n            member = mtool.getAuthenticatedMember()\n            member_id = member.getId()\n            if member_id:\n                if 'compat3x' not in tiny_config['plugins']:\n                    tiny_config['plugins'].append('compat3x')\n                tiny_config['external_plugins']['AtD'] = (\n                    '{0}/++plone++static/tinymce-AtD-plugin/'\n                    'editor_plugin.js'.format(self.nav_root_url)\n                )\n                # None when Anonymous User\n                tiny_config['atd_rpc_id'] = 'plone-' + member_id\n                tiny_config['atd_rpc_url'] = self.nav_root_url\n                tiny_config['atd_show_types'] = ','.join(\n                    settings.libraries_atd_show_types\n                )\n                tiny_config['atd_ignore_strings'] = ','.join(\n                    settings.libraries_atd_ignore_strings\n                )\n                toolbar_additions.append('AtD')\n        elif settings.libraries_spellchecker_choice == 'AtD':\n            tiny_config['browser_spellcheck'] = True\n\n        if toolbar_additions:\n            tiny_config['toolbar'] += ' | {0}'.format(\n                ' '.join(toolbar_additions)\n            )\n\n        for plugin in settings.custom_plugins or []:\n            parts = plugin.split('|')\n            if len(parts) != 2:\n                continue\n            tiny_config['external_plugins'][parts[0]] = parts[1]\n\n        tiny_config['style_formats'] = self.get_all_style_formats()\n        if settings.formats:\n            try:\n                tiny_config['formats'] = json.loads(settings.formats)\n            except ValueError:\n                pass\n\n        if settings.menubar:\n            tiny_config['menubar'] = settings.menubar\n        if settings.menu:\n            try:\n                tiny_config['menu'] = json.loads(settings.menu)\n            except ValueError:\n                pass\n\n        if hasattr(settings, 'templates') and settings.templates:\n            try:\n                tiny_config['templates'] = json.loads(settings.templates)\n            except ValueError:\n                pass\n\n        # add safe_html settings, which are useed in backend for filtering:\n        if not self.filter_settings.disable_filtering:\n            valid_tags = self.filter_settings.valid_tags\n            nasty_tags = self.filter_settings.nasty_tags\n            custom_attributes = self.filter_settings.custom_attributes\n            safe_attributes = [attr.decode() for attr in html.defs.safe_attrs]\n            valid_attributes = safe_attributes + custom_attributes\n            # valid_elements : 'a[href|target=_blank],strong/b,div[align],br'\n            tiny_valid_elements = []\n            for tag in valid_tags:\n                tag_str = \"%s[%s]\" % (tag, \"|\".join(valid_attributes))\n                tiny_valid_elements.append(tag_str)\n            # We want to remove the nasty tag including the content in the\n            # backend, so TinyMCE should allow them here.\n            for tag in nasty_tags:\n                tag_str = \"%s[%s]\" % (tag, \"|\".join(valid_attributes))\n                tiny_valid_elements.append(tag_str)\n            tiny_config['valid_elements'] = \",\".join(tiny_valid_elements)\n\n        if settings.other_settings:\n            try:\n                tiny_config.update(json.loads(settings.other_settings))\n            except ValueError:\n                pass\n\n        return tiny_config\n", "path": "Products/CMFPlone/patterns/tinymce.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom lxml import html\nfrom plone.app.layout.navigation.root import getNavigationRootObject\nfrom plone.app.theming.utils import theming_policy\nfrom plone.registry.interfaces import IRegistry\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone.interfaces import IFilterSchema\nfrom Products.CMFPlone.interfaces import ITinyMCESchema\nfrom Products.CMFPlone.utils import get_portal\nfrom zope.component import getUtility\n\nimport json\n\n\nclass TinyMCESettingsGenerator(object):\n\n    def __init__(self, context, request):\n        self.context = context\n        self.request = request\n        self.settings = getUtility(IRegistry).forInterface(\n            ITinyMCESchema,\n            prefix=\"plone\",\n            check=False\n        )\n        self.filter_settings = getUtility(IRegistry).forInterface(\n            IFilterSchema,\n            prefix=\"plone\",\n            check=False\n        )\n        self.nav_root = getNavigationRootObject(\n            self.context,\n            get_portal(),\n        )\n        self.nav_root_url = self.nav_root.absolute_url()\n\n    def get_theme(self):\n        return theming_policy().get_theme()\n\n    def get_content_css(self, style_css=''):\n        files = [\n            '{0}/++plone++static/plone-compiled.css'.format(self.nav_root_url)\n        ]\n        if style_css:\n            files.extend(style_css.split(','))\n        content_css = self.settings.content_css or []\n        for url in content_css:\n            if url and url.strip():\n                files.append('/'.join([self.nav_root_url, url.strip()]))\n        theme = self.get_theme()\n        tinymce_content_css = getattr(theme, 'tinymce_content_css', None)\n        if tinymce_content_css:\n            for path in theme.tinymce_content_css.split(','):\n                if path.startswith('http://') or path.startswith('https://'):\n                    files.append(path)\n                else:\n                    files.append(self.nav_root_url + path)\n\n        return ','.join(files)\n\n    def get_style_format(self, txt, _type='format', base=None):\n        parts = txt.strip().split('|')\n        if len(parts) < 2:\n            return\n        if base is None:\n            val = {}\n        else:\n            val = base.copy()\n        val.update({\n            'title': parts[0],\n            _type: parts[1]\n        })\n        if len(parts) > 2:\n            val['icon'] = parts[2]\n        return val\n\n    def get_styles(self, styles, _type='format', base=None):\n        result = []\n        for style in styles:\n            style = self.get_style_format(style, _type, base)\n            if not style:\n                continue\n            result.append(style)\n        return result\n\n    def get_all_style_formats(self):\n        header_styles = self.settings.header_styles or []\n        block_styles = self.settings.block_styles or []\n        inline_styles = self.settings.inline_styles or []\n        alignment_styles = self.settings.alignment_styles or []\n        table_styles = self.settings.table_styles or []\n        return [{\n            'title': 'Headers',\n            'items': self.get_styles(header_styles)\n        }, {\n            'title': 'Block',\n            'items': self.get_styles(block_styles)\n        }, {\n            'title': 'Inline',\n            'items': self.get_styles(inline_styles)\n        }, {\n            'title': 'Alignment',\n            'items': self.get_styles(alignment_styles)\n        }, {\n            'title': 'Tables',\n            'items': self.get_styles(\n                table_styles, 'classes', {'selector': 'table'})\n        }]\n\n    def get_tiny_config(self):\n        settings = self.settings\n        importcss_file_filter = '%s/++plone++static/tinymce-styles.css' % (\n            self.nav_root_url\n        )\n\n        theme = self.get_theme()\n        if theme and getattr(theme, 'tinymce_styles_css', None):\n            importcss_file_filter += ',%s/%s' % (\n                self.nav_root_url,\n                theme.tinymce_styles_css.lstrip('/'))\n\n        tiny_config = {\n            'resize': 'both' if settings.resizing else False,\n            'content_css': self.get_content_css(importcss_file_filter),\n            'plugins': [\n                'plonelink',\n                'ploneimage',\n                'importcss'\n            ] + settings.plugins,\n            'external_plugins': {},\n            'toolbar': settings.toolbar,\n            'entity_encoding': settings.entity_encoding,\n            'importcss_append': True,\n            'importcss_file_filter': importcss_file_filter,\n            'browser_spellcheck': True\n        }\n        toolbar_additions = settings.custom_buttons or []\n\n        if settings.editor_height:\n            tiny_config['height'] = settings.editor_height\n        if settings.autoresize:\n            tiny_config['plugins'].append('autoresize')\n            tiny_config['autoresize_max_height'] = 1000  # hard coded?\n        if settings.editor_width:\n            tiny_config['width'] = settings.editor_width\n\n        # specific plugin options\n        if 'contextmenu' in settings.plugins:\n            tiny_config['contextmenu'] = \"plonelink ploneimage inserttable |\"\\\n                \" cell row column deletetable\"\n\n        if settings.libraries_spellchecker_choice == 'AtD':\n            mtool = getToolByName(self.context, 'portal_membership')\n            member = mtool.getAuthenticatedMember()\n            member_id = member.getId()\n            if member_id:\n                if 'compat3x' not in tiny_config['plugins']:\n                    tiny_config['plugins'].append('compat3x')\n                tiny_config['external_plugins']['AtD'] = (\n                    '{0}/++plone++static/tinymce-AtD-plugin/'\n                    'editor_plugin.js'.format(self.nav_root_url)\n                )\n                # None when Anonymous User\n                tiny_config['atd_rpc_id'] = 'plone-' + member_id\n                tiny_config['atd_rpc_url'] = self.nav_root_url\n                tiny_config['atd_show_types'] = ','.join(\n                    settings.libraries_atd_show_types\n                )\n                tiny_config['atd_ignore_strings'] = ','.join(\n                    settings.libraries_atd_ignore_strings\n                )\n                toolbar_additions.append('AtD')\n        elif settings.libraries_spellchecker_choice == 'AtD':\n            tiny_config['browser_spellcheck'] = True\n\n        if toolbar_additions:\n            tiny_config['toolbar'] += ' | {0}'.format(\n                ' '.join(toolbar_additions)\n            )\n\n        for plugin in settings.custom_plugins or []:\n            parts = plugin.split('|')\n            if len(parts) != 2:\n                continue\n            tiny_config['external_plugins'][parts[0]] = parts[1]\n\n        tiny_config['style_formats'] = self.get_all_style_formats()\n        if settings.formats:\n            try:\n                tiny_config['formats'] = json.loads(settings.formats)\n            except ValueError:\n                pass\n\n        if settings.menubar:\n            tiny_config['menubar'] = settings.menubar\n        if settings.menu:\n            try:\n                tiny_config['menu'] = json.loads(settings.menu)\n            except ValueError:\n                pass\n\n        if hasattr(settings, 'templates') and settings.templates:\n            try:\n                tiny_config['templates'] = json.loads(settings.templates)\n            except ValueError:\n                pass\n\n        # add safe_html settings, which are useed in backend for filtering:\n        if not self.filter_settings.disable_filtering:\n            valid_tags = self.filter_settings.valid_tags\n            nasty_tags = self.filter_settings.nasty_tags\n            custom_attributes = self.filter_settings.custom_attributes\n            safe_attributes = [attr.decode() for attr in html.defs.safe_attrs]\n            valid_attributes = safe_attributes + custom_attributes\n            # valid_elements : 'a[href|target=_blank],strong/b,div[align],br'\n            tiny_valid_elements = []\n            for tag in valid_tags:\n                tag_str = \"%s[%s]\" % (tag, \"|\".join(valid_attributes))\n                tiny_valid_elements.append(tag_str)\n            # We want to remove the nasty tag including the content in the\n            # backend, so TinyMCE should allow them here.\n            for tag in nasty_tags:\n                tag_str = \"%s[%s]\" % (tag, \"|\".join(valid_attributes))\n                tiny_valid_elements.append(tag_str)\n            tiny_config['valid_elements'] = \",\".join(tiny_valid_elements)\n\n        if settings.other_settings:\n            try:\n                tiny_config.update(json.loads(settings.other_settings))\n            except ValueError:\n                pass\n\n        return tiny_config\n", "path": "Products/CMFPlone/patterns/tinymce.py"}]}