[IMP] web: introduce LegacyComponent
This commit introduces LegacyComponent and removes patches on Component. LegacyComponent is used instead of Component when the component uses features from owl 1 like getting its `el` or `trigger` an event. Part-of: odoo/odoo#85389
This commit is contained in:
@@ -361,6 +361,7 @@ This module provides the core of the Odoo Web Client.
|
||||
'web/static/lib/owl/owl.js',
|
||||
'web/static/src/owl2_compatibility/*.js',
|
||||
'web/static/src/legacy/js/component_extension.js',
|
||||
'web/static/src/legacy/legacy_component.js',
|
||||
'web/static/lib/jquery/jquery.js',
|
||||
'web/static/lib/jquery.ui/jquery-ui.js',
|
||||
'web/static/lib/jquery/jquery.browser.js',
|
||||
|
||||
@@ -1,45 +1,10 @@
|
||||
(function () {
|
||||
|
||||
const { Component } = owl;
|
||||
owl.Component.env = {};
|
||||
|
||||
/**
|
||||
* Symbol used in ComponentWrapper to redirect Owl events to Odoo legacy
|
||||
* events.
|
||||
*/
|
||||
odoo.widgetSymbol = Symbol('widget');
|
||||
|
||||
/**
|
||||
* Add a new method to owl Components to ensure that no performed RPC is
|
||||
* resolved/rejected when the component is destroyed.
|
||||
*/
|
||||
Component.prototype.rpc = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.env.services.rpc(...arguments)
|
||||
.then(result => {
|
||||
if (owl.status(this) !== "destroyed") {
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
.catch(reason => {
|
||||
if (owl.status(this) !== "destroyed") {
|
||||
reject(reason);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Patch Component.__trigger method to call a hook that adds a listener
|
||||
* for the triggered event just before triggering it. This is useful if
|
||||
* there are legacy widgets in the ancestors. In that case, there would be
|
||||
* a widgetSymbol key in the environment, corresponding to the hook to call
|
||||
* (see ComponentWrapper).
|
||||
*/
|
||||
const originalTrigger = owl.Component.prototype.__trigger;
|
||||
Component.prototype.__trigger = function (evType, payload) {
|
||||
if (this.env[odoo.widgetSymbol]) {
|
||||
this.env[odoo.widgetSymbol](evType);
|
||||
}
|
||||
originalTrigger.call(this, evType, payload);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* This component SHOULD NOT be used!
|
||||
* It's used in legacy when components should work like in owl 1.
|
||||
*
|
||||
* If you need to get the component's `el` then use `useRef`
|
||||
* and if you need to send info to the component's parent then use props.
|
||||
*
|
||||
* e.g.
|
||||
* // OWL 1
|
||||
* class Component_OWL1 extends owl.Component {
|
||||
* static template = owl.tags.xml`
|
||||
* <button t-on-click="() => this.trigger('up')">click me</button>
|
||||
* `;
|
||||
* mounted() {
|
||||
* this.el.style = "color: red";
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // OWL 2
|
||||
* class Component_OWL2 extends owl.Component {
|
||||
* static template = owl.xml`
|
||||
* <button t-ref="btn" t-on-click="() => props.up()">click me</button>
|
||||
* `;
|
||||
* setup() {
|
||||
* this.btnRef = useRef("btn");
|
||||
* owl.onMounted(() => {
|
||||
* this.btnRef.el.style = "color: red";
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
export class LegacyComponent extends owl.Component {
|
||||
get el() {
|
||||
const bdom = this.__owl__.bdom;
|
||||
if (!bdom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hasOwnProperty.call(bdom, "component")) {
|
||||
return bdom.component.el;
|
||||
} else {
|
||||
return bdom.firstNode();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add a new method to owl Components to ensure that no performed RPC is
|
||||
* resolved/rejected when the component is destroyed.
|
||||
*/
|
||||
rpc() {
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.env.services
|
||||
.rpc(...arguments)
|
||||
.then((result) => {
|
||||
if (owl.status(this) !== "destroyed") {
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
.catch((reason) => {
|
||||
if (owl.status(this) !== "destroyed") {
|
||||
reject(reason);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a custom event of type 'eventType' with the given 'payload' on the
|
||||
* component's el, if it exists. However, note that the event will only bubble
|
||||
* up to the parent DOM nodes. Thus, it must be called between mounted() and
|
||||
* willUnmount().
|
||||
*/
|
||||
trigger(eventType, payload) {
|
||||
this.__trigger(eventType, payload);
|
||||
}
|
||||
/**
|
||||
* Private trigger method, allows to choose the component which triggered
|
||||
* the event in the first place
|
||||
*/
|
||||
__trigger(eventType, payload) {
|
||||
if (this.env[odoo.widgetSymbol]) {
|
||||
this.env[odoo.widgetSymbol](eventType);
|
||||
}
|
||||
if (this.el) {
|
||||
const ev = new CustomEvent(eventType, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: payload,
|
||||
});
|
||||
this.el.dispatchEvent(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
(function () {
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
owl.Component = class extends owl.Component {
|
||||
get el() {
|
||||
const bdom = this.__owl__.bdom;
|
||||
if (!bdom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hasOwnProperty.call(bdom, "component")) {
|
||||
return bdom.component.el;
|
||||
} else {
|
||||
return bdom.firstNode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a custom event of type 'eventType' with the given 'payload' on the
|
||||
* component's el, if it exists. However, note that the event will only bubble
|
||||
* up to the parent DOM nodes. Thus, it must be called between mounted() and
|
||||
* willUnmount().
|
||||
*/
|
||||
trigger(eventType, payload) {
|
||||
this.__trigger(eventType, payload);
|
||||
}
|
||||
/**
|
||||
* Private trigger method, allows to choose the component which triggered
|
||||
* the event in the first place
|
||||
*/
|
||||
__trigger(eventType, payload) {
|
||||
if (this.el) {
|
||||
const ev = new CustomEvent(eventType, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: payload,
|
||||
});
|
||||
this.el.dispatchEvent(ev);
|
||||
}
|
||||
}
|
||||
};
|
||||
owl.Component.env = {};
|
||||
})();
|
||||
Reference in New Issue
Block a user