Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 7aa0fc6

Browse files
committed
remove useless redraw (because we insert 'commit' command)
+ perf when use 'commit'
1 parent 211640a commit 7aa0fc6

File tree

6 files changed

+85
-146
lines changed

6 files changed

+85
-146
lines changed

packages/bundle-odoo-website-editor/OdooWebsiteEditor.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ export class OdooWebsiteEditor extends JWEditor {
9191
constructor(options: OdooWebsiteEditorOptions) {
9292
super();
9393
class CustomPlugin extends JWPlugin {
94-
commands = options.customCommands;
94+
commands = Object.assign(
95+
{ commit: { handler: options.afterRender } },
96+
options.customCommands,
97+
);
9598
}
9699

97100
this.configure({
@@ -210,7 +213,6 @@ export class OdooWebsiteEditor extends JWEditor {
210213
['editable', ['main']],
211214
],
212215
location: options.location,
213-
afterRender: options.afterRender,
214216
});
215217
this.configure(DomEditable, {
216218
autoFocus: true,
@@ -237,7 +239,7 @@ export class OdooWebsiteEditor extends JWEditor {
237239
}
238240

239241
async render(): Promise<void> {
240-
const domLayout = this.plugins.get(DomLayout);
241-
return domLayout.redraw();
242+
// const domLayout = this.plugins.get(DomLayout);
243+
// return domLayout._redrawAfterCommand();
242244
}
243245
}

packages/plugin-dom-layout/src/ActionableDomObjectRenderer.ts

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@ export class ActionableDomObjectRenderer extends NodeRenderer<DomObject> {
1515
engine: DomObjectRenderingEngine;
1616
predicate: Predicate = ActionableNode;
1717

18+
actionableNodes = new Map<ActionableNode, HTMLElement>();
19+
20+
constructor(engine: DomObjectRenderingEngine) {
21+
super(engine);
22+
this.engine.editor.dispatcher.registerCommandHook(
23+
'commit',
24+
this._updateActionables.bind(this),
25+
);
26+
}
27+
1828
async render(button: ActionableNode): Promise<DomObjectActionable> {
19-
let updateButton: () => void;
2029
let handler: (ev: MouseEvent) => void;
2130
const objectButton: DomObjectActionable = {
2231
tag: 'BUTTON',
@@ -34,13 +43,11 @@ export class ActionableDomObjectRenderer extends NodeRenderer<DomObject> {
3443
objectButton.handler();
3544
};
3645
el.addEventListener('click', handler);
37-
updateButton = this._updateButton.bind(this, button, el);
38-
updateButton();
39-
this.engine.editor.dispatcher.registerCommandHook('*', updateButton);
46+
this.actionableNodes.set(button, el);
4047
},
4148
detach: (el: HTMLButtonElement): void => {
4249
el.removeEventListener('click', handler);
43-
this.engine.editor.dispatcher.removeCommandHook('*', updateButton);
50+
this.actionableNodes.delete(button);
4451
},
4552
};
4653
const attributes = button.modifiers.find(Attributes);
@@ -55,33 +62,38 @@ export class ActionableDomObjectRenderer extends NodeRenderer<DomObject> {
5562

5663
return objectButton;
5764
}
65+
5866
/**
5967
* Update button rendering after the command if the value of selected or
6068
* enabled change.
61-
*
62-
* @param button
63-
* @param element
6469
*/
65-
private _updateButton(button: ActionableNode, element: HTMLButtonElement): void {
66-
const editor = this.engine.editor;
67-
const select = !!button.selected(editor);
68-
const enable = !!button.enabled(editor);
70+
protected _updateActionables(): void {
71+
const commandNames = this.engine.editor.memoryInfo.commandNames;
72+
if (commandNames.length === 1 && commandNames.includes('insertText')) {
73+
// By default the actionable buttons are not update for a text insertion.
74+
return;
75+
}
76+
for (const [actionable, element] of this.actionableNodes) {
77+
const editor = this.engine.editor;
78+
const select = !!actionable.selected(editor);
79+
const enable = !!actionable.enabled(editor);
6980

70-
const attrSelected = element.getAttribute('aria-pressed');
71-
if (select.toString() !== attrSelected) {
72-
element.setAttribute('aria-pressed', select.toString());
73-
if (select) {
74-
element.classList.add('pressed');
75-
} else {
76-
element.classList.remove('pressed');
81+
const attrSelected = element.getAttribute('aria-pressed');
82+
if (select.toString() !== attrSelected) {
83+
element.setAttribute('aria-pressed', select.toString());
84+
if (select) {
85+
element.classList.add('pressed');
86+
} else {
87+
element.classList.remove('pressed');
88+
}
7789
}
78-
}
79-
const domEnable = !element.getAttribute('disabled');
80-
if (enable !== domEnable) {
81-
if (enable) {
82-
element.removeAttribute('disabled');
83-
} else {
84-
element.setAttribute('disabled', 'true');
90+
const domEnable = !element.getAttribute('disabled');
91+
if (enable !== domEnable) {
92+
if (enable) {
93+
element.removeAttribute('disabled');
94+
} else {
95+
element.setAttribute('disabled', 'true');
96+
}
8597
}
8698
}
8799
}

packages/plugin-dom-layout/src/ActionableGroupSelectItemDomObjectRenderer.ts

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,19 @@ export class ActionableGroupSelectItemDomObjectRenderer extends NodeRenderer<Dom
1717
engine: DomObjectRenderingEngine;
1818
predicate = (node: VNode): boolean => node.ancestors(ActionableGroupNode).length >= 2;
1919

20+
actionableNodes = new Map<ActionableNode, HTMLElement>();
21+
22+
constructor(engine: DomObjectRenderingEngine) {
23+
super(engine);
24+
this.engine.editor.dispatcher.registerCommandHook(
25+
'commit',
26+
this._updateActionables.bind(this),
27+
);
28+
}
29+
2030
async render(item: VNode): Promise<DomObject> {
2131
let domObject: DomObject;
2232
if (item instanceof ActionableNode) {
23-
let updateOption: () => void;
2433
let handler: (ev: Event) => void;
2534
const domObjectActionable: DomObjectActionable = {
2635
tag: 'OPTION',
@@ -43,14 +52,12 @@ export class ActionableGroupSelectItemDomObjectRenderer extends NodeRenderer<Dom
4352
}
4453
};
4554
select.addEventListener('change', handler);
46-
updateOption = this._updateOption.bind(this, item, el);
47-
updateOption();
48-
this.engine.editor.dispatcher.registerCommandHook('*', updateOption);
55+
this.actionableNodes.set(item, el);
4956
},
5057
detach: (el: HTMLOptionElement): void => {
5158
const select = el.closest('select') || el.parentElement;
5259
select.removeEventListener('change', handler);
53-
this.engine.editor.dispatcher.removeCommandHook('*', updateOption);
60+
this.actionableNodes.delete(item);
5461
},
5562
};
5663
domObject = domObjectActionable;
@@ -100,32 +107,40 @@ export class ActionableGroupSelectItemDomObjectRenderer extends NodeRenderer<Dom
100107
}
101108
return domObject;
102109
}
110+
103111
/**
104112
* Update option rendering after the command if the value of selected or
105113
* enabled change.
106114
*
107-
* @param button
115+
* @param aactionable
108116
* @param element
109117
*/
110-
private _updateOption(button: ActionableNode, element: HTMLOptionElement): void {
111-
const editor = this.engine.editor;
112-
const select = button.selected(editor);
113-
const enable = button.enabled(editor);
114-
const attrSelected = element.getAttribute('selected');
115-
if (select.toString() !== attrSelected) {
116-
if (select) {
117-
element.setAttribute('selected', 'true');
118-
element.closest('select').value = element.getAttribute('value');
119-
} else {
120-
element.removeAttribute('selected');
121-
}
118+
protected _updateActionables(): void {
119+
const commandNames = this.engine.editor.memoryInfo.commandNames;
120+
if (commandNames.length === 1 && commandNames.includes('insertText')) {
121+
// By default the actionable buttons are not update for a text insertion.
122+
return;
122123
}
123-
const domEnable = !element.getAttribute('disabled');
124-
if (enable !== domEnable) {
125-
if (enable) {
126-
element.removeAttribute('disabled');
127-
} else {
128-
element.setAttribute('disabled', 'true');
124+
for (const [aactionable, element] of this.actionableNodes) {
125+
const editor = this.engine.editor;
126+
const select = aactionable.selected(editor);
127+
const enable = aactionable.enabled(editor);
128+
const attrSelected = element.getAttribute('selected');
129+
if (select.toString() !== attrSelected) {
130+
if (select) {
131+
element.setAttribute('selected', 'true');
132+
element.closest('select').value = element.getAttribute('value');
133+
} else {
134+
element.removeAttribute('selected');
135+
}
136+
}
137+
const domEnable = !element.getAttribute('disabled');
138+
if (enable !== domEnable) {
139+
if (enable) {
140+
element.removeAttribute('disabled');
141+
} else {
142+
element.setAttribute('disabled', 'true');
143+
}
129144
}
130145
}
131146
}

packages/plugin-dom-layout/src/DomLayout.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export interface DomLayoutConfig extends JWPluginConfig {
3030
locations?: [ComponentId, DomLayoutLocation][];
3131
components?: ComponentDefinition[];
3232
componentZones?: [ComponentId, ZoneIdentifier[]][];
33-
afterRender?: Function;
3433
}
3534

3635
export class DomLayout<T extends DomLayoutConfig = DomLayoutConfig> extends JWPlugin<T> {
@@ -53,7 +52,7 @@ export class DomLayout<T extends DomLayoutConfig = DomLayoutConfig> extends JWPl
5352
domLocations: this._loadComponentLocations,
5453
};
5554
commandHooks = {
56-
'commit': this._redraw,
55+
'commit': this.redraw,
5756
};
5857

5958
constructor(editor: JWEditor, configuration: T) {
@@ -76,9 +75,6 @@ export class DomLayout<T extends DomLayoutConfig = DomLayoutConfig> extends JWPl
7675
this._loadComponentLocations(this.configuration.locations || []);
7776
domLayoutEngine.location = this.configuration.location;
7877
await domLayoutEngine.start();
79-
if (this.configuration.afterRender) {
80-
await this.configuration.afterRender();
81-
}
8278
window.addEventListener('keydown', this.processKeydown, true);
8379
}
8480
async stop(): Promise<void> {
@@ -137,7 +133,6 @@ export class DomLayout<T extends DomLayoutConfig = DomLayoutConfig> extends JWPl
137133
}
138134
}
139135
await domLayoutEngine.redraw(...nodes);
140-
await this.configuration.afterRender?.();
141136
}
142137
}
143138

packages/plugin-dom-layout/src/DomLayoutEngine.ts

Lines changed: 1 addition & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
ComponentDefinition,
77
} from '../../plugin-layout/src/LayoutEngine';
88
import { Renderer } from '../../plugin-renderer/src/Renderer';
9-
import { ZoneNode, ZoneIdentifier } from '../../plugin-layout/src/ZoneNode';
9+
import { ZoneNode } from '../../plugin-layout/src/ZoneNode';
1010
import { Direction, VSelectionDescription } from '../../core/src/VSelection';
1111
import { ContainerNode } from '../../core/src/VNodes/ContainerNode';
1212
import { DomSelectionDescription } from '../../plugin-dom-editable/src/EventNormalizer';
@@ -115,86 +115,6 @@ export class DomLayoutEngine extends LayoutEngine {
115115
getDomNodes(node: VNode): Node[] {
116116
return this._domReconciliationEngine.toDom(node);
117117
}
118-
/**
119-
* Redraw the layout component after insertion.
120-
* If the target zone is the root, prepare its location before redrawing.
121-
*
122-
* @override
123-
*/
124-
async prepend(componentId: ComponentId, zoneId: ZoneIdentifier, props?: {}): Promise<VNode[]> {
125-
const nodes = await super.prepend(componentId, zoneId, props);
126-
// Filter out children of nodes that we are already going to redraw.
127-
const nodeToRedraw = nodes.filter(node => !node.ancestor(n => nodes.includes(n)));
128-
for (const node of nodeToRedraw) {
129-
nodeToRedraw.push(...node.childVNodes);
130-
}
131-
// only used if the zone want to return a Node but hide the component (eg: a panel)
132-
// TODO: adapt when add memory
133-
await this.redraw(...nodeToRedraw);
134-
return nodes;
135-
}
136-
/**
137-
* Redraw the layout component after insertion.
138-
* If the target zone is the root, prepare its location before redrawing.
139-
*
140-
* @override
141-
*/
142-
async append(componentId: ComponentId, zoneId: ZoneIdentifier, props?: {}): Promise<VNode[]> {
143-
const nodes = await super.append(componentId, zoneId, props);
144-
// Filter out children of nodes that we are already going to redraw.
145-
const nodeToRedraw = nodes.filter(node => !node.ancestor(n => nodes.includes(n)));
146-
for (const node of nodeToRedraw) {
147-
nodeToRedraw.push(...node.childVNodes);
148-
}
149-
// only used if the zone want to return a Node but hide the component (eg: a panel)
150-
// TODO: adapt when add memory
151-
await this.redraw(...nodeToRedraw);
152-
return nodes;
153-
}
154-
/**
155-
* Redraw the layout component after removal.
156-
*
157-
* @override
158-
*/
159-
async remove(componentId: ComponentId): Promise<ZoneNode[]> {
160-
const zones = await super.remove(componentId);
161-
// TODO: adapt when add memory
162-
await this.redraw(...zones);
163-
return zones;
164-
}
165-
/**
166-
* Redraw the layout component after showing the component.
167-
*
168-
* @override
169-
*/
170-
async show(componentId: ComponentId): Promise<VNode[]> {
171-
const nodes = await super.show(componentId);
172-
const nodeToRedraw = [...nodes];
173-
for (const node of nodeToRedraw) {
174-
nodeToRedraw.push(...node.childVNodes);
175-
}
176-
for (const node of nodes) {
177-
nodeToRedraw.push(node.ancestor(ZoneNode));
178-
}
179-
// TODO: adapt when add memory
180-
await this.redraw(...nodeToRedraw);
181-
return nodes;
182-
}
183-
/**
184-
* Redraw the layout component after hidding the component.
185-
*
186-
* @override
187-
*/
188-
async hide(componentId: ComponentId): Promise<VNode[]> {
189-
const nodes = await super.hide(componentId);
190-
const nodeToRedraw = [...nodes];
191-
for (const node of nodes) {
192-
nodeToRedraw.push(node.ancestor(ZoneNode));
193-
}
194-
// TODO: adapt when add memory
195-
await this.redraw(...nodeToRedraw);
196-
return nodes;
197-
}
198118
async redraw(...nodes: VNode[]): Promise<void> {
199119
if (
200120
!this.editor.enableRender ||

packages/plugin-theme/src/Theme.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { ThemeNode } from './ThemeNode';
1111
import { ZoneNode } from '../../plugin-layout/src/ZoneNode';
1212
import { ActionableGroupNode } from '../../plugin-layout/src/ActionableGroupNode';
1313
import { ActionableNode } from '../../plugin-layout/src/ActionableNode';
14-
import { DomLayoutEngine } from '../../plugin-dom-layout/src/DomLayoutEngine';
1514
import { VElement } from '../../core/src/VNodes/VElement';
1615

1716
interface ThemeComponent extends ComponentDefinition {
@@ -103,10 +102,6 @@ export class Theme<T extends ThemeConfig = ThemeConfig> extends JWPlugin<T> {
103102
const ancestor = this.editor.selection.anchor.ancestor(ThemeNode);
104103
if (ancestor) {
105104
ancestor.themeName = params.theme;
106-
107-
// TODO: remove this redraw when memory send the nodes to redraw into domLayout
108-
const domEngine = this.editor.plugins.get(Layout).engines.dom as DomLayoutEngine;
109-
await domEngine.redraw(ancestor);
110105
}
111106
}
112107
}

0 commit comments

Comments
 (0)