From 36bd5b1699d16b27e34ee00f331ba40f89b24648 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Thu, 3 Mar 2022 14:40:45 +0000 Subject: [PATCH] [IMP] web: allow to access wowl services in legacy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces the "useWowlService" hook. This hook allows Owl components that use the legacy env (not the one of the webclient for instance, typically called the "wowl" env) to access services from the wowl env. Its API is the same as the classical "useService" hook. closes odoo/odoo#85769 Signed-off-by: Géry Debongnie --- addons/web/static/lib/owl/owl.js | 5 +-- addons/web/static/src/legacy/utils.js | 22 +++++++++++++ .../tests/legacy/owl_compatibility_tests.js | 33 +++++++++++++++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/addons/web/static/lib/owl/owl.js b/addons/web/static/lib/owl/owl.js index 3f2c7825867..f23bdf2383a 100644 --- a/addons/web/static/lib/owl/owl.js +++ b/addons/web/static/lib/owl/owl.js @@ -5132,8 +5132,9 @@ See https://github.com/odoo/owl/blob/${hash}/doc/reference/app.md#configuration if (this.dev && !config.test) { console.info(DEV_MSG()); } - const descrs = Object.getOwnPropertyDescriptors(config.env || {}); - this.env = Object.freeze(Object.defineProperties({}, descrs)); + const env = config.env || {}; + const descrs = Object.getOwnPropertyDescriptors(env); + this.env = Object.freeze(Object.create(Object.getPrototypeOf(env), descrs)); this.props = config.props || {}; } mount(target, options) { diff --git a/addons/web/static/src/legacy/utils.js b/addons/web/static/src/legacy/utils.js index 4f888affb44..0f52fde1505 100644 --- a/addons/web/static/src/legacy/utils.js +++ b/addons/web/static/src/legacy/utils.js @@ -9,6 +9,11 @@ import { ConnectionLostError, } from "../core/network/rpc_service"; import { ErrorDialog } from "../core/errors/error_dialogs"; +import { useService } from "@web/core/utils/hooks"; + +const { useComponent } = owl; + +const wowlServicesSymbol = Symbol("wowlServices"); export function makeLegacyRpcService(legacyEnv) { return { @@ -136,6 +141,9 @@ export function makeLegacySessionService(legacyEnv, session) { } export function mapLegacyEnvToWowlEnv(legacyEnv, wowlEnv) { + // store wowl services on the legacy env (used by the 'useWowlService' hook) + legacyEnv[wowlServicesSymbol] = wowlEnv.services; + // rpc legacyEnv.session.rpc = (...args) => { let rejection; @@ -332,3 +340,17 @@ export function useLegacyRefs() { return legacyRefs; } + +/** + * This hook allows legacy owl Components to use services coming from the wowl env. + * @param {string} serviceName + * @returns {any} + */ +export function useWowlService(serviceName) { + const component = useComponent(); + const env = component.env; + component.env = { services: env[wowlServicesSymbol] }; + const service = useService(serviceName); + component.env = env; + return service; +} diff --git a/addons/web/static/tests/legacy/owl_compatibility_tests.js b/addons/web/static/tests/legacy/owl_compatibility_tests.js index ca45449b7e0..bf986ff212e 100644 --- a/addons/web/static/tests/legacy/owl_compatibility_tests.js +++ b/addons/web/static/tests/legacy/owl_compatibility_tests.js @@ -12,15 +12,20 @@ odoo.define('web.OwlCompatibilityTests', function (require) { } = require('web.OwlCompatibility'); const testUtils = require('web.test_utils'); const Widget = require('web.Widget'); + const { registry } = require("@web/core/registry"); const { LegacyComponent } = require("@web/legacy/legacy_component"); + const { mapLegacyEnvToWowlEnv, useWowlService } = require("@web/legacy/utils"); + + const makeTestEnvironment = require("web.test_env"); + const { makeTestEnv } = require("@web/../tests/helpers/mock_env"); + const { getFixture, mount, useLogLifeCycle, destroy } = require("@web/../tests/helpers/utils"); const makeTestPromise = testUtils.makeTestPromise; const nextTick = testUtils.nextTick; const addMockEnvironmentOwl = testUtils.mock.addMockEnvironmentOwl; - const { mount, useLogLifeCycle, destroy } = require("@web/../tests/helpers/utils"); - const { + Component, onError, onMounted, onWillDestroy, @@ -1658,5 +1663,29 @@ odoo.define('web.OwlCompatibilityTests', function (require) { delete fieldRegistry.map.pad_like; delete widgetRegistry.map.widget_comp; }); + + QUnit.module("useWowlService"); + + QUnit.test("simple use case of useWowlService", async function (assert) { + assert.expect(1); + + registry.category("services").add("test", { + start() { + return "I'm a wowl service"; + }, + }); + const wowlEnv = await makeTestEnv(); + const legacyEnv = makeTestEnvironment(); + mapLegacyEnvToWowlEnv(legacyEnv, wowlEnv); + + class MyComponent extends Component { + setup() { + assert.strictEqual(useWowlService("test"), "I'm a wowl service"); + } + } + MyComponent.template = xml`
`; + + await mount(MyComponent, getFixture(), { env: legacyEnv }); + }); }); });