[FIX] qweb: css minified in multiple page for IE
On internet explorer 6, 7, 8 and 9, the limit of CSS rules in a stylesheet is 4095 (http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/10164546.aspx). This commit breaks down a CSS bundle in several pages for these IE versions. To do this, the CSS tag added is of the kind : /web/css.0/{xmlid}/{version} in which there is: - the whole CSS if there is no more than one page, - a list of @import pointing to the multiple pages. note: if a modification lowers the number of page, an old page may stay in ir_attachment (e.g: go from 4 to 3 pages, the old 4th page of another version will not be deleted untill the number goes again up to 4). Note: the method css(self) previously returned an unicode variable (the first time) or an str variable (the following times, if already cached), the fix also correct this so an str variable is always returned. fixes #5050 opw-627116
This commit is contained in:
parent
b1dd5d6045
commit
37959d45f3
|
@ -534,14 +534,15 @@ class Home(http.Controller):
|
|||
@http.route([
|
||||
'/web/css/<xmlid>',
|
||||
'/web/css/<xmlid>/<version>',
|
||||
'/web/css.<int:page>/<xmlid>/<version>',
|
||||
], type='http', auth='public')
|
||||
def css_bundle(self, xmlid, version=None, **kw):
|
||||
def css_bundle(self, xmlid, version=None, page=None, **kw):
|
||||
try:
|
||||
bundle = AssetsBundle(xmlid)
|
||||
except QWebTemplateNotFound:
|
||||
return request.not_found()
|
||||
|
||||
response = request.make_response(bundle.css(), [('Content-Type', 'text/css')])
|
||||
response = request.make_response(bundle.css(page), [('Content-Type', 'text/css')])
|
||||
return make_conditional(response, bundle.last_modified, max_age=BUNDLE_MAXAGE)
|
||||
|
||||
class WebClient(http.Controller):
|
||||
|
|
|
@ -33,6 +33,8 @@ from openerp.tools.translate import _
|
|||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
MAX_CSS_RULES = 4095
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# QWeb template engine
|
||||
#--------------------------------------------------------------------
|
||||
|
@ -1142,7 +1144,12 @@ class AssetsBundle(object):
|
|||
else:
|
||||
url_for = self.context.get('url_for', lambda url: url)
|
||||
if css and self.stylesheets:
|
||||
href = '/web/css/%s/%s' % (self.xmlid, self.version)
|
||||
suffix = ''
|
||||
if request:
|
||||
ua = request.httprequest.user_agent
|
||||
if ua.browser == "msie" and int((ua.version or '0').split('.')[0]) < 10:
|
||||
suffix = '.0'
|
||||
href = '/web/css%s/%s/%s' % (suffix, self.xmlid, self.version)
|
||||
response.append('<link href="%s" rel="stylesheet"/>' % url_for(href))
|
||||
if js:
|
||||
src = '/web/js/%s/%s' % (self.xmlid, self.version)
|
||||
|
@ -1178,7 +1185,10 @@ class AssetsBundle(object):
|
|||
self.set_cache('js', content)
|
||||
return content
|
||||
|
||||
def css(self):
|
||||
def css(self, page_number=None):
|
||||
if page_number is not None:
|
||||
return self.css_page(page_number)
|
||||
|
||||
content = self.get_cache('css')
|
||||
if content is None:
|
||||
self.compile_sass()
|
||||
|
@ -1198,12 +1208,43 @@ class AssetsBundle(object):
|
|||
|
||||
matches.append(content)
|
||||
content = u'\n'.join(matches)
|
||||
if self.css_errors:
|
||||
return content
|
||||
self.set_cache('css', content)
|
||||
if not self.css_errors:
|
||||
self.set_cache('css', content)
|
||||
content = content.encode('utf-8')
|
||||
|
||||
return content
|
||||
|
||||
def css_page(self, page_number):
|
||||
content = self.get_cache('css.%d' % (page_number,))
|
||||
if page_number:
|
||||
return content
|
||||
if content is None:
|
||||
css = self.css()
|
||||
re_rules = '([^{]+\{(?:[^{}]|\{[^{}]*\})*\})'
|
||||
re_selectors = '()(?:\s*@media\s*[^{]*\{)?(?:\s*(?:[^,{]*(?:,|\{(?:[^}]*\}))))'
|
||||
css_url = '@import url(\'/web/css.%%d/%s/%s\');' % (self.xmlid, self.version)
|
||||
pages = [[]]
|
||||
page = pages[0]
|
||||
page_selectors = 0
|
||||
for rule in re.findall(re_rules, css):
|
||||
selectors = len(re.findall(re_selectors, rule))
|
||||
if page_selectors + selectors < MAX_CSS_RULES:
|
||||
page_selectors += selectors
|
||||
page.append(rule)
|
||||
else:
|
||||
pages.append([rule])
|
||||
page = pages[-1]
|
||||
page_selectors = selectors
|
||||
if len(pages) == 1:
|
||||
pages = []
|
||||
for idx, page in enumerate(pages):
|
||||
self.set_cache("css.%d" % (idx+1), ''.join(page))
|
||||
content = '\n'.join(css_url % i for i in range(1,len(pages)+1))
|
||||
self.set_cache("css.0", content)
|
||||
if not content:
|
||||
return self.css()
|
||||
return content
|
||||
|
||||
def get_cache(self, type):
|
||||
content = None
|
||||
domain = [('url', '=', '/web/%s/%s/%s' % (type, self.xmlid, self.version))]
|
||||
|
|
Loading…
Reference in New Issue