mirror of
https://github.com/codex-team/editor.js
synced 2024-05-07 00:46:45 +02:00
581289c03e
* Default tunes to popover * Add the rest of default tunes * Add popover * Cleanup * Rename custom content * Cleanup * Add ability to open block settings upwards * Fix tests * Cleanup default tunes * Rename and cleanup * Add ability to display rendered custom tunes * cleanup * Rename * Add flag to close tunes popover * Cleanup * i18n * Cleanup * Fix build and tests * Fix for iframe * Add comments * Display active item, move closeOnActivate to popover * Add confirmation support to popover * Handle boolean value in confirmation param * Clarify flippable logic in popover * Comments * Pass editor element as a param of popover constructor * Fix readability * Tests * Fix flipper for confirmation element * Update confirmation config structure * Rename onClick to onActivate * Fix tests and build * Make confirmation props optional * Simplify processing tunes * Renamings * Fix text block tunes * Docs * Update event type * Move enabling confirmation state to separate method * move popover types * Unhardcode color * Support toggling * Add support of disabled items * Fix tab in empty block leading to selecting second item in popover * Remove margins for styles api settings button class * Fix arrow navigation between blocks after opening block tunes * Cleaup in default tunes code * Fix chaining confirmations * Colors * Types * Change the way flippable elements of popover custom area are set * Remove borders around popover icons * Fix untabbable inline toolbar * Fix locked scroll after closing tunes popover on mobile * Cleanup * Set max popover width * Make popover icon's border outside * Fix tab issue * Fix focus/hover issue * Reformat * Cleanup * Fix opening block tunes via keyboard * Add disableSpecialHoverAndFocusBehavior * Add deprecated comment * Cleanup * Fix popover active state * Fix checklist deletion with confirmation * Fix checklist deletion 2 * Fix popover focus * Fix popover items being impossible to flip after searching * Fix popover item highlighting issue * Update flipper.spec.ts * Fixes after review * Add Tunes Api tests * Fix multiple popover entries configured by one tune * Add tool's renderSettings() tests * Add popover confirmation state test * Fix popover width on mobile * Add popover tests * Add changelog and update version * Update changelog * Fix block tunes being unable to open after tune activation Co-authored-by: Peter Savchenko <specc.dev@gmail.com>
197 lines
5 KiB
TypeScript
197 lines
5 KiB
TypeScript
import Module from '../../__module';
|
|
import $ from '../../dom';
|
|
import * as _ from '../../utils';
|
|
import SelectionUtils from '../../selection';
|
|
import Block from '../../block';
|
|
import Popover, { PopoverEvent } from '../../utils/popover';
|
|
import I18n from '../../i18n';
|
|
import { I18nInternalNS } from '../../i18n/namespace-internal';
|
|
import Flipper from '../../flipper';
|
|
|
|
/**
|
|
* HTML Elements that used for BlockSettings
|
|
*/
|
|
interface BlockSettingsNodes {
|
|
wrapper: HTMLElement;
|
|
}
|
|
|
|
/**
|
|
* Block Settings
|
|
*
|
|
* @todo Make Block Settings no-module but a standalone class, like Toolbox
|
|
*/
|
|
export default class BlockSettings extends Module<BlockSettingsNodes> {
|
|
/**
|
|
* Module Events
|
|
*
|
|
* @returns {{opened: string, closed: string}}
|
|
*/
|
|
public get events(): { opened: string; closed: string } {
|
|
return {
|
|
opened: 'block-settings-opened',
|
|
closed: 'block-settings-closed',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Block Settings CSS
|
|
*/
|
|
public get CSS(): { [name: string]: string } {
|
|
return {
|
|
settings: 'ce-settings',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Opened state
|
|
*/
|
|
public opened = false;
|
|
|
|
/**
|
|
* Getter for inner popover's flipper instance
|
|
*
|
|
* @todo remove once BlockSettings becomes standalone non-module class
|
|
*/
|
|
public get flipper(): Flipper {
|
|
return this.popover.flipper;
|
|
}
|
|
|
|
/**
|
|
* Page selection utils
|
|
*/
|
|
private selection: SelectionUtils = new SelectionUtils();
|
|
|
|
/**
|
|
* Popover instance. There is a util for vertical lists.
|
|
*/
|
|
private popover: Popover;
|
|
|
|
/**
|
|
* Panel with block settings with 2 sections:
|
|
* - Tool's Settings
|
|
* - Default Settings [Move, Remove, etc]
|
|
*/
|
|
public make(): void {
|
|
this.nodes.wrapper = $.make('div');
|
|
}
|
|
|
|
/**
|
|
* Destroys module
|
|
*/
|
|
public destroy(): void {
|
|
this.removeAllNodes();
|
|
}
|
|
|
|
/**
|
|
* Open Block Settings pane
|
|
*
|
|
* @param targetBlock - near which Block we should open BlockSettings
|
|
*/
|
|
public open(targetBlock: Block = this.Editor.BlockManager.currentBlock): void {
|
|
this.opened = true;
|
|
|
|
/**
|
|
* If block settings contains any inputs, focus will be set there,
|
|
* so we need to save current selection to restore it after block settings is closed
|
|
*/
|
|
this.selection.save();
|
|
|
|
/**
|
|
* Highlight content of a Block we are working with
|
|
*/
|
|
targetBlock.selected = true;
|
|
this.Editor.BlockSelection.clearCache();
|
|
|
|
/**
|
|
* Fill Tool's settings
|
|
*/
|
|
const [tunesItems, customHtmlTunesContainer] = targetBlock.getTunes();
|
|
|
|
/** Tell to subscribers that block settings is opened */
|
|
this.eventsDispatcher.emit(this.events.opened);
|
|
|
|
this.popover = new Popover({
|
|
className: this.CSS.settings,
|
|
searchable: true,
|
|
filterLabel: I18n.ui(I18nInternalNS.ui.popover, 'Filter'),
|
|
nothingFoundLabel: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),
|
|
items: tunesItems,
|
|
customContent: customHtmlTunesContainer,
|
|
customContentFlippableItems: this.getControls(customHtmlTunesContainer),
|
|
scopeElement: this.Editor.API.methods.ui.nodes.redactor,
|
|
});
|
|
this.popover.on(PopoverEvent.OverlayClicked, this.onOverlayClicked);
|
|
this.popover.on(PopoverEvent.Close, () => this.close());
|
|
|
|
this.nodes.wrapper.append(this.popover.getElement());
|
|
|
|
this.popover.show();
|
|
}
|
|
|
|
/**
|
|
* Returns root block settings element
|
|
*/
|
|
public getElement(): HTMLElement {
|
|
return this.nodes.wrapper;
|
|
}
|
|
|
|
/**
|
|
* Close Block Settings pane
|
|
*/
|
|
public close(): void {
|
|
this.opened = false;
|
|
|
|
/**
|
|
* If selection is at editor on Block Settings closing,
|
|
* it means that caret placed at some editable element inside the Block Settings.
|
|
* Previously we have saved the selection, then open the Block Settings and set caret to the input
|
|
*
|
|
* So, we need to restore selection back to Block after closing the Block Settings
|
|
*/
|
|
if (!SelectionUtils.isAtEditor) {
|
|
this.selection.restore();
|
|
}
|
|
|
|
this.selection.clearSaved();
|
|
|
|
/**
|
|
* Remove highlighted content of a Block we are working with
|
|
*/
|
|
if (!this.Editor.CrossBlockSelection.isCrossBlockSelectionStarted && this.Editor.BlockManager.currentBlock) {
|
|
this.Editor.BlockManager.currentBlock.selected = false;
|
|
}
|
|
|
|
/** Tell to subscribers that block settings is closed */
|
|
this.eventsDispatcher.emit(this.events.closed);
|
|
|
|
if (this.popover) {
|
|
this.popover.off(PopoverEvent.OverlayClicked, this.onOverlayClicked);
|
|
this.popover.destroy();
|
|
this.popover.getElement().remove();
|
|
this.popover = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns list of buttons and inputs inside specified container
|
|
*
|
|
* @param container - container to query controls inside of
|
|
*/
|
|
private getControls(container: HTMLElement): HTMLElement[] {
|
|
const { StylesAPI } = this.Editor;
|
|
/** Query buttons and inputs inside tunes html */
|
|
const controls = container.querySelectorAll<HTMLElement>(
|
|
`.${StylesAPI.classes.settingsButton}, ${$.allInputsSelector}`
|
|
);
|
|
|
|
return Array.from(controls);
|
|
}
|
|
|
|
/**
|
|
* Handles overlay click
|
|
*/
|
|
private onOverlayClicked = (): void => {
|
|
this.close();
|
|
}
|
|
}
|