mirror of
https://github.com/codex-team/editor.js
synced 2024-05-20 15:26:48 +02:00
ff91466b14
* chore(block-tune-toggler): toggler moved to the left (draft) * toolbox ui updated * fixd caret jumpling, improved some styles * toolbar moving by block-hover - UI module triggers 'block-hovered' event - Toolbar uses 'block-hovered' for appearing - `currentBlock` setter added to the BlockManager - (reactangle-selection): the throttling added to the mousemove and scroll handlers - `getBlockIndex` method added to the Api - (api-blocks): toolbar moving logic removed from `blocks.move()` and `blocks.swap()` methods. Instead, MoveUp and MoveDown tunes uses Toolbar API * the dark-theme to the example-dev.html * positioning improved * fix(rectangle-selection): first click after RS does not clears selection state * toolbox position fixed * the toolbox module became a standalone class - Toolbox became a standalone class from the editor module. It can be accessed only via the owner (the Toolbar module) - (api.blocks) the insert() method now has the `replace` param. Also, it returns inserted Block API now. * new(api.listeners): `on()` now returns the listener id. The new `offById()` method added * fix bug with Tab pressing on hovered but not focused block * mobile version improved * upd example dev * small updaets * add nested-list * linting * (api.toolbar): `toggleBlockSettings` now fires toggling event with the same state * EventDispatcher used instead of callbacks for the Toolbox * UIApi added * fix ci * git submodules removed from the ci flow * add paragraph submodule to the ci flow * Update CHANGELOG.md * Update package.json * use ubuntu-latest for chrome ci
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import { isEmpty } from '../utils';
|
|
|
|
/**
|
|
* @class EventDispatcher
|
|
*
|
|
* Has two important methods:
|
|
* - {Function} on - appends subscriber to the event. If event doesn't exist - creates new one
|
|
* - {Function} emit - fires all subscribers with data
|
|
* - {Function off - unsubscribes callback
|
|
*
|
|
* @version 1.0.0
|
|
*
|
|
* @typedef {Events} Events
|
|
* @property {object} subscribers - all subscribers grouped by event name
|
|
*/
|
|
export default class EventsDispatcher<Events extends string = string> {
|
|
/**
|
|
* Object with events` names as key and array of callback functions as value
|
|
*
|
|
* @type {{}}
|
|
*/
|
|
private subscribers: {[name: string]: Array<(data?: object) => unknown>} = {};
|
|
|
|
/**
|
|
* Subscribe any event on callback
|
|
*
|
|
* @param {string} eventName - event name
|
|
* @param {Function} callback - subscriber
|
|
*/
|
|
public on(eventName: Events, callback: (data: object) => unknown): void {
|
|
if (!(eventName in this.subscribers)) {
|
|
this.subscribers[eventName] = [];
|
|
}
|
|
|
|
// group by events
|
|
this.subscribers[eventName].push(callback);
|
|
}
|
|
|
|
/**
|
|
* Subscribe any event on callback. Callback will be called once and be removed from subscribers array after call.
|
|
*
|
|
* @param {string} eventName - event name
|
|
* @param {Function} callback - subscriber
|
|
*/
|
|
public once(eventName: Events, callback: (data: object) => unknown): void {
|
|
if (!(eventName in this.subscribers)) {
|
|
this.subscribers[eventName] = [];
|
|
}
|
|
|
|
const wrappedCallback = (data: object): unknown => {
|
|
const result = callback(data);
|
|
|
|
const indexOfHandler = this.subscribers[eventName].indexOf(wrappedCallback);
|
|
|
|
if (indexOfHandler !== -1) {
|
|
this.subscribers[eventName].splice(indexOfHandler, 1);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
// group by events
|
|
this.subscribers[eventName].push(wrappedCallback);
|
|
}
|
|
|
|
/**
|
|
* Emit callbacks with passed data
|
|
*
|
|
* @param {string} eventName - event name
|
|
* @param {object} data - subscribers get this data when they were fired
|
|
*/
|
|
public emit(eventName: Events, data?: object): void {
|
|
if (isEmpty(this.subscribers) || !this.subscribers[eventName]) {
|
|
return;
|
|
}
|
|
|
|
this.subscribers[eventName].reduce((previousData, currentHandler) => {
|
|
const newData = currentHandler(previousData);
|
|
|
|
return newData || previousData;
|
|
}, data);
|
|
}
|
|
|
|
/**
|
|
* Unsubscribe callback from event
|
|
*
|
|
* @param {string} eventName - event name
|
|
* @param {Function} callback - event handler
|
|
*/
|
|
public off(eventName: Events, callback: (data: object) => unknown): void {
|
|
for (let i = 0; i < this.subscribers[eventName].length; i++) {
|
|
if (this.subscribers[eventName][i] === callback) {
|
|
delete this.subscribers[eventName][i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroyer
|
|
* clears subscribers list
|
|
*/
|
|
public destroy(): void {
|
|
this.subscribers = null;
|
|
}
|
|
}
|