[IMP] web: lazy load nvd3, ace and fullCalendar lib to reduce asset size

This commit is contained in:
Christophe Matthieu
2017-08-31 16:26:11 +02:00
parent 6f60a9a179
commit 95c2bd33a2
19 changed files with 168 additions and 118 deletions
+7 -6
View File
@@ -6,10 +6,8 @@
if (!i.require || !i.require.packaged) r.original = i.require, i.require = r, i.require.packaged = !0
}
var ACE_NAMESPACE = "",
e = function() {
return this
}();
!e && typeof window != "undefined" && (e = window);
e = {};
window.ace = e;
if (!ACE_NAMESPACE && typeof requirejs != "undefined") return;
var t = function(e, n, r) {
if (typeof e != "string") {
@@ -76,7 +74,9 @@
return s
};
o(ACE_NAMESPACE)
})(), define("ace/lib/regexp", ["require", "exports", "module"], function(e, t, n) {
})();
(function() {var define = ace.define, require = ace.require;
define("ace/lib/regexp", ["require", "exports", "module"], function(e, t, n) {
"use strict";
function o(e) {
@@ -9826,7 +9826,7 @@
}, t.EditSession = o, t.UndoManager = u
});
(function() {
window.require(["ace/ace"], function(a) {
require(["ace/ace"], function(a) {
a && a.config.init(true);
if (!window.ace)
window.ace = a;
@@ -9835,3 +9835,4 @@
window.ace[key] = a[key];
});
})();
})();
+2
View File
@@ -1,3 +1,4 @@
(function() {var define = ace.define, require = ace.require;
define("ace/mode/less", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text", "ace/tokenizer", "ace/mode/less_highlight_rules", "ace/mode/matching_brace_outdent", "ace/mode/folding/cstyle"], function(e, t) {
var r = e("../lib/oop"),
o = e("./text").Mode,
@@ -204,3 +205,4 @@ define("ace/mode/less", ["require", "exports", "module", "ace/lib/oop", "ace/mod
}
}).call(o.prototype)
});
})();
+3 -1
View File
@@ -1,3 +1,4 @@
(function() {var define = ace.define, require = ace.require;
define("ace/mode/python_highlight_rules", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text_highlight_rules"], function(e, t, n) {
"use strict";
var r = e("../lib/oop"),
@@ -182,4 +183,5 @@ define("ace/mode/python_highlight_rules", ["require", "exports", "module", "ace/
r.slice(-i.length) == i && t.remove(new u(n, r.length - i.length, n, r.length))
}, this.$id = "ace/mode/python"
}.call(a.prototype), t.Mode = a
});
});
})();
+3 -1
View File
@@ -1,3 +1,4 @@
(function() {var define = ace.define, require = ace.require;
define("ace/mode/xml_highlight_rules", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text_highlight_rules"], function(e, t, n) {
"use strict";
var r = e("../lib/oop"),
@@ -499,4 +500,5 @@ define("ace/mode/xml_highlight_rules", ["require", "exports", "module", "ace/lib
}), t
}, this.$id = "ace/mode/xml"
}.call(l.prototype), t.Mode = l
});
});
})();
+1 -1
View File
@@ -1,4 +1,4 @@
define("ace/theme/monokai",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
exports.isDark = true;
exports.cssClass = "ace-monokai";
+2 -2
View File
@@ -2,8 +2,8 @@
;(function(window) {
if (typeof window.window != "undefined" && window.document)
return;
if (window.require && window.define)
return;
var define = ace.define, require = ace.require;
if (!window.console) {
window.console = function() {
+38 -1
View File
@@ -433,15 +433,52 @@ var loadXML = (function () {
};
})();
return {
/**
* Loads the given js and css libraries. Note that the ajax loadJS and loadCSS methods
* don't do anything if the given file is already loaded.
*
* @param {Object} libs
* @Param {Array | Array<Array>} [libs.jsLibs=[]] The list of JS files that we want to
* load. The list may contain strings (the files to load), or lists of strings. The
* first level is loaded sequentially, and files listed in inner lists are loaded in
* parallel.
* @param {Array<string>} [libs.cssLibs=[]] A list of css files, to be loaded in
* parallel
*
* @returns {Deferred}
*/
function loadLibs (libs) {
var defs = [];
_.each(libs.jsLibs || [], function (urls) {
defs.push($.when.apply($, defs).then(function () {
if (typeof(urls) === 'string') {
return ajax.loadJS(urls);
} else {
return $.when.apply($, _.map(urls, function (url) {
return ajax.loadJS(url);
}));
}
}));
});
_.each(libs.cssLibs || [], function (url) {
defs.push(ajax.loadCSS(url));
});
return $.when.apply($, defs);
}
var ajax = {
jsonRpc: jsonRpc,
jsonpRpc: jsonpRpc,
rpc: rpc,
loadCSS: loadCSS,
loadJS: loadJS,
loadXML: loadXML,
loadLibs: loadLibs,
get_file: get_file,
post: post,
};
return ajax;
});
@@ -30,10 +30,13 @@ odoo.define('web.AbstractField', function (require) {
* @module web.AbstractField
*/
var ajax = require('web.ajax');
var field_utils = require('web.field_utils');
var Widget = require('web.Widget');
var AbstractField = Widget.extend({
cssLibs: [],
jsLibs: [],
events: {
'keydown': '_onKeydown',
},
@@ -173,6 +176,14 @@ var AbstractField = Widget.extend({
return self._render();
});
},
/**
* Loads the libraries listed in this.jsLibs and this.cssLibs
*
* @override
*/
willStart: function () {
return $.when(ajax.loadLibs(this), this._super.apply(this, arguments));
},
//--------------------------------------------------------------------------
// Public
+15 -20
View File
@@ -8,7 +8,6 @@ odoo.define('web.basic_fields', function (require) {
*/
var AbstractField = require('web.AbstractField');
var ajax = require('web.ajax');
var config = require('web.config');
var core = require('web.core');
var crash_manager = require('web.crash_manager');
@@ -1949,6 +1948,14 @@ var FieldToggleBoolean = AbstractField.extend({
var JournalDashboardGraph = AbstractField.extend({
className: "o_dashboard_graph",
cssLibs: [
'/web/static/lib/nvd3/nv.d3.css'
],
jsLibs: [
'/web/static/lib/nvd3/d3.v3.js',
'/web/static/lib/nvd3/nv.d3.js',
'/web/static/src/js/libs/nvd3.js'
],
init: function () {
this._super.apply(this, arguments);
this.graph_type = this.attrs.graph_type;
@@ -2069,7 +2076,6 @@ var JournalDashboardGraph = AbstractField.extend({
this._customizeChart();
}
},
});
/**
@@ -2282,25 +2288,14 @@ var FieldDomain = AbstractField.extend({
*/
var AceEditor = DebouncedField.extend({
template: "AceEditor",
jsLibs: [
'/web/static/lib/ace/ace.odoo-custom.js',
[
'/web/static/lib/ace/mode-python.js',
'/web/static/lib/ace/mode-xml.js'
]
],
events: {}, // events are triggered manually for this debounced widget
/**
* @override willStart from AbstractField (Widget)
* Loads the ace library if not already loaded.
*
* @returns {Deferred}
*/
willStart: function () {
var loadJSDef;
if (!window.ace) {
loadJSDef = ajax.loadJS('/web/static/lib/ace/ace.odoo-custom.js').then(function () {
return $.when(
ajax.loadJS('/web/static/lib/ace/mode-python.js'),
ajax.loadJS('/web/static/lib/ace/mode-xml.js')
);
});
}
return $.when(this._super.apply(this, arguments), loadJSDef);
},
/**
* @override start from AbstractField (Widget)
*
-4
View File
@@ -6,10 +6,6 @@ odoo.define('web.nvd3.extensions', function () {
* in place.
*/
if (!('nv' in window)) {
return;
}
nv.dev = false; // sets nvd3 library in production mode
// monkey patch nvd3 to allow removing eventhandler on windowresize events
+11 -40
View File
@@ -23,13 +23,12 @@ odoo.define('web.AbstractView', function (require) {
* in most case discarded.
*/
var ajax = require('web.ajax');
var Class = require('web.Class');
var Context = require('web.Context');
var ajax = require('web.ajax');
var AbstractModel = require('web.AbstractModel');
var AbstractRenderer = require('web.AbstractRenderer');
var AbstractController = require('web.AbstractController');
var Context = require('web.Context');
var AbstractView = Class.extend({
// name displayed in view switchers
@@ -51,8 +50,6 @@ var AbstractView = Class.extend({
Model: AbstractModel,
Renderer: AbstractRenderer,
Controller: AbstractController,
js_libs: [],
css_libs: [],
},
/**
@@ -125,7 +122,15 @@ var AbstractView = Class.extend({
//--------------------------------------------------------------------------
/**
* Main method of the view class.
* Main method of the view class. Create a controller, and make sure that
* data and libraries are loaded.
*
* There is a unusual thing going in this method with parents: we create
* renderer/model with parent as parent, then we have to reassign them at
* the end to make sure that we have the proper relationships. This is
* necessary to solve the problem that the controller need the model and the
* renderer to be instantiated, but the model need a parent to be able to
* load itself, and the renderer needs the data in its constructor.
*
* @param {Widget} parent The parent of the resulting Controller (most
* likely a view manager)
@@ -133,7 +138,7 @@ var AbstractView = Class.extend({
*/
getController: function (parent) {
var self = this;
return $.when(this._loadData(parent), this._loadLibs()).then(function () {
return $.when(this._loadData(parent), ajax.loadLibs(this)).then(function () {
var model = self.getModel();
var state = model.get(arguments[0]);
var renderer = self.getRenderer(parent, state);
@@ -202,40 +207,6 @@ var AbstractView = Class.extend({
var model = this.getModel(parent);
return model.load(this.loadParams);
},
/**
* Makes sure that the js_libs and css_libs are properly loaded. Note that
* the ajax loadJS and loadCSS methods don't do anything if the given file
* is already loaded.
*
* @private
* @returns {Deferred}
*/
_loadLibs: function () {
var defs = [];
var jsDefs;
_.each(this.config.js_libs, function (urls) {
if (typeof(urls) === 'string') {
// js_libs is an array of urls: those urls can be loaded in
// parallel
defs.push(ajax.loadJS(urls));
} else {
// js_libs is an array of arrays of urls: those arrays of urls
// must be loaded sequentially, but the urls inside each
// sub-array can be loaded in parallel
defs.push($.when.apply($, jsDefs).then(function () {
jsDefs = [];
_.each(urls, function (url) {
jsDefs.push(ajax.loadJS(url));
});
return $.when.apply($, jsDefs);
}));
}
});
_.each(this.config.css_libs, function (url) {
defs.push(ajax.loadCSS(url));
});
return $.when.apply($, defs);
},
/**
* Loads the subviews for x2many fields when they are not inline
*
@@ -21,6 +21,8 @@ var fieldsToGather = [
var CalendarView = AbstractView.extend({
display_name: _lt('Calendar'),
icon: 'fa-calendar',
jsLibs: ['/web/static/lib/fullcalendar/js/fullcalendar.js'],
cssLibs: ['/web/static/lib/fullcalendar/css/fullcalendar.css'],
config: {
Model: CalendarModel,
Controller: CalendarController,
@@ -19,6 +19,14 @@ var _lt = core._lt;
var GraphView = AbstractView.extend({
display_name: _lt('Graph'),
icon: 'fa-bar-chart',
cssLibs: [
'/web/static/lib/nvd3/nv.d3.css'
],
jsLibs: [
'/web/static/lib/nvd3/d3.v3.js',
'/web/static/lib/nvd3/nv.d3.js',
'/web/static/src/js/libs/nvd3.js'
],
config: {
Model: GraphModel,
Controller: Controller,
@@ -32,10 +32,9 @@ QUnit.module('Views', {
assert.step(url + ' loaded');
});
};
var View = AbstractView.extend({
config: _.extend({}, AbstractView.prototype.config, {
js_libs: ['a', 'b'],
}),
jsLibs: [['a', 'b']],
});
createAsyncView({
View: View,
@@ -71,13 +70,12 @@ QUnit.module('Views', {
assert.step(url + ' loaded');
});
};
var View = AbstractView.extend({
config: _.extend({}, AbstractView.prototype.config, {
js_libs: [
['a', 'b'],
['c'],
],
}),
jsLibs: [
['a', 'b'],
'c',
],
});
createAsyncView({
View: View,
@@ -85,7 +83,7 @@ QUnit.module('Views', {
data: this.data,
model: 'fake_model',
}).then(function (view) {
assert.verifySteps(['a', 'b', 'a loaded', 'b loaded', 'c', 'c loaded'],
assert.verifySteps(['a', 'b', 'b loaded', 'a loaded', 'c', 'c loaded'],
"should for all libs to be loaded");
ajax.loadJS = loadJS;
view.destroy();
@@ -94,11 +92,11 @@ QUnit.module('Views', {
assert.verifySteps(['a', 'b'],
"libs 'a' and 'b' should be loaded in parallel");
defs.a.resolve();
assert.verifySteps(['a', 'b', 'a loaded'],
"should wait for 'a' and 'b' to be loaded before loading 'c'");
defs.b.resolve();
assert.verifySteps(['a', 'b', 'a loaded', 'b loaded', 'c'],
assert.verifySteps(['a', 'b', 'b loaded'],
"should wait for 'a' and 'b' to be loaded before loading 'c'");
defs.a.resolve();
assert.verifySteps(['a', 'b', 'b loaded', 'a loaded', 'c'],
"should load 'c' when 'a' and 'b' are loaded");
defs.c.resolve();
});
+12 -7
View File
@@ -95,7 +95,6 @@
<link rel="stylesheet" type="text/less" href="/web/static/src/less/import_bootstrap.less"/>
<link rel="stylesheet" type="text/css" href="/web/static/lib/nvd3/nv.d3.css"/>
<link rel="stylesheet" type="text/css" href="/base/static/src/css/modules.css"/>
<link rel="stylesheet" type="text/less" href="/web/static/src/less/bootstrap_overridden.less"/>
@@ -129,8 +128,6 @@
<link rel="stylesheet" type="text/less" href="/web/static/src/less/data_export.less"/>
<script type="text/javascript" src="/web/static/lib/jquery.scrollTo/jquery.scrollTo.js"></script>
<script type="text/javascript" src="/web/static/lib/nvd3/d3.v3.js"></script>
<script type="text/javascript" src="/web/static/lib/nvd3/nv.d3.js"></script>
<script type="text/javascript" src="/web/static/lib/backbone/backbone.js"></script>
<script type="text/javascript" src="/web/static/lib/fuzzy-master/fuzzy.js"></script>
@@ -142,7 +139,6 @@
<!-- Special case: core.js declares $.browser needed by ba-bbq -->
<script type="text/javascript" src="/web/static/lib/jquery.ba-bbq/jquery.ba-bbq.js"></script>
<script type="text/javascript" src="/web/static/src/js/libs/nvd3.js"></script>
<script type="text/javascript" src="/web/static/src/js/core/domain.js"></script>
<script type="text/javascript" src="/web/static/src/js/core/pyeval.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome/action_manager.js"></script>
@@ -222,9 +218,6 @@
<script type="text/javascript" src="/web/static/src/js/views/pivot/pivot_renderer.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/pivot/pivot_view.js"></script>
<script type="text/javascript" src="/web/static/lib/fullcalendar/js/fullcalendar.js"></script>
<link rel="stylesheet" href="/web/static/lib/fullcalendar/css/fullcalendar.css"/>
<script type="text/javascript" src="/web/static/src/js/views/calendar/calendar_controller.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/calendar/calendar_model.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/calendar/calendar_quick_create.js"></script>
@@ -408,6 +401,18 @@
<t t-call-assets="web.assets_backend" t-js="false"/>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
<!-- add lazy-loaded libs -->
<link rel="stylesheet" href="/web/static/lib/fullcalendar/css/fullcalendar.css"/>
<script type="text/javascript" src="/web/static/lib/fullcalendar/js/fullcalendar.js"></script>
<link rel="stylesheet" type="text/css" href="/web/static/lib/nvd3/nv.d3.css"/>
<script type="text/javascript" src="/web/static/lib/nvd3/d3.v3.js"></script>
<script type="text/javascript" src="/web/static/lib/nvd3/nv.d3.js"></script>
<script type="text/javascript" src="/web/static/src/js/libs/nvd3.js"></script>
<script type="text/javascript" src="/web/static/lib/ace/ace.odoo-custom.js"></script>
<script type="text/javascript" src="/web/static/lib/ace/mode-python.js"></script>
<script type="text/javascript" src="/web/static/lib/ace/mode-xml.js"></script>
<script type="text/javascript">
// define the 'web.web_client' module because some other modules require it
odoo.define('web.web_client', function (require) {
@@ -17,15 +17,16 @@ var DiagramView = BasicView.extend({
icon: 'fa-code-fork',
multi_record: false,
searchable: false,
jsLibs: [[
'/web_diagram/static/lib/js/jquery.mousewheel.js',
'/web_diagram/static/lib/js/raphael.js',
]],
config: {
Model: DiagramModel,
Renderer: DiagramRenderer,
Controller: DiagramController,
js_libs: [
'/web_diagram/static/lib/js/jquery.mousewheel.js',
'/web_diagram/static/lib/js/raphael.js',
],
},
/**
* @override
* @param {Object} viewInfo
@@ -89,7 +90,7 @@ var DiagramView = BasicView.extend({
},
//--------------------------------------------------------------------------
// Private
// Public
//--------------------------------------------------------------------------
/**
@@ -104,14 +105,13 @@ var DiagramView = BasicView.extend({
* present, while we are loading Raphael.
*
* @override
* @private
* @returns {Deferred}
*/
_loadLibs: function () {
getController: function () {
var oldDefine = window.define;
delete window.define;
return this._super.apply(this, arguments).then(function () {
return this._super.apply(this, arguments).then(function (view) {
window.define = oldDefine;
return view;
});
},
});
+13 -8
View File
@@ -112,6 +112,14 @@ function formatLESS(less) {
var ViewEditor = Widget.extend({
template: 'web_editor.ace_view_editor',
xmlDependencies: ['/web_editor/static/src/xml/ace.xml'],
jsLibs: [
'/web/static/lib/ace/ace.odoo-custom.js',
[
'/web/static/lib/ace/mode-xml.js',
'/web/static/lib/ace/mode-less.js',
'/web/static/lib/ace/theme-monokai.js'
]
],
events: {
'click .o_ace_type_switcher_choice': '_onTypeChoice',
'change .o_res_list': '_onResChange',
@@ -170,14 +178,11 @@ var ViewEditor = Widget.extend({
* @override
*/
willStart: function () {
var js_def = ajax.loadJS('/web/static/lib/ace/ace.odoo-custom.js').then(function () {
return $.when(
ajax.loadJS('/web/static/lib/ace/mode-xml.js'),
ajax.loadJS('/web/static/lib/ace/mode-less.js'),
ajax.loadJS('/web/static/lib/ace/theme-monokai.js')
);
});
return $.when(this._super.apply(this, arguments), js_def, this._loadResources());
return $.when(
this._super.apply(this, arguments),
ajax.loadLibs(this),
this._loadResources()
);
},
/**
* Initializes the library and initial view once the DOM is ready. It also
@@ -25,6 +25,14 @@ var utils = require('web.utils');
var GaugeWidget = AbstractField.extend({
className: "oe_gauge",
cssLibs: [
'/web/static/lib/nvd3/nv.d3.css'
],
jsLibs: [
'/web/static/lib/nvd3/d3.v3.js',
'/web/static/lib/nvd3/nv.d3.js',
'/web/static/src/js/libs/nvd3.js'
],
//--------------------------------------------------------------------------
// Private
@@ -1,6 +1,7 @@
odoo.define('website.backend.dashboard', function (require) {
'use strict';
var ajax = require('web.ajax');
var ControlPanelMixin = require('web.ControlPanelMixin');
var core = require('web.core');
var Dialog = require('web.Dialog');
@@ -16,6 +17,14 @@ var QWeb = core.qweb;
var Dashboard = Widget.extend(ControlPanelMixin, {
template: 'website.WebsiteDashboardMain',
cssLibs: [
'/web/static/lib/nvd3/nv.d3.css'
],
jsLibs: [
'/web/static/lib/nvd3/d3.v3.js',
'/web/static/lib/nvd3/nv.d3.js',
'/web/static/src/js/libs/nvd3.js'
],
events: {
'click .js_link_analytics_settings': 'on_link_analytics_settings',
'click .o_dashboard_action': 'on_dashboard_action',
@@ -37,10 +46,8 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
willStart: function() {
var self = this;
return this._super().then(function() {
return $.when(
self.fetch_data()
);
return $.when(ajax.loadLibs(this), this._super()).then(function() {
return self.fetch_data();
});
},