We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
HTML filtering requires a "re save" on each page for the settings to take effect. 
Using:  Plone 5.0b4.dev0 (5007)

Been testing the HTML filtering settings using iFrame video. 
When I add an "iframe" video the saved page does not show the video (as expected). But when I toggle ON the "Disable HTML Filtering" checkbox the video still does not display on the page (even after emptying cache). If I edit the video page and immediately "Save" (making no edits) the video displays as expected. The reverse is also true. If I have video correctly displaying on the page (with html filtering disabled) and uncheck "Disable HTML Filtering" checkbox in the HTML Filtering panel, go back to the video page and reload the video still displays. If I edit the page and immediately save the page the video properly does not display. Is this the expected behavior?

In addition. If I add "iFrame" to the "Custom tags" dialogue box I cannot get the video to display with "Disable HTML Filtering" checkbox OFF. Even if I do the "Edit" and "Save" trick from above.


--- 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/controlpanel/browser/filter.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from Products.CMFCore.utils import getToolByName
3 from Products.CMFPlone import PloneMessageFactory as _  # NOQA
4 from Products.CMFPlone.interfaces import IFilterSchema
5 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
6 from Products.statusmessages.interfaces import IStatusMessage
7 from plone.autoform.form import AutoExtensibleForm
8 from plone.z3cform import layout
9 from z3c.form import button
10 from z3c.form import form
11 from Products.PortalTransforms.transforms.safe_html import VALID_TAGS
12 from Products.PortalTransforms.transforms.safe_html import NASTY_TAGS
13 
14 
15 class FilterControlPanel(AutoExtensibleForm, form.EditForm):
16     id = "FilterControlPanel"
17     label = _(u"HTML Filtering Settings")
18     description = _(
19         'description_html_filtering',
20         default=u"HTML generation is heavily cached across Plone. "
21                 u"After changing settings here, you may have to edit "
22                 u"existing content to see the changes in these filter settings "
23                 u"or restart your server.")
24     schema = IFilterSchema
25     form_name = _(u"HTML Filtering Settings")
26     control_panel_view = "filter-controlpanel"
27 
28     def updateActions(self):  # NOQA
29         """Have to override this because we only have Save, not Cancel
30         """
31         super(FilterControlPanel, self).updateActions()
32         self.actions['save'].addClass("context")
33 
34     @button.buttonAndHandler(_(u"Save"), name='save')
35     def handleSave(self, action):  # NOQA
36         data, errors = self.extractData()
37         if errors:
38             self.status = self.formErrorsMessage
39             return
40 
41         # Save in portal tools
42         safe_html = getattr(
43             getToolByName(self.context, 'portal_transforms'),
44             'safe_html',
45             None)
46 
47         nasty_tags = data['nasty_tags']
48         custom_tags = data['custom_tags']
49         stripped_tags = data['stripped_tags']
50 
51         valid = safe_html._config['valid_tags']
52 
53         # start with removing tags that do not belong in valid tags
54         for value in nasty_tags + stripped_tags:
55             if value in valid:
56                 del valid[value]
57         # add in custom tags
58         for custom in custom_tags:
59             if value not in valid:
60                 valid[custom] = 1
61         # then, check if something was previously prevented but is no longer
62         for tag in set(VALID_TAGS.keys()) - set(valid.keys()):
63             if tag not in nasty_tags and tag not in stripped_tags:
64                 valid[tag] = VALID_TAGS[tag]
65 
66         # nasty tags are simple, just set the value here
67         nasty_value = {}
68         for tag in nasty_tags:
69             nasty_value[tag] = NASTY_TAGS.get(tag, VALID_TAGS.get(tag, 1))
70         safe_html._config['nasty_tags'] = nasty_value
71 
72         disable_filtering = int(data['disable_filtering'])
73         if disable_filtering != safe_html._config['disable_transform']:
74             safe_html._config['disable_transform'] = disable_filtering
75 
76         for attr in ('stripped_combinations', 'class_blacklist', 'stripped_attributes',
77                      'style_whitelist'):
78             value = data[attr]
79             if value is None:
80                 if attr == 'stripped_combinations':
81                     value = {}
82                 else:
83                     value = []
84             if value != safe_html._config[attr]:
85                 safe_html._config[attr] = value
86 
87         # always reload the transform
88         safe_html._p_changed = True
89         safe_html.reload()
90 
91         self.applyChanges(data)
92         IStatusMessage(self.request).addStatusMessage(
93             _(u"Changes saved."),
94             "info")
95         self.request.response.redirect(self.request.getURL())
96 
97 
98 class ControlPanelFormWrapper(layout.FormWrapper):
99     """Use this form as the plone.z3cform layout wrapper to get the control
100     panel layout.
101     """
102     index = ViewPageTemplateFile('filter_controlpanel.pt')
103 
104 
105 FilterControlPanelView = layout.wrap_form(
106     FilterControlPanel, ControlPanelFormWrapper)
107
```
--- 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/controlpanel/browser/filter.py b/Products/CMFPlone/controlpanel/browser/filter.py
--- a/Products/CMFPlone/controlpanel/browser/filter.py
+++ b/Products/CMFPlone/controlpanel/browser/filter.py
@@ -15,12 +15,7 @@
 class FilterControlPanel(AutoExtensibleForm, form.EditForm):
     id = "FilterControlPanel"
     label = _(u"HTML Filtering Settings")
-    description = _(
-        'description_html_filtering',
-        default=u"HTML generation is heavily cached across Plone. "
-                u"After changing settings here, you may have to edit "
-                u"existing content to see the changes in these filter settings "
-                u"or restart your server.")
+    description = ""
     schema = IFilterSchema
     form_name = _(u"HTML Filtering Settings")
     control_panel_view = "filter-controlpanel"
@@ -73,8 +68,8 @@
         if disable_filtering != safe_html._config['disable_transform']:
             safe_html._config['disable_transform'] = disable_filtering
 
-        for attr in ('stripped_combinations', 'class_blacklist', 'stripped_attributes',
-                     'style_whitelist'):
+        for attr in ('stripped_combinations', 'class_blacklist',
+                     'stripped_attributes', 'style_whitelist'):
             value = data[attr]
             if value is None:
                 if attr == 'stripped_combinations':
@@ -92,6 +87,11 @@
         IStatusMessage(self.request).addStatusMessage(
             _(u"Changes saved."),
             "info")
+        IStatusMessage(self.request).addStatusMessage(
+            _(u"HTML generation is heavily cached across Plone. You may "
+              u"have to edit existing content or restart your server to see "
+              u"the changes."),
+            "warning")
         self.request.response.redirect(self.request.getURL())

{"golden_diff": "diff --git a/Products/CMFPlone/controlpanel/browser/filter.py b/Products/CMFPlone/controlpanel/browser/filter.py\n--- a/Products/CMFPlone/controlpanel/browser/filter.py\n+++ b/Products/CMFPlone/controlpanel/browser/filter.py\n@@ -15,12 +15,7 @@\n class FilterControlPanel(AutoExtensibleForm, form.EditForm):\n     id = \"FilterControlPanel\"\n     label = _(u\"HTML Filtering Settings\")\n-    description = _(\n-        'description_html_filtering',\n-        default=u\"HTML generation is heavily cached across Plone. \"\n-                u\"After changing settings here, you may have to edit \"\n-                u\"existing content to see the changes in these filter settings \"\n-                u\"or restart your server.\")\n+    description = \"\"\n     schema = IFilterSchema\n     form_name = _(u\"HTML Filtering Settings\")\n     control_panel_view = \"filter-controlpanel\"\n@@ -73,8 +68,8 @@\n         if disable_filtering != safe_html._config['disable_transform']:\n             safe_html._config['disable_transform'] = disable_filtering\n \n-        for attr in ('stripped_combinations', 'class_blacklist', 'stripped_attributes',\n-                     'style_whitelist'):\n+        for attr in ('stripped_combinations', 'class_blacklist',\n+                     'stripped_attributes', 'style_whitelist'):\n             value = data[attr]\n             if value is None:\n                 if attr == 'stripped_combinations':\n@@ -92,6 +87,11 @@\n         IStatusMessage(self.request).addStatusMessage(\n             _(u\"Changes saved.\"),\n             \"info\")\n+        IStatusMessage(self.request).addStatusMessage(\n+            _(u\"HTML generation is heavily cached across Plone. You may \"\n+              u\"have to edit existing content or restart your server to see \"\n+              u\"the changes.\"),\n+            \"warning\")\n         self.request.response.redirect(self.request.getURL())\n", "issue": "HTML filtering requires a \"re save\" on each page for the settings to take effect. \nUsing:  Plone 5.0b4.dev0 (5007)\n\nBeen testing the HTML filtering settings using iFrame video. \nWhen I add an \"iframe\" video the saved page does not show the video (as expected). But when I toggle ON the \"Disable HTML Filtering\" checkbox the video still does not display on the page (even after emptying cache). If I edit the video page and immediately \"Save\" (making no edits) the video displays as expected. The reverse is also true. If I have video correctly displaying on the page (with html filtering disabled) and uncheck \"Disable HTML Filtering\" checkbox in the HTML Filtering panel, go back to the video page and reload the video still displays. If I edit the page and immediately save the page the video properly does not display. Is this the expected behavior?\n\nIn addition. If I add \"iFrame\" to the \"Custom tags\" dialogue box I cannot get the video to display with \"Disable HTML Filtering\" checkbox OFF. Even if I do the \"Edit\" and \"Save\" trick from above.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone import PloneMessageFactory as _  # NOQA\nfrom Products.CMFPlone.interfaces import IFilterSchema\nfrom Products.Five.browser.pagetemplatefile import ViewPageTemplateFile\nfrom Products.statusmessages.interfaces import IStatusMessage\nfrom plone.autoform.form import AutoExtensibleForm\nfrom plone.z3cform import layout\nfrom z3c.form import button\nfrom z3c.form import form\nfrom Products.PortalTransforms.transforms.safe_html import VALID_TAGS\nfrom Products.PortalTransforms.transforms.safe_html import NASTY_TAGS\n\n\nclass FilterControlPanel(AutoExtensibleForm, form.EditForm):\n    id = \"FilterControlPanel\"\n    label = _(u\"HTML Filtering Settings\")\n    description = _(\n        'description_html_filtering',\n        default=u\"HTML generation is heavily cached across Plone. \"\n                u\"After changing settings here, you may have to edit \"\n                u\"existing content to see the changes in these filter settings \"\n                u\"or restart your server.\")\n    schema = IFilterSchema\n    form_name = _(u\"HTML Filtering Settings\")\n    control_panel_view = \"filter-controlpanel\"\n\n    def updateActions(self):  # NOQA\n        \"\"\"Have to override this because we only have Save, not Cancel\n        \"\"\"\n        super(FilterControlPanel, self).updateActions()\n        self.actions['save'].addClass(\"context\")\n\n    @button.buttonAndHandler(_(u\"Save\"), name='save')\n    def handleSave(self, action):  # NOQA\n        data, errors = self.extractData()\n        if errors:\n            self.status = self.formErrorsMessage\n            return\n\n        # Save in portal tools\n        safe_html = getattr(\n            getToolByName(self.context, 'portal_transforms'),\n            'safe_html',\n            None)\n\n        nasty_tags = data['nasty_tags']\n        custom_tags = data['custom_tags']\n        stripped_tags = data['stripped_tags']\n\n        valid = safe_html._config['valid_tags']\n\n        # start with removing tags that do not belong in valid tags\n        for value in nasty_tags + stripped_tags:\n            if value in valid:\n                del valid[value]\n        # add in custom tags\n        for custom in custom_tags:\n            if value not in valid:\n                valid[custom] = 1\n        # then, check if something was previously prevented but is no longer\n        for tag in set(VALID_TAGS.keys()) - set(valid.keys()):\n            if tag not in nasty_tags and tag not in stripped_tags:\n                valid[tag] = VALID_TAGS[tag]\n\n        # nasty tags are simple, just set the value here\n        nasty_value = {}\n        for tag in nasty_tags:\n            nasty_value[tag] = NASTY_TAGS.get(tag, VALID_TAGS.get(tag, 1))\n        safe_html._config['nasty_tags'] = nasty_value\n\n        disable_filtering = int(data['disable_filtering'])\n        if disable_filtering != safe_html._config['disable_transform']:\n            safe_html._config['disable_transform'] = disable_filtering\n\n        for attr in ('stripped_combinations', 'class_blacklist', 'stripped_attributes',\n                     'style_whitelist'):\n            value = data[attr]\n            if value is None:\n                if attr == 'stripped_combinations':\n                    value = {}\n                else:\n                    value = []\n            if value != safe_html._config[attr]:\n                safe_html._config[attr] = value\n\n        # always reload the transform\n        safe_html._p_changed = True\n        safe_html.reload()\n\n        self.applyChanges(data)\n        IStatusMessage(self.request).addStatusMessage(\n            _(u\"Changes saved.\"),\n            \"info\")\n        self.request.response.redirect(self.request.getURL())\n\n\nclass ControlPanelFormWrapper(layout.FormWrapper):\n    \"\"\"Use this form as the plone.z3cform layout wrapper to get the control\n    panel layout.\n    \"\"\"\n    index = ViewPageTemplateFile('filter_controlpanel.pt')\n\n\nFilterControlPanelView = layout.wrap_form(\n    FilterControlPanel, ControlPanelFormWrapper)\n", "path": "Products/CMFPlone/controlpanel/browser/filter.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone import PloneMessageFactory as _  # NOQA\nfrom Products.CMFPlone.interfaces import IFilterSchema\nfrom Products.Five.browser.pagetemplatefile import ViewPageTemplateFile\nfrom Products.statusmessages.interfaces import IStatusMessage\nfrom plone.autoform.form import AutoExtensibleForm\nfrom plone.z3cform import layout\nfrom z3c.form import button\nfrom z3c.form import form\nfrom Products.PortalTransforms.transforms.safe_html import VALID_TAGS\nfrom Products.PortalTransforms.transforms.safe_html import NASTY_TAGS\n\n\nclass FilterControlPanel(AutoExtensibleForm, form.EditForm):\n    id = \"FilterControlPanel\"\n    label = _(u\"HTML Filtering Settings\")\n    description = \"\"\n    schema = IFilterSchema\n    form_name = _(u\"HTML Filtering Settings\")\n    control_panel_view = \"filter-controlpanel\"\n\n    def updateActions(self):  # NOQA\n        \"\"\"Have to override this because we only have Save, not Cancel\n        \"\"\"\n        super(FilterControlPanel, self).updateActions()\n        self.actions['save'].addClass(\"context\")\n\n    @button.buttonAndHandler(_(u\"Save\"), name='save')\n    def handleSave(self, action):  # NOQA\n        data, errors = self.extractData()\n        if errors:\n            self.status = self.formErrorsMessage\n            return\n\n        # Save in portal tools\n        safe_html = getattr(\n            getToolByName(self.context, 'portal_transforms'),\n            'safe_html',\n            None)\n\n        nasty_tags = data['nasty_tags']\n        custom_tags = data['custom_tags']\n        stripped_tags = data['stripped_tags']\n\n        valid = safe_html._config['valid_tags']\n\n        # start with removing tags that do not belong in valid tags\n        for value in nasty_tags + stripped_tags:\n            if value in valid:\n                del valid[value]\n        # add in custom tags\n        for custom in custom_tags:\n            if value not in valid:\n                valid[custom] = 1\n        # then, check if something was previously prevented but is no longer\n        for tag in set(VALID_TAGS.keys()) - set(valid.keys()):\n            if tag not in nasty_tags and tag not in stripped_tags:\n                valid[tag] = VALID_TAGS[tag]\n\n        # nasty tags are simple, just set the value here\n        nasty_value = {}\n        for tag in nasty_tags:\n            nasty_value[tag] = NASTY_TAGS.get(tag, VALID_TAGS.get(tag, 1))\n        safe_html._config['nasty_tags'] = nasty_value\n\n        disable_filtering = int(data['disable_filtering'])\n        if disable_filtering != safe_html._config['disable_transform']:\n            safe_html._config['disable_transform'] = disable_filtering\n\n        for attr in ('stripped_combinations', 'class_blacklist',\n                     'stripped_attributes', 'style_whitelist'):\n            value = data[attr]\n            if value is None:\n                if attr == 'stripped_combinations':\n                    value = {}\n                else:\n                    value = []\n            if value != safe_html._config[attr]:\n                safe_html._config[attr] = value\n\n        # always reload the transform\n        safe_html._p_changed = True\n        safe_html.reload()\n\n        self.applyChanges(data)\n        IStatusMessage(self.request).addStatusMessage(\n            _(u\"Changes saved.\"),\n            \"info\")\n        IStatusMessage(self.request).addStatusMessage(\n            _(u\"HTML generation is heavily cached across Plone. You may \"\n              u\"have to edit existing content or restart your server to see \"\n              u\"the changes.\"),\n            \"warning\")\n        self.request.response.redirect(self.request.getURL())\n\n\nclass ControlPanelFormWrapper(layout.FormWrapper):\n    \"\"\"Use this form as the plone.z3cform layout wrapper to get the control\n    panel layout.\n    \"\"\"\n    index = ViewPageTemplateFile('filter_controlpanel.pt')\n\n\nFilterControlPanelView = layout.wrap_form(\n    FilterControlPanel, ControlPanelFormWrapper)\n", "path": "Products/CMFPlone/controlpanel/browser/filter.py"}]}