diff --git a/addons/account/static/src/js/account_reconciliation_widgets.js b/addons/account/static/src/js/account_reconciliation_widgets.js index 5491f2fddee..cfd21ea7987 100644 --- a/addons/account/static/src/js/account_reconciliation_widgets.js +++ b/addons/account/static/src/js/account_reconciliation_widgets.js @@ -27,9 +27,6 @@ var _t = core._t; var QWeb = core.qweb; var bus = core.bus; -var _ = require('_'); -var $ = require('$'); - function defaultIfUndef(variable, defaultValue) { return variable === undefined ? defaultValue : variable; } diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js index 2adf913faab..27daf2ea831 100644 --- a/addons/mail/static/src/js/chat_manager.js +++ b/addons/mail/static/src/js/chat_manager.js @@ -4,6 +4,7 @@ odoo.define('mail.chat_manager', function (require) { var bus = require('bus.bus').bus; var utils = require('mail.utils'); var config = require('web.config'); +var Bus = require('web.Bus'); var core = require('web.core'); var data = require('web.data'); var Model = require('web.Model'); @@ -837,7 +838,7 @@ var chat_manager = { return message.channel_ids.length === 0 && message.model === model; }); }, - bus: new core.Bus(), + bus: new Bus(), create_channel: function (name, type) { var method = type === "dm" ? "channel_get" : "channel_create"; diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js index fa88f1cf943..b1f1bea8c99 100644 --- a/addons/web/static/src/js/action_manager.js +++ b/addons/web/static/src/js/action_manager.js @@ -1,6 +1,7 @@ odoo.define('web.ActionManager', function (require) { "use strict"; +var Bus = require('web.Bus'); var ControlPanel = require('web.ControlPanel'); var core = require('web.core'); var crash_manager = require('web.crash_manager'); @@ -712,7 +713,7 @@ var ActionManager = Widget.extend({ if (this.dialog_widget.need_control_panel) { // Set a fake bus to Dialogs needing a ControlPanel as they should not // communicate with the main ControlPanel - this.dialog_widget.set_cp_bus(new core.Bus()); + this.dialog_widget.set_cp_bus(new Bus()); } this.dialog_widget.setParent(this.dialog); diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index 2cc4abe29bb..842858926a9 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -36,11 +36,7 @@ var job_deps = []; var job_deferred = []; - var services = Object.create({ - qweb: new QWeb2.Engine(), - $: $, - _: _, - }); + var services = Object.create({}); var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg; var cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g; diff --git a/addons/web/static/src/js/compatibility.js b/addons/web/static/src/js/compatibility.js index fe3ef096d63..d6a97b76f0e 100644 --- a/addons/web/static/src/js/compatibility.js +++ b/addons/web/static/src/js/compatibility.js @@ -261,5 +261,28 @@ ListView.include({ }, }); +// IE patch +//------------------------------------------------------------------------- +if (typeof(console) === "undefined") { + // Even IE9 only exposes console object if debug window opened + window.console = {}; + ('log error debug info warn assert clear dir dirxml trace group' + + ' groupCollapsed groupEnd time timeEnd profile profileEnd count' + + ' exception').split(/\s+/).forEach(function(property) { + console[property] = _.identity; + }); +} + +/** + Some hack to make placeholders work in ie9. +*/ +if (!('placeholder' in document.createElement('input'))) { + document.addEventListener("DOMNodeInserted",function(event){ + var nodename = event.target.nodeName.toLowerCase(); + if ( nodename === "input" || nodename === "textarea" ) { + $(event.target).placeholder(); + } + }); +} }); diff --git a/addons/web/static/src/js/control_panel.js b/addons/web/static/src/js/control_panel.js index 80744f243e9..42aac397d07 100644 --- a/addons/web/static/src/js/control_panel.js +++ b/addons/web/static/src/js/control_panel.js @@ -31,7 +31,7 @@ return ControlPanelMixin; odoo.define('web.ControlPanel', function (require) { "use strict"; -var core = require('web.core'); +var Bus = require('web.Bus'); var data = require('web.data'); var Widget = require('web.Widget'); @@ -47,7 +47,7 @@ var ControlPanel = Widget.extend({ this.template = template; } - this.bus = new core.Bus(); + this.bus = new Bus(); this.bus.on("update", this, this.update); }, /** diff --git a/addons/web/static/src/js/framework/ajax.js b/addons/web/static/src/js/framework/ajax.js index 71c742b026c..50e0e2f0c59 100644 --- a/addons/web/static/src/js/framework/ajax.js +++ b/addons/web/static/src/js/framework/ajax.js @@ -119,6 +119,11 @@ function jsonpRpc(url, fct_name, params, settings) { }); } +// helper function to make a rpc with a function name hardcoded to 'call' +function rpc(url, params, settings) { + return jsonRpc(url, 'call', params, settings); +} + // helper function realSetTimeout (fct, millis) { var finished = new Date().getTime() + millis; @@ -363,6 +368,7 @@ var loadXML = (function () { return { jsonRpc: jsonRpc, jsonpRpc: jsonpRpc, + rpc: rpc, loadCSS: loadCSS, loadJS: loadJS, loadXML: loadXML, diff --git a/addons/web/static/src/js/framework/bus.js b/addons/web/static/src/js/framework/bus.js new file mode 100644 index 00000000000..bf33c1fe01e --- /dev/null +++ b/addons/web/static/src/js/framework/bus.js @@ -0,0 +1,16 @@ +odoo.define('web.Bus', function (require) { +"use strict"; + +var Class = require('web.Class'); +var mixins = require('web.mixins'); + +/** + * Event Bus used to bind events scoped in the current instance + */ +return Class.extend(mixins.EventDispatcherMixin, { + init: function() { + mixins.EventDispatcherMixin.init.call(this, parent); + }, +}); + +}); diff --git a/addons/web/static/src/js/framework/core.js b/addons/web/static/src/js/framework/core.js deleted file mode 100644 index 1c8b55ee377..00000000000 --- a/addons/web/static/src/js/framework/core.js +++ /dev/null @@ -1,196 +0,0 @@ -odoo.define('web.core', function (require) { -"use strict"; - -var Class = require('web.Class'); -var mixins = require('web.mixins'); -var Registry = require('web.Registry'); -var translation = require('web.translation'); - -var qweb = require('qweb'); -var _ = require('_'); -var $ = require('$'); - -var debug = $.deparam($.param.querystring()).debug !== undefined; - -var _t = translation._t; -var _lt = translation._lt; - -/** - * Event Bus used to bind events scoped in the current instance - */ -var Bus = Class.extend(mixins.EventDispatcherMixin, { - init: function() { - mixins.EventDispatcherMixin.init.call(this, parent); - }, -}); - -var main_bus = new Bus (); - -_.each('click,dblclick,keydown,keypress,keyup'.split(','), function(evtype) { - $('html').on(evtype, function(ev) { - main_bus.trigger(evtype, ev); - }); -}); -_.each('resize,scroll'.split(','), function(evtype) { - $(window).on(evtype, function(ev) { - main_bus.trigger(evtype, ev); - }); -}); - - -// Underscore customization -//------------------------------------------------------------------------- -_.str.toBoolElse = function (str, elseValues, trueValues, falseValues) { - var ret = _.str.toBool(str, trueValues, falseValues); - if (_.isUndefined(ret)) { - return elseValues; - } - return ret; -}; - -// IE patch -//------------------------------------------------------------------------- -if (typeof(console) === "undefined") { - // Even IE9 only exposes console object if debug window opened - window.console = {}; - ('log error debug info warn assert clear dir dirxml trace group' - + ' groupCollapsed groupEnd time timeEnd profile profileEnd count' - + ' exception').split(/\s+/).forEach(function(property) { - console[property] = _.identity; - }); -} - -/** - Some hack to make placeholders work in ie9. -*/ -if (!('placeholder' in document.createElement('input'))) { - document.addEventListener("DOMNodeInserted",function(event){ - var nodename = event.target.nodeName.toLowerCase(); - if ( nodename === "input" || nodename == "textarea" ) { - $(event.target).placeholder(); - } - }); -} - - - -/** - * Lazy translation function, only performs the translation when actually - * printed (e.g. inserted into a template) - * - * Useful when defining translatable strings in code evaluated before the - * translation database is loaded, as class attributes or at the top-level of - * an OpenERP Web module - * - * @param {String} s string to translate - * @returns {Object} lazy translation object - */ -qweb.debug = debug; -_.extend(qweb.default_dict, { - '__debug__': debug, - 'moment': function(date) { return new moment(date); }, -}); - -qweb.default_dict.csrf_token = odoo.csrf_token; - -qweb.preprocess_node = function() { - // Note that 'this' is the Qweb Node - switch (this.node.nodeType) { - case Node.TEXT_NODE: - case Node.CDATA_SECTION_NODE: - // Text and CDATAs - var translation = this.node.parentNode.attributes['t-translation']; - if (translation && translation.value === 'off') { - return; - } - var match = /^(\s*)([\s\S]+?)(\s*)$/.exec(this.node.data); - if (match) { - this.node.data = match[1] + _t(match[2]) + match[3]; - } - break; - case Node.ELEMENT_NODE: - // Element - var attr, attrs = ['label', 'title', 'alt', 'placeholder']; - while ((attr = attrs.pop())) { - if (this.attributes[attr]) { - this.attributes[attr] = _t(this.attributes[attr]); - } - } - } -}; - -/** Setup jQuery timeago */ -/* - * Strings in timeago are "composed" with prefixes, words and suffixes. This - * makes their detection by our translating system impossible. Use all literal - * strings we're using with a translation mark here so the extractor can do its - * job. - */ -{ - _t('less than a minute ago'); - _t('about a minute ago'); - _t('%d minutes ago'); - _t('about an hour ago'); - _t('%d hours ago'); - _t('a day ago'); - _t('%d days ago'); - _t('about a month ago'); - _t('%d months ago'); - _t('about a year ago'); - _t('%d years ago'); -} - -$.async_when = function() { - var async = false; - var def = $.Deferred(); - $.when.apply($, arguments).done(function() { - var args = arguments; - var action = function() { - def.resolve.apply(def, args); - }; - if (async) - action(); - else - setTimeout(action, 0); - }).fail(function() { - var args = arguments; - var action = function() { - def.reject.apply(def, args); - }; - if (async) - action(); - else - setTimeout(action, 0); - }); - async = true; - return def; -}; - -return { - debug: debug, - qweb: qweb, - - // core classes and functions - Class: Class, - Bus: Bus, - mixins: mixins, - bus: main_bus, - _t: _t, - _lt: _lt, - - // registries - action_registry : new Registry(), - crash_registry: new Registry(), - form_custom_registry: new Registry(), - form_tag_registry: new Registry(), - form_widget_registry: new Registry(), - list_widget_registry: new Registry(), - one2many_view_registry: new Registry(), - search_filters_registry: new Registry(), - search_widgets_registry: new Registry(), - view_registry: new Registry(), - - csrf_token: odoo.csrf_token, -}; - -}); diff --git a/addons/web/static/src/js/framework/data.js b/addons/web/static/src/js/framework/data.js index e969616e7b6..92c85de3c16 100644 --- a/addons/web/static/src/js/framework/data.js +++ b/addons/web/static/src/js/framework/data.js @@ -1,15 +1,15 @@ odoo.define('web.data', function (require) { "use strict"; -var core = require('web.core'); +var Class = require('web.Class'); +var mixins = require('web.mixins'); var Model = require('web.Model'); var session = require('web.session'); +var translation = require('web.translation'); var pyeval = require('web.pyeval'); var utils = require('web.utils'); -var Class = core.Class; -var mixins = core.mixins; -var _t = core._t; +var _t = translation._t; /** * Serializes the sort criterion array of a dataset into a form which can be @@ -816,7 +816,7 @@ var BufferedDataSet = DataSetStatic.extend({ }); this.set_ids(_.difference(this.ids, _.pluck(_.filter(this.cache, function (c) {return c.to_delete;}), 'id'))); this.trigger("dataset_changed", ids, callback, error_callback); - return $.async_when({result: true}).done(callback); + return utils.async_when({result: true}).done(callback); }, reset_ids: function(ids, options) { var self = this; diff --git a/addons/web/static/src/js/framework/formats.js b/addons/web/static/src/js/framework/formats.js index 52a2fa5b0b0..24358a7361b 100644 --- a/addons/web/static/src/js/framework/formats.js +++ b/addons/web/static/src/js/framework/formats.js @@ -1,11 +1,11 @@ odoo.define('web.formats', function (require) { "use strict"; -var core = require('web.core'); +var translation = require('web.translation'); var time = require('web.time'); var utils = require('web.utils'); -var _t = core._t; +var _t = translation._t; /** * Formats a single atomic value based on a field descriptor diff --git a/addons/web/static/src/js/framework/misc.js b/addons/web/static/src/js/framework/misc.js index 73345df94c0..22bbace458c 100644 --- a/addons/web/static/src/js/framework/misc.js +++ b/addons/web/static/src/js/framework/misc.js @@ -3,7 +3,7 @@ odoo.define('web.framework', function (require) { var core = require('web.core'); var crash_manager = require('web.crash_manager'); -var session = require('web.session'); +var ajax = require('web.ajax'); var Widget = require('web.Widget'); var _t = core._t; @@ -43,17 +43,6 @@ var Throbber = Widget.extend({ }, }); - -// special tweak for the web client -var old_async_when = $.async_when; -$.async_when = function() { - if (session.synch) - return $.when.apply(this, arguments); - else - return old_async_when.apply(this, arguments); -}; - - /** Setup blockui */ if ($.blockUI) { $.blockUI.defaults.baseZ = 1100; @@ -100,7 +89,7 @@ function redirect (url, wait) { }; var wait_server = function() { - session.rpc("/web/webclient/version_info", {}).done(load).fail(function() { + ajax.rpc("/web/webclient/version_info", {}).done(load).fail(function() { setTimeout(wait_server, 250); }); }; @@ -176,7 +165,7 @@ core.action_registry.add("logout", logout); */ function ReloadContext (parent, action) { // side-effect of get_session_info is to refresh the session context - session.rpc("/web/session/get_session_info", {}).then(function() { + ajax.rpc("/web/session/get_session_info", {}).then(function() { Reload(parent, action); }); } diff --git a/addons/web/static/src/js/framework/qweb.js b/addons/web/static/src/js/framework/qweb.js new file mode 100644 index 00000000000..2202460a18a --- /dev/null +++ b/addons/web/static/src/js/framework/qweb.js @@ -0,0 +1,50 @@ +odoo.define('web.QWeb', function (require) { +"use strict"; + +var translation = require('web.translation'); + +var _t = translation._t; + +function QWeb(debug) { + var qweb = new QWeb2.Engine(); + qweb.default_dict = { + '_' : _, + 'JSON': JSON, + '_t' : translation._t, + '__debug__': debug, + 'moment': function(date) { return new moment(date); }, + 'csrf_token': odoo.csrf_token, + }; + qweb.debug = debug; + return qweb; +} + +QWeb.prototype.preprocess_node = function() { + // Note that 'this' is the Qweb Node + switch (this.node.nodeType) { + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + // Text and CDATAs + var translation = this.node.parentNode.attributes['t-translation']; + if (translation && translation.value === 'off') { + return; + } + var match = /^(\s*)([\s\S]+?)(\s*)$/.exec(this.node.data); + if (match) { + this.node.data = match[1] + _t(match[2]) + match[3]; + } + break; + case Node.ELEMENT_NODE: + // Element + var attr, attrs = ['label', 'title', 'alt', 'placeholder']; + while ((attr = attrs.pop())) { + if (this.attributes[attr]) { + this.attributes[attr] = _t(this.attributes[attr]); + } + } + } +}; + +return QWeb; + +}); diff --git a/addons/web/static/src/js/framework/session.js b/addons/web/static/src/js/framework/session.js index 718e4c52c33..93e2707d24d 100644 --- a/addons/web/static/src/js/framework/session.js +++ b/addons/web/static/src/js/framework/session.js @@ -266,15 +266,6 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { options.session = this; ajax.get_file(options); }, - synchronized_mode: function(to_execute) { - var synch = this.synch; - this.synch = true; - try { - return to_execute(); - } finally { - this.synch = synch; - } - }, /** * (re)loads the content of a session: db name, username, user id, session * context and status of the support contract diff --git a/addons/web/static/src/js/framework/translation.js b/addons/web/static/src/js/framework/translation.js index 69743e9787d..2b6e5a4cecc 100644 --- a/addons/web/static/src/js/framework/translation.js +++ b/addons/web/static/src/js/framework/translation.js @@ -3,8 +3,6 @@ odoo.define('web.translation', function (require) { "use strict"; var Class = require('web.Class'); -var qweb = require('qweb'); - var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase# */{ init: function() { @@ -76,15 +74,42 @@ var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase# }); var _t = new TranslationDataBase().build_translation_function(); +/** + * Lazy translation function, only performs the translation when actually + * printed (e.g. inserted into a template) + * + * Useful when defining translatable strings in code evaluated before the + * translation database is loaded, as class attributes or at the top-level of + * an OpenERP Web module + * + * @param {String} s string to translate + * @returns {Object} lazy translation object + */ var _lt = function (s) { return {toString: function () { return _t(s); }}; }; -qweb.default_dict = { - '_' : _, - 'JSON': JSON, - '_t' : _t, -}; +/** Setup jQuery timeago */ +/* + * Strings in timeago are "composed" with prefixes, words and suffixes. This + * makes their detection by our translating system impossible. Use all literal + * strings we're using with a translation mark here so the extractor can do its + * job. + */ +{ + _t('less than a minute ago'); + _t('about a minute ago'); + _t('%d minutes ago'); + _t('about an hour ago'); + _t('%d hours ago'); + _t('a day ago'); + _t('%d days ago'); + _t('about a month ago'); + _t('%d months ago'); + _t('about a year ago'); + _t('%d years ago'); +} + return { _t: _t, @@ -93,4 +118,3 @@ return { }; }); - diff --git a/addons/web/static/src/js/framework/utils.js b/addons/web/static/src/js/framework/utils.js index 40774e9095d..e19246823c5 100644 --- a/addons/web/static/src/js/framework/utils.js +++ b/addons/web/static/src/js/framework/utils.js @@ -462,6 +462,40 @@ function swap(array, elem1, elem2) { array[i1] = elem2; } +function toBoolElse (str, elseValues, trueValues, falseValues) { + var ret = _.str.toBool(str, trueValues, falseValues); + if (_.isUndefined(ret)) { + return elseValues; + } + return ret; +} + +function async_when() { + var async = false; + var def = $.Deferred(); + $.when.apply($, arguments).done(function() { + var args = arguments; + var action = function() { + def.resolve.apply(def, args); + }; + if (async) + action(); + else + setTimeout(action, 0); + }).fail(function() { + var args = arguments; + var action = function() { + def.reject.apply(def, args); + }; + if (async) + action(); + else + setTimeout(action, 0); + }); + async = true; + return def; +} + return { divmod: divmod, modf: modf, @@ -491,6 +525,8 @@ return { reject_after: reject_after, delay: delay, swap: swap, + toBoolElse: toBoolElse, + async_when: async_when, }; }); diff --git a/addons/web/static/src/js/services/core.js b/addons/web/static/src/js/services/core.js new file mode 100644 index 00000000000..41e30c1bd52 --- /dev/null +++ b/addons/web/static/src/js/services/core.js @@ -0,0 +1,53 @@ +odoo.define('web.core', function (require) { +"use strict"; + +var Bus = require('web.Bus'); +var Class = require('web.Class'); +var mixins = require('web.mixins'); +var QWeb = require('web.QWeb'); +var Registry = require('web.Registry'); +var translation = require('web.translation'); + +var debug = $.deparam($.param.querystring()).debug !== undefined; + +var bus = new Bus (); + +_.each('click,dblclick,keydown,keypress,keyup'.split(','), function(evtype) { + $('html').on(evtype, function(ev) { + bus.trigger(evtype, ev); + }); +}); +_.each('resize,scroll'.split(','), function(evtype) { + $(window).on(evtype, function(ev) { + bus.trigger(evtype, ev); + }); +}); + +return { + debug: debug, + qweb: new QWeb(debug), + + // core classes and functions + Class: Class, + mixins: mixins, + bus: bus, + main_bus: new Bus(), + _t: translation._t, + _lt: translation._lt, + + // registries + action_registry : new Registry(), + crash_registry: new Registry(), + form_custom_registry: new Registry(), + form_tag_registry: new Registry(), + form_widget_registry: new Registry(), + list_widget_registry: new Registry(), + one2many_view_registry: new Registry(), + search_filters_registry: new Registry(), + search_widgets_registry: new Registry(), + view_registry: new Registry(), + + csrf_token: odoo.csrf_token, +}; + +}); diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js index d4c67db5218..4c7b84b6dfc 100644 --- a/addons/web/static/src/js/views/form_relational_widgets.js +++ b/addons/web/static/src/js/views/form_relational_widgets.js @@ -802,13 +802,13 @@ var FieldX2Many = AbstractManyField.extend({ this.viewmanager.on("switch_mode", self, function(n_mode) { $.when(self.commit_value()).done(function() { if (n_mode === "list") { - $.async_when().done(function() { + utils.async_when().done(function() { self.reload_current_view(); }); } }); }); - $.async_when().done(function () { + utils.async_when().done(function () { self.$el.addClass('o_view_manager_content'); self.alive(self.viewmanager.attachTo(self.$el)); }); diff --git a/addons/web/static/src/js/views/form_view.js b/addons/web/static/src/js/views/form_view.js index a9da2e40304..f517a94c819 100644 --- a/addons/web/static/src/js/views/form_view.js +++ b/addons/web/static/src/js/views/form_view.js @@ -717,7 +717,7 @@ var FormView = View.extend(common.FieldManagerMixin, { def.resolve(); }); } else { - $.async_when().done(function () { + utils.async_when().done(function () { def.reject(); }); } diff --git a/addons/web/static/src/js/views/list_view.js b/addons/web/static/src/js/views/list_view.js index b0ed903bdb5..d905dfdadfd 100644 --- a/addons/web/static/src/js/views/list_view.js +++ b/addons/web/static/src/js/views/list_view.js @@ -1459,7 +1459,7 @@ ListView.Groups = Class.extend({ var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name'); var options = { offset: current_min - 1, limit: view._limit, context: {bin_size: true} }; - return $.async_when().then(function() { + return utils.async_when().then(function() { return dataset.read_slice(fields, options).then(function (records) { // FIXME: ignominious hacks, parents (aka form view) should not send two ListView#reload_content concurrently if (self.records.length) { @@ -1525,7 +1525,7 @@ ListView.Groups = Class.extend({ seq = to ? list.records.at(to - 1).get(seqname) : 0; var defs = []; var fct = function (dataset, id, seq) { - defs.push($.async_when().then(function () { + defs.push(utils.async_when().then(function () { var attrs = {}; attrs[seqname] = seq; return dataset.write(id, attrs, {internal_dataset_changed: true}); @@ -2047,5 +2047,3 @@ function for_ (id, field, node) { return ListView; }); - - diff --git a/addons/web/static/test/framework.js b/addons/web/static/test/framework.js index 70cc016fbcc..f3add74d7c5 100644 --- a/addons/web/static/test/framework.js +++ b/addons/web/static/test/framework.js @@ -433,30 +433,30 @@ odoo.define_section('Widget.events', ['web.Widget', 'web.core'], function (test) }); }); -odoo.define_section('Widget.async', ['web.Widget'], function (test) { - test("alive(alive)", function (assert, Widget) { +odoo.define_section('Widget.async', ['web.Widget', 'web.utils'], function (test) { + test("alive(alive)", function (assert, Widget, utils) { assert.expect(1); var widget = new (Widget.extend({})); - return $.async_when(widget.start()) - .then(function () { return widget.alive($.async_when()) }) + return utils.async_when(widget.start()) + .then(function () { return widget.alive(utils.async_when()) }) .then(function () { assert.ok(true); }); }); - test("alive(dead)", function (assert, Widget) { + test("alive(dead)", function (assert, Widget, utils) { assert.expect(1); var widget = new (Widget.extend({})); return $.Deferred(function (d) { - $.async_when(widget.start()) + utils.async_when(widget.start()) .then(function () { // destroy widget widget.destroy(); - var promise = $.async_when(); + var promise = utils.async_when(); // leave time for alive() to do its stuff promise.then(function () { - return $.async_when(); + return utils.async_when(); }).then(function () { assert.ok(true); d.resolve(); @@ -470,26 +470,26 @@ odoo.define_section('Widget.async', ['web.Widget'], function (test) { }); }); - test("alive(alive, true)", function (assert, Widget) { + test("alive(alive, true)", function (assert, Widget, utils) { assert.expect(1); var widget = new (Widget.extend({})); - return $.async_when(widget.start()) - .then(function () { return widget.alive($.async_when(), true) }) + return utils.async_when(widget.start()) + .then(function () { return widget.alive(utils.async_when(), true) }) .then(function () { assert.ok(true); }); }); - test("alive(dead, true)", function (assert, Widget) { + test("alive(dead, true)", function (assert, Widget, utils) { assert.expect(1); var done = assert.async(); var widget = new (Widget.extend({})); - $.async_when(widget.start()) + utils.async_when(widget.start()) .then(function () { // destroy widget widget.destroy(); console.log('destroyed'); - return widget.alive($.async_when().done(function () { console.log('when'); }), true); + return widget.alive(utils.async_when().done(function () { console.log('when'); }), true); }).then(function () { console.log('unfailed') assert.ok(false, "alive(p, true) should fail its promise"); @@ -630,4 +630,3 @@ odoo.define_section('server-formats', ['web.time'], function (test) { }); }); - diff --git a/addons/web/static/test/testing.js b/addons/web/static/test/testing.js index 4fea9f9337b..2ec911740b2 100644 --- a/addons/web/static/test/testing.js +++ b/addons/web/static/test/testing.js @@ -3,6 +3,7 @@ odoo.testing = {}; odoo.testing.start_services = function () { var factories = odoo.__DEBUG__.factories; + delete factories['mail.chat_manager']; var jobs = _.map(factories, function (factory, name) { return { name: name, @@ -10,11 +11,7 @@ odoo.testing.start_services = function () { deps: factory.deps, }; }); - var services = Object.create({ - qweb: new QWeb2.Engine(), - $: $, - _: _, - }); + var services = Object.create({}); return odoo.process_jobs(jobs, services); }; @@ -95,7 +92,7 @@ odoo.define_section = function (name, section_deps) { QUnit.test(name, function (assert) { var services = odoo.testing.start_services(); var deps = _.map(section_deps.concat(dep_names), function (name) { return services[name]; }); - services.qweb.add_template(odoo.testing.templates); + services['web.core'].qweb.add_template(odoo.testing.templates); mock.clear(); mock.interceptRPC(services['web.session']); var info = { @@ -144,4 +141,3 @@ QUnit.moduleDone(function(result) { } }); - diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index f14e5cd2f57..cdf3877eeb4 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -67,7 +67,9 @@ - + + + diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js index 73abe402dab..e907f09ffd8 100644 --- a/addons/web_calendar/static/src/js/web_calendar.js +++ b/addons/web_calendar/static/src/js/web_calendar.js @@ -10,6 +10,7 @@ var form_common = require('web.form_common'); var formats = require('web.formats'); var Model = require('web.DataModel'); var time = require('web.time'); +var utils = require('web.utils'); var View = require('web.View'); var widgets = require('web_calendar.widgets'); var local_storage = require('web.local_storage'); @@ -138,14 +139,14 @@ var CalendarView = View.extend({ //if quick_add = not specified in view, we use the default quick_create_instance //if quick_add = is NOT False and IS specified in view, we this one for quick_create_instance' - this.quick_add_pop = (isNullOrUndef(attrs.quick_add) || _.str.toBoolElse(attrs.quick_add, true)); + this.quick_add_pop = (isNullOrUndef(attrs.quick_add) || utils.toBoolElse(attrs.quick_add, true)); // The display format which will be used to display the event where fields are between "[" and "]" if (!isNullOrUndef(attrs.display)) { this.how_display_event = attrs.display; // String with [FIELD] } // If this field is set ot true, we don't open the event in form view, but in a popup with the view_id passed by this parameter - if (isNullOrUndef(attrs.event_open_popup) || !_.str.toBoolElse(attrs.event_open_popup, true)) { + if (isNullOrUndef(attrs.event_open_popup) || !utils.toBoolElse(attrs.event_open_popup, true)) { this.open_popup_action = false; } else { this.open_popup_action = attrs.event_open_popup; @@ -155,7 +156,7 @@ var CalendarView = View.extend({ // If this field is set ot true, we don't add itself as an attendee when we use attendee_people to add each attendee icon on an event // The color is the color of the attendee, so don't need to show again that it will be present - this.colorIsAttendee = !(isNullOrUndef(attrs.color_is_attendee) || !_.str.toBoolElse(attrs.color_is_attendee, true)); + this.colorIsAttendee = !(isNullOrUndef(attrs.color_is_attendee) || !utils.toBoolElse(attrs.color_is_attendee, true)); // if we have not sidebar, (eg: Dashboard), we don't use the filter "coworkers" if (isNullOrUndef(this.options.sidebar)) { @@ -807,7 +808,7 @@ var CalendarView = View.extend({ value: key, label: val[1], color: self.get_color(key), - avatar_model: (_.str.toBoolElse(self.avatar_filter, true) ? self.avatar_filter : false ), + avatar_model: (utils.toBoolElse(self.avatar_filter, true) ? self.avatar_filter : false ), is_checked: true }; self.all_filters[key] = filter_item; diff --git a/addons/web_editor/views/iframe.xml b/addons/web_editor/views/iframe.xml index 6d44ba43b7f..24983557818 100644 --- a/addons/web_editor/views/iframe.xml +++ b/addons/web_editor/views/iframe.xml @@ -41,8 +41,9 @@ if(window['odoo']) { odoo.define('web.csrf', function (require) { var token = ""; - require('web.core').csrf_token = token; - require('qweb').default_dict.csrf_token = token; + var core = require('web.core'); + core.csrf_token = token; + core.qweb.default_dict.csrf_token = token; }); } diff --git a/addons/web_kanban/static/src/js/kanban_view.js b/addons/web_kanban/static/src/js/kanban_view.js index eb9c7e99b03..0f243e20cdf 100644 --- a/addons/web_kanban/static/src/js/kanban_view.js +++ b/addons/web_kanban/static/src/js/kanban_view.js @@ -9,6 +9,7 @@ var Dialog = require('web.Dialog'); var form_common = require('web.form_common'); var Pager = require('web.Pager'); var pyeval = require('web.pyeval'); +var QWeb = require('web.QWeb'); var session = require('web.session'); var utils = require('web.utils'); var View = require('web.View'); @@ -18,7 +19,7 @@ var quick_create = require('web_kanban.quick_create'); var KanbanRecord = require('web_kanban.Record'); var kanban_widgets = require('web_kanban.widgets'); -var QWeb = core.qweb; +var qweb = core.qweb; var _lt = core._lt; var _t = core._t; var ColumnQuickCreate = quick_create.ColumnQuickCreate; @@ -59,10 +60,7 @@ var KanbanView = View.extend({ init: function () { this._super.apply(this, arguments); - // qweb setup - this.qweb = new QWeb2.Engine(); - this.qweb.debug = session.debug; - this.qweb.default_dict = _.clone(QWeb.default_dict); + this.qweb = new QWeb(session.debug); this.limit = this.options.limit || 40; this.fields = {}; @@ -323,7 +321,7 @@ var KanbanView = View.extend({ render_buttons: function($node) { var self = this; if (this.options.action_buttons !== false && this.is_action_enabled('create')) { - this.$buttons = $(QWeb.render("KanbanView.buttons", {'widget': this})); + this.$buttons = $(qweb.render("KanbanView.buttons", {'widget': this})); this.$buttons.on('click', 'button.o-kanban-button-new', function () { if (self.grouped && self.widgets.length && self.on_create === 'quick_create') { // Activate the quick create in the first column @@ -347,7 +345,6 @@ var KanbanView = View.extend({ $button_new.removeClass('btn-default').addClass('btn-primary'); }); } - this.$buttons.appendTo($node); } }, @@ -423,7 +420,7 @@ var KanbanView = View.extend({ }, render_no_content: function (fragment) { - var content = QWeb.render('KanbanView.nocontent', {content: this.no_content_msg}); + var content = qweb.render('KanbanView.nocontent', {content: this.no_content_msg}); $(content).appendTo(fragment); }, @@ -788,10 +785,10 @@ var KanbanView = View.extend({ }); function qweb_add_if(node, condition) { - if (node.attrs[QWeb.prefix + '-if']) { - condition = _.str.sprintf("(%s) and (%s)", node.attrs[QWeb.prefix + '-if'], condition); + if (node.attrs[qweb.prefix + '-if']) { + condition = _.str.sprintf("(%s) and (%s)", node.attrs[qweb.prefix + '-if'], condition); } - node.attrs[QWeb.prefix + '-if'] = condition; + node.attrs[qweb.prefix + '-if'] = condition; } function transform_qweb_template (node, fvg, many2manys) { @@ -815,8 +812,8 @@ function transform_qweb_template (node, fvg, many2manys) { } else if (fields_registry.contains(ftype)) { // do nothing, the kanban record will handle it } else { - node.tag = QWeb.prefix; - node.attrs[QWeb.prefix + '-esc'] = 'record.' + node.attrs.name + '.value'; + node.tag = qweb.prefix; + node.attrs[qweb.prefix + '-esc'] = 'record.' + node.attrs.name + '.value'; } break; case 'button': diff --git a/addons/website_mail/static/src/js/message_post.js b/addons/website_mail/static/src/js/message_post.js index 3ddb5e2ce90..2e93e8708a0 100644 --- a/addons/website_mail/static/src/js/message_post.js +++ b/addons/website_mail/static/src/js/message_post.js @@ -1,11 +1,13 @@ odoo.define('website_mail.thread', function(require) { 'use strict'; - var web_editor_base = require('web_editor.base') - var qweb = require('qweb'); + var web_editor_base = require('web_editor.base'); var ajax = require('web.ajax'); + var core = require('web.core'); var Widget = require('web.Widget'); + var qweb = core.qweb; + // load qweb template ajax.loadXML('/website_mail/static/src/xml/chatter_message.xml', qweb);