diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js
index cf5fe87b2ae..67a46e29d55 100644
--- a/addons/web/static/src/js/core/ajax.js
+++ b/addons/web/static/src/js/core/ajax.js
@@ -428,6 +428,8 @@ var loadXML = (function () {
* Loads a template file according to the given xmlId.
*
* @param {string} [xmlId] - the template xmlId
+ * @param {Object} [context]
+ * additionnal rpc context to be merged with the default one
* @returns {Deferred} resolved with an object
* cssLibs: list of css files
* cssContents: list of style tag contents
@@ -437,16 +439,17 @@ var loadXML = (function () {
var loadAsset = (function () {
var cache = {};
- var load = function loadAsset(xmlId) {
+ var load = function loadAsset(xmlId, context) {
if (cache[xmlId]) {
return Promise.resolve(cache[xmlId]);
}
+ context = _.extend({}, odoo.session_info.user_context, context);
var params = {
args: [xmlId, {
debug: config.isDebug()
}],
kwargs: {
- context: odoo.session_info.user_context,
+ context: context,
},
method: 'render_template',
model: 'ir.ui.view',
@@ -499,10 +502,12 @@ var loadAsset = (function () {
* List of inline styles to add after loading the CSS files.
* @param {string[]} [libs.jsContents=[]]
* List of inline scripts to add after loading the JS files.
+ * @param {Object} [context]
+ * additionnal rpc context to be merged with the default one
*
* @returns {Promise}
*/
-function loadLibs(libs) {
+function loadLibs(libs, context) {
var mutex = new concurrency.Mutex();
mutex.exec(function () {
var defs = [];
@@ -525,7 +530,7 @@ function loadLibs(libs) {
});
mutex.exec(function () {
return _loadArray(libs.assetLibs || [], function (xmlID) {
- return ajax.loadAsset(xmlID).then(function (asset) {
+ return ajax.loadAsset(xmlID, context).then(function (asset) {
return ajax.loadLibs(asset);
});
});
diff --git a/addons/web/static/src/js/core/service_mixins.js b/addons/web/static/src/js/core/service_mixins.js
index 0576364fa7c..9e6a40b494c 100644
--- a/addons/web/static/src/js/core/service_mixins.js
+++ b/addons/web/static/src/js/core/service_mixins.js
@@ -123,6 +123,15 @@ var ServicesMixin = {
});
return result;
},
+ /**
+ * @private
+ * @param {Object} libs - @see ajax.loadLibs
+ * @param {Object} [context] - @see ajax.loadLibs
+ * @returns {Promise}
+ */
+ _loadLibs: function (libs, context) {
+ return this.call('ajax', 'loadLibs', libs, context);
+ },
/**
* Builds and executes RPC query. Returns a promise resolved with
* the RPC result.
diff --git a/addons/web/static/src/js/core/widget.js b/addons/web/static/src/js/core/widget.js
index c6530b7fb7a..a089f8876fe 100644
--- a/addons/web/static/src/js/core/widget.js
+++ b/addons/web/static/src/js/core/widget.js
@@ -148,7 +148,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
}));
}
if (this.jsLibs || this.cssLibs || this.assetLibs) {
- proms.push(ajax.loadLibs(this));
+ proms.push(this._loadLibs(this));
}
return Promise.all(proms);
},
diff --git a/addons/web/static/src/js/public/public_root.js b/addons/web/static/src/js/public/public_root.js
index a567734546b..33d442e1d76 100644
--- a/addons/web/static/src/js/public/public_root.js
+++ b/addons/web/static/src/js/public/public_root.js
@@ -101,15 +101,25 @@ var PublicRoot = publicWidget.RootWidget.extend(ServiceProviderMixin, {
if (_.str.startsWith(route, '/web/dataset/call_kw/')) {
var params = ev.data.args[1];
var options = ev.data.args[2];
- params.kwargs.context = _.extend({}, this._getContext(), params.kwargs.context || {});
+ var noContextKeys = undefined;
if (options) {
- params.kwargs.context = _.omit(params.kwargs.context, options.noContextKeys);
+ noContextKeys = options.noContextKeys;
ev.data.args[2] = _.omit(options, 'noContextKeys');
}
- params.kwargs.context = JSON.parse(JSON.stringify(params.kwargs.context));
+ params.kwargs.context = _computeContext.call(this, params.kwargs.context, noContextKeys);
}
+ } else if (ev.data.service === 'ajax' && ev.data.method === 'loadLibs') {
+ ev.data.args[1] = _computeContext.call(this, ev.data.args[1]);
}
return ServiceProviderMixin._call_service.apply(this, arguments);
+
+ function _computeContext(context, noContextKeys) {
+ context = _.extend({}, this._getContext(), context);
+ if (noContextKeys) {
+ context = _.omit(context, noContextKeys);
+ }
+ return JSON.parse(JSON.stringify(context));
+ }
},
/**
* Retrieves the global context of the public environment. This is the
diff --git a/addons/web/static/src/js/services/ajax_service.js b/addons/web/static/src/js/services/ajax_service.js
index cb83dd9d553..f2fc3436991 100644
--- a/addons/web/static/src/js/services/ajax_service.js
+++ b/addons/web/static/src/js/services/ajax_service.js
@@ -2,10 +2,18 @@ odoo.define('web.AjaxService', function (require) {
"use strict";
var AbstractService = require('web.AbstractService');
+var ajax = require('web.ajax');
var core = require('web.core');
var session = require('web.session');
var AjaxService = AbstractService.extend({
+ /**
+ * @param {Object} libs - @see ajax.loadLibs
+ * @param {Object} [context] - @see ajax.loadLibs
+ */
+ loadLibs: function (libs, context) {
+ return ajax.loadLibs(libs, context);
+ },
rpc: function (route, args, options, target) {
var rpcPromise;
var promise = new Promise(function (resolve, reject) {
diff --git a/addons/web/static/tests/helpers/test_utils_mock.js b/addons/web/static/tests/helpers/test_utils_mock.js
index fe45bbb0e8e..e72dcc0d692 100644
--- a/addons/web/static/tests/helpers/test_utils_mock.js
+++ b/addons/web/static/tests/helpers/test_utils_mock.js
@@ -253,7 +253,7 @@ function addMockEnvironment(widget, params) {
var service = services[ev.data.service];
args = (ev.data.args || []);
result = service[ev.data.method].apply(service, args);
- } else if (ev.data.service === 'ajax') {
+ } else if (ev.data.service === 'ajax' && ev.data.method === 'rpc') {
// use ajax service that is mocked by the server
var route = ev.data.args[0];
args = ev.data.args[1];
diff --git a/addons/website/static/tests/tours/specific_website_editor.js b/addons/website/static/tests/tours/specific_website_editor.js
new file mode 100644
index 00000000000..b51256670b1
--- /dev/null
+++ b/addons/website/static/tests/tours/specific_website_editor.js
@@ -0,0 +1,29 @@
+odoo.define('website.tour.specific_website_editor', function (require) {
+'use strict';
+
+var tour = require('web_tour.tour');
+
+tour.register('generic_website_editor', {
+ test: true,
+}, [{
+ trigger: 'a[data-action=edit]',
+ content: 'Click edit button',
+}, {
+ trigger: 'body:not([data-hello="world"])',
+ extra_trigger: '#oe_snippets.o_loaded',
+ content: 'Check that the editor DOM matches its website-generic features',
+ run: function () {}, // Simple check
+}]);
+
+tour.register('specific_website_editor', {
+ test: true,
+}, [{
+ trigger: 'a[data-action=edit]',
+ content: 'Click edit button',
+}, {
+ trigger: 'body[data-hello="world"]',
+ extra_trigger: '#oe_snippets.o_loaded',
+ content: 'Check that the editor DOM matches its website-specific features',
+ run: function () {}, // Simple check
+}]);
+});
diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py
index 98e06dc7924..b0bfa241226 100644
--- a/addons/website/tests/test_ui.py
+++ b/addons/website/tests/test_ui.py
@@ -112,3 +112,21 @@ class TestUi(odoo.tests.HttpCase):
def test_04_backend_dashboard(self):
self.start_tour("/", 'backend_dashboard', login='admin')
+
+ def test_05_specific_website_editor(self):
+ website_default = self.env['website'].search([], limit=1)
+ new_website = self.env['website'].create({'name': 'New Website'})
+ website_editor_assets_view = self.env.ref('website.assets_wysiwyg')
+ self.env['ir.ui.view'].create({
+ 'name': 'Editor Extension',
+ 'type': 'qweb',
+ 'inherit_id': website_editor_assets_view.id,
+ 'website_id': new_website.id,
+ 'arch': """
+
+
+
+ """,
+ })
+ self.start_tour("/?fw=%s" % website_default.id, "generic_website_editor", login='admin')
+ self.start_tour("/?fw=%s" % new_website.id, "specific_website_editor", login='admin')
diff --git a/addons/website/views/assets.xml b/addons/website/views/assets.xml
index 56500ba06c5..7046d544cb2 100644
--- a/addons/website/views/assets.xml
+++ b/addons/website/views/assets.xml
@@ -24,6 +24,7 @@
+