The CDN implementation for resources works by matching well-know attributes (`href`, `src`, `action`) that hold URLs matching the CDN filters and injects the CDN prefix. However 13.0 introduced lazy loading for assets in #32181, so the attributes are now prefixed with `data-` and replaced at runtime. This PR updates the tag matching in order to cover both variants of attribute names. closes odoo/odoo#54156 X-original-commit: 6d4b5fcd11e96fd170d8df1ed27be2a8cea26e8b Signed-off-by: Toufik Benjaa (tbe) <tbe@odoo.com>
83 lines
3.1 KiB
Python
83 lines
3.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
import re
|
|
from collections import OrderedDict
|
|
|
|
from odoo import models
|
|
from odoo.http import request
|
|
from odoo.addons.base.models.assetsbundle import AssetsBundle
|
|
from odoo.addons.http_routing.models.ir_http import url_for
|
|
from odoo.osv import expression
|
|
from odoo.addons.website.models import ir_http
|
|
from odoo.tools import html_escape as escape
|
|
|
|
re_background_image = re.compile(r"(background-image\s*:\s*url\(\s*['\"]?\s*)([^)'\"]+)")
|
|
|
|
|
|
class AssetsBundleMultiWebsite(AssetsBundle):
|
|
def _get_asset_url_values(self, id, unique, extra, name, sep, type):
|
|
website_id = self.env.context.get('website_id')
|
|
website_id_path = website_id and ('%s/' % website_id) or ''
|
|
extra = website_id_path + extra
|
|
res = super(AssetsBundleMultiWebsite, self)._get_asset_url_values(id, unique, extra, name, sep, type)
|
|
return res
|
|
|
|
def _get_assets_domain_for_already_processed_css(self, assets):
|
|
res = super(AssetsBundleMultiWebsite, self)._get_assets_domain_for_already_processed_css(assets)
|
|
current_website = self.env['website'].get_current_website(fallback=False)
|
|
res = expression.AND([res, current_website.website_domain()])
|
|
return res
|
|
|
|
class QWeb(models.AbstractModel):
|
|
""" QWeb object for rendering stuff in the website context """
|
|
|
|
_inherit = 'ir.qweb'
|
|
|
|
URL_ATTRS = {
|
|
'form': 'action',
|
|
'a': 'href',
|
|
'link': 'href',
|
|
'script': 'src',
|
|
'img': 'src',
|
|
}
|
|
|
|
def get_asset_bundle(self, xmlid, files, env=None):
|
|
return AssetsBundleMultiWebsite(xmlid, files, env=env)
|
|
|
|
def _post_processing_att(self, tagName, atts, options):
|
|
if atts.get('data-no-post-process'):
|
|
return atts
|
|
|
|
atts = super(QWeb, self)._post_processing_att(tagName, atts, options)
|
|
|
|
if options.get('inherit_branding') or options.get('rendering_bundle') or \
|
|
options.get('edit_translations') or options.get('debug') or (request and request.session.debug):
|
|
return atts
|
|
|
|
website = ir_http.get_request_website()
|
|
if not website and options.get('website_id'):
|
|
website = self.env['website'].browse(options['website_id'])
|
|
|
|
if not website:
|
|
return atts
|
|
|
|
name = self.URL_ATTRS.get(tagName)
|
|
if request and name and name in atts:
|
|
atts[name] = url_for(atts[name])
|
|
|
|
if not website.cdn_activated:
|
|
return atts
|
|
|
|
data_name = f'data-{name}'
|
|
if name and (name in atts or data_name in atts):
|
|
atts = OrderedDict(atts)
|
|
if name in atts:
|
|
atts[name] = website.get_cdn_url(atts[name])
|
|
if data_name in atts:
|
|
atts[data_name] = website.get_cdn_url(atts[data_name])
|
|
if isinstance(atts.get('style'), str) and 'background-image' in atts['style']:
|
|
atts = OrderedDict(atts)
|
|
atts['style'] = re_background_image.sub(lambda m: '%s%s' % (m.group(1), website.get_cdn_url(m.group(2))), atts['style'])
|
|
|
|
return atts
|