mirror of
https://github.com/codex-team/editor.js
synced 2024-06-10 18:03:25 +02:00
Progress
This commit is contained in:
parent
ecc8204658
commit
1a1120a421
|
@ -54,16 +54,31 @@ export default class BoldInlineTool implements InlineTool {
|
|||
button: undefined,
|
||||
};
|
||||
|
||||
// /**
|
||||
// * Create button for Inline Toolbar
|
||||
// */
|
||||
// public render(): HTMLElement {
|
||||
// this.nodes.button = document.createElement('button') as HTMLButtonElement;
|
||||
// this.nodes.button.type = 'button';
|
||||
// this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);
|
||||
// this.nodes.button.innerHTML = IconBold;
|
||||
|
||||
// return this.nodes.button;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Create button for Inline Toolbar
|
||||
*/
|
||||
public render(): HTMLElement {
|
||||
this.nodes.button = document.createElement('button') as HTMLButtonElement;
|
||||
this.nodes.button.type = 'button';
|
||||
this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier);
|
||||
this.nodes.button.innerHTML = IconBold;
|
||||
|
||||
return this.nodes.button;
|
||||
public render(): any {
|
||||
return {
|
||||
icon: IconBold,
|
||||
title: 'Bold',
|
||||
onActivate: () => {
|
||||
// console.log('clicked, need range');
|
||||
document.execCommand(this.commandName);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,7 +96,7 @@ export default class BoldInlineTool implements InlineTool {
|
|||
public checkState(): boolean {
|
||||
const isActive = document.queryCommandState(this.commandName);
|
||||
|
||||
this.nodes.button.classList.toggle(this.CSS.buttonActive, isActive);
|
||||
this.nodes.button?.classList.toggle(this.CSS.buttonActive, isActive);
|
||||
|
||||
return isActive;
|
||||
}
|
||||
|
|
|
@ -128,6 +128,19 @@ export default class LinkInlineTool implements InlineTool {
|
|||
return this.nodes.button;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Create button for Inline Toolbar
|
||||
// */
|
||||
// public render(): any {
|
||||
// return {
|
||||
// icon: IconLink,
|
||||
// title: 'Link',
|
||||
// onActivate: () => {
|
||||
// // this.surround(this.selection.get());
|
||||
// },
|
||||
// };
|
||||
// }
|
||||
|
||||
/**
|
||||
* Input for the link
|
||||
*/
|
||||
|
@ -135,12 +148,17 @@ export default class LinkInlineTool implements InlineTool {
|
|||
this.nodes.input = document.createElement('input') as HTMLInputElement;
|
||||
this.nodes.input.placeholder = this.i18n.t('Add a link');
|
||||
this.nodes.input.classList.add(this.CSS.input);
|
||||
// this.nodes.input.classList.add(this.CSS.inputShowed);
|
||||
this.nodes.input.addEventListener('keydown', (event: KeyboardEvent) => {
|
||||
if (event.keyCode === this.ENTER_KEY) {
|
||||
this.enterPressed(event);
|
||||
}
|
||||
});
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.nodes.input.focus();
|
||||
// }, 1000);
|
||||
|
||||
return this.nodes.input;
|
||||
}
|
||||
|
||||
|
@ -150,6 +168,8 @@ export default class LinkInlineTool implements InlineTool {
|
|||
* @param {Range} range - range to wrap with link
|
||||
*/
|
||||
public surround(range: Range): void {
|
||||
debugger;
|
||||
console.log('surround');
|
||||
/**
|
||||
* Range will be null when user makes second click on the 'link icon' to close opened input
|
||||
*/
|
||||
|
@ -231,6 +251,7 @@ export default class LinkInlineTool implements InlineTool {
|
|||
* Show/close link input
|
||||
*/
|
||||
private toggleActions(): void {
|
||||
debugger;
|
||||
if (!this.inputOpened) {
|
||||
this.openActions(true);
|
||||
} else {
|
||||
|
|
|
@ -20,7 +20,8 @@ import UiAPI from './api/ui';
|
|||
import BlockSettings from './toolbar/blockSettings';
|
||||
import ConversionToolbar from './toolbar/conversion';
|
||||
import Toolbar from './toolbar/index';
|
||||
import InlineToolbar from './toolbar/inline';
|
||||
// import InlineToolbar from './toolbar/inline';
|
||||
import InlineToolbar from './toolbar/inline2';
|
||||
|
||||
/** . */
|
||||
import BlockEvents from './blockEvents';
|
||||
|
@ -78,4 +79,4 @@ export default {
|
|||
Saver,
|
||||
Tools,
|
||||
UI,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -154,8 +154,8 @@ export default class ConversionToolbar extends Module<ConversionToolbarNodes> {
|
|||
*/
|
||||
public close(): void {
|
||||
this.opened = false;
|
||||
this.flipper.deactivate();
|
||||
this.nodes.wrapper.classList.remove(ConversionToolbar.CSS.conversionToolbarShowed);
|
||||
this.flipper?.deactivate();
|
||||
this.nodes.wrapper?.classList.remove(ConversionToolbar.CSS.conversionToolbarShowed);
|
||||
|
||||
if (_.isFunction(this.togglingCallback)) {
|
||||
this.togglingCallback(false);
|
||||
|
|
|
@ -9,7 +9,7 @@ import Shortcuts from '../../utils/shortcuts';
|
|||
import * as tooltip from '../../utils/tooltip';
|
||||
import { ModuleConfig } from '../../../types-internal/module-config';
|
||||
import { CommonInternalSettings } from '../../tools/base';
|
||||
import { Popover, PopoverEvent, PopoverItemDefaultParams, PopoverItemParams, PopoverItemWithChildrenParams } from '../../utils/popover';
|
||||
import { Popover, PopoverEvent, PopoverItemDefaultParams, PopoverItemParams, PopoverItemType, PopoverItemWithChildrenParams } from '../../utils/popover';
|
||||
import { PopoverInline } from '../../utils/popover/popover-inline';
|
||||
import { getConvertToItems } from '../../utils/blocks';
|
||||
import { IconReplace } from '@codexteam/icons';
|
||||
|
@ -455,7 +455,7 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
|
|||
},
|
||||
});
|
||||
popoverItems.push({
|
||||
type: 'separator',
|
||||
type: PopoverItemType.Separator,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -481,23 +481,47 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
|
|||
tool.title || _.capitalize(tool.name)
|
||||
);
|
||||
|
||||
if ($.isElement(controlData)) {
|
||||
htmlElements.push(
|
||||
this.prepareInlineToolHtml(controlData, instance, toolTitle, shortcutBeautified)
|
||||
);
|
||||
} else if (Array.isArray(controlData)) {
|
||||
const items = (controlData as PopoverItemParams[]).map(item => this.prepareInlineToolItem(item, instance, toolTitle, shortcutBeautified));
|
||||
[ controlData ].flat().forEach((item) => {
|
||||
let popoverItem = {
|
||||
onActivate: (activatedItem: PopoverItemParams) => {
|
||||
debugger;
|
||||
this.toolClicked(instance);
|
||||
},
|
||||
hint: {
|
||||
title: toolTitle,
|
||||
description: shortcutBeautified,
|
||||
},
|
||||
isActive: instance.checkState(SelectionUtils.get()),
|
||||
} as PopoverItemParams;
|
||||
|
||||
popoverItems.push(...items);
|
||||
} else {
|
||||
popoverItems.push(this.prepareInlineToolItem(controlData, instance, toolTitle, shortcutBeautified));
|
||||
}
|
||||
if ($.isElement(item)) {
|
||||
popoverItem = {
|
||||
...popoverItem,
|
||||
type: PopoverItemType.Html,
|
||||
element: item,
|
||||
};
|
||||
} else {
|
||||
popoverItem = {
|
||||
...popoverItem,
|
||||
...(item as PopoverItemParams),
|
||||
};
|
||||
}
|
||||
|
||||
// if (_.isFunction(instance.renderActions)) {
|
||||
// const actions = instance.renderActions();
|
||||
if (_.isFunction(instance.renderActions)) {
|
||||
const actions = instance.renderActions();
|
||||
|
||||
// // this.nodes.actions.appendChild(actions);
|
||||
// }
|
||||
popoverItem.children = {
|
||||
items: [
|
||||
{
|
||||
type: PopoverItemType.Html,
|
||||
element: actions,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
popoverItems.push(popoverItem);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
|
@ -517,7 +541,7 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
|
|||
private prepareInlineToolItem(item: PopoverItemParams, toolInstance: IInlineTool, toolTitle: string, shortcut: string | undefined): PopoverItemDefaultParams {
|
||||
const result = {
|
||||
...item,
|
||||
onActivate: (activatedItem: PopoverItemParams) => {
|
||||
onActivate: (activatedItem: PopoverItemParams, event) => {
|
||||
// @todo proper check
|
||||
if ('children' in activatedItem) {
|
||||
return;
|
||||
|
|
|
@ -43,6 +43,15 @@ interface UINodes {
|
|||
* @property {Element} nodes.redactor - <ce-redactor>
|
||||
*/
|
||||
export default class UI extends Module<UINodes> {
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
*/
|
||||
constructor(params) {
|
||||
super(params);
|
||||
// debugger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor.js UI CSS class names
|
||||
*
|
||||
|
@ -97,6 +106,19 @@ export default class UI extends Module<UINodes> {
|
|||
*/
|
||||
public isMobile = false;
|
||||
|
||||
private _ignoreSelectionChangeEvents = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public ignoreSelectionChangeEvents(value: boolean): void {
|
||||
console.log('ignoreSelectionChangeEvents', value);
|
||||
// debugger;
|
||||
this._ignoreSelectionChangeEvents = value;
|
||||
// debugger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache for center column rectangle info
|
||||
* Invalidates on window resize
|
||||
|
@ -105,6 +127,7 @@ export default class UI extends Module<UINodes> {
|
|||
*/
|
||||
private contentRectCache: DOMRect = undefined;
|
||||
|
||||
|
||||
/**
|
||||
* Handle window resize only when it finished
|
||||
*
|
||||
|
@ -135,6 +158,7 @@ export default class UI extends Module<UINodes> {
|
|||
this.loadStyles();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggle read-only state
|
||||
*
|
||||
|
@ -234,6 +258,22 @@ export default class UI extends Module<UINodes> {
|
|||
Toolbar.toolbox.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public enableSelectionChangeEvents(): void {
|
||||
this.listeners.on(document, 'selectionchange', this.selectionChangeDebounced, true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public disableSelectionChangeEvents(): void {
|
||||
// this.listeners.removeAll();
|
||||
this.listeners.off(document, 'selectionchange', this.selectionChangeDebounced, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for mobile mode and save the result
|
||||
*/
|
||||
|
@ -330,6 +370,13 @@ export default class UI extends Module<UINodes> {
|
|||
$.prepend(document.head, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle selection change to manipulate Inline Toolbar appearance
|
||||
*/
|
||||
private selectionChangeDebounced = _.debounce(() => {
|
||||
this.selectionChanged();
|
||||
}, selectionChangeDebounceTimeout);
|
||||
|
||||
/**
|
||||
* Bind events on the Editor.js interface
|
||||
*/
|
||||
|
@ -363,11 +410,11 @@ export default class UI extends Module<UINodes> {
|
|||
/**
|
||||
* Handle selection change to manipulate Inline Toolbar appearance
|
||||
*/
|
||||
const selectionChangeDebounced = _.debounce(() => {
|
||||
this.selectionChanged();
|
||||
}, selectionChangeDebounceTimeout);
|
||||
// const selectionChangeDebounced = _.debounce(() => {
|
||||
// this.selectionChanged();
|
||||
// }, selectionChangeDebounceTimeout);
|
||||
|
||||
this.readOnlyMutableListeners.on(document, 'selectionchange', selectionChangeDebounced, true);
|
||||
this.listeners.on(document, 'selectionchange', this.selectionChangeDebounced, true);
|
||||
|
||||
this.readOnlyMutableListeners.on(window, 'resize', () => {
|
||||
this.resizeDebouncer();
|
||||
|
@ -381,6 +428,7 @@ export default class UI extends Module<UINodes> {
|
|||
this.watchBlockHoveredEvents();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Listen redactor mousemove to emit 'block-hovered' event
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,7 @@ import Dom from '../../../../../dom';
|
|||
import { IconDotCircle, IconChevronRight } from '@codexteam/icons';
|
||||
import {
|
||||
PopoverItemDefaultParams as PopoverItemDefaultParams,
|
||||
PopoverItemParams as PopoverItemParams,
|
||||
// PopoverItemParams as PopoverItemParams,
|
||||
PopoverItemRenderParamsMap,
|
||||
PopoverItemType
|
||||
} from '../popover-item.types';
|
||||
|
@ -75,7 +75,6 @@ export class PopoverItemDefault extends PopoverItem {
|
|||
icon: null,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* If item is in confirmation state, stores confirmation params such as icon, label, onActivate callback and so on
|
||||
*/
|
||||
|
@ -88,8 +87,8 @@ export class PopoverItemDefault extends PopoverItem {
|
|||
* @param renderParams - popover item render params.
|
||||
* The parameters that are not set by user via popover api but rather depend on technical implementation
|
||||
*/
|
||||
constructor(private readonly params: PopoverItemDefaultParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Default]) {
|
||||
super();
|
||||
constructor(protected readonly params: PopoverItemDefaultParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Default]) {
|
||||
super(params);
|
||||
|
||||
this.nodes.root = this.make(params, renderParams);
|
||||
}
|
||||
|
@ -148,30 +147,30 @@ export class PopoverItemDefault extends PopoverItem {
|
|||
this.disableSpecialHoverAndFocusBehavior();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns item children that are represented as popover items
|
||||
*/
|
||||
public get children(): PopoverItemParams[] {
|
||||
return 'children' in this.params && this.params.children?.items !== undefined ? this.params.children.items : [];
|
||||
}
|
||||
// /**
|
||||
// * Returns item children that are represented as popover items
|
||||
// */
|
||||
// public get children(): PopoverItemParams[] {
|
||||
// return 'children' in this.params && this.params.children?.items !== undefined ? this.params.children.items : [];
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns item children that are represented as custom HTML
|
||||
*/
|
||||
public get childrenHTML(): HTMLElement | undefined {
|
||||
if (!('children' in this.params)) {
|
||||
return undefined;
|
||||
}
|
||||
// /**
|
||||
// * Returns item children that are represented as custom HTML
|
||||
// */
|
||||
// public get childrenHTML(): HTMLElement | undefined {
|
||||
// if (!('children' in this.params)) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
return this.params.children?.customHtml;
|
||||
}
|
||||
// return this.params.children?.customHtml;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns true if item has any type of children
|
||||
*/
|
||||
public get hasChildren(): boolean {
|
||||
return this.children.length > 0 || this.childrenHTML !== undefined;
|
||||
}
|
||||
// /**
|
||||
// * Returns true if item has any type of children
|
||||
// */
|
||||
// public get hasChildren(): boolean {
|
||||
// return this.children.length > 0; // || this.childrenHTML !== undefined;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns true if item has children that should be searchable
|
||||
|
|
|
@ -20,7 +20,7 @@ export class PopoverItemHtml extends PopoverItem {
|
|||
* The parameters that are not set by user via popover api but rather depend on technical implementation
|
||||
*/
|
||||
constructor(params: PopoverItemHtmlParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Html]) {
|
||||
super();
|
||||
super(params);
|
||||
|
||||
this.nodes = {
|
||||
root: Dom.make('div', css.root),
|
||||
|
@ -63,4 +63,12 @@ export class PopoverItemHtml extends PopoverItem {
|
|||
|
||||
return Array.from(controls);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public handleClick(): void {
|
||||
// debugger;
|
||||
this.params.onActivate?.(this.params);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
import * as tooltip from '../../../../utils/tooltip';
|
||||
import { type HintPosition, Hint } from '../hint';
|
||||
import { PopoverItemParams } from './popover-item.types';
|
||||
|
||||
/**
|
||||
* Popover item abstract class
|
||||
*/
|
||||
export abstract class PopoverItem {
|
||||
/**
|
||||
* Constructs the instance
|
||||
*
|
||||
* @param params - instance parameters
|
||||
*/
|
||||
constructor(protected readonly params?: PopoverItemParams) {}
|
||||
|
||||
/**
|
||||
* Adds hint to the item element if hint data is provided
|
||||
*
|
||||
|
@ -31,4 +39,18 @@ export abstract class PopoverItem {
|
|||
* @param isHidden - true if item should be hidden
|
||||
*/
|
||||
public abstract toggleHidden(isHidden: boolean): void;
|
||||
|
||||
/**
|
||||
* Returns item children that are represented as popover items
|
||||
*/
|
||||
public get children(): PopoverItemParams[] {
|
||||
return 'children' in this.params && this.params.children?.items !== undefined ? this.params.children.items : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if item has any type of children
|
||||
*/
|
||||
public get hasChildren(): boolean {
|
||||
return this.children.length > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,21 @@ export enum PopoverItemType {
|
|||
Html = 'html'
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents popover item children configuration
|
||||
*/
|
||||
export interface PopoverItemChildren {
|
||||
/**
|
||||
* True if children items should be searchable
|
||||
*/
|
||||
searchable?: boolean;
|
||||
|
||||
/**
|
||||
* Items of nested popover that should be open on the current item hover/click (depending on platform)
|
||||
*/
|
||||
items?: PopoverItemParams[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents popover item separator.
|
||||
* Special item type that is used to separate items in the popover.
|
||||
|
@ -45,6 +60,10 @@ export interface PopoverItemHtmlParams {
|
|||
hint?: HintParams;
|
||||
}
|
||||
|
||||
export interface PopoverItemHtmlWithChildrenParams extends PopoverItemHtmlParams{
|
||||
children?: PopoverItemChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common parameters for all kinds of default popover items: with or without confirmation
|
||||
*/
|
||||
|
@ -131,7 +150,6 @@ export interface PopoverItemWithoutConfirmationParams extends PopoverItemDefault
|
|||
onActivate: (item: PopoverItemParams, event?: PointerEvent) => void;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents popover item with children (nested popover items)
|
||||
*/
|
||||
|
@ -142,16 +160,7 @@ export interface PopoverItemWithChildrenParams extends PopoverItemDefaultBasePar
|
|||
/**
|
||||
* Items of nested popover that should be open on the current item hover/click (depending on platform)
|
||||
*/
|
||||
children?: {
|
||||
/**
|
||||
* True if children items should be searchable
|
||||
*/
|
||||
searchable?: boolean;
|
||||
|
||||
items?: PopoverItemParams[];
|
||||
|
||||
customHtml?: HTMLElement;
|
||||
}
|
||||
children?: PopoverItemChildren
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,7 +177,8 @@ export type PopoverItemDefaultParams =
|
|||
export type PopoverItemParams =
|
||||
PopoverItemDefaultParams |
|
||||
PopoverItemSeparatorParams |
|
||||
PopoverItemHtmlParams;
|
||||
PopoverItemHtmlParams |
|
||||
PopoverItemHtmlWithChildrenParams;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -174,7 +174,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
* @param event - event to retrieve popover item from
|
||||
*/
|
||||
protected getTargetItem(event: Event): PopoverItemDefault | undefined {
|
||||
return this.itemsDefault.find(el => {
|
||||
return this.items.find(el => {
|
||||
const itemEl = el.getElement();
|
||||
|
||||
if (itemEl === null) {
|
||||
|
@ -248,6 +248,8 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
if (item.hasChildren) {
|
||||
this.showNestedItems(item);
|
||||
|
||||
item.handleClick();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export class PopoverDesktop extends PopoverAbstract {
|
|||
*/
|
||||
constructor(params: PopoverParams) {
|
||||
super(params);
|
||||
console.log(params.items);
|
||||
|
||||
if (params.nestingLevel !== undefined) {
|
||||
this.nestingLevel = params.nestingLevel;
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
border-radius: 0 0 4px 4px;
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
padding: 10px;
|
||||
/* padding: 10px; */
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
|
|
Loading…
Reference in a new issue