We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Allow TinyMCE to be used in inline-mode
Inline-mode of TinyMCE (https://www.tiny.cloud/docs/demo/inline) is nice among other reasons because the edited text looks exactly the way as the saved result. 

To enable it you could simply set `{"inline": "true"}` as the value in the field "Other settings" of the TinyMCE controlpanel. That is enough to trigger it. 

But that fails with `Could not initialize inline editor on invalid inline target element` since the html-tag that renders the TinyMCE is a `<textarea>`. See https://www.tiny.cloud/blog/tinymce-inline-option-not-working for details about that constraint.

The `<textarea>` thing is defined in `plone.app.z3cform.widget.RichTextWidget` which has `TextareaWidget` as `_base`. In `render_input_mode` of the widget it is possible to conditionally render a different html element like `div` around the text. But then fallback to textarea no longer works and saving also fails and and and... 

So it seems that using inline-mode in not straightforward. The question is do we like that option enough to do the required work?


--- 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/settings.py`
Content:
```
1 from Acquisition import aq_inner
2 from Acquisition import aq_parent
3 from borg.localrole.interfaces import IFactoryTempFolder
4 from plone.app.content.browser.interfaces import IFolderContentsView
5 from plone.app.widgets.utils import get_relateditems_options
6 from plone.app.z3cform.utils import call_callables
7 from plone.registry.interfaces import IRegistry
8 from plone.uuid.interfaces import IUUID
9 from Products.CMFCore.interfaces._content import IFolderish
10 from plone.base.interfaces import ILinkSchema
11 from plone.base.interfaces import IPatternsSettings
12 from plone.base.interfaces import IPloneSiteRoot
13 from Products.CMFPlone.patterns.tinymce import TinyMCESettingsGenerator
14 from Products.CMFPlone.utils import get_portal
15 from zope.component import getUtility
16 from zope.i18n import translate
17 from zope.interface import implementer
18 from zope.schema.interfaces import IVocabularyFactory
19 
20 import json
21 
22 
23 @implementer(IPatternsSettings)
24 class PatternSettingsAdapter:
25     """
26     Provides default plone settings relevant for patterns.
27     """
28 
29     def __init__(self, context, request, field):
30         self.request = request
31         self.context = context
32         self.field = field
33 
34     def __call__(self):
35         data = {}
36         data.update(self.mark_special_links())
37         data.update(self.structure_updater())
38         return data
39 
40     def structure_updater(self):
41         """Generate the options for the structure updater pattern.
42         If we're not in folder contents view, do not expose these options.
43         """
44         data = {}
45         view = self.request.get("PUBLISHED", None)
46         if IFolderContentsView.providedBy(view):
47             data = {
48                 "data-pat-structureupdater": json.dumps(
49                     {
50                         "titleSelector": ".documentFirstHeading",
51                         "descriptionSelector": ".documentDescription",
52                     }
53                 )
54             }
55         return data
56 
57     def mark_special_links(self):
58         result = {}
59 
60         registry = getUtility(IRegistry)
61         settings = registry.forInterface(ILinkSchema, prefix="plone", check=False)
62 
63         msl = settings.mark_special_links
64         elonw = settings.external_links_open_new_window
65         if msl or elonw:
66             result = {
67                 "data-pat-markspeciallinks": json.dumps(
68                     {"external_links_open_new_window": elonw, "mark_special_links": msl}
69                 )
70             }
71         return result
72 
73     @property
74     def image_scales(self):
75         factory = getUtility(IVocabularyFactory, "plone.app.vocabularies.ImagesScales")
76         vocabulary = factory(self.context)
77         ret = [{"title": translate(it.title), "value": it.value} for it in vocabulary]
78         ret = sorted(ret, key=lambda it: it["title"])
79         return json.dumps(ret)
80 
81     def tinymce(self):
82         """
83         data-pat-tinymce : JSON.stringify({
84             relatedItems: {
85               vocabularyUrl: config.portal_url +
86                 '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
87             },
88             tiny: config,
89             prependToUrl: 'resolveuid/',
90             linkAttribute: 'UID',
91             prependToScalePart: '/@@images/image/'
92           })
93         """
94 
95         generator = TinyMCESettingsGenerator(self.context, self.request)
96         settings = generator.settings
97         folder = aq_inner(self.context)
98 
99         # Test if we are currently creating an Archetype object
100         if IFactoryTempFolder.providedBy(aq_parent(folder)):
101             folder = aq_parent(aq_parent(aq_parent(folder)))
102         if not IFolderish.providedBy(folder):
103             folder = aq_parent(folder)
104 
105         if IPloneSiteRoot.providedBy(folder):
106             initial = None
107         else:
108             initial = IUUID(folder, None)
109 
110         portal = get_portal()
111         portal_url = portal.absolute_url()
112         current_path = folder.absolute_url()[len(portal_url) :]
113 
114         image_types = settings.image_objects or []
115 
116         server_url = self.request.get("SERVER_URL", "")
117         site_path = portal_url[len(server_url) :]
118 
119         related_items_config = get_relateditems_options(
120             context=self.context,
121             value=None,
122             separator=";",
123             vocabulary_name="plone.app.vocabularies.Catalog",
124             vocabulary_view="@@getVocabulary",
125             field_name=None,
126         )
127         related_items_config = call_callables(related_items_config, self.context)
128 
129         configuration = {
130             "base_url": self.context.absolute_url(),
131             "imageTypes": image_types,
132             "imageScales": self.image_scales,
133             "linkAttribute": "UID",
134             # This is for loading the languages on tinymce
135             "loadingBaseUrl": "{}/++plone++static/components/tinymce-builded/"
136             "js/tinymce".format(portal_url),
137             "relatedItems": related_items_config,
138             "prependToScalePart": "/@@images/image/",
139             "prependToUrl": "{}/resolveuid/".format(site_path.rstrip("/")),
140             "tiny": generator.get_tiny_config(),
141             "upload": {
142                 "baseUrl": portal_url,
143                 "currentPath": current_path,
144                 "initialFolder": initial,
145                 "maxFiles": 1,
146                 "relativePath": "@@fileUpload",
147                 "showTitle": False,
148                 "uploadMultiple": False,
149             },
150         }
151         return {"data-pat-tinymce": json.dumps(configuration)}
152
```
--- 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/settings.py b/Products/CMFPlone/patterns/settings.py
--- a/Products/CMFPlone/patterns/settings.py
+++ b/Products/CMFPlone/patterns/settings.py
@@ -137,6 +137,7 @@
             "relatedItems": related_items_config,
             "prependToScalePart": "/@@images/image/",
             "prependToUrl": "{}/resolveuid/".format(site_path.rstrip("/")),
+            "inline": settings.inline,
             "tiny": generator.get_tiny_config(),
             "upload": {
                 "baseUrl": portal_url,

{"golden_diff": "diff --git a/Products/CMFPlone/patterns/settings.py b/Products/CMFPlone/patterns/settings.py\n--- a/Products/CMFPlone/patterns/settings.py\n+++ b/Products/CMFPlone/patterns/settings.py\n@@ -137,6 +137,7 @@\n             \"relatedItems\": related_items_config,\n             \"prependToScalePart\": \"/@@images/image/\",\n             \"prependToUrl\": \"{}/resolveuid/\".format(site_path.rstrip(\"/\")),\n+            \"inline\": settings.inline,\n             \"tiny\": generator.get_tiny_config(),\n             \"upload\": {\n                 \"baseUrl\": portal_url,\n", "issue": "Allow TinyMCE to be used in inline-mode\nInline-mode of TinyMCE (https://www.tiny.cloud/docs/demo/inline) is nice among other reasons because the edited text looks exactly the way as the saved result. \r\n\r\nTo enable it you could simply set `{\"inline\": \"true\"}` as the value in the field \"Other settings\" of the TinyMCE controlpanel. That is enough to trigger it. \r\n\r\nBut that fails with `Could not initialize inline editor on invalid inline target element` since the html-tag that renders the TinyMCE is a `<textarea>`. See https://www.tiny.cloud/blog/tinymce-inline-option-not-working for details about that constraint.\r\n\r\nThe `<textarea>` thing is defined in `plone.app.z3cform.widget.RichTextWidget` which has `TextareaWidget` as `_base`. In `render_input_mode` of the widget it is possible to conditionally render a different html element like `div` around the text. But then fallback to textarea no longer works and saving also fails and and and... \r\n\r\nSo it seems that using inline-mode in not straightforward. The question is do we like that option enough to do the required work?\r\n\n", "before_files": [{"content": "from Acquisition import aq_inner\nfrom Acquisition import aq_parent\nfrom borg.localrole.interfaces import IFactoryTempFolder\nfrom plone.app.content.browser.interfaces import IFolderContentsView\nfrom plone.app.widgets.utils import get_relateditems_options\nfrom plone.app.z3cform.utils import call_callables\nfrom plone.registry.interfaces import IRegistry\nfrom plone.uuid.interfaces import IUUID\nfrom Products.CMFCore.interfaces._content import IFolderish\nfrom plone.base.interfaces import ILinkSchema\nfrom plone.base.interfaces import IPatternsSettings\nfrom plone.base.interfaces import IPloneSiteRoot\nfrom Products.CMFPlone.patterns.tinymce import TinyMCESettingsGenerator\nfrom Products.CMFPlone.utils import get_portal\nfrom zope.component import getUtility\nfrom zope.i18n import translate\nfrom zope.interface import implementer\nfrom zope.schema.interfaces import IVocabularyFactory\n\nimport json\n\n\n@implementer(IPatternsSettings)\nclass PatternSettingsAdapter:\n    \"\"\"\n    Provides default plone settings relevant for patterns.\n    \"\"\"\n\n    def __init__(self, context, request, field):\n        self.request = request\n        self.context = context\n        self.field = field\n\n    def __call__(self):\n        data = {}\n        data.update(self.mark_special_links())\n        data.update(self.structure_updater())\n        return data\n\n    def structure_updater(self):\n        \"\"\"Generate the options for the structure updater pattern.\n        If we're not in folder contents view, do not expose these options.\n        \"\"\"\n        data = {}\n        view = self.request.get(\"PUBLISHED\", None)\n        if IFolderContentsView.providedBy(view):\n            data = {\n                \"data-pat-structureupdater\": json.dumps(\n                    {\n                        \"titleSelector\": \".documentFirstHeading\",\n                        \"descriptionSelector\": \".documentDescription\",\n                    }\n                )\n            }\n        return data\n\n    def mark_special_links(self):\n        result = {}\n\n        registry = getUtility(IRegistry)\n        settings = registry.forInterface(ILinkSchema, prefix=\"plone\", check=False)\n\n        msl = settings.mark_special_links\n        elonw = settings.external_links_open_new_window\n        if msl or elonw:\n            result = {\n                \"data-pat-markspeciallinks\": json.dumps(\n                    {\"external_links_open_new_window\": elonw, \"mark_special_links\": msl}\n                )\n            }\n        return result\n\n    @property\n    def image_scales(self):\n        factory = getUtility(IVocabularyFactory, \"plone.app.vocabularies.ImagesScales\")\n        vocabulary = factory(self.context)\n        ret = [{\"title\": translate(it.title), \"value\": it.value} for it in vocabulary]\n        ret = sorted(ret, key=lambda it: it[\"title\"])\n        return json.dumps(ret)\n\n    def tinymce(self):\n        \"\"\"\n        data-pat-tinymce : JSON.stringify({\n            relatedItems: {\n              vocabularyUrl: config.portal_url +\n                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'\n            },\n            tiny: config,\n            prependToUrl: 'resolveuid/',\n            linkAttribute: 'UID',\n            prependToScalePart: '/@@images/image/'\n          })\n        \"\"\"\n\n        generator = TinyMCESettingsGenerator(self.context, self.request)\n        settings = generator.settings\n        folder = aq_inner(self.context)\n\n        # Test if we are currently creating an Archetype object\n        if IFactoryTempFolder.providedBy(aq_parent(folder)):\n            folder = aq_parent(aq_parent(aq_parent(folder)))\n        if not IFolderish.providedBy(folder):\n            folder = aq_parent(folder)\n\n        if IPloneSiteRoot.providedBy(folder):\n            initial = None\n        else:\n            initial = IUUID(folder, None)\n\n        portal = get_portal()\n        portal_url = portal.absolute_url()\n        current_path = folder.absolute_url()[len(portal_url) :]\n\n        image_types = settings.image_objects or []\n\n        server_url = self.request.get(\"SERVER_URL\", \"\")\n        site_path = portal_url[len(server_url) :]\n\n        related_items_config = get_relateditems_options(\n            context=self.context,\n            value=None,\n            separator=\";\",\n            vocabulary_name=\"plone.app.vocabularies.Catalog\",\n            vocabulary_view=\"@@getVocabulary\",\n            field_name=None,\n        )\n        related_items_config = call_callables(related_items_config, self.context)\n\n        configuration = {\n            \"base_url\": self.context.absolute_url(),\n            \"imageTypes\": image_types,\n            \"imageScales\": self.image_scales,\n            \"linkAttribute\": \"UID\",\n            # This is for loading the languages on tinymce\n            \"loadingBaseUrl\": \"{}/++plone++static/components/tinymce-builded/\"\n            \"js/tinymce\".format(portal_url),\n            \"relatedItems\": related_items_config,\n            \"prependToScalePart\": \"/@@images/image/\",\n            \"prependToUrl\": \"{}/resolveuid/\".format(site_path.rstrip(\"/\")),\n            \"tiny\": generator.get_tiny_config(),\n            \"upload\": {\n                \"baseUrl\": portal_url,\n                \"currentPath\": current_path,\n                \"initialFolder\": initial,\n                \"maxFiles\": 1,\n                \"relativePath\": \"@@fileUpload\",\n                \"showTitle\": False,\n                \"uploadMultiple\": False,\n            },\n        }\n        return {\"data-pat-tinymce\": json.dumps(configuration)}\n", "path": "Products/CMFPlone/patterns/settings.py"}], "after_files": [{"content": "from Acquisition import aq_inner\nfrom Acquisition import aq_parent\nfrom borg.localrole.interfaces import IFactoryTempFolder\nfrom plone.app.content.browser.interfaces import IFolderContentsView\nfrom plone.app.widgets.utils import get_relateditems_options\nfrom plone.app.z3cform.utils import call_callables\nfrom plone.registry.interfaces import IRegistry\nfrom plone.uuid.interfaces import IUUID\nfrom Products.CMFCore.interfaces._content import IFolderish\nfrom plone.base.interfaces import ILinkSchema\nfrom plone.base.interfaces import IPatternsSettings\nfrom plone.base.interfaces import IPloneSiteRoot\nfrom Products.CMFPlone.patterns.tinymce import TinyMCESettingsGenerator\nfrom Products.CMFPlone.utils import get_portal\nfrom zope.component import getUtility\nfrom zope.i18n import translate\nfrom zope.interface import implementer\nfrom zope.schema.interfaces import IVocabularyFactory\n\nimport json\n\n\n@implementer(IPatternsSettings)\nclass PatternSettingsAdapter:\n    \"\"\"\n    Provides default plone settings relevant for patterns.\n    \"\"\"\n\n    def __init__(self, context, request, field):\n        self.request = request\n        self.context = context\n        self.field = field\n\n    def __call__(self):\n        data = {}\n        data.update(self.mark_special_links())\n        data.update(self.structure_updater())\n        return data\n\n    def structure_updater(self):\n        \"\"\"Generate the options for the structure updater pattern.\n        If we're not in folder contents view, do not expose these options.\n        \"\"\"\n        data = {}\n        view = self.request.get(\"PUBLISHED\", None)\n        if IFolderContentsView.providedBy(view):\n            data = {\n                \"data-pat-structureupdater\": json.dumps(\n                    {\n                        \"titleSelector\": \".documentFirstHeading\",\n                        \"descriptionSelector\": \".documentDescription\",\n                    }\n                )\n            }\n        return data\n\n    def mark_special_links(self):\n        result = {}\n\n        registry = getUtility(IRegistry)\n        settings = registry.forInterface(ILinkSchema, prefix=\"plone\", check=False)\n\n        msl = settings.mark_special_links\n        elonw = settings.external_links_open_new_window\n        if msl or elonw:\n            result = {\n                \"data-pat-markspeciallinks\": json.dumps(\n                    {\"external_links_open_new_window\": elonw, \"mark_special_links\": msl}\n                )\n            }\n        return result\n\n    @property\n    def image_scales(self):\n        factory = getUtility(IVocabularyFactory, \"plone.app.vocabularies.ImagesScales\")\n        vocabulary = factory(self.context)\n        ret = [{\"title\": translate(it.title), \"value\": it.value} for it in vocabulary]\n        ret = sorted(ret, key=lambda it: it[\"title\"])\n        return json.dumps(ret)\n\n    def tinymce(self):\n        \"\"\"\n        data-pat-tinymce : JSON.stringify({\n            relatedItems: {\n              vocabularyUrl: config.portal_url +\n                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'\n            },\n            tiny: config,\n            prependToUrl: 'resolveuid/',\n            linkAttribute: 'UID',\n            prependToScalePart: '/@@images/image/'\n          })\n        \"\"\"\n\n        generator = TinyMCESettingsGenerator(self.context, self.request)\n        settings = generator.settings\n        folder = aq_inner(self.context)\n\n        # Test if we are currently creating an Archetype object\n        if IFactoryTempFolder.providedBy(aq_parent(folder)):\n            folder = aq_parent(aq_parent(aq_parent(folder)))\n        if not IFolderish.providedBy(folder):\n            folder = aq_parent(folder)\n\n        if IPloneSiteRoot.providedBy(folder):\n            initial = None\n        else:\n            initial = IUUID(folder, None)\n\n        portal = get_portal()\n        portal_url = portal.absolute_url()\n        current_path = folder.absolute_url()[len(portal_url) :]\n\n        image_types = settings.image_objects or []\n\n        server_url = self.request.get(\"SERVER_URL\", \"\")\n        site_path = portal_url[len(server_url) :]\n\n        related_items_config = get_relateditems_options(\n            context=self.context,\n            value=None,\n            separator=\";\",\n            vocabulary_name=\"plone.app.vocabularies.Catalog\",\n            vocabulary_view=\"@@getVocabulary\",\n            field_name=None,\n        )\n        related_items_config = call_callables(related_items_config, self.context)\n\n        configuration = {\n            \"base_url\": self.context.absolute_url(),\n            \"imageTypes\": image_types,\n            \"imageScales\": self.image_scales,\n            \"linkAttribute\": \"UID\",\n            # This is for loading the languages on tinymce\n            \"loadingBaseUrl\": \"{}/++plone++static/components/tinymce-builded/\"\n            \"js/tinymce\".format(portal_url),\n            \"relatedItems\": related_items_config,\n            \"prependToScalePart\": \"/@@images/image/\",\n            \"prependToUrl\": \"{}/resolveuid/\".format(site_path.rstrip(\"/\")),\n            \"inline\": settings.inline,\n            \"tiny\": generator.get_tiny_config(),\n            \"upload\": {\n                \"baseUrl\": portal_url,\n                \"currentPath\": current_path,\n                \"initialFolder\": initial,\n                \"maxFiles\": 1,\n                \"relativePath\": \"@@fileUpload\",\n                \"showTitle\": False,\n                \"uploadMultiple\": False,\n            },\n        }\n        return {\"data-pat-tinymce\": json.dumps(configuration)}\n", "path": "Products/CMFPlone/patterns/settings.py"}]}