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

add test for perf #278

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions examples/layout/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,20 @@ editor.configure(Theme, {
.get(Parser)
.parse(
'text/html',
`<div style="background: lightblue; height: 100%;"><t-placeholder/></div>`,
`<div style="background: lightblue; min-height: 100%;"><t-placeholder/></div>`,
);
},
},
{
id: 'iframe',
label: 'Theme color red in iframe',
render: async (editor: JWEditor): Promise<VNode[]> => {
return editor.plugins
.get(Parser)
.parse(
'text/html',
`<t-iframe style="border: 0; width: 100%;"><div style="background: #ffaaaa; height: 100%;"><t-placeholder/></div></t-iframe>`,
);
return editor.plugins.get(Parser).parse(
'text/html',
`<t-iframe style="border-width: 80px 14px 40px; border-radius: 16px; border-style: solid; border-color: #000; background-color: white; width: 400px; height: 600px; margin: auto; display: block;">
<div style="background: #ffaaaa; min-height: 100%;"><t-placeholder/></div>
</t-iframe>`,
);
},
},
],
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"dev": "webpack-dev-server --config webpack-examples.config.js",
"build": "rm -rf build/examples; mkdir -p build/examples/; cp -r ./examples ./build; webpack --config webpack-examples.config.js",
"build-odoo": "rm -rf build/examples; mkdir -p build/examples/; cp -r ./examples ./build; webpack --config webpack-odoo.config.js",
"perf": "karma start --include-files test/**/*.perf.ts",
"coverage": "karma start --coverage",
"debug": "karma start --no-browsers --debug",
"test": "karma start"
"perf": "karma start --include-files **/*.perf.ts",
"coverage": "karma start --coverage --include-files **/*.test.ts",
"debug": "karma start --no-browsers --debug --include-files **/*.test.ts",
"test": "karma start --include-files **/*.test.ts"
},
"repository": {
"type": "git",
Expand Down
3 changes: 3 additions & 0 deletions packages/bundle-basic-editor/BasicEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { BackgroundColor } from '../../packages/plugin-backgroundcolor/src/Backg
import { Layout } from '../../packages/plugin-layout/src/Layout';
import { DomLayout } from '../../packages/plugin-dom-layout/src/DomLayout';
import { DomEditable } from '../../packages/plugin-dom-editable/src/DomEditable';
import { History } from '../../packages/plugin-history/src/History';
import { VNode } from '../../packages/core/src/VNodes/VNode';
import { Input } from '../../packages/plugin-input/src/Input';
import { Dialog } from '../../packages/plugin-dialog/src/Dialog';
Expand Down Expand Up @@ -64,6 +65,7 @@ export class BasicEditor extends JWEditor {
[Html],
[DomLayout],
[DomEditable],
[History],
[Inline],
[Char],
[LineBreak],
Expand Down Expand Up @@ -146,6 +148,7 @@ export class BasicEditor extends JWEditor {
['OrderedListButton', 'UnorderedListButton', 'ChecklistButton'],
['IndentButton', 'OutdentButton'],
['LinkButton', 'UnlinkButton'],
['UndoButton', 'RedoButton'],
],
});
}
Expand Down
11 changes: 4 additions & 7 deletions packages/bundle-odoo-website-editor/OdooWebsiteEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ export class OdooWebsiteEditor extends JWEditor {
constructor(options: OdooWebsiteEditorOptions) {
super();
class CustomPlugin extends JWPlugin {
commands = options.customCommands;
commands = Object.assign(
{ commit: { handler: options.afterRender } },
options.customCommands,
);
}

this.configure({
Expand Down Expand Up @@ -219,7 +222,6 @@ export class OdooWebsiteEditor extends JWEditor {
['editable', ['main']],
],
location: options.location,
afterRender: options.afterRender,
});
this.configure(DomEditable, {
autoFocus: true,
Expand All @@ -244,9 +246,4 @@ export class OdooWebsiteEditor extends JWEditor {
const nodes = await renderer.render<Node[]>('dom/html', editable);
return nodes && nodes[0];
}

async render(): Promise<void> {
const domLayout = this.plugins.get(DomLayout);
return domLayout.redraw();
}
}
3 changes: 1 addition & 2 deletions packages/bundle-odoo-website-editor/odoo-integration.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BasicEditor } from '../bundle-basic-editor/BasicEditor';
import { DevTools } from '../plugin-devtools/src/DevTools';
import { OdooWebsiteEditor } from './OdooWebsiteEditor';
import { VRange, withRange } from '../core/src/VRange';
import { VRange } from '../core/src/VRange';
import { DomLayoutEngine } from '../plugin-dom-layout/src/DomLayoutEngine';
import { Layout } from '../plugin-layout/src/Layout';
import { Renderer } from '../plugin-renderer/src/Renderer';
Expand All @@ -27,7 +27,6 @@ export {
DomLayoutEngine,
Renderer,
ImageNode,
withRange,
VRange,
InlineNode,
LinkFormat,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/Core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class Core<T extends JWPluginConfig = JWPluginConfig> extends JWPlugin<T>
range.mode.is(range.startContainer, RuleProperty.EDITABLE)
) {
// Otherwise set range start at previous valid leaf.
let ancestor = range.start.parent;
let ancestor: VNode = range.start.parent;
while (
ancestor &&
range.mode.is(ancestor, RuleProperty.BREAKABLE) &&
Expand Down Expand Up @@ -129,7 +129,7 @@ export class Core<T extends JWPluginConfig = JWPluginConfig> extends JWPlugin<T>
range.mode.is(range.endContainer, RuleProperty.EDITABLE)
) {
// Otherwise set range end at next valid leaf.
let ancestor = range.end.parent;
let ancestor: VNode = range.end.parent;
while (
ancestor &&
range.mode.is(ancestor, RuleProperty.BREAKABLE) &&
Expand Down
134 changes: 114 additions & 20 deletions packages/core/src/JWEditor.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Dispatcher } from './Dispatcher';
import { Dispatcher, CommandParams } from './Dispatcher';
import { JWPlugin, JWPluginConfig } from './JWPlugin';
import { Core } from './Core';
import { ContextManager } from './ContextManager';
import { VSelection } from './VSelection';
import { VRange } from './VRange';
import { isConstructor } from '../../utils/src/utils';
import { Keymap } from '../../plugin-keymap/src/Keymap';
import { StageError } from '../../utils/src/errors';
import { ContainerNode } from './VNodes/ContainerNode';
import { AtomicNode } from './VNodes/AtomicNode';
import { SeparatorNode } from './VNodes/SeparatorNode';
import { ModeIdentifier, ModeDefinition, Mode } from './Mode';
import { Memory, ChangesLocations } from './Memory/Memory';
import { makeVersionable } from './Memory/Versionable';
import { VersionableArray } from './Memory/VersionableArray';
import { Point } from './VNodes/VNode';

export enum EditorStage {
CONFIGURATION = 'configuration',
Expand All @@ -26,9 +31,13 @@ export type Loadables<T extends JWPlugin = JWPlugin> = {
};

type Commands<T extends JWPlugin> = Extract<keyof T['commands'], string>;
type CommandParams<T extends JWPlugin, K extends string> = K extends Commands<T>
type CommandParamsType<T extends JWPlugin, K extends string> = K extends Commands<T>
? Parameters<T['commands'][K]['handler']>[0]
: never;
export interface CommitParams extends CommandParams {
changesLocations: ChangesLocations;
commandNames: string[];
}

export interface JWEditorConfig {
/**
Expand Down Expand Up @@ -68,7 +77,10 @@ export class JWEditor {
plugins: [],
loadables: {},
};
selection = new VSelection(this);
memory: Memory;
memoryInfo: { commandNames: string[] };
private _memoryID = 0;
selection: VSelection;
loaders: Record<string, Loader> = {};
private mutex = Promise.resolve();
// Use a set so that when asynchronous functions are called we ensure that
Expand All @@ -86,6 +98,7 @@ export class JWEditor {
constructor() {
this.dispatcher = new Dispatcher(this);
this.plugins = new Map();
this.selection = new VSelection(this);
this.contextManager = new ContextManager(this);

this.nextEventMutex = this.nextEventMutex.bind(this);
Expand Down Expand Up @@ -130,9 +143,18 @@ export class JWEditor {
this.setMode(this.configuration.mode);
}

for (const plugin of this.plugins.values()) {
await plugin.start();
}
// create memory
this.memoryInfo = makeVersionable({ commandNames: [] });
this.memory = new Memory();
this.memory.attach(this.memoryInfo);
this.memory.create(this._memoryID.toString());

// Start all plugins in the first memory slice.
return this.execCommand(async () => {
for (const plugin of this.plugins.values()) {
await plugin.start();
}
});
}

//--------------------------------------------------------------------------
Expand Down Expand Up @@ -303,13 +325,12 @@ export class JWEditor {
}
}

async execBatch(callback: () => Promise<void>): Promise<void> {
this.preventRenders.add(callback);
await callback();
this.preventRenders.delete(callback);
await this.dispatcher.dispatchHooks('@batch');
}

/**
* Execute arbitrary code in `callback`, then dispatch the commit event.
*
* @param callback
*/
async execCommand(callback: () => Promise<void> | void): Promise<void>;
/**
* Execute the given command.
*
Expand All @@ -318,28 +339,101 @@ export class JWEditor {
*/
async execCommand<P extends JWPlugin, C extends Commands<P> = Commands<P>>(
commandName: C,
params?: CommandParams<P, C>,
params?: CommandParamsType<P, C>,
): Promise<void>;
/**
* Execute the command or arbitrary code in `callback` in memory.
*
* TODO: create memory for each plugin who use the command then use
* squashInto(winnerSliceKey, winnerSliceKey, newMasterSliceKey)
*
* @param commandName name identifier of the command to execute or callback
* @param params arguments object of the command to execute
*/
async execCommand<P extends JWPlugin, C extends Commands<P> = Commands<P>>(
commandName: C | (() => Promise<void> | void),
params?: CommandParamsType<P, C>,
): Promise<void> {
return await this.dispatcher.dispatch(commandName, params);
const isFrozen = this.memory.isFrozen();

let memorySlice: string;
if (isFrozen) {
// Switch to the next memory slice (unfreeze the memory).
memorySlice = this._memoryID.toString();
this.memory.switchTo(memorySlice);
this.memoryInfo.commandNames = new VersionableArray();
}

// Execute command.
if (typeof commandName === 'function') {
this.memoryInfo.commandNames.push('@custom');
await commandName();
} else {
this.memoryInfo.commandNames.push(commandName);
await this.dispatcher.dispatch(commandName, params);
}

if (isFrozen) {
// Check if it's frozen for calling execCommand inside a call of
// execCommand Create the next memory slice (and freeze the
// current memory).
this._memoryID++;
const nextMemorySlice = this._memoryID.toString();
this.memory.create(nextMemorySlice);

// Send the commit message with a froozen memory.
const changesLocations = this.memory.getChangesLocations(
memorySlice,
this.memory.sliceKey,
);
await this.dispatcher.dispatchHooks('@commit', {
changesLocations: changesLocations,
commandNames: this.memoryInfo.commandNames,
});
}
}

/**
* Execute arbitrary code in `callback`, then dispatch the event.
* Create a temporary range corresponding to the given boundary points and
* call the given callback with the newly created range as argument. The
* range is automatically destroyed after calling the callback.
*
* @param bounds The points corresponding to the range boundaries.
* @param callback The callback to call with the newly created range.
* @param mode
*/
async execCustomCommand<P extends JWPlugin, C extends Commands<P> = Commands<P>>(
callback: () => Promise<void>,
async withRange(
bounds: [Point, Point],
callback: (range: VRange) => Promise<void> | void,
mode?: Mode,
): Promise<void> {
await callback();
await this.dispatcher.dispatchHooks('@custom');
return this.execCommand(async () => {
this.memoryInfo.commandNames.push('@withRange');
const range = new VRange(this, bounds, mode);
await callback(range);
range.remove();
});
}

/**
* Stop this editor instance.
*/
async stop(): Promise<void> {
if (this.memory) {
this.memory.create('stop');
this.memory.switchTo('stop'); // Unfreeze the memory.
}
for (const plugin of this.plugins.values()) {
await plugin.stop();
}
if (this.memory) {
this.memory.create('stopped'); // Freeze the memory.
this.memory = null;
}
this.plugins.clear();
this.dispatcher = new Dispatcher(this);
this.selection = new VSelection(this);
this.contextManager = new ContextManager(this);
// Clear loaders.
this.loaders = {};
this._stage = EditorStage.CONFIGURATION;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/JWPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export class JWPlugin<T extends JWPluginConfig = {}> {
async stop(): Promise<void> {
// This is where plugins can do asynchronous work when the editor is
// stopping (e.g. save on a server, close connections, etc).
this.dependencies.clear();
this.editor = null;
}
}
export interface JWPlugin {
Expand Down
Loading