--- 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,