prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  add data-base-url attribute to HTML body tag in Plone 4
  Since plone 4.3.12, the `<base href` attribute in HTML generated by Plone no longer always points to the context URL as it used to prior to the change. This change broke Plone and some add-ons. More breakage may still surface. Fixes have varied because no alternative was provided when the change was made.
  
  For a lengthy background, see the [discussion](https://community.plone.org/t/how-to-get-context-url-in-js-on-plone-4-3-12/4031). 
  
  Rather than rolling back the change which was done to support some other things and would require reverting them, I suggest providing a future-proof alternative (thanks @rodfersou for suggesting using a new attribute):
  
  Plone 5 has removed `<base href` completely. Instead Plone 5 has added a `data-base-url` attribute to the HTML `body` tag. Which points to the context URL.
  
  So, I suggest same be done for Plone 4. That way, anything in Plone core and/or add-ons needing context URL in Javascript have a future-proof way of getting it from here on.
  
  
  @@sharing is broken on Page objects in Plone 4.3.12 and 4.3.14
  ## BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)
  
  ### What I did:
  
  1. Create vanilla Plone 4.3.14 site.
  2. Add private Page with title Test at the top of the site
  3. Navigate to sharing tab for that page
  4. Type some characters into the Search box
  5. Kaboom: exception
  
  ### What I expect to happen:
  
  List of potential users as search results
  
  ### What actually happened:
  
  Large python back trace because the search form AJAX accessed:
  
    http://localhost:8080/Plone2/test/@@sharing/@@updateSharingInfo
  
  rather than the following used by Plone 4.3.11:
  
    http://localhost:8080/Plone2/test/@@updateSharingInfo
   
  The root cause appears to be:
  
  https://pypi.python.org/pypi/plone.app.layout/2.3.17
  
    2.3.15 (2016-06-28)
     Fixes:
     _Fix base tag differs from actual URL (fixes [86](https://github.com/plone/plone.app.layout/issues/86)). [rodfersou]_
  
  which was actually made **after** plone.app.layout 2.3.15 was released, (December 2016): that comment is placed incorrectly in the README file. I'm happy to make a bug report there as well.
  
  ### What version of Plone/ Addons I am using:
  
  Vanilla Plone 4.3.14, which uses  plone.app.layout 2.3.17. So does Plone 4.3.12, and I see exactly the same problem there.
  
  (NB: Pinning plone.app.layout 2.3.15 in Plone 4.3.14 resolves the problem).
  
  Update: appears to be the same issue discussed in: https://github.com/plone/Products.CMFPlone/issues/2051
  
  
  </issue>
  <code>
  [start of Products/CMFPlone/browser/jsvariables.py]
  1 from zope.i18n import translate
  2 from zope.publisher.browser import BrowserView
  3 
  4 from Products.CMFCore.utils import getToolByName
  5 from Products.CMFPlone import PloneMessageFactory as _
  6 
  7 
  8 TEMPLATE = """\
  9 var portal_url = '%(portal_url)s';
  10 var form_modified_message = '%(form_modified)s';
  11 var form_resubmit_message = '%(form_resubmit)s';
  12 var external_links_open_new_window = '%(open_links)s';
  13 var mark_special_links = '%(mark_links)s';
  14 var ajax_noresponse_message = '%(ajax_noresponse)s';
  15 """
  16 
  17 FORM_MODIFIED = _(u'text_form_modified_message',
  18                   default=u'Your form has not been saved. All changes you '
  19                           u'have made will be lost.')
  20 
  21 FORM_RESUBMIT = _(u'text_form_resubmit_message',
  22                   default=u'You already clicked the submit button. Do you '
  23                           u'really want to submit this form again?')
  24 
  25 AJAX_NORESPONSE = _(u'text_ajax_noresponse_message',
  26                     default=u'No response from server. Please try again '
  27                             u'later.')
  28 
  29 
  30 class JSVariables(BrowserView):
  31 
  32     def __call__(self, *args, **kwargs):
  33         context = self.context
  34         response = self.request.response
  35         response.setHeader('content-type', 'text/javascript;;charset=utf-8')
  36 
  37         props = getToolByName(context, 'portal_properties').site_properties
  38         portal_url = getToolByName(context, 'portal_url')()
  39 
  40         # the following are flags for mark_special_links.js
  41         # links get the target="_blank" attribute
  42         open_links = props.getProperty('external_links_open_new_window',
  43                                        'false')
  44         mark_links = props.getProperty('mark_special_links', 'false')
  45 
  46         form_modified = translate(FORM_MODIFIED, context=self.request)
  47         form_resubmit = translate(FORM_RESUBMIT, context=self.request)
  48         ajax_noresponse = translate(AJAX_NORESPONSE, context=self.request)
  49 
  50         # escape_for_js
  51         form_modified = form_modified.replace("'", "\\'")
  52         form_resubmit = form_resubmit.replace("'", "\\'")
  53         ajax_noresponse = ajax_noresponse.replace("'", "\\'")
  54 
  55         return TEMPLATE % dict(
  56             portal_url=portal_url,
  57             open_links=open_links,
  58             mark_links=mark_links,
  59             form_modified=form_modified,
  60             form_resubmit=form_resubmit,
  61             ajax_noresponse=ajax_noresponse,
  62         )
  63
  [end of Products/CMFPlone/browser/jsvariables.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/browser/jsvariables.py b/Products/CMFPlone/browser/jsvariables.py
  --- a/Products/CMFPlone/browser/jsvariables.py
  +++ b/Products/CMFPlone/browser/jsvariables.py
  @@ -7,6 +7,7 @@
   
   TEMPLATE = """\
   var portal_url = '%(portal_url)s';
  +var base_url = '%(base_url)s';
   var form_modified_message = '%(form_modified)s';
   var form_resubmit_message = '%(form_resubmit)s';
   var external_links_open_new_window = '%(open_links)s';
  @@ -36,6 +37,7 @@
   
           props = getToolByName(context, 'portal_properties').site_properties
           portal_url = getToolByName(context, 'portal_url')()
  +        base_url = self.request['HTTP_REFERER']
   
           # the following are flags for mark_special_links.js
           # links get the target="_blank" attribute
  @@ -54,6 +56,7 @@
   
           return TEMPLATE % dict(
               portal_url=portal_url,
  +            base_url=base_url,
               open_links=open_links,
               mark_links=mark_links,
               form_modified=form_modified,
  
verification_info: {"golden_diff": "diff --git a/Products/CMFPlone/browser/jsvariables.py b/Products/CMFPlone/browser/jsvariables.py\n--- a/Products/CMFPlone/browser/jsvariables.py\n+++ b/Products/CMFPlone/browser/jsvariables.py\n@@ -7,6 +7,7 @@\n \n TEMPLATE = \"\"\"\\\n var portal_url = '%(portal_url)s';\n+var base_url = '%(base_url)s';\n var form_modified_message = '%(form_modified)s';\n var form_resubmit_message = '%(form_resubmit)s';\n var external_links_open_new_window = '%(open_links)s';\n@@ -36,6 +37,7 @@\n \n         props = getToolByName(context, 'portal_properties').site_properties\n         portal_url = getToolByName(context, 'portal_url')()\n+        base_url = self.request['HTTP_REFERER']\n \n         # the following are flags for mark_special_links.js\n         # links get the target=\"_blank\" attribute\n@@ -54,6 +56,7 @@\n \n         return TEMPLATE % dict(\n             portal_url=portal_url,\n+            base_url=base_url,\n             open_links=open_links,\n             mark_links=mark_links,\n             form_modified=form_modified,\n", "issue": "add data-base-url attribute to HTML body tag in Plone 4\nSince plone 4.3.12, the `<base href` attribute in HTML generated by Plone no longer always points to the context URL as it used to prior to the change. This change broke Plone and some add-ons. More breakage may still surface. Fixes have varied because no alternative was provided when the change was made.\r\n\r\nFor a lengthy background, see the [discussion](https://community.plone.org/t/how-to-get-context-url-in-js-on-plone-4-3-12/4031). \r\n\r\nRather than rolling back the change which was done to support some other things and would require reverting them, I suggest providing a future-proof alternative (thanks @rodfersou for suggesting using a new attribute):\r\n\r\nPlone 5 has removed `<base href` completely. Instead Plone 5 has added a `data-base-url` attribute to the HTML `body` tag. Which points to the context URL.\r\n\r\nSo, I suggest same be done for Plone 4. That way, anything in Plone core and/or add-ons needing context URL in Javascript have a future-proof way of getting it from here on.\r\n\r\n\n@@sharing is broken on Page objects in Plone 4.3.12 and 4.3.14\n## BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)\r\n\r\n### What I did:\r\n\r\n1. Create vanilla Plone 4.3.14 site.\r\n2. Add private Page with title Test at the top of the site\r\n3. Navigate to sharing tab for that page\r\n4. Type some characters into the Search box\r\n5. Kaboom: exception\r\n\r\n### What I expect to happen:\r\n\r\nList of potential users as search results\r\n\r\n### What actually happened:\r\n\r\nLarge python back trace because the search form AJAX accessed:\r\n\r\n  http://localhost:8080/Plone2/test/@@sharing/@@updateSharingInfo\r\n\r\nrather than the following used by Plone 4.3.11:\r\n\r\n  http://localhost:8080/Plone2/test/@@updateSharingInfo\r\n \r\nThe root cause appears to be:\r\n\r\nhttps://pypi.python.org/pypi/plone.app.layout/2.3.17\r\n\r\n  2.3.15 (2016-06-28)\r\n   Fixes:\r\n   _Fix base tag differs from actual URL (fixes [86](https://github.com/plone/plone.app.layout/issues/86)). [rodfersou]_\r\n\r\nwhich was actually made **after** plone.app.layout 2.3.15 was released, (December 2016): that comment is placed incorrectly in the README file. I'm happy to make a bug report there as well.\r\n\r\n### What version of Plone/ Addons I am using:\r\n\r\nVanilla Plone 4.3.14, which uses  plone.app.layout 2.3.17. So does Plone 4.3.12, and I see exactly the same problem there.\r\n\r\n(NB: Pinning plone.app.layout 2.3.15 in Plone 4.3.14 resolves the problem).\r\n\r\nUpdate: appears to be the same issue discussed in: https://github.com/plone/Products.CMFPlone/issues/2051\r\n\n", "before_files": [{"content": "from zope.i18n import translate\nfrom zope.publisher.browser import BrowserView\n\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFPlone import PloneMessageFactory as _\n\n\nTEMPLATE = \"\"\"\\\nvar portal_url = '%(portal_url)s';\nvar form_modified_message = '%(form_modified)s';\nvar form_resubmit_message = '%(form_resubmit)s';\nvar external_links_open_new_window = '%(open_links)s';\nvar mark_special_links = '%(mark_links)s';\nvar ajax_noresponse_message = '%(ajax_noresponse)s';\n\"\"\"\n\nFORM_MODIFIED = _(u'text_form_modified_message',\n                  default=u'Your form has not been saved. All changes you '\n                          u'have made will be lost.')\n\nFORM_RESUBMIT = _(u'text_form_resubmit_message',\n                  default=u'You already clicked the submit button. Do you '\n                          u'really want to submit this form again?')\n\nAJAX_NORESPONSE = _(u'text_ajax_noresponse_message',\n                    default=u'No response from server. Please try again '\n                            u'later.')\n\n\nclass JSVariables(BrowserView):\n\n    def __call__(self, *args, **kwargs):\n        context = self.context\n        response = self.request.response\n        response.setHeader('content-type', 'text/javascript;;charset=utf-8')\n\n        props = getToolByName(context, 'portal_properties').site_properties\n        portal_url = getToolByName(context, 'portal_url')()\n\n        # the following are flags for mark_special_links.js\n        # links get the target=\"_blank\" attribute\n        open_links = props.getProperty('external_links_open_new_window',\n                                       'false')\n        mark_links = props.getProperty('mark_special_links', 'false')\n\n        form_modified = translate(FORM_MODIFIED, context=self.request)\n        form_resubmit = translate(FORM_RESUBMIT, context=self.request)\n        ajax_noresponse = translate(AJAX_NORESPONSE, context=self.request)\n\n        # escape_for_js\n        form_modified = form_modified.replace(\"'\", \"\\\\'\")\n        form_resubmit = form_resubmit.replace(\"'\", \"\\\\'\")\n        ajax_noresponse = ajax_noresponse.replace(\"'\", \"\\\\'\")\n\n        return TEMPLATE % dict(\n            portal_url=portal_url,\n            open_links=open_links,\n            mark_links=mark_links,\n            form_modified=form_modified,\n            form_resubmit=form_resubmit,\n            ajax_noresponse=ajax_noresponse,\n        )\n", "path": "Products/CMFPlone/browser/jsvariables.py"}]}