mirror of
https://github.com/codex-team/editor.js
synced 2024-06-26 09:20:07 +02:00
Merge branch 'release/2.16' of github.com:codex-team/editor.js into refactor/rectangle-selection
This commit is contained in:
commit
c11149ea8b
25981
dist/editor.js
vendored
25981
dist/editor.js
vendored
File diff suppressed because one or more lines are too long
|
@ -3,6 +3,7 @@
|
|||
### 2.16
|
||||
|
||||
- `Refactoring` — Constants of tools settings separated by internal and external to correspond API
|
||||
- `Refactoring` — Created universal Flipper class that responses for navigation by keyboard inside of any Toolbars
|
||||
|
||||
### 2.15
|
||||
|
||||
|
|
|
@ -519,85 +519,6 @@ export default class Dom {
|
|||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leafs nodes inside the target list from active element
|
||||
*
|
||||
* @param {HTMLElement[]} nodeList - target list of nodes
|
||||
* @param {number} activeIndex — index of active node. By default it must be -1
|
||||
* @param {string} direction - leaf direction. Can be 'left' or 'right'
|
||||
* @param {string} activeCSSClass - css class that will be added
|
||||
*
|
||||
* @return {Number} index of active node
|
||||
*/
|
||||
public static leafNodesAndReturnIndex(
|
||||
nodeList: HTMLElement[],
|
||||
activeIndex: number,
|
||||
direction: string,
|
||||
activeCSSClass: string,
|
||||
): number {
|
||||
/**
|
||||
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
|
||||
*/
|
||||
if (activeIndex === -1) {
|
||||
/**
|
||||
* Normalize "previous" Tool index depending on direction.
|
||||
* We need to do this to highlight "first" Tool correctly
|
||||
*
|
||||
* Order of Tools: [0] [1] ... [n - 1]
|
||||
* [0 = n] because of: n % n = 0 % n
|
||||
*
|
||||
* Direction 'right': for [0] the [n - 1] is a previous index
|
||||
* [n - 1] -> [0]
|
||||
*
|
||||
* Direction 'left': for [n - 1] the [0] is a previous index
|
||||
* [n - 1] <- [0]
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
activeIndex = direction === 'right' ? -1 : 0;
|
||||
} else {
|
||||
/**
|
||||
* If we have chosen Tool then remove highlighting
|
||||
*/
|
||||
nodeList[activeIndex].classList.remove(activeCSSClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count index for next Tool
|
||||
*/
|
||||
if (direction === 'right') {
|
||||
/**
|
||||
* If we go right then choose next (+1) Tool
|
||||
* @type {number}
|
||||
*/
|
||||
activeIndex = (activeIndex + 1) % nodeList.length;
|
||||
} else {
|
||||
/**
|
||||
* If we go left then choose previous (-1) Tool
|
||||
* Before counting module we need to add length before because of "The JavaScript Modulo Bug"
|
||||
* @type {number}
|
||||
*/
|
||||
activeIndex = (nodeList.length + activeIndex - 1) % nodeList.length;
|
||||
}
|
||||
|
||||
if (Dom.isNativeInput(nodeList[activeIndex])) {
|
||||
/**
|
||||
* Focus input
|
||||
*/
|
||||
nodeList[activeIndex].focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight new chosen Tool
|
||||
*/
|
||||
nodeList[activeIndex].classList.add(activeCSSClass);
|
||||
|
||||
/**
|
||||
* Return Active index
|
||||
*/
|
||||
return activeIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for get holder from {string} or return HTMLElement
|
||||
* @param element
|
||||
|
|
163
src/components/domIterator.ts
Normal file
163
src/components/domIterator.ts
Normal file
|
@ -0,0 +1,163 @@
|
|||
import Dom from './dom';
|
||||
|
||||
/**
|
||||
* Iterator above passed Elements list.
|
||||
* Each next or previous action adds provides CSS-class and sets cursor to this item
|
||||
*/
|
||||
export default class DomIterator {
|
||||
/**
|
||||
* This is a static property that defines iteration directions
|
||||
* @type {{RIGHT: string, LEFT: string}}
|
||||
*/
|
||||
public static directions = {
|
||||
RIGHT: 'right',
|
||||
LEFT: 'left',
|
||||
};
|
||||
|
||||
/**
|
||||
* User-provided CSS-class name for focused button
|
||||
*/
|
||||
private focusedCssClass: string;
|
||||
|
||||
/**
|
||||
* Focused button index.
|
||||
* Default is -1 which means nothing is active
|
||||
* @type {number}
|
||||
*/
|
||||
private cursor: number = -1;
|
||||
|
||||
/**
|
||||
* Items to flip
|
||||
*/
|
||||
private items: HTMLElement[] = [];
|
||||
|
||||
/**
|
||||
* @param {HTMLElement[]} nodeList — the list of iterable HTML-items
|
||||
* @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process
|
||||
*/
|
||||
constructor(
|
||||
nodeList: HTMLElement[],
|
||||
focusedCssClass: string,
|
||||
) {
|
||||
this.items = nodeList;
|
||||
this.focusedCssClass = focusedCssClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Focused button Node
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
public get currentItem(): HTMLElement {
|
||||
if (this.cursor === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.items[this.cursor];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets items. Can be used when iterable items changed dynamically
|
||||
* @param {HTMLElement[]} nodeList
|
||||
*/
|
||||
public setItems(nodeList: HTMLElement[]): void {
|
||||
this.items = nodeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cursor next to the current
|
||||
*/
|
||||
public next(): void {
|
||||
this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.RIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cursor before current
|
||||
*/
|
||||
public previous(): void {
|
||||
this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cursor to the default position and removes CSS-class from previously focused item
|
||||
*/
|
||||
public dropCursor(): void {
|
||||
if (this.cursor === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.items[this.cursor].classList.remove(this.focusedCssClass);
|
||||
this.cursor = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leafs nodes inside the target list from active element
|
||||
*
|
||||
* @param {string} direction - leaf direction. Can be 'left' or 'right'
|
||||
* @return {Number} index of focused node
|
||||
*/
|
||||
private leafNodesAndReturnIndex(direction: string): number {
|
||||
let focusedButtonIndex = this.cursor;
|
||||
|
||||
/**
|
||||
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
|
||||
*/
|
||||
if (focusedButtonIndex === -1) {
|
||||
/**
|
||||
* Normalize "previous" Tool index depending on direction.
|
||||
* We need to do this to highlight "first" Tool correctly
|
||||
*
|
||||
* Order of Tools: [0] [1] ... [n - 1]
|
||||
* [0 = n] because of: n % n = 0 % n
|
||||
*
|
||||
* Direction 'right': for [0] the [n - 1] is a previous index
|
||||
* [n - 1] -> [0]
|
||||
*
|
||||
* Direction 'left': for [n - 1] the [0] is a previous index
|
||||
* [n - 1] <- [0]
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
focusedButtonIndex = direction === DomIterator.directions.RIGHT ? -1 : 0;
|
||||
} else {
|
||||
/**
|
||||
* If we have chosen Tool then remove highlighting
|
||||
*/
|
||||
this.items[focusedButtonIndex].classList.remove(this.focusedCssClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count index for next Tool
|
||||
*/
|
||||
if (direction === DomIterator.directions.RIGHT) {
|
||||
/**
|
||||
* If we go right then choose next (+1) Tool
|
||||
* @type {number}
|
||||
*/
|
||||
focusedButtonIndex = (focusedButtonIndex + 1) % this.items.length;
|
||||
} else {
|
||||
/**
|
||||
* If we go left then choose previous (-1) Tool
|
||||
* Before counting module we need to add length before because of "The JavaScript Modulo Bug"
|
||||
* @type {number}
|
||||
*/
|
||||
focusedButtonIndex = (this.items.length + focusedButtonIndex - 1) % this.items.length;
|
||||
}
|
||||
|
||||
if (Dom.isNativeInput(this.items[focusedButtonIndex])) {
|
||||
/**
|
||||
* Focus input
|
||||
*/
|
||||
this.items[focusedButtonIndex].focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight new chosen Tool
|
||||
*/
|
||||
this.items[focusedButtonIndex].classList.add(this.focusedCssClass);
|
||||
|
||||
/**
|
||||
* Return focused button's index
|
||||
*/
|
||||
return focusedButtonIndex;
|
||||
}
|
||||
}
|
194
src/components/flipper.ts
Normal file
194
src/components/flipper.ts
Normal file
|
@ -0,0 +1,194 @@
|
|||
import DomIterator from './domIterator';
|
||||
import _ from './utils';
|
||||
|
||||
/**
|
||||
* Flipper is a component that iterates passed items array by TAB or Arrows and clicks it by ENTER
|
||||
*/
|
||||
export default class Flipper {
|
||||
/**
|
||||
* Instance of flipper iterator
|
||||
* @type {DomIterator|null}
|
||||
*/
|
||||
private iterator: DomIterator = null;
|
||||
|
||||
/**
|
||||
* Flag that defines activation status
|
||||
* @type {boolean}
|
||||
*/
|
||||
private activated: boolean = false;
|
||||
|
||||
/**
|
||||
* Flag that allows arrows usage to flip items
|
||||
* @type {boolean}
|
||||
*/
|
||||
private allowArrows: boolean = true;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {HTMLElement[]} nodeList - The list of iterable HTML-items
|
||||
* @param {string} focusedCssClass - CSS class name that will be set when item is focused
|
||||
* @param {boolean} allowArrows - Defines arrows usage. By default Flipper leafs items also via RIGHT/LEFT.
|
||||
* Pass 'false' if you don't need this behaviour
|
||||
* (for example, Inline Toolbar should be closed by arrows,
|
||||
* because it means caret moving with selection clearing)
|
||||
*/
|
||||
constructor(
|
||||
nodeList: HTMLElement[],
|
||||
focusedCssClass: string,
|
||||
allowArrows: boolean = true,
|
||||
) {
|
||||
this.allowArrows = allowArrows;
|
||||
this.iterator = new DomIterator(nodeList, focusedCssClass);
|
||||
|
||||
/**
|
||||
* Listening all keydowns on document and react on TAB/Enter press
|
||||
* TAB will leaf iterator items
|
||||
* ENTER will click the focused item
|
||||
*/
|
||||
document.addEventListener('keydown', (event) => {
|
||||
const isReady = this.isEventReadyForHandling(event);
|
||||
|
||||
if (!isReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
switch (event.keyCode) {
|
||||
case _.keyCodes.TAB:
|
||||
this.handleTabPress(event);
|
||||
break;
|
||||
case _.keyCodes.LEFT:
|
||||
this.flipLeft();
|
||||
break;
|
||||
case _.keyCodes.RIGHT:
|
||||
this.flipRight();
|
||||
break;
|
||||
case _.keyCodes.ENTER:
|
||||
this.handleEnterPress(event);
|
||||
break;
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Active tab/arrows handling by flipper
|
||||
* @param {HTMLElement[]} items - Some modules (like, InlineToolbar, BlockSettings) might refresh buttons dynamically
|
||||
*/
|
||||
public activate(items?: HTMLElement[]): void {
|
||||
this.activated = true;
|
||||
|
||||
if (items) {
|
||||
this.iterator.setItems(items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable tab/arrows handling by flipper
|
||||
*/
|
||||
public deactivate(): void {
|
||||
this.activated = false;
|
||||
this.dropCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current focused button
|
||||
* @return {HTMLElement|null}
|
||||
*/
|
||||
public get currentItem(): HTMLElement|null {
|
||||
return this.iterator.currentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus first item
|
||||
*/
|
||||
public focusFirst(): void {
|
||||
this.dropCursor();
|
||||
this.flipRight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops flipper's iterator cursor
|
||||
* @see DomIterator#dropCursor
|
||||
*/
|
||||
private dropCursor(): void {
|
||||
this.iterator.dropCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is fired before handling flipper keycodes
|
||||
* The result of this function defines if it is need to be handled or not
|
||||
* @param {KeyboardEvent} event
|
||||
* @return {boolean}
|
||||
*/
|
||||
private isEventReadyForHandling(event: KeyboardEvent): boolean {
|
||||
const handlingKeyCodeList = [
|
||||
_.keyCodes.TAB,
|
||||
_.keyCodes.ENTER,
|
||||
];
|
||||
|
||||
if (this.allowArrows) {
|
||||
handlingKeyCodeList.push(
|
||||
_.keyCodes.LEFT,
|
||||
_.keyCodes.RIGHT,
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.activated || handlingKeyCodeList.indexOf(event.keyCode) === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When flipper is activated tab press will leaf the items
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
private handleTabPress(event: KeyboardEvent): void {
|
||||
/** this property defines leaf direction */
|
||||
const shiftKey = event.shiftKey,
|
||||
direction = shiftKey ? DomIterator.directions.LEFT : DomIterator.directions.RIGHT;
|
||||
|
||||
switch (direction) {
|
||||
case DomIterator.directions.RIGHT:
|
||||
this.flipRight();
|
||||
break;
|
||||
case DomIterator.directions.LEFT:
|
||||
this.flipLeft();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses previous flipper iterator item
|
||||
*/
|
||||
private flipLeft(): void {
|
||||
this.iterator.previous();
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses next flipper iterator item
|
||||
*/
|
||||
private flipRight(): void {
|
||||
this.iterator.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter press will click current item if flipper is activated
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
private handleEnterPress(event: KeyboardEvent): void {
|
||||
if (!this.activated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.iterator.currentItem) {
|
||||
this.iterator.currentItem.click();
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
|
@ -101,7 +101,7 @@ export default class BlockEvents extends Module {
|
|||
return;
|
||||
}
|
||||
|
||||
const { InlineToolbar, ConversionToolbar, UI, BlockManager } = this.Editor;
|
||||
const { InlineToolbar, ConversionToolbar, UI, BlockManager, BlockSettings } = this.Editor;
|
||||
const block = BlockManager.getBlock(event.target);
|
||||
|
||||
/**
|
||||
|
@ -110,6 +110,7 @@ export default class BlockEvents extends Module {
|
|||
*/
|
||||
if (SelectionUtils.almostAllSelected(block.pluginsContent.textContent)) {
|
||||
InlineToolbar.close();
|
||||
BlockSettings.close();
|
||||
ConversionToolbar.tryToShow(block);
|
||||
} else {
|
||||
ConversionToolbar.close();
|
||||
|
@ -180,36 +181,24 @@ export default class BlockEvents extends Module {
|
|||
*/
|
||||
this.Editor.BlockSelection.clearSelection(event);
|
||||
|
||||
const { BlockManager, Tools, ConversionToolbar, InlineToolbar } = this.Editor;
|
||||
const { BlockManager, Tools, InlineToolbar, ConversionToolbar } = this.Editor;
|
||||
const currentBlock = BlockManager.currentBlock;
|
||||
|
||||
if (!currentBlock) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** Prevent Default behaviour */
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
/** this property defines leaf direction */
|
||||
const shiftKey = event.shiftKey,
|
||||
direction = shiftKey ? 'left' : 'right';
|
||||
|
||||
const canLeafToolbox = Tools.isInitial(currentBlock.tool) && currentBlock.isEmpty;
|
||||
const canLeafInlineToolbar = !currentBlock.isEmpty && !SelectionUtils.isCollapsed && InlineToolbar.opened;
|
||||
const canLeafConversionToolbar = !currentBlock.isEmpty && ConversionToolbar.opened;
|
||||
const canOpenToolbox = Tools.isInitial(currentBlock.tool) && currentBlock.isEmpty;
|
||||
const conversionToolbarOpened = !currentBlock.isEmpty && ConversionToolbar.opened;
|
||||
const inlineToolbarOpened = !currentBlock.isEmpty && !SelectionUtils.isCollapsed && InlineToolbar.opened;
|
||||
|
||||
/**
|
||||
* For empty Blocks we show Plus button via Toobox only for initial Blocks
|
||||
* For empty Blocks we show Plus button via Toolbox only for initial Blocks
|
||||
*/
|
||||
if (canLeafToolbox) {
|
||||
this.leafToolboxTools(direction);
|
||||
} else if (canLeafInlineToolbar) {
|
||||
this.leafInlineToolbarTools(direction);
|
||||
} else if (canLeafConversionToolbar) {
|
||||
this.leafConversionToolbarTools(direction);
|
||||
} else {
|
||||
this.leafBlockSettingsTools(direction);
|
||||
if (canOpenToolbox) {
|
||||
this.activateToolbox();
|
||||
} else if (!conversionToolbarOpened && !inlineToolbarOpened) {
|
||||
this.activateBlockSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,6 +220,8 @@ export default class BlockEvents extends Module {
|
|||
this.Editor.BlockSettings.close();
|
||||
} else if (this.Editor.InlineToolbar.opened) {
|
||||
this.Editor.InlineToolbar.close();
|
||||
} else if (this.Editor.ConversionToolbar.opened) {
|
||||
this.Editor.ConversionToolbar.close();
|
||||
} else {
|
||||
this.Editor.Toolbar.close();
|
||||
}
|
||||
|
@ -314,7 +305,7 @@ export default class BlockEvents extends Module {
|
|||
* @param {KeyboardEvent} event - keydown
|
||||
*/
|
||||
private enter(event: KeyboardEvent): void {
|
||||
const { BlockManager, Toolbox, BlockSettings, InlineToolbar, ConversionToolbar, Tools } = this.Editor;
|
||||
const { BlockManager, Tools, UI } = this.Editor;
|
||||
const currentBlock = BlockManager.currentBlock;
|
||||
const tool = Tools.available[currentBlock.name];
|
||||
|
||||
|
@ -322,29 +313,14 @@ export default class BlockEvents extends Module {
|
|||
* Don't handle Enter keydowns when Tool sets enableLineBreaks to true.
|
||||
* Uses for Tools like <code> where line breaks should be handled by default behaviour.
|
||||
*/
|
||||
if (tool
|
||||
&& tool[Tools.INTERNAL_SETTINGS.IS_ENABLED_LINE_BREAKS]
|
||||
&& !BlockSettings.opened
|
||||
&& !InlineToolbar.opened
|
||||
&& !ConversionToolbar.opened) {
|
||||
if (tool && tool[Tools.INTERNAL_SETTINGS.IS_ENABLED_LINE_BREAKS]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Toolbox.opened && Toolbox.getActiveTool) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
Toolbox.toolButtonActivate(event, Toolbox.getActiveTool);
|
||||
return;
|
||||
}
|
||||
|
||||
if (InlineToolbar.opened && InlineToolbar.focusedButton) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
InlineToolbar.focusedButton.click();
|
||||
/**
|
||||
* Opened Toolbars uses Flipper with own Enter handling
|
||||
*/
|
||||
if (UI.someToolbarOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -388,8 +364,6 @@ export default class BlockEvents extends Module {
|
|||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -502,6 +476,13 @@ export default class BlockEvents extends Module {
|
|||
* Handle right and down keyboard keys
|
||||
*/
|
||||
private arrowRightAndDown(event: KeyboardEvent): void {
|
||||
/**
|
||||
* Arrows might be handled on toolbars by flipper
|
||||
*/
|
||||
if (this.Editor.UI.someToolbarOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldEnableCBS = this.Editor.Caret.isAtEnd || this.Editor.BlockSelection.anyBlockSelected;
|
||||
|
||||
if (event.shiftKey && event.keyCode === _.keyCodes.DOWN && shouldEnableCBS) {
|
||||
|
@ -536,6 +517,13 @@ export default class BlockEvents extends Module {
|
|||
* Handle left and up keyboard keys
|
||||
*/
|
||||
private arrowLeftAndUp(event: KeyboardEvent): void {
|
||||
/**
|
||||
* Arrows might be handled on toolbars by flipper
|
||||
*/
|
||||
if (this.Editor.UI.someToolbarOpened) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldEnableCBS = this.Editor.Caret.isAtStart || this.Editor.BlockSelection.anyBlockSelected;
|
||||
|
||||
if (event.shiftKey && event.keyCode === _.keyCodes.UP && shouldEnableCBS) {
|
||||
|
@ -598,46 +586,20 @@ export default class BlockEvents extends Module {
|
|||
|
||||
/**
|
||||
* If Toolbox is not open, then just open it and show plus button
|
||||
* Next Tab press will leaf Toolbox Tools
|
||||
*
|
||||
* @param {string} direction
|
||||
*/
|
||||
private leafToolboxTools(direction: string): void {
|
||||
private activateToolbox(): void {
|
||||
if (!this.Editor.Toolbar.opened) {
|
||||
this.Editor.Toolbar.open(false , false);
|
||||
this.Editor.Toolbar.plusButton.show();
|
||||
} else {
|
||||
this.Editor.Toolbox.leaf(direction);
|
||||
}
|
||||
|
||||
this.Editor.Toolbox.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* If InlineToolbar is not open, just open it and focus first button
|
||||
* Next Tab press will leaf InlineToolbar Tools
|
||||
*
|
||||
* @param {string} direction
|
||||
*/
|
||||
private leafInlineToolbarTools(direction: string): void {
|
||||
if (this.Editor.InlineToolbar.opened) {
|
||||
this.Editor.InlineToolbar.leaf(direction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaf Conversion Toolbar Tools
|
||||
* @param {string} direction
|
||||
*/
|
||||
private leafConversionToolbarTools(direction: string): void {
|
||||
this.Editor.ConversionToolbar.leaf(direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Toolbar and show BlockSettings before flipping Tools
|
||||
* @param {string} direction
|
||||
*/
|
||||
private leafBlockSettingsTools(direction: string): void {
|
||||
private activateBlockSettings(): void {
|
||||
if (!this.Editor.Toolbar.opened) {
|
||||
this.Editor.BlockManager.currentBlock.focused = true;
|
||||
this.Editor.Toolbar.open(true, false);
|
||||
|
@ -651,7 +613,5 @@ export default class BlockEvents extends Module {
|
|||
if (!this.Editor.BlockSettings.opened) {
|
||||
this.Editor.BlockSettings.open();
|
||||
}
|
||||
|
||||
this.Editor.BlockSettings.leaf(direction);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Module from '../../__module';
|
||||
import $ from '../../dom';
|
||||
import Flipper from '../../flipper';
|
||||
|
||||
/**
|
||||
* Block Settings
|
||||
|
@ -67,9 +68,10 @@ export default class BlockSettings extends Module {
|
|||
private buttons: HTMLElement[] = [];
|
||||
|
||||
/**
|
||||
* Index of active button
|
||||
* Instance of class that responses for leafing buttons by arrows/tab
|
||||
* @type {Flipper|null}
|
||||
*/
|
||||
private focusedButtonIndex: number = -1;
|
||||
private flipper: Flipper = null;
|
||||
|
||||
/**
|
||||
* Panel with block settings with 2 sections:
|
||||
|
@ -85,6 +87,12 @@ export default class BlockSettings extends Module {
|
|||
this.nodes.defaultSettings = $.make('div', this.CSS.defaultSettings);
|
||||
|
||||
$.append(this.nodes.wrapper, [this.nodes.toolSettings, this.nodes.defaultSettings]);
|
||||
|
||||
/**
|
||||
* Active leafing by arrows/tab
|
||||
* Buttons will be filled on opening
|
||||
*/
|
||||
this.enableFlipper();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,6 +113,8 @@ export default class BlockSettings extends Module {
|
|||
|
||||
/** Tell to subscribers that block settings is opened */
|
||||
this.Editor.Events.emit(this.events.opened);
|
||||
|
||||
this.flipper.activate(this.blockTunesButtons);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,8 +134,7 @@ export default class BlockSettings extends Module {
|
|||
this.buttons = [];
|
||||
|
||||
/** Clear focus on active button */
|
||||
this.focusedButtonIndex = -1;
|
||||
|
||||
this.flipper.deactivate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,11 +153,8 @@ export default class BlockSettings extends Module {
|
|||
const toolSettings = this.nodes.toolSettings.querySelectorAll(`.${this.Editor.StylesAPI.classes.settingsButton}`);
|
||||
const defaultSettings = this.nodes.defaultSettings.querySelectorAll(`.${this.CSS.button}`);
|
||||
|
||||
toolSettings.forEach((item, index) => {
|
||||
toolSettings.forEach((item) => {
|
||||
this.buttons.push((item as HTMLElement));
|
||||
if (item.classList.contains(this.CSS.focusedButton)) {
|
||||
this.focusedButtonIndex = index;
|
||||
}
|
||||
});
|
||||
|
||||
defaultSettings.forEach((item) => {
|
||||
|
@ -158,27 +164,6 @@ export default class BlockSettings extends Module {
|
|||
return this.buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaf Block Tunes
|
||||
* @param {string} direction
|
||||
*/
|
||||
public leaf(direction: string = 'right'): void {
|
||||
this.focusedButtonIndex = $.leafNodesAndReturnIndex(
|
||||
this.blockTunesButtons, this.focusedButtonIndex, direction, this.CSS.focusedButton,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns active button HTML element
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
public get focusedButton(): HTMLElement {
|
||||
if (this.focusedButtonIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (this.buttons[this.focusedButtonIndex] as HTMLElement);
|
||||
}
|
||||
/**
|
||||
* Add Tool's settings
|
||||
*/
|
||||
|
@ -194,4 +179,12 @@ export default class BlockSettings extends Module {
|
|||
private addDefaultSettings(): void {
|
||||
$.append(this.nodes.defaultSettings, this.Editor.BlockManager.currentBlock.renderTunes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Active leafing by arrows/tab
|
||||
* Buttons will be filled on opening
|
||||
*/
|
||||
private enableFlipper(): void {
|
||||
this.flipper = new Flipper([], this.CSS.focusedButton);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import {BlockToolConstructable} from '../../../../types';
|
|||
import _ from '../../utils';
|
||||
import {SavedData} from '../../../types-internal/block-data';
|
||||
import Block from '../../block';
|
||||
import Flipper from '../../flipper';
|
||||
|
||||
/**
|
||||
* Block Converter
|
||||
|
@ -38,18 +39,17 @@ export default class ConversionToolbar extends Module {
|
|||
*/
|
||||
public opened: boolean = false;
|
||||
|
||||
/**
|
||||
* Focused button index
|
||||
* -1 equals no chosen Tool
|
||||
* @type {number}
|
||||
*/
|
||||
private focusedButtonIndex: number = -1;
|
||||
|
||||
/**
|
||||
* Available tools
|
||||
*/
|
||||
private tools: { [key: string]: HTMLElement } = {};
|
||||
|
||||
/**
|
||||
* Instance of class that responses for leafing buttons by arrows/tab
|
||||
* @type {Flipper|null}
|
||||
*/
|
||||
private flipper: Flipper = null;
|
||||
|
||||
/**
|
||||
* Create UI of Conversion Toolbar
|
||||
*/
|
||||
|
@ -62,6 +62,11 @@ export default class ConversionToolbar extends Module {
|
|||
*/
|
||||
this.addTools();
|
||||
|
||||
/**
|
||||
* Prepare Flipper to be able to leaf tools by arrows/tab
|
||||
*/
|
||||
this.enableFlipper();
|
||||
|
||||
$.append(this.nodes.wrapper, this.nodes.tools);
|
||||
$.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);
|
||||
}
|
||||
|
@ -77,21 +82,10 @@ export default class ConversionToolbar extends Module {
|
|||
return;
|
||||
}
|
||||
|
||||
const currentToolName = block.name;
|
||||
|
||||
/**
|
||||
* Focus current tool in conversion toolbar
|
||||
* Mark current block's button with color
|
||||
*/
|
||||
if (this.tools[currentToolName]) {
|
||||
/**
|
||||
* Drop previous active button before moving
|
||||
*/
|
||||
if (this.focusedButton && this.focusedButton.classList.contains(ConversionToolbar.CSS.conversionToolActive)) {
|
||||
this.focusedButton.classList.remove(ConversionToolbar.CSS.conversionToolActive);
|
||||
}
|
||||
|
||||
this.tools[currentToolName].classList.add(ConversionToolbar.CSS.conversionToolActive);
|
||||
}
|
||||
this.highlightActiveTool(block.name);
|
||||
|
||||
this.move(block);
|
||||
|
||||
|
@ -105,6 +99,8 @@ export default class ConversionToolbar extends Module {
|
|||
*/
|
||||
public open(): void {
|
||||
this.opened = true;
|
||||
this.flipper.activate();
|
||||
this.flipper.focusFirst();
|
||||
this.nodes.wrapper.classList.add(ConversionToolbar.CSS.conversionToolbarShowed);
|
||||
}
|
||||
|
||||
|
@ -113,43 +109,8 @@ export default class ConversionToolbar extends Module {
|
|||
*/
|
||||
public close(): void {
|
||||
this.opened = false;
|
||||
this.flipper.deactivate();
|
||||
this.nodes.wrapper.classList.remove(ConversionToolbar.CSS.conversionToolbarShowed);
|
||||
|
||||
this.dropFocusedButton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaf tools by Tab
|
||||
* @todo use class with tool iterator
|
||||
*/
|
||||
public leaf(direction: string = 'right'): void {
|
||||
const toolsElements = (Array.from(this.nodes.tools.childNodes) as HTMLElement[]);
|
||||
this.focusedButtonIndex = $.leafNodesAndReturnIndex(
|
||||
toolsElements, this.focusedButtonIndex, direction, ConversionToolbar.CSS.conversionToolFocused,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns focused tool as HTML element
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
public get focusedButton(): HTMLElement {
|
||||
if (this.focusedButtonIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
return (this.nodes.tools.childNodes[this.focusedButtonIndex] as HTMLElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops focused button
|
||||
*/
|
||||
public dropFocusedButton() {
|
||||
Object.values(this.tools).forEach( (tool) => {
|
||||
(tool as HTMLElement).classList
|
||||
.remove(ConversionToolbar.CSS.conversionToolActive, ConversionToolbar.CSS.conversionToolFocused);
|
||||
});
|
||||
|
||||
this.focusedButtonIndex = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,4 +266,29 @@ export default class ConversionToolbar extends Module {
|
|||
await this.replaceWithBlock(toolName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks current Blocks button with highlighting color
|
||||
*/
|
||||
private highlightActiveTool(toolName: string): void {
|
||||
if (!this.tools[toolName]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop previous active button
|
||||
*/
|
||||
Object.values(this.tools).forEach((el) => {
|
||||
el.classList.remove(ConversionToolbar.CSS.conversionToolActive);
|
||||
});
|
||||
|
||||
this.tools[toolName].classList.add(ConversionToolbar.CSS.conversionToolActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare Flipper to be able to leaf tools by arrows/tab
|
||||
*/
|
||||
private enableFlipper(): void {
|
||||
this.flipper = new Flipper(Object.values(this.tools), ConversionToolbar.CSS.conversionToolFocused);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Module from '../../__module';
|
||||
import $ from '../../dom';
|
||||
import _ from '../../utils';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -229,7 +230,7 @@ export default class Toolbar extends Module {
|
|||
* This flag allows to open Toolbar with Toolbox
|
||||
*/
|
||||
public open(withBlockActions: boolean = true, needToCloseToolbox: boolean = true): void {
|
||||
setTimeout(() => {
|
||||
_.delay(() => {
|
||||
this.move(needToCloseToolbox);
|
||||
this.nodes.wrapper.classList.add(this.CSS.toolbarOpened);
|
||||
|
||||
|
@ -238,7 +239,7 @@ export default class Toolbar extends Module {
|
|||
} else {
|
||||
this.blockActions.hide();
|
||||
}
|
||||
}, 50);
|
||||
}, 50)();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import Module from '../../__module';
|
||||
import $ from '../../dom';
|
||||
|
||||
import BoldInlineTool from '../../inline-tools/inline-tool-bold';
|
||||
import ItalicInlineTool from '../../inline-tools/inline-tool-italic';
|
||||
import LinkInlineTool from '../../inline-tools/inline-tool-link';
|
||||
import SelectionUtils from '../../selection';
|
||||
import _ from '../../utils';
|
||||
import {InlineTool, InlineToolConstructable, ToolConstructable, ToolSettings} from '../../../../types';
|
||||
import Flipper from '../../flipper';
|
||||
|
||||
/**
|
||||
* Inline toolbar with actions that modifies selected text fragment
|
||||
|
@ -68,25 +66,17 @@ export default class InlineToolbar extends Module {
|
|||
*/
|
||||
private buttonsList: NodeList = null;
|
||||
|
||||
/**
|
||||
* Visible Buttons
|
||||
* Some Blocks might disable inline tools
|
||||
* @type {HTMLElement[]}
|
||||
*/
|
||||
private visibleButtonsList: HTMLElement[] = [];
|
||||
|
||||
/**
|
||||
* Focused button index
|
||||
* @type {number}
|
||||
*/
|
||||
private focusedButtonIndex: number = -1;
|
||||
|
||||
/**
|
||||
* Cache for Inline Toolbar width
|
||||
* @type {number}
|
||||
*/
|
||||
private width: number = 0;
|
||||
|
||||
/**
|
||||
* Instance of class that responses for leafing buttons by arrows/tab
|
||||
*/
|
||||
private flipper: Flipper = null;
|
||||
|
||||
/**
|
||||
* Inline Toolbar Tools
|
||||
*
|
||||
|
@ -141,6 +131,12 @@ export default class InlineToolbar extends Module {
|
|||
* Recalculate initial width with all buttons
|
||||
*/
|
||||
this.recalculateWidth();
|
||||
|
||||
/**
|
||||
* Allow to leaf buttons by arrows / tab
|
||||
* Buttons will be filled on opening
|
||||
*/
|
||||
this.enableFlipper();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,47 +214,6 @@ export default class InlineToolbar extends Module {
|
|||
this.nodes.wrapper.style.top = Math.floor(newCoords.y) + 'px';
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaf Inline Tools
|
||||
* @param {string} direction
|
||||
*/
|
||||
public leaf(direction: string = 'right'): void {
|
||||
this.visibleButtonsList = (Array.from(this.buttonsList)
|
||||
.filter((tool) => !(tool as HTMLElement).hidden) as HTMLElement[]);
|
||||
|
||||
if (this.visibleButtonsList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.focusedButtonIndex = $.leafNodesAndReturnIndex(
|
||||
this.visibleButtonsList, this.focusedButtonIndex, direction, this.CSS.focusedButton,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops focused button index
|
||||
*/
|
||||
public dropFocusedButtonIndex(): void {
|
||||
if (this.focusedButtonIndex === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.visibleButtonsList[this.focusedButtonIndex].classList.remove(this.CSS.focusedButton);
|
||||
this.focusedButtonIndex = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Focused button Node
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
public get focusedButton(): HTMLElement {
|
||||
if (this.focusedButtonIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.visibleButtonsList[this.focusedButtonIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides Inline Toolbar
|
||||
*/
|
||||
|
@ -272,17 +227,13 @@ export default class InlineToolbar extends Module {
|
|||
|
||||
this.opened = false;
|
||||
|
||||
if (this.focusedButtonIndex !== -1) {
|
||||
this.visibleButtonsList[this.focusedButtonIndex].classList.remove(this.CSS.focusedButton);
|
||||
this.focusedButtonIndex = -1;
|
||||
}
|
||||
this.flipper.deactivate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows Inline Toolbar
|
||||
*/
|
||||
public open(): void {
|
||||
|
||||
/**
|
||||
* Filter inline-tools and show only allowed by Block's Tool
|
||||
*/
|
||||
|
@ -304,6 +255,14 @@ export default class InlineToolbar extends Module {
|
|||
|
||||
this.buttonsList = this.nodes.buttons.querySelectorAll(`.${this.CSS.inlineToolButton}`);
|
||||
this.opened = true;
|
||||
|
||||
/**
|
||||
* Get currently visible buttons to pass it to the Flipper
|
||||
*/
|
||||
const visibleTools = Array.from(this.buttonsList)
|
||||
.filter((tool) => !(tool as HTMLElement).hidden) as HTMLElement[];
|
||||
|
||||
this.flipper.activate(visibleTools);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -565,4 +524,12 @@ export default class InlineToolbar extends Module {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to leaf buttons by arrows / tab
|
||||
* Buttons will be filled on opening
|
||||
*/
|
||||
private enableFlipper(): void {
|
||||
this.flipper = new Flipper([], this.CSS.focusedButton, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import Module from '../../__module';
|
|||
import $ from '../../dom';
|
||||
import _ from '../../utils';
|
||||
import {BlockToolConstructable} from '../../../../types';
|
||||
import Flipper from '../../flipper';
|
||||
|
||||
/**
|
||||
* @class Toolbox
|
||||
|
@ -33,22 +34,6 @@ export default class Toolbox extends Module {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* get tool name when it is selected
|
||||
* In case when nothing selected returns null
|
||||
*
|
||||
* @return {String|null}
|
||||
*/
|
||||
public get getActiveTool(): string {
|
||||
const childNodes = this.nodes.toolbox.childNodes;
|
||||
|
||||
if (this.activeButtonIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (childNodes[this.activeButtonIndex] as HTMLElement).dataset.tool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns True if Toolbox is Empty and nothing to show
|
||||
* @return {boolean}
|
||||
|
@ -57,11 +42,6 @@ export default class Toolbox extends Module {
|
|||
return this.displayedToolsCount === 0;
|
||||
}
|
||||
|
||||
private static LEAF_DIRECTIONS = {
|
||||
RIGHT: 'right',
|
||||
LEFT: 'left',
|
||||
};
|
||||
|
||||
/**
|
||||
* Opening state
|
||||
* @type {boolean}
|
||||
|
@ -81,19 +61,18 @@ export default class Toolbox extends Module {
|
|||
buttons: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Active button index
|
||||
* -1 equals no chosen Tool
|
||||
* @type {number}
|
||||
*/
|
||||
private activeButtonIndex: number = -1;
|
||||
|
||||
/**
|
||||
* How many tools displayed in Toolbox
|
||||
* @type {number}
|
||||
*/
|
||||
private displayedToolsCount: number = 0;
|
||||
|
||||
/**
|
||||
* Instance of class that responses for leafing buttons by arrows/tab
|
||||
* @type {Flipper|null}
|
||||
*/
|
||||
private flipper: Flipper = null;
|
||||
|
||||
/**
|
||||
* Makes the Toolbox
|
||||
*/
|
||||
|
@ -103,6 +82,7 @@ export default class Toolbox extends Module {
|
|||
|
||||
this.addTools();
|
||||
this.addTooltip();
|
||||
this.enableFlipper();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,6 +109,7 @@ export default class Toolbox extends Module {
|
|||
this.nodes.toolbox.classList.add(this.CSS.toolboxOpened);
|
||||
|
||||
this.opened = true;
|
||||
this.flipper.activate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,16 +122,7 @@ export default class Toolbox extends Module {
|
|||
this.Editor.UI.nodes.wrapper.classList.remove(this.CSS.openedToolbarHolderModifier);
|
||||
|
||||
this.opened = false;
|
||||
|
||||
/**
|
||||
* Remove active item pointer
|
||||
*/
|
||||
if (this.activeButtonIndex !== -1) {
|
||||
(this.nodes.toolbox.childNodes[this.activeButtonIndex] as HTMLElement)
|
||||
.classList.remove(this.CSS.toolboxButtonActive);
|
||||
|
||||
this.activeButtonIndex = -1;
|
||||
}
|
||||
this.flipper.deactivate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,18 +136,6 @@ export default class Toolbox extends Module {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaf
|
||||
* flip through the toolbox items
|
||||
* @param {String} direction - leaf direction, right is default
|
||||
*/
|
||||
public leaf(direction: string = Toolbox.LEAF_DIRECTIONS.RIGHT): void {
|
||||
const childNodes = (Array.from(this.nodes.toolbox.childNodes) as HTMLElement[]);
|
||||
this.activeButtonIndex = $.leafNodesAndReturnIndex(
|
||||
childNodes, this.activeButtonIndex, direction, this.CSS.toolboxButtonActive,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide toolbox tooltip
|
||||
*/
|
||||
|
@ -355,6 +315,14 @@ export default class Toolbox extends Module {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Flipper instance to be able to leaf tools
|
||||
*/
|
||||
private enableFlipper(): void {
|
||||
const tools = Array.from(this.nodes.toolbox.childNodes) as HTMLElement[];
|
||||
this.flipper = new Flipper(tools, this.CSS.toolboxButtonActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts new block
|
||||
* Can be called when button clicked on Toolbox or by ShortcutData
|
||||
|
|
|
@ -186,6 +186,17 @@ export default class UI extends Module {
|
|||
this.nodes.wrapper.classList.toggle(this.CSS.editorEmpty, BlockManager.isEditorEmpty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if one of Toolbar is opened
|
||||
* Used to prevent global keydowns (for example, Enter) conflicts with Enter-on-toolbar
|
||||
* @return {boolean}
|
||||
*/
|
||||
public get someToolbarOpened() {
|
||||
const { Toolbox, BlockSettings, InlineToolbar, ConversionToolbar } = this.Editor;
|
||||
|
||||
return BlockSettings.opened || InlineToolbar.opened || ConversionToolbar.opened || Toolbox.opened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean editor`s UI
|
||||
*/
|
||||
|
@ -373,67 +384,9 @@ export default class UI extends Module {
|
|||
* @param event
|
||||
*/
|
||||
private enterPressed(event: KeyboardEvent): void {
|
||||
const { BlockManager, BlockSelection, Caret, BlockSettings, ConversionToolbar } = this.Editor;
|
||||
const { BlockManager, BlockSelection, Caret } = this.Editor;
|
||||
const hasPointerToBlock = BlockManager.currentBlockIndex >= 0;
|
||||
|
||||
/**
|
||||
* If Block Settings is opened and have some active button
|
||||
* Enter press is fired as out of the Block and that's why
|
||||
* we handle it here
|
||||
*/
|
||||
if (BlockSettings.opened && BlockSettings.focusedButton) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
/** Click on settings button */
|
||||
BlockSettings.focusedButton.click();
|
||||
|
||||
/**
|
||||
* Focused button can be deleted by click, for example with 'Remove Block' api
|
||||
*/
|
||||
if (BlockSettings.focusedButton) {
|
||||
/**
|
||||
* Add animation on click
|
||||
*/
|
||||
BlockSettings.focusedButton.classList.add(BlockSettings.CSS.focusedButtonAnimated);
|
||||
|
||||
/**
|
||||
* Remove animation class
|
||||
*/
|
||||
_.delay( () => {
|
||||
if (BlockSettings.focusedButton) {
|
||||
BlockSettings.focusedButton.classList.remove(BlockSettings.CSS.focusedButtonAnimated);
|
||||
}
|
||||
}, 280)();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restoring focus on current Block
|
||||
*
|
||||
* After changing Block state (when settings clicked, for example)
|
||||
* Block's content points to the Node that is not in DOM, that's why we can not
|
||||
* set caret and leaf next (via Tab)
|
||||
*
|
||||
* For that set cursor via Caret module to the current Block's content
|
||||
* after some timeout
|
||||
*/
|
||||
_.delay( () => {
|
||||
Caret.setToBlock(BlockManager.currentBlock);
|
||||
}, 10)();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConversionToolbar.opened && ConversionToolbar.focusedButton) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
ConversionToolbar.focusedButton.click();
|
||||
return;
|
||||
}
|
||||
|
||||
if (BlockSelection.anyBlockSelected) {
|
||||
const selectionPositionIndex = BlockManager.removeSelectedBlocks();
|
||||
Caret.setToBlock(BlockManager.insertInitialBlockAtIndex(selectionPositionIndex, true), Caret.positions.START);
|
||||
|
@ -459,7 +412,7 @@ export default class UI extends Module {
|
|||
* So, BlockManager points some Block and Enter press is on Body
|
||||
* We can create a new block
|
||||
*/
|
||||
if (hasPointerToBlock && (event.target as HTMLElement).tagName === 'BODY') {
|
||||
if (!this.someToolbarOpened && hasPointerToBlock && (event.target as HTMLElement).tagName === 'BODY') {
|
||||
/**
|
||||
* Insert initial typed Block
|
||||
*/
|
||||
|
@ -487,6 +440,13 @@ export default class UI extends Module {
|
|||
* @param {MouseEvent} event - Click
|
||||
*/
|
||||
private documentClicked(event: MouseEvent): void {
|
||||
/**
|
||||
* Sometimes we emulate click on some UI elements, for example by Enter on Block Settings button
|
||||
* We don't need to handle such events, because they handled in other place.
|
||||
*/
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Close Inline Toolbar when nothing selected
|
||||
* Do not fire check on clicks at the Inline Toolbar buttons
|
||||
|
|
31
yarn.lock
31
yarn.lock
|
@ -1509,10 +1509,6 @@ color@^3.0.0:
|
|||
color-convert "^1.9.1"
|
||||
color-string "^1.5.2"
|
||||
|
||||
colors@>=0.6.0:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
|
||||
|
||||
commander@^2.12.1, commander@^2.19.0, commander@^2.8.1:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
|
||||
|
@ -3503,10 +3499,6 @@ miller-rabin@^4.0.0:
|
|||
bn.js "^4.0.0"
|
||||
brorand "^1.0.1"
|
||||
|
||||
mime@^1.2.9:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
|
||||
mimic-fn@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||
|
@ -3544,10 +3536,6 @@ minimist@^1.2.0:
|
|||
version "1.2.0"
|
||||
resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
|
||||
minimist@~0.0.1:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
|
||||
|
||||
minipass@^2.2.1, minipass@^2.3.4:
|
||||
version "2.3.5"
|
||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848"
|
||||
|
@ -3711,14 +3699,6 @@ node-releases@^1.1.8:
|
|||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
node-static@^0.7.11:
|
||||
version "0.7.11"
|
||||
resolved "https://registry.yarnpkg.com/node-static/-/node-static-0.7.11.tgz#60120d349f3cef533e4e820670057eb631882e7f"
|
||||
dependencies:
|
||||
colors ">=0.6.0"
|
||||
mime "^1.2.9"
|
||||
optimist ">=0.3.4"
|
||||
|
||||
nopt@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
|
||||
|
@ -3857,13 +3837,6 @@ onetime@^2.0.0:
|
|||
dependencies:
|
||||
mimic-fn "^1.0.0"
|
||||
|
||||
optimist@>=0.3.4:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
|
||||
dependencies:
|
||||
minimist "~0.0.1"
|
||||
wordwrap "~0.0.2"
|
||||
|
||||
optionator@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
|
||||
|
@ -6132,10 +6105,6 @@ wide-align@^1.1.0:
|
|||
dependencies:
|
||||
string-width "^1.0.2 || 2"
|
||||
|
||||
wordwrap@~0.0.2:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
|
||||
|
||||
wordwrap@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
|
|
Loading…
Reference in a new issue