mirror of
https://github.com/codex-team/editor.js
synced 2024-06-18 13:45:20 +02:00
Issue-616: Handle backspace, cmd+X, cmd+C and enter on RectangleSelection (#617)
* cut-n-copy multiple selection with rectangle * use pop instead of shift * enter and backspace behavior with rectangeSelection * bump version and minify bundle * optimize code
This commit is contained in:
parent
e6adb4cb5b
commit
8d6ac74b57
|
@ -10,6 +10,7 @@ Welcome to testing stage. Please, join a [public Telegram-chat](//t.me/codex_edi
|
|||
|
||||
### 2.7-2.9 changelog
|
||||
|
||||
- `New` Blocks selected with RectangleSelection can be also removed, copied or cut
|
||||
- `New` Migrate from postcss-cssnext to postcss-preset-env and disable postcss-custom-properties which conflicts with postcss-preset-env
|
||||
- `New` *RectangeSelection* - Ability to select Block or several Blocks with mouse
|
||||
|
||||
|
|
24603
dist/codex-editor.js
vendored
24603
dist/codex-editor.js
vendored
File diff suppressed because one or more lines are too long
1
dist/codex-editor.js.map
vendored
1
dist/codex-editor.js.map
vendored
File diff suppressed because one or more lines are too long
52
dist/codex-editor.licenses.txt
vendored
52
dist/codex-editor.licenses.txt
vendored
|
@ -21,6 +21,32 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
|
||||
|
||||
@babel/runtime
|
||||
MIT
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2014-2018 Sebastian McKenzie and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@babel/polyfill
|
||||
MIT
|
||||
MIT License
|
||||
|
@ -50,32 +76,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
regenerator-runtime
|
||||
MIT
|
||||
|
||||
@babel/runtime
|
||||
MIT
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2014-2018 Sebastian McKenzie and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
codex-notifier
|
||||
MIT
|
||||
MIT License
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
### 2.9.2
|
||||
|
||||
- `New` Blocks selected with RectangleSelection can be also removed, copied or cut
|
||||
|
||||
### 2.9.1
|
||||
|
||||
- `Improvements` Migrate from postcss-cssnext to postcss-preset-env and disable postcss-custom-properties which conflicts with postcss-preset-env
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "codex.editor",
|
||||
"version": "2.9.1",
|
||||
"version": "2.9.2",
|
||||
"description": "CodeX Editor. Native JS, based on API and Open Source",
|
||||
"main": "dist/codex-editor.js",
|
||||
"types": "./types/index.d.ts",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
*/
|
||||
import Module from '../__module';
|
||||
import _ from '../utils';
|
||||
import Block from '../block';
|
||||
|
||||
export default class BlockEvents extends Module {
|
||||
/**
|
||||
|
@ -197,32 +196,26 @@ export default class BlockEvents extends Module {
|
|||
*/
|
||||
public handleCommandX(event): void {
|
||||
const { BlockSelection, BlockManager, Caret } = this.Editor;
|
||||
const currentBlock = BlockManager.currentBlock;
|
||||
|
||||
if (!currentBlock) {
|
||||
if (!BlockSelection.anyBlockSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** Copy Blocks before removing */
|
||||
if (currentBlock.selected || BlockManager.currentBlock.isEmpty) {
|
||||
/**
|
||||
* Prevent default copy
|
||||
* Remove "decline sound" on macOS
|
||||
*/
|
||||
event.preventDefault();
|
||||
/**
|
||||
* Copy Blocks before removing
|
||||
*
|
||||
* Prevent default copy
|
||||
* Remove "decline sound" on macOS
|
||||
*/
|
||||
event.preventDefault();
|
||||
|
||||
BlockSelection.copySelectedBlocks();
|
||||
BlockSelection.copySelectedBlocks();
|
||||
|
||||
if (BlockSelection.allBlocksSelected) {
|
||||
BlockManager.removeAllBlocks();
|
||||
} else {
|
||||
BlockManager.removeBlock();
|
||||
Caret.setToBlock(BlockManager.insert(), Caret.positions.START);
|
||||
}
|
||||
const selectionPositionIndex = BlockManager.removeSelectedBlocks();
|
||||
Caret.setToBlock(BlockManager.insertAtIndex(selectionPositionIndex, true), Caret.positions.START);
|
||||
|
||||
/** Clear selection */
|
||||
BlockSelection.clearSelection();
|
||||
}
|
||||
/** Clear selection */
|
||||
BlockSelection.clearSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,26 +223,10 @@ export default class BlockEvents extends Module {
|
|||
* @param {KeyboardEvent} event - keydown
|
||||
*/
|
||||
private enter(event: KeyboardEvent): void {
|
||||
const {BlockSelection, BlockManager, Tools, Caret} = this.Editor;
|
||||
const {BlockManager, Tools} = this.Editor;
|
||||
const currentBlock = BlockManager.currentBlock;
|
||||
const tool = Tools.available[currentBlock.name];
|
||||
|
||||
if (currentBlock.selected) {
|
||||
if (BlockSelection.allBlocksSelected) {
|
||||
BlockManager.removeAllBlocks();
|
||||
} else {
|
||||
/** Replace current Block */
|
||||
const newBlock = BlockManager.replace();
|
||||
|
||||
/** Set caret to the current block */
|
||||
Caret.setToBlock(newBlock);
|
||||
}
|
||||
|
||||
/** Clear selection */
|
||||
BlockSelection.clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -325,25 +302,21 @@ export default class BlockEvents extends Module {
|
|||
if (currentBlock.selected || currentBlock.isEmpty && currentBlock.currentInput === currentBlock.firstInput) {
|
||||
event.preventDefault();
|
||||
|
||||
if (BlockSelection.allBlocksSelected) {
|
||||
BlockManager.removeAllBlocks();
|
||||
const index = BlockManager.currentBlockIndex;
|
||||
|
||||
if (BlockManager.previousBlock && BlockManager.previousBlock.inputs.length === 0) {
|
||||
/** If previous block doesn't contain inputs, remove it */
|
||||
BlockManager.removeBlock(index - 1);
|
||||
} else {
|
||||
const index = BlockManager.currentBlockIndex;
|
||||
|
||||
if (BlockManager.previousBlock && BlockManager.previousBlock.inputs.length === 0) {
|
||||
/** If previous block doesn't contain inputs, remove it */
|
||||
BlockManager.removeBlock(index - 1);
|
||||
} else {
|
||||
/** If block is empty, just remove it */
|
||||
BlockManager.removeBlock();
|
||||
}
|
||||
|
||||
Caret.setToBlock(
|
||||
BlockManager.currentBlock,
|
||||
index ? Caret.positions.END : Caret.positions.START,
|
||||
);
|
||||
/** If block is empty, just remove it */
|
||||
BlockManager.removeBlock();
|
||||
}
|
||||
|
||||
Caret.setToBlock(
|
||||
BlockManager.currentBlock,
|
||||
index ? Caret.positions.END : Caret.positions.START,
|
||||
);
|
||||
|
||||
/** Close Toolbar */
|
||||
this.Editor.Toolbar.close();
|
||||
|
||||
|
|
|
@ -347,6 +347,29 @@ export default class BlockManager extends Module {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove only selected Blocks
|
||||
* and returns first Block index where started removing...
|
||||
* @return number|undefined
|
||||
*/
|
||||
public removeSelectedBlocks(): number|undefined {
|
||||
let firstSelectedBlockIndex;
|
||||
|
||||
/**
|
||||
* Remove selected Blocks from the end
|
||||
*/
|
||||
for (let index = this.blocks.length - 1; index >= 0; index--) {
|
||||
if (!this.blocks[index].selected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.removeBlock(index);
|
||||
firstSelectedBlockIndex = index;
|
||||
}
|
||||
|
||||
return firstSelectedBlockIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attention!
|
||||
* After removing insert new initial typed Block and focus on it
|
||||
|
|
|
@ -47,7 +47,7 @@ export default class Shortcuts extends Module {
|
|||
|
||||
const newShortcut = new Shortcut({
|
||||
name: shortcut.name,
|
||||
on: UI.nodes.redactor,
|
||||
on: document, // UI.nodes.redactor
|
||||
callback: shortcut.handler,
|
||||
});
|
||||
|
||||
|
|
|
@ -202,6 +202,9 @@ export default class UI extends Module {
|
|||
case _.keyCodes.ENTER:
|
||||
this.enterPressed(event);
|
||||
break;
|
||||
case _.keyCodes.BACKSPACE:
|
||||
this.backspacePressed(event);
|
||||
break;
|
||||
default:
|
||||
this.defaultBehaviour(event);
|
||||
break;
|
||||
|
@ -220,7 +223,7 @@ export default class UI extends Module {
|
|||
/**
|
||||
* Ignore keydowns on editor and meta keys
|
||||
*/
|
||||
if (keyDownOnEditor || currentBlock && isMetaKey) {
|
||||
if (keyDownOnEditor || (currentBlock && isMetaKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -235,14 +238,51 @@ export default class UI extends Module {
|
|||
this.Editor.Toolbar.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
private backspacePressed(event: KeyboardEvent): void {
|
||||
const {BlockManager, BlockSelection, Caret} = this.Editor;
|
||||
|
||||
if (BlockSelection.anyBlockSelected) {
|
||||
const selectionPositionIndex = BlockManager.removeSelectedBlocks();
|
||||
Caret.setToBlock(BlockManager.insertAtIndex(selectionPositionIndex, true), Caret.positions.START);
|
||||
|
||||
/** Clear selection */
|
||||
BlockSelection.clearSelection();
|
||||
|
||||
/**
|
||||
* Stop propagations
|
||||
* Manipulation with BlockSelections is handled in global backspacePress because they may occur
|
||||
* with CMD+A or RectangleSelection and they can be handled on document event
|
||||
*/
|
||||
event.stopPropagation();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter pressed on document
|
||||
* @param event
|
||||
*/
|
||||
private enterPressed(event: KeyboardEvent): void {
|
||||
const hasPointerToBlock = this.Editor.BlockManager.currentBlockIndex >= 0;
|
||||
const {BlockManager, BlockSelection, Caret} = this.Editor;
|
||||
const hasPointerToBlock = BlockManager.currentBlockIndex >= 0;
|
||||
|
||||
if (this.Editor.BlockSelection.anyBlockSelected) {
|
||||
if (BlockSelection.anyBlockSelected) {
|
||||
const selectionPositionIndex = BlockManager.removeSelectedBlocks();
|
||||
Caret.setToBlock(BlockManager.insertAtIndex(selectionPositionIndex, true), Caret.positions.START);
|
||||
|
||||
/** Clear selection */
|
||||
BlockSelection.clearSelection();
|
||||
|
||||
/**
|
||||
* Stop propagations
|
||||
* Manipulation with BlockSelections is handled in global enterPress because they may occur
|
||||
* with CMD+A or RectangleSelection
|
||||
*/
|
||||
event.stopImmediatePropagation();
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue