prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <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.
  
  
  </issue>
  <code>
  [start of Products/CMFPlone/controlpanel/browser/filter.py]
  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 of Products/CMFPlone/controlpanel/browser/filter.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: 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())
  
verification_info: {"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"}]}