merge
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 29 Jul 2009 10:44:55 +0200
changeset 2560 fee7fb9832d8
parent 2551 91f579b7a1e1 (current diff)
parent 2559 46859078c866 (diff)
child 2561 c6f0634e2d77
child 2562 dd76d0f88796
merge
--- a/utils.py	Wed Jul 29 09:09:11 2009 +0200
+++ b/utils.py	Wed Jul 29 10:44:55 2009 +0200
@@ -255,10 +255,10 @@
         # 1/ variable declaration if any
         if self.jsvars:
             from simplejson import dumps
-            w(u'<script type="text/javascript">\n')
+            w(u'<script type="text/javascript"><!--//--><![CDATA[//><!--\n')
             for var, value in self.jsvars:
                 w(u'%s = %s;\n' % (var, dumps(value)))
-            w(u'</script>\n')
+            w(u'//--><!]]></script>\n')
         # 2/ css files
         for cssfile, media in self.cssfiles:
             w(u'<link rel="stylesheet" type="text/css" media="%s" href="%s"/>\n' %
--- a/web/request.py	Wed Jul 29 09:09:11 2009 +0200
+++ b/web/request.py	Wed Jul 29 10:44:55 2009 +0200
@@ -26,6 +26,7 @@
 from cubicweb.common.mail import header
 from cubicweb.common.uilib import remove_html_tags
 from cubicweb.utils import SizeConstrainedList, HTMLHead
+from cubicweb.view import STRICT_DOCTYPE
 from cubicweb.web import (INTERNAL_FIELD_VALUE, LOGGER, NothingToEdit,
                           RequestError, StatusResponse)
 
@@ -80,7 +81,7 @@
         # to create a relation with another)
         self.search_state = ('normal',)
         # tabindex generator
-        self.tabindexgen = count()
+        self.tabindexgen = count(1)
         self.next_tabindex = self.tabindexgen.next
         # page id, set by htmlheader template
         self.pageid = None
@@ -699,6 +700,14 @@
         return useragent and 'MSIE' in useragent
 
     def xhtml_browser(self):
+        """return True if the browser is considered as xhtml compatible.
+
+        If the instance is configured to always return text/html and not
+        application/xhtml+xml, this method will always return False, even though
+        this is semantically different
+        """
+        if self.vreg.config['force-html-content-type']:
+            return False
         useragent = self.useragent()
         # * MSIE/Konqueror does not support xml content-type
         # * Opera supports xhtml and handles namespaces properly but it breaks
@@ -713,5 +722,11 @@
             return 'application/xhtml+xml'
         return 'text/html'
 
+    def document_surrounding_div(self):
+        if self.xhtml_browser():
+            return (u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE +
+                    u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
+        return u'<div>'
+
 from cubicweb import set_log_methods
 set_log_methods(CubicWebRequestBase, LOGGER)
--- a/web/test/unittest_views_basecontrollers.py	Wed Jul 29 09:09:11 2009 +0200
+++ b/web/test/unittest_views_basecontrollers.py	Wed Jul 29 10:44:55 2009 +0200
@@ -8,16 +8,13 @@
 import simplejson
 
 from logilab.common.testlib import unittest_main, mock_object
-
-from cubicweb import Binary, Unauthorized
-from cubicweb.devtools._apptest import TestEnvironment
 from cubicweb.devtools.apptest import EnvBasedTC, ControllerTC
 
-from cubicweb.common import ValidationError
+from cubicweb import Binary, NoSelectableObject, ValidationError
+from cubicweb.view import STRICT_DOCTYPE
 from cubicweb.common.uilib import rql_for_eid
 
 from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError
-from cubicweb.web.views.basecontrollers import xhtml_wrap
 
 from cubicweb.entities.authobjs import CWUser
 
@@ -515,7 +512,7 @@
     def test_not_usable_by_guets(self):
         self.login('anon')
         req = self.request()
-        self.assertRaises(Unauthorized, self.env.app.select_controller, 'sendmail', req)
+        self.assertRaises(NoSelectableObject, self.env.vreg.select, 'controllers', 'sendmail', req)
 
 
 
@@ -538,8 +535,13 @@
         ctrl = self.ctrl(req)
         rset = self.john.as_rset()
         rset.req = req
-        self.assertTextEquals(ctrl.publish(),
-                              xhtml_wrap(mock_object(req=req), ctrl.view('primary', rset)))
+        source = ctrl.publish()
+        self.failUnless(source.startswith('<?xml version="1.0"?>\n' + STRICT_DOCTYPE +
+                                          u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
+                        )
+        req.xhtml_browser = lambda: False
+        source = ctrl.publish()
+        self.failUnless(source.startswith('<div>'))
 
 #     def test_json_exec(self):
 #         rql = 'Any T,N WHERE T is Tag, T name N'
--- a/web/views/basecontrollers.py	Wed Jul 29 09:09:11 2009 +0200
+++ b/web/views/basecontrollers.py	Wed Jul 29 10:44:55 2009 +0200
@@ -33,16 +33,6 @@
 except ImportError: # gae
     HAS_SEARCH_RESTRICTION = False
 
-
-def xhtml_wrap(self, source):
-    # XXX factor out, watch view.py ~ Maintemplate.doctype
-    if self.req.xhtml_browser():
-        dt = STRICT_DOCTYPE
-    else:
-        dt = STRICT_DOCTYPE_NOEXT
-    head = u'<?xml version="1.0"?>\n' + dt
-    return head + u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">%s</div>' % source.strip()
-
 def jsonize(func):
     """decorator to sets correct content_type and calls `simplejson.dumps` on
     results
@@ -58,7 +48,8 @@
     def wrapper(self, *args, **kwargs):
         self.req.set_content_type(self.req.html_content_type())
         result = func(self, *args, **kwargs)
-        return xhtml_wrap(self, result)
+        return ''.join((self.req.document_surrounding_div(), result.strip(),
+                        u'</div>'))
     wrapper.__name__ = func.__name__
     return wrapper
 
@@ -216,18 +207,21 @@
 class FormValidatorController(Controller):
     id = 'validateform'
 
+    def response(self, domid, status, args):
+        self.req.set_content_type('text/html')
+        jsargs = simplejson.dumps( (status, args) )
+        return """<script type="text/javascript">
+ window.parent.handleFormValidationResponse('%s', null, null, %s);
+</script>""" %  (domid, jsargs)
+
     def publish(self, rset=None):
         self.req.json_request = True
         # XXX unclear why we have a separated controller here vs
         # js_validate_form on the json controller
         status, args = _validate_form(self.req, self.vreg)
-        self.req.set_content_type('text/html')
-        jsarg = simplejson.dumps( (status, args) )
         domid = self.req.form.get('__domid', 'entityForm').encode(
             self.req.encoding)
-        return """<script type="text/javascript">
- window.parent.handleFormValidationResponse('%s', null, null, %s);
-</script>""" %  (domid, simplejson.dumps( (status, args) ))
+        return self.response(domid, status, args)
 
 
 class JSonController(Controller):
--- a/web/views/basetemplates.py	Wed Jul 29 09:09:11 2009 +0200
+++ b/web/views/basetemplates.py	Wed Jul 29 10:44:55 2009 +0200
@@ -15,6 +15,7 @@
 from cubicweb.view import View, MainTemplate, NOINDEX, NOFOLLOW
 from cubicweb.utils import make_uid, UStringIO
 
+
 # main templates ##############################################################
 
 class LogInOutTemplate(MainTemplate):
@@ -83,15 +84,15 @@
     def call(self, view):
         view.set_request_content_type()
         view.set_stream()
-        xhtml_wrap = (self.req.form.has_key('__notemplate') and view.templatable
-                      and view.content_type == self.req.html_content_type())
-        if xhtml_wrap:
-            view.w(u'<?xml version="1.0"?>\n' + self.doctype)
-            view.w(u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
-        # have to replace our unicode stream using view's binary stream
-        view.render()
-        if xhtml_wrap:
+        if (self.req.form.has_key('__notemplate') and view.templatable
+            and view.content_type == self.req.html_content_type()):
+            view.w(self.req.document_surrounding_div())
+            view.render()
             view.w(u'</div>')
+        else:
+            view.render()
+        # have to replace our stream by view's stream (which may be a binary
+        # stream)
         self._stream = view._stream
 
 
--- a/web/webconfig.py	Wed Jul 29 09:09:11 2009 +0200
+++ b/web/webconfig.py	Wed Jul 29 10:44:55 2009 +0200
@@ -145,6 +145,13 @@
           'sessions. Default to 2 min.',
           'group': 'web', 'inputlevel': 2,
           }),
+        ('force-html-content-type',
+         {'type' : 'yn',
+          'default': False,
+          'help': 'force text/html content type for your html pages instead of cubicweb user-agent based'\
+          'deduction of an appropriate content type',
+          'group': 'web', 'inputlevel': 2,
+          }),
         ('embed-allowed',
          {'type' : 'regexp',
           'default': None,