Jodit - Best WYSIWYG Editor for You
Observer
module renamed to History
, accessed via Jodit.history
Jodit.observer
field deprecated and will be removed in future releaseshistory
in observer
settings. The observer
field has been deprecated.stack
field from History
class (former Observer
).history.timeout
. Now the second setting is just for history.
Timeouts for all asynchronous operations in Jodit now apply the defaultTimeout
settingBefore:
const editor = Jodit.make({
observer: {
timeout: 122,
maxHistoryLength: 100
}
});
console.log(editor.defaultTimeout); // 122
editor.observer.stack.clear();
Now:
const editor = Jodit.make({
defaultTimeout: 122,
history: {
timeout: 1000,
maxHistoryLength: 100
}
});
console.log(editor.defaultTimeout); // 122
editor.history.clear();
Jodit.value
, the history of changes will be process immediately,
without a timeout. Read more https://github.com/xdan/jodit/issues/792
ObserveObject
removedobservable
function which makes object observable. In this case, the function returns the same object.const obj = {
a: 1,
b: {
c: 5
}
};
const obsObj = Jodit.modules.observable(obj);
console.log(obj === obsObj); // true
obsObj.on('change', () => {
console.log('Object changed');
});
obsObj.on('change.a', () => {
console.log('Key a changed');
});
obsObj.on('change.b.c', () => {
console.log('Key b.c changed');
});
obj.a = 6;
// Object changed
// Key a changed
obj.b = { c: 6 };
// Object changed
obj.b.c = 8;
// Object changed
// Key b.c changed
const hotkeys = {
delete: ['delete', 'cmd+backspace'],
deleteWord: ['ctrl+delete', 'cmd+alt+backspace', 'ctrl+alt+backspace'],
backspace: ['backspace'],
backspaceWord: ['ctrl+backspace']
};
But the setting was called incorrectly, when the combination was pressed, not one word was deleted, but a whole sentence. Now added one more setting:
const hotkeys = {
delete: ['delete', 'cmd+backspace'],
deleteWord: ['ctrl+delete', 'cmd+alt+backspace', 'ctrl+alt+backspace'],
deleteSentence: ['ctrl+shift+delete', 'cmd+shift+delete'],
backspace: ['backspace'],
backspaceWord: ['ctrl+backspace'],
backspaceSentence: ['ctrl+shift+backspace', 'cmd+shift+backspace']
};
inline-popup
plugin,
a setting has been added to it: popup.toolbar
, which lists the buttons that will be shown in such a toolbar.
Added the showInline
method to the ToolbarEditorCollection
itself:const editor = Jodit.make('#editor', {
preset: 'inline',
popup: {
toolbar: Jodit.atom(['bold', 'italic', 'image'])
}
});
editor.s.focus();
editor.toolbar.showInline();
// or
editor.e.fire('showInlineToolbar');
Also added ToolbarCollection.hide
and ToolbarCollection.show
methods.
const editor = Jodit.make('#editor');
editor.toolbar.hide();
editor.toolbar.show();
console.log(Jodit.modules.UIButton.getFullElName('element')); // jodit-ui-button__element
console.log(Jodit.modules.UIButton.componentName); // jodit-ui-button
filebrowser.saveStateInStorage
split to dictionary:interface IFileBrowserOptions: {}
saveStateInStorage: false | {
storeLastOpenedFolder?: boolean;
storeView?: boolean;
storeSortBy?: boolean;
};
}
By default:
{
saveStateInStorage: {
storeLastOpenedFolder: true,
storeView: true,
storeSortBy: true
}
}
Disable it:
Jodit.make('#editor', {
filebrowser: {
saveStateInStorage: false
}
});
// or
Jodit.make('#editor', {
filebrowser: {
saveStateInStorage: {
storeLastOpenedFolder: false
}
}
});
|
metacharacters and \n
which stand for separator and newline, the ---
metacharacter has appeared,
which allows you to add a spacer element which pushes all buttons behind the spacer to the right side of the toolbar
and creates space in the middle.Jodit.make('#editor', {
buttons: [
'source',
'bold',
'|',
'---',
'|',
'brush',
'about',
'\n',
'italic'
]
});
Travis.CI
👋👋👋EventsNative
module - renamed to EventEmitter
const editor = Jodit.make('#editor');
console.log(editor.e instanceof Jodit.modules.EventEmitter); // true
console.log(editor.events instanceof Jodit.modules.EventEmitter); // true
console.log(editor.events instanceof Jodit.modules.EventsNative); // true, deprecated
request
folder.import { Ajax } from 'jodit/src/core/request';
const editor = Jodit.make('#editor');
// Before
await new Ajax(editor, {
url: 'index.php'
}).send(); // {success: true, data: ...}
// Now
await new Ajax(editor, {
url: 'index.php'
})
.send()Ëš
.then(resp => resp.json()); // {success: true, data: ...}
.npmignore
added:
In Dom
module added nextGen
and eachGen
methods. These methods return generators:
const editor = Jodit.make('#editor');
editor.value = '<ul><li><img>1</li><li>2</li><li>3</li></ul>';
const gen = Dom.nextGen(editor.editor.querySelector('img'), editor.editor);
let next = gen.next();
while (!next.done) {
console.log(next.value); // 1, LI, 2, LI, 3
next = gen.next();
}
const gen2 = Dom.eachGen(editor.editor);
let next2 = gen2.next();
while (!next2.done) {
console.log(next2.value); // UL, LI, 1, LI, 2, LI, 3
next2 = gen2.next();
}
tags #680
Style
to CommitStyle
const editor = Jodit.make('#editor');
const style = new Jodit.ns.CommitStyle({
style: {
color: 'red'
}
});
editor.execCommand('selectall');
style.apply(editor);
Dom
refactoring: from isNode
,isElement
,isHTMLElement
removed Window
argument.Before
const editor = Jodit.make('#editor', { iframe: true });
Dom.isNode({}, editor.ow); // false
Dom.isNode(document.body, window); // true
Dom.isNode(document.body, editor.ow); // true
Dom.isNode(editor.od.body, editor.ow); // true
Dom.isNode(editor.ed.body, editor.ow); // false
Now
const editor = Jodit.make('#editor', { iframe: true });
Dom.isNode({}); // false
Dom.isNode(document.body); // true
Dom.isNode(document.body); // true
Dom.isNode(editor.od.body); // true
Dom.isNode(editor.ed.body); // true
KeyArrowOutside
, allowing to go outside of an inline element if there is no other element after that.const editor = Jodit.make('#editor', {
styleValues: {
'color-icon': '#0f0',
'color-text': 'red',
colorBorder: 'black',
'color-panel': 'blue'
}
});
classSpan
plugin. Applying some className to selected text. Thanks https://github.com/s-renier-taonix-fr
const editor = new Jodit('#editor', {
controls: {
classSpan: {
list: {
class1: 'Classe 1',
class2: 'Classe 2',
class3: 'Classe 3',
class4: 'Classe 4',
class5: 'Classe 5'
}
}
}
});
UIFileInput
element.UIButtonGroup
element.const group = new UIButtonGroup(jodit, {
label: 'Theme',
name: 'theme',
value: this.state.theme,
radio: true,
options: [
{ value: 'default', text: 'Light' },
{ value: 'dark', text: 'Dark' }
],
onChange: (values) => {
this.state.theme = values[0].value as string;
}
}),
"importsNotUsedAsValues": "error"
in tsconfig
Filebrowser
moduleDialog
moduleConfig
system. You can change default setting in you extensions.// before
const a = new Jodit();
a.options.allowResizeY; // true
Jodit.defaultOptions.allowResizeY = false;
a.options.allowResizeY; // true
// Now
const a = new Jodit();
a.options.allowResizeY; // true
Jodit.defaultOptions.allowResizeY = false;
a.options.allowResizeY; // false
promisify
mode in debounce
and throttle
decorators.src/core/ui/form/validators/key-validator.ts
.Async
.requestIdlePromise
method.Helpers
.extend
method.Helpers
.loadImage
method.render
method in state/ui system.// Before
@component()
class UIBtn extends UIElement {
className() {
return 'UIBtn';
}
createContainer() {
const button = this.j.c.element('button');
button.style.color = 'red';
button.classList.add(this.getFullElName('button'))
this.j.e.on('click', button, this.onClick);
return button;
}
@autobind
onClick() {
alert('click');
}
}
// Now
@component()
class UIBtn extends UIElement {
className() {
return 'UIBtn';
}
render() {
return `<button class="&__button" style="color:red"></button>`;
}
@watch('container:click')
onClick() {
alert('click');
}
}
and styles
.jodit-ui-btn__button {
border: 1px solid #ccc;
}
useAceEditor
option. https://github.com/xdan/jodit/issues/544
component
and persistent
decoratorsimport {component, persistent} from "./src/core/decorators";
@component
class Item extends UIElement{
@persistent
options = {
some: true
};
}
const item = new Item(jodit);
console.log(item.options); // {some: true}
item.options = {
some: false
};
const item2 = new Item(jodit); // or reload page
console.log(item.options); // {some: false}
UIInput
added autocomplete
, clearButton
, icon
options.Jodit.Array
and Jodit.Object
marked as deprecated. In 3.5
they will be removed. Instead, use Jodit.atom
.
const editor = Jodit.make('#editor', {
buttons: Jodit.atom(['bold', 'italic']),
popup: {
img: Jodit.atom({
// full rewrite
})
}
});
observer.maxHistoryLength: number = Infinity
Related with https://github.com/xdan/jodit/issues/574. In some cases need to limit size of undo history.
link.plugin
{ value: "", text: "" },
{ value: "val1", text: "text1" },
{ value: "val2", text: "text2" },
{ value: "val3", text: "text3" }
]
PR: https://github.com/xdan/jodit/pull/577 Thanks @s-renier-taonix-fr
statusbar: boolean = true
Issue https://github.com/xdan/jodit/issues/535
const editor = Jodit.make('#editor', {
statusbar: false
});
console.log(editor.statusbar.isShown); // false
editor.statusbar.show();
console.log(editor.statusbar.isShown); // true
The buttons
option can contain named groups of buttons.
Each plugin decides which button belongs to which group.
Thus, if you turn off the plugin, then its buttons will not be shown either.
Available groups: ["source", "font-style", "script", "list", "indent", "font", "color", "media", "state", "clipboard", "insert", "history", "search", "other", "info"];
const editor = Jodit.make('#editor', {
buttons: [
{
group: "custom",
buttons: []
},
"bold"
]
});
Jodit.defaultOptions.controls.someButton = {
icon: 'pencil',
command: 'selectall'
};
Jodit.plugins.add('somePlugin', function (editor) {
editor.registerButton({
name: 'someButton',
group: 'custom'
});
})
Added hotkey settings for Delete and Backspace buttons.
And added hotkey ctrl+backspace
for removing left part of text.
Issue: https://github.com/xdan/jodit/issues/532
Jodit.make('#editor', {
delete: Jodit.atom({
hotkeys: {
delete: ['delete', 'cmd+backspace'],
deleteWord: ['ctrl+delete', 'cmd+alt+backspace', 'ctrl+alt+backspace'],
backspace: ['backspace'],
backspaceWord: ['ctrl+backspace']
}
})
});
one
method in event systemconst editor = Jodit.make('#editor');
editor.events
.one('keydown', () => {
console.log('Fire only one time');
})
.on('keydown', () => {
console.log('Fire everytime');
});
Added extraIcons
option.
By default, you can only install an icon from the Jodit suite.
You can add your icon to the set using the Jodit.modules.Icon.set (name, svg Code)
method.
But for a declarative declaration, you can use this option.
Jodit.modules.Icon.set('someIcon', '<svg><path.../></svg>');
const editor = Jodit.make({
extraButtons: [
{
name: 'someButton',
icon: 'someIcon'
}
]
});
const editor = Jodit.make({
extraIcons: {
someIcon: '<svg><path.../></svg>'
},
extraButtons: [
{
name: 'someButton',
icon: 'someIcon'
}
]
});
const editor = Jodit.make({
extraButtons: [
{
name: 'someButton',
icon: '<svg><path.../></svg>'
}
]
});