[FIX] web: register template of dynamic classes once
Before this commit, the template of some dynamic classes (usually as WOWL to legacyAdapters) were registered at each definition of the class which is potentially at every doAction/switchView After this commit, they are all registered only once, as early as possible. closes odoo/odoo#72476 Related: odoo/enterprise#19199 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
@@ -13,6 +13,8 @@ import { cleanDomFromBootstrap, wrapSuccessOrFail, mapDoActionOptionAPI } from "
|
||||
|
||||
const { Component, tags } = owl;
|
||||
|
||||
const warningDialogBodyTemplate = tags.xml`<t t-esc="props.message"/>`;
|
||||
|
||||
class ActionAdapter extends ComponentAdapter {
|
||||
setup() {
|
||||
super.setup();
|
||||
@@ -95,7 +97,7 @@ class ActionAdapter extends ComponentAdapter {
|
||||
this.title = this.props.title;
|
||||
}
|
||||
}
|
||||
WarningDialog.bodyTemplate = tags.xml`<t t-esc="props.message"/>`;
|
||||
WarningDialog.bodyTemplate = warningDialogBodyTemplate;
|
||||
this.dialogs.add(WarningDialog, {
|
||||
title: payload.title,
|
||||
message: payload.message,
|
||||
|
||||
@@ -16,6 +16,8 @@ odoo.define('web.OwlCompatibility', function () {
|
||||
const widgetSymbol = odoo.widgetSymbol;
|
||||
const children = new WeakMap(); // associates legacy widgets with their Owl children
|
||||
|
||||
const templateForLegacy = tags.xml`<div/>`;
|
||||
const templateForOwl = tags.xml`<t t-component="props.Component" t-props="childProps" />`;
|
||||
/**
|
||||
* Case 1) An Owl component has to instantiate legacy widgets
|
||||
* ----------------------------------------------------------
|
||||
@@ -85,15 +87,9 @@ odoo.define('web.OwlCompatibility', function () {
|
||||
}
|
||||
let template;
|
||||
if (!(props.Component.prototype instanceof Component)) {
|
||||
template = tags.xml`<div/>`;
|
||||
template = templateForLegacy;
|
||||
} else {
|
||||
let propsStr = '';
|
||||
for (let p in props) {
|
||||
if (p !== 'Component') {
|
||||
propsStr += ` ${p}="props.${p}"`;
|
||||
}
|
||||
}
|
||||
template = tags.xml`<t t-component="props.Component"${propsStr}/>`;
|
||||
template = templateForOwl;
|
||||
}
|
||||
ComponentAdapter.template = template;
|
||||
super(...arguments);
|
||||
@@ -103,6 +99,14 @@ odoo.define('web.OwlCompatibility', function () {
|
||||
this.widget = null; // widget instance, if Component is a legacy widget
|
||||
}
|
||||
|
||||
get childProps() {
|
||||
if (!this._childProps) {
|
||||
this._childProps = Object.assign({}, this.props);
|
||||
delete this._childProps.Component;
|
||||
}
|
||||
return this._childProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the legacy widget (not in the DOM yet)
|
||||
*
|
||||
|
||||
@@ -11,6 +11,11 @@ import { breadcrumbsToLegacy } from "./utils";
|
||||
const { Component, hooks, tags } = owl;
|
||||
const actionRegistry = registry.category("actions");
|
||||
|
||||
const legacyClientActionTemplate = tags.xml`
|
||||
<ClientActionAdapter Component="Widget" widgetArgs="widgetArgs" widget="widget"
|
||||
onReverseBreadcrumb="onReverseBreadcrumb" t-ref="controller"
|
||||
t-on-scrollTo.stop="onScrollTo"/>`;
|
||||
|
||||
// registers an action from the legacy action registry to the wowl one, ensuring
|
||||
// that widget actions are actually Components
|
||||
function registerClientAction(name, action) {
|
||||
@@ -44,11 +49,7 @@ function registerClientAction(name, action) {
|
||||
};
|
||||
}
|
||||
}
|
||||
Action.template = tags.xml`
|
||||
<ClientActionAdapter Component="Widget" widgetArgs="widgetArgs" widget="widget"
|
||||
onReverseBreadcrumb="onReverseBreadcrumb" t-ref="controller"
|
||||
t-on-scrollTo.stop="onScrollTo"/>
|
||||
`;
|
||||
Action.template = legacyClientActionTemplate;
|
||||
Action.components = { ClientActionAdapter };
|
||||
Action.isLegacy = true;
|
||||
Action.target = action.prototype.target;
|
||||
|
||||
@@ -18,6 +18,11 @@ function getJsClassWidget(fieldsInfo) {
|
||||
return legacyViewRegistry.get(key);
|
||||
}
|
||||
|
||||
const legacyViewTemplate = tags.xml`
|
||||
<ViewAdapter Component="Widget" View="View" viewInfo="viewInfo" viewParams="viewParams"
|
||||
widget="widget" onReverseBreadcrumb="onReverseBreadcrumb" t-ref="controller"
|
||||
t-on-scrollTo.stop="onScrollTo"/>`;
|
||||
|
||||
// registers a view from the legacy view registry to the wowl one, but wrapped
|
||||
// into an Owl Component
|
||||
function registerView(name, LegacyView) {
|
||||
@@ -106,7 +111,7 @@ function registerView(name, LegacyView) {
|
||||
.map(([vid, vtype]) => {
|
||||
const view = this.props.viewSwitcherEntries.find((v) => v.type === vtype);
|
||||
if (view) {
|
||||
return Object.assign({}, view, {viewID: vid});
|
||||
return Object.assign({}, view, { viewID: vid });
|
||||
} else {
|
||||
return {
|
||||
viewID: vid,
|
||||
@@ -122,12 +127,8 @@ function registerView(name, LegacyView) {
|
||||
});
|
||||
}
|
||||
}
|
||||
Controller.template = legacyViewTemplate;
|
||||
|
||||
Controller.template = tags.xml`
|
||||
<ViewAdapter Component="Widget" View="View" viewInfo="viewInfo" viewParams="viewParams"
|
||||
widget="widget" onReverseBreadcrumb="onReverseBreadcrumb" t-ref="controller"
|
||||
t-on-scrollTo.stop="onScrollTo"/>
|
||||
`;
|
||||
Controller.components = { ViewAdapter };
|
||||
Controller.display_name = LegacyView.prototype.display_name;
|
||||
Controller.icon = LegacyView.prototype.icon;
|
||||
|
||||
@@ -20,6 +20,8 @@ const legacySystrayMenuItems = legacySystrayMenu.Items;
|
||||
const convertedItems = [];
|
||||
let id = 1;
|
||||
|
||||
const legacySystrayItemTemplate = tags.xml`<SystrayItemAdapter Component="Widget" />`;
|
||||
|
||||
function addSystrayItem(Widget) {
|
||||
const name = `_legacy_systray_item_${id++}`;
|
||||
|
||||
@@ -29,7 +31,7 @@ function addSystrayItem(Widget) {
|
||||
this.Widget = Widget;
|
||||
}
|
||||
}
|
||||
SystrayItem.template = tags.xml`<SystrayItemAdapter Component="Widget" />`;
|
||||
SystrayItem.template = legacySystrayItemTemplate;
|
||||
SystrayItem.components = { SystrayItemAdapter };
|
||||
|
||||
systrayRegistry.add(name, { Component: SystrayItem }, { sequence: Widget.prototype.sequence });
|
||||
|
||||
@@ -69,6 +69,13 @@ export class InvalidButtonParamsError extends Error {}
|
||||
// regex that matches context keys not to forward from an action to another
|
||||
const CTX_KEY_REGEX = /^(?:(?:default_|search_default_|show_).+|.+_view_ref|group_by|group_by_no_leaf|active_id|active_ids|orderedBy)$/;
|
||||
|
||||
// only register this template once for all dynamic classes ControllerComponent
|
||||
const ControllerComponentTemplate = tags.xml`<t t-component="Component" t-props="props"
|
||||
registerCallback="registerCallback"
|
||||
t-ref="component"
|
||||
t-on-history-back="onHistoryBack"
|
||||
t-on-controller-title-updated.stop="onTitleUpdated"/>`;
|
||||
|
||||
function makeActionManager(env) {
|
||||
const keepLast = new KeepLast();
|
||||
let id = 0;
|
||||
@@ -525,13 +532,7 @@ function makeActionManager(env) {
|
||||
controller.title = ev.detail;
|
||||
}
|
||||
}
|
||||
|
||||
ControllerComponent.template = tags.xml`<t t-component="Component" t-props="props"
|
||||
registerCallback="registerCallback"
|
||||
t-ref="component"
|
||||
t-on-history-back="onHistoryBack"
|
||||
t-on-controller-title-updated.stop="onTitleUpdated"/>`;
|
||||
|
||||
ControllerComponent.template = ControllerComponentTemplate;
|
||||
ControllerComponent.Component = controller.Component;
|
||||
|
||||
let nextDialog = {};
|
||||
|
||||
Reference in New Issue
Block a user