[IMP] base: add "defer" and "lazy" load options to assets

Thanks to this commit, when using the `t-call-assets` command, we can
use the "defer_load" attribute or the "lazy_load" attribute which will
respectively add the "defer" HTML attribute on the script tags and
replace the "src" attribute of the script tags with a "data-src" one.

In the lazy case, it is up to a custom page script to replace the
"data-src" attribute with the "src" attribute at the appropriate time.
This will be done in a future commit of this PR.

Part of https://github.com/odoo/odoo/pull/32181
task-1961045
This commit is contained in:
qsm-odoo
2019-06-04 07:57:20 +00:00
parent 8132884840
commit 91d68e296a
2 changed files with 13 additions and 10 deletions
+5 -4
View File
@@ -111,8 +111,8 @@ class AssetsBundle(object):
self.javascripts.append(JavascriptAsset(self, url=f['url'], filename=f['filename'], inline=f['content']))
# depreciated and will remove after v11
def to_html(self, sep=None, css=True, js=True, debug=False, async_load=False, url_for=(lambda url: url)):
nodes = self.to_node(css=css, js=js, debug=debug, async_load=async_load)
def to_html(self, sep=None, css=True, js=True, debug=False, async_load=False, defer_load=False, lazy_load=False, url_for=(lambda url: url)):
nodes = self.to_node(css=css, js=js, debug=debug, async_load=async_load, defer_load=defer_load, lazy_load=lazy_load)
if sep is None:
sep = u'\n '
@@ -130,7 +130,7 @@ class AssetsBundle(object):
return sep + sep.join(response)
def to_node(self, css=True, js=True, debug=False, async_load=False):
def to_node(self, css=True, js=True, debug=False, async_load=False, defer_load=False, lazy_load=False):
"""
:returns [(tagName, attributes, content)] if the tag is auto close
"""
@@ -167,8 +167,9 @@ class AssetsBundle(object):
if js and self.javascripts:
attr = OrderedDict([
["async", "async" if async_load else None],
["defer", "defer" if defer_load or lazy_load else None],
["type", "text/javascript"],
["src", self.js().url],
["data-src" if lazy_load else "src", self.js().url],
])
response.append(("script", attr, None))
+8 -6
View File
@@ -215,6 +215,8 @@ class IrQWeb(models.AbstractModel, QWeb):
keywords=[], starargs=None, kwargs=None
)),
ast.keyword('async_load', self._get_attr_bool(el.get('async_load', False))),
ast.keyword('defer_load', self._get_attr_bool(el.get('defer_load', False))),
ast.keyword('lazy_load', self._get_attr_bool(el.get('lazy_load', False))),
ast.keyword('values', ast.Name(id='values', ctx=ast.Load())),
],
starargs=None, kwargs=None
@@ -286,24 +288,24 @@ class IrQWeb(models.AbstractModel, QWeb):
# compatibility to remove after v11 - DEPRECATED
@tools.conditional(
'xml' not in tools.config['dev_mode'],
tools.ormcache_context('xmlid', 'options.get("lang", "en_US")', 'css', 'js', 'debug', 'async_load', keys=("website_id",)),
tools.ormcache_context('xmlid', 'options.get("lang", "en_US")', 'css', 'js', 'debug', 'async_load', 'defer_load', 'lazy_load', keys=("website_id",)),
)
def _get_asset(self, xmlid, options, css=True, js=True, debug=False, async_load=False, values=None):
def _get_asset(self, xmlid, options, css=True, js=True, debug=False, async_load=False, defer_load=False, lazy_load=False, values=None):
files, remains = self._get_asset_content(xmlid, options)
asset = self.get_asset_bundle(xmlid, files, remains, env=self.env)
return asset.to_html(css=css, js=js, debug=debug, async_load=async_load, url_for=(values or {}).get('url_for', lambda url: url))
return asset.to_html(css=css, js=js, debug=debug, async_load=async_load, defer_load=defer_load, lazy_load=lazy_load, url_for=(values or {}).get('url_for', lambda url: url))
@tools.conditional(
# in non-xml-debug mode we want assets to be cached forever, and the admin can force a cache clear
# by restarting the server after updating the source code (or using the "Clear server cache" in debug tools)
'xml' not in tools.config['dev_mode'],
tools.ormcache_context('xmlid', 'options.get("lang", "en_US")', 'css', 'js', 'debug', 'async_load', keys=("website_id",)),
tools.ormcache_context('xmlid', 'options.get("lang", "en_US")', 'css', 'js', 'debug', 'async_load', 'defer_load', 'lazy_load', keys=("website_id",)),
)
def _get_asset_nodes(self, xmlid, options, css=True, js=True, debug=False, async_load=False, values=None):
def _get_asset_nodes(self, xmlid, options, css=True, js=True, debug=False, async_load=False, defer_load=False, lazy_load=False, values=None):
files, remains = self._get_asset_content(xmlid, options)
asset = self.get_asset_bundle(xmlid, files, env=self.env)
remains = [node for node in remains if (css and node[0] == 'link') or (js and node[0] != 'link')]
return remains + asset.to_node(css=css, js=js, debug=debug, async_load=async_load)
return remains + asset.to_node(css=css, js=js, debug=debug, async_load=async_load, defer_load=defer_load, lazy_load=lazy_load)
@tools.ormcache_context('xmlid', 'options.get("lang", "en_US")', keys=("website_id",))
def _get_asset_content(self, xmlid, options):