diff options
| author | qsm-odoo <qsm@odoo.com> | 2018-12-11 16:48:06 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2019-02-26 17:02:59 +0000 |
| commit | 7b960c66bb6cfdcd835f127fff4161e72c324380 (patch) | |
| tree | d1ad7e4a13f7b5d8705e244a8abeb0761e5bc3ab /addons/website/static/src/js/content/website_root.js | |
| parent | dd2ba3c4f3928adc760a1f0c4f11016723504d76 (diff) | |
[REF] website, web, *: move part of website into web
* im_livechat, survey, website_forum
When website is installed, the JavaScript code has access to utilities
to define improved widgets which are automatically attached to existing
DOM elements on page load. Those mechanics are more and more needed in
portal which does not depend on website (as it is website which depends
on portal). This commit moves part of website JS to web, so that it can
be used by all 'frontend' apps whose only common dependency is web
(portal, survey, auth_signup, ...).
This PR also questioned several other similar issues which will be
handled later like:
- website should maybe not depends on portal but only on http_routing
- part of portal should be moved to http_routing and http_routing
should be renamed (especially for frontend layouts, etc) so that apps
like survey can reuse some common code
Part of https://github.com/odoo/odoo/pull/29442
task-1932066
Diffstat (limited to 'addons/website/static/src/js/content/website_root.js')
| -rw-r--r-- | addons/website/static/src/js/content/website_root.js | 294 |
1 files changed, 32 insertions, 262 deletions
diff --git a/addons/website/static/src/js/content/website_root.js b/addons/website/static/src/js/content/website_root.js index 1abef2589a4..ff398b2ff2d 100644 --- a/addons/website/static/src/js/content/website_root.js +++ b/addons/website/static/src/js/content/website_root.js @@ -1,80 +1,30 @@ -odoo.define('website.WebsiteRoot', function (require) { +odoo.define('website.root', function (require) { 'use strict'; -var ajax = require('web.ajax'); var core = require('web.core'); var Dialog = require('web.Dialog'); -var ServiceProviderMixin = require('web.ServiceProviderMixin'); -var session = require('web.session'); -var utils = require('web.utils'); -var rootWidget = require('web_editor.root_widget'); -var sAnimation = require('website.content.snippets.animation'); -require("website.content.zoomodoo"); +var publicRootData = require('web.public.root'); +require('website.content.zoomodoo'); var _t = core._t; -var websiteRootRegistry = new rootWidget.RootWidgetRegistry(); +var websiteRootRegistry = publicRootData.publicRootRegistry; -// Load localizations outside the WebsiteRoot to not wait for DOM ready (but -// wait for them in WebsiteRoot) -function getLang() { - var html = document.documentElement; - return (html.getAttribute('lang') || 'en_US').replace('-', '_'); -} -var lang = utils.get_cookie('frontend_lang') || getLang(); // FIXME the cookie value should maybe be in the ctx? -var localeDef = ajax.loadJS('/web/webclient/locale/' + lang.replace('-', '_')); - -/** - * Element which is designed to be unique and that will be the top-most element - * in the widget hierarchy. So, all other widgets will be indirectly linked to - * this Class instance. Its main role will be to retrieve RPC demands from its - * children and handle them. - */ -var WebsiteRoot = rootWidget.RootWidget.extend(ServiceProviderMixin, { - events: _.extend({}, rootWidget.RootWidget.prototype.events || {}, { +var WebsiteRoot = publicRootData.PublicRoot.extend({ + events: _.extend({}, publicRootData.PublicRoot.prototype.events || {}, { 'click .js_change_lang': '_onLangChangeClick', 'click .js_publish_management .js_publish_btn': '_onPublishBtnClick', - 'submit .js_website_submit_form': '_onWebsiteFormSubmit', - 'click .js_disable_on_click': '_onDisableOnClick', - 'click .js_multi_website_switch': '_multiWebsiteSwitch', - 'click .js_multi_company_switch': '_multiCompanySwitch', + 'click .js_multi_website_switch': '_onWebsiteSwitch', + 'click .js_multi_company_switch': '_onCompanySwitch', }), - custom_events: _.extend({}, rootWidget.RootWidget.prototype.custom_events || {}, { - animation_start_demand: '_onAnimationStartDemand', - animation_stop_demand: '_onAnimationStopDemand', - context_get: '_onContextGet', - main_object_request: '_onMainObjectRequest', - ready_to_clean_for_save: '_onAnimationStopDemand', + custom_events: _.extend({}, publicRootData.PublicRoot.prototype.custom_events || {}, { + 'ready_to_clean_for_save': '_onAnimationStopDemand', }), /** - * @constructor - */ - init: function () { - this._super.apply(this, arguments); - ServiceProviderMixin.init.call(this); - this.animations = []; - }, - /** - * @override - */ - willStart: function () { - // TODO would be even greater to wait for those only if necessary - return $.when( - this._super.apply(this, arguments), - session.is_bound, - localeDef - ); - }, - /** * @override */ start: function () { - var defs = [this._super.apply(this, arguments)]; - - // Animations - defs.push(this._startAnimations()); - // Compatibility lang change ? if (!this.$('.js_change_lang').length) { var $links = this.$('ul.js_language_selector li a:not([data-oe-id])'); @@ -89,28 +39,10 @@ var WebsiteRoot = rootWidget.RootWidget.extend(ServiceProviderMixin, { }); } - // Display image thumbnail - this.$(".o_image[data-mimetype^='image']").each(function () { - var $img = $(this); - if (/gif|jpe|jpg|png/.test($img.data('mimetype')) && $img.data('src')) { - $img.css('background-image', "url('" + $img.data('src') + "')"); - } - }); - // Enable magnify on zommable img this.$('.zoomable img[data-zoom]').zoomOdoo(); - // Auto scroll - if (window.location.hash.indexOf("scrollTop=") > -1) { - this.el.scrollTop = +window.location.hash.match(/scrollTop=([0-9]+)/)[1]; - } - - // Fix for IE: - if ($.fn.placeholder) { - $('input, textarea').placeholder(); - } - - return $.when.apply($, defs); + return this._super.apply(this, arguments); }, //-------------------------------------------------------------------------- @@ -118,124 +50,24 @@ var WebsiteRoot = rootWidget.RootWidget.extend(ServiceProviderMixin, { //-------------------------------------------------------------------------- /** - * Automatically add the global context to RPC commands. - * * @override */ - _call_service: function (ev) { - if (ev.data.service === 'ajax' && ev.data.method === 'rpc') { - var route = ev.data.args[0]; - 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 || {}); - if (options) { - params.kwargs.context = _.omit(params.kwargs.context, options.noContextKeys); - ev.data.args[2] = _.omit(options, 'noContextKeys'); - } - params.kwargs.context = JSON.parse(JSON.stringify(params.kwargs.context)); - } - } - return ServiceProviderMixin._call_service.apply(this, arguments); - }, - /** - * Retrieves the global context of the public environment. This is the - * context which is automatically added to each RPC. - * - * @private - * @param {Object} [context] - * @returns {Object} - */ _getContext: function (context) { var html = document.documentElement; return _.extend({ - 'lang': getLang(), 'website_id': html.getAttribute('data-website-id') | 0, - }, context || {}); + }, this._super.apply(this, arguments)); }, /** - * Retrieves the global context of the public environment (as - * @see _getContext) but with extra informations that would be useless to - * send with each RPC. - * - * @private - * @param {Object} [context] - * @returns {Object} + * @override */ _getExtraContext: function (context) { var html = document.documentElement; - return _.extend(this._getContext(), { + return _.extend({ 'editable': !!(html.dataset.editable || $('[data-oe-model]').length), // temporary hack, this should be done in python 'translatable': !!html.dataset.translatable, 'edit_translations': !!html.dataset.edit_translations, - }, context || {}); - }, - /** - * As the WebsiteRoot instance is designed to be unique, the associated - * registry has been instantiated outside of the class and is simply - * returned here. - * - * @private - * @override - */ - _getRegistry: function () { - return websiteRootRegistry; - }, - /** - * Creates an Animation instance for each DOM element which matches the - * `selector` key of one of the registered animations - * (@see Animation.selector). - * - * @private - * @param {boolean} [editableMode=false] - true if the page is in edition mode - * @param {jQuery} [$from] - * only initialize the animations whose `selector` matches the - * element or one of its descendant (default to the wrapwrap element) - * @returns {Deferred} - */ - _startAnimations: function (editableMode, $from) { - var self = this; - - editableMode = editableMode || false; - if ($from === undefined) { - $from = this.$('#wrapwrap'); - } - - this._stopAnimations($from); - - var defs = _.map(sAnimation.registry, function (Animation, animationName) { - var selector = Animation.prototype.selector || ''; - var $target = $from.find(selector).addBack(selector); - - var defs = _.map($target, function (el) { - var animation = new Animation(self, editableMode); - self.animations.push(animation); - return animation.attachTo($(el)); - }); - return $.when.apply($, defs); - }); - return $.when.apply($, defs); - }, - /** - * Destroys all animation instances. Especially needed before saving while - * in edition mode for example. - * - * @private - * @param {jQuery} [$from] - * only stop the animations linked to the given element(s) or one of - * its descendants - */ - _stopAnimations: function ($from) { - var removedAnimations = _.map(this.animations, function (animation) { - if (!$from - || $from.filter(animation.el).length - || $from.find(animation.el).length) { - animation.destroy(); - return animation; - } - return null; - }); - this.animations = _.difference(this.animations, removedAnimations); + }, this._super.apply(this, arguments)); }, //-------------------------------------------------------------------------- @@ -243,39 +75,12 @@ var WebsiteRoot = rootWidget.RootWidget.extend(ServiceProviderMixin, { //-------------------------------------------------------------------------- /** - * Called when the root is notified that the animations have to be - * (re)started. - * - * @private - * @param {OdooEvent} ev + * @override */ _onAnimationStartDemand: function (ev) { - this._startAnimations(ev.data.editableMode, ev.data.$target) - .done(ev.data.onSuccess) - .fail(ev.data.onFailure); - }, - /** - * Called when the root is notified that the animations have to be - * stopped. - * - * @private - * @param {OdooEvent} ev - */ - _onAnimationStopDemand: function (ev) { - this._stopAnimations(ev.data.$target); - }, - /** - * Called when someone asked for the global public context. - * - * @private - * @param {OdooEvent} ev - */ - _onContextGet: function (ev) { - if (ev.data.extra) { - ev.data.callback(this._getExtraContext(ev.data.context)); - } else { - ev.data.callback(this._getContext(ev.data.context)); - } + ev.data.options = _.clone(ev.data.options || {}); + ev.data.options.editableMode = ev.data.editableMode; + this._super.apply(this, arguments); }, /** * @todo review @@ -294,20 +99,6 @@ var WebsiteRoot = rootWidget.RootWidget.extend(ServiceProviderMixin, { window.location.href = _.str.sprintf("/website/lang/%(lang)s?r=%(url)s%(hash)s", redirect); }, /** - * Checks information about the page main object. - * - * @private - * @param {OdooEvent} ev - */ - _onMainObjectRequest: function (ev) { - var repr = $('html').data('main-object'); - var m = repr.match(/(.+)\((\d+),(.*)\)/); - ev.data.callback({ - model: m[1], - id: m[2] | 0, - }); - }, - /** * @todo review * @private */ @@ -343,56 +134,35 @@ var WebsiteRoot = rootWidget.RootWidget.extend(ServiceProviderMixin, { }); }, /** - * @todo review - * @private - */ - _onWebsiteFormSubmit: function (ev) { - var $buttons = $(ev.currentTarget).find('button[type="submit"], a.a-submit'); - _.each($buttons, function (btn) { - var $btn = $(btn); - $btn.attr('data-loading-text', '<i class="fa fa-spinner fa-spin"></i> ' + $(btn).text()); - $btn.button('loading'); - }); - }, - /** - * Called when the root is notified that the button should be - * disabled after the first click. - * * @private * @param {Event} ev */ - _onDisableOnClick: function (ev) { - $(ev.currentTarget).addClass('disabled'); - }, - - /** - * Called when clicking on the multi-website switcher. - * - * @param {OdooEvent} ev - */ - _multiWebsiteSwitch: function (ev) { - var website_id_to_switch_to = ev.currentTarget.getAttribute('website-id'); + _onWebsiteSwitch: function (ev) { + var websiteID = ev.currentTarget.getAttribute('website-id'); // need to force in each case, even if domain is set // Website 1: localhost; Website 2: 0.0.0.0; website 3: - // when you switch 3 <--> 1, you need to force the website - var website_domain = ev.currentTarget.getAttribute('domain'); - var url = $.param.querystring(window.location.href, {'fw': website_id_to_switch_to}); - if (website_domain && window.location.hostname !== website_domain) { + var websiteDomain = ev.currentTarget.getAttribute('domain'); + var url = $.param.querystring(window.location.href, {fw: websiteID}); + if (websiteDomain && window.location.hostname !== websiteDomain) { // if domain unchanged, this line will do a nop while we need to refresh // the page to load the new forced website. url = new URL(url); - url.hostname = website_domain; + url.hostname = websiteDomain; } window.location.href = url; }, - - _multiCompanySwitch: function (ev) { - var company_id_to_switch_to = ev.currentTarget.getAttribute('company-id'); + /** + * @private + * @param {Event} ev + */ + _onCompanySwitch: function (ev) { + var companyID = parseInt(ev.currentTarget.getAttribute('company-id'), 10); this._rpc({model: 'res.users', method: 'write', - args: [odoo.session_info.user_id, {'company_id': parseInt(company_id_to_switch_to, 10)}], + args: [odoo.session_info.user_id, {'company_id': companyID}], }).then(function () { window.location.reload(true); }); |
