# HG changeset patch # User Sylvain Thénault # Date 1248857095 -7200 # Node ID fee7fb9832d8a0bf0a9578c9a1218f602b7f82f6 # Parent 91f579b7a1e1bcdd43a9c4280a32b037f6695a86# Parent 46859078c8669d4d4f8887d009c0e961072292f8 merge diff -r 91f579b7a1e1 -r fee7fb9832d8 utils.py --- 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'\n') + w(u'//-->\n') # 2/ css files for cssfile, media in self.cssfiles: w(u'\n' % diff -r 91f579b7a1e1 -r fee7fb9832d8 view.py diff -r 91f579b7a1e1 -r fee7fb9832d8 web/request.py --- 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'\n' + STRICT_DOCTYPE + + u'
') + return u'
' + from cubicweb import set_log_methods set_log_methods(CubicWebRequestBase, LOGGER) diff -r 91f579b7a1e1 -r fee7fb9832d8 web/test/unittest_views_basecontrollers.py --- 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('\n' + STRICT_DOCTYPE + + u'
') + ) + req.xhtml_browser = lambda: False + source = ctrl.publish() + self.failUnless(source.startswith('
')) # def test_json_exec(self): # rql = 'Any T,N WHERE T is Tag, T name N' diff -r 91f579b7a1e1 -r fee7fb9832d8 web/views/basecontrollers.py --- 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'\n' + dt - return head + u'
%s
' % 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'
')) 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 """""" % (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 """""" % (domid, simplejson.dumps( (status, args) )) + return self.response(domid, status, args) class JSonController(Controller): diff -r 91f579b7a1e1 -r fee7fb9832d8 web/views/basetemplates.py --- 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'\n' + self.doctype) - view.w(u'
') - # 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'
') + else: + view.render() + # have to replace our stream by view's stream (which may be a binary + # stream) self._stream = view._stream diff -r 91f579b7a1e1 -r fee7fb9832d8 web/webconfig.py --- 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,