jodit
Version:
Jodit is awesome and usefully wysiwyg editor with filebrowser
151 lines (130 loc) • 3.57 kB
text/typescript
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Licensed under GNU General Public License version 2 or later or a commercial license or MIT;
* For GPL see LICENSE-GPL.txt in the project root for license information.
* For MIT see LICENSE-MIT.txt in the project root for license information.
* For commercial licenses see https://xdsoft.net/jodit/commercial/
* Copyright (c) 2013-2019 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import { Config } from '../../Config';
import { IJodit, SnapshotType } from '../../types';
import { Component } from '../Component';
import { debounce } from '../helpers/async';
import { Snapshot } from '../Snapshot';
import { Stack } from '../Stack';
import { Command } from './command';
/**
* @property{object} observer module settings {@link Observer|Observer}
* @property{int} observer.timeout=100 Delay on every change
*/
declare module '../../Config' {
interface Config {
observer: {
timeout: number;
};
}
}
Config.prototype.observer = {
timeout: 100
};
/**
* The module monitors the status of the editor and creates / deletes the required number of Undo / Redo shots .
* To track changes in use {@link https://developer.mozilla.org/ru/docs/Web/API/MutationObserver|MutationObserver}
*
* @module Observer
* @see {@link Snapshot|Snapshot}
* @params {Jodit} parent Jodit main object
*/
export class Observer extends Component<IJodit> {
private __startValue: SnapshotType;
private __newValue: SnapshotType;
private onChangeStack = () => {
this.__newValue = this.snapshot.make();
if (!Snapshot.equal(this.__newValue, this.__startValue)) {
this.stack.push(
new Command(this.__startValue, this.__newValue, this)
);
this.__startValue = this.__newValue;
this.changeStack();
}
};
/**
* @property {Stack} stack
*/
public stack: Stack;
/**
* @property{Snapshot} snapshot
*/
public snapshot: Snapshot;
/**
* Return state of the WYSIWYG editor to step back
*/
public redo() {
if (this.stack.redo()) {
this.__startValue = this.snapshot.make();
this.changeStack();
}
}
/**
* Return the state of the WYSIWYG editor to step forward
*/
public undo() {
if (this.stack.undo()) {
this.__startValue = this.snapshot.make();
this.changeStack();
}
}
public clear() {
this.__startValue = this.snapshot.make();
this.stack.clear();
this.changeStack();
}
public changeStack() {
this.jodit &&
!this.jodit.isDestructed &&
this.jodit.events &&
this.jodit.events.fire('changeStack');
}
constructor(editor: IJodit) {
super(editor);
this.stack = new Stack();
this.snapshot = new Snapshot(editor);
const onChangeStack = debounce(
this.onChangeStack,
editor.defaultTimeout
);
editor.events.on('afterInit.observer', () => {
if (this.isDestructed) {
return;
}
this.__startValue = this.snapshot.make();
editor.events
// save selection
.on(
'changeSelection.observer selectionstart.observer selectionchange.observer mousedown.observer mouseup.observer keydown.observer keyup.observer',
() => {
if (
this.__startValue.html ===
this.jodit.getNativeEditorValue()
) {
this.__startValue = this.snapshot.make();
}
}
)
.on('change.observer', () => {
if (!this.snapshot.isBlocked) {
onChangeStack();
}
});
});
}
destruct(): any {
if (this.jodit.events) {
this.jodit.events.off('.observer');
}
this.snapshot.destruct();
delete this.snapshot;
delete this.stack;
super.destruct();
}
}