Enable editor autofocus (#581)

This commit is contained in:
George Berezhnoy 2019-01-12 03:44:43 +03:00 committed by GitHub
parent e8d43c8fc7
commit da9255a98d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 60 additions and 32 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,9 @@
# Changelog
### 2.2.25 changelog
- `New` *Autofocus — Now you can set focus at Editor after page has been loaded
### 2.2.24 changelog
- `Improvements` *Paste handling — minor paste handling improvements

View file

@ -56,3 +56,17 @@ var editor = CodexEditor({
});
```
## Autofocus
If you want to focus Editor after page has been loaded, you can enable autofocus by passing `autofocus` to the initial config
```js
var editor = CodexEditor({
//...
autofocus: true
//...
});
```

View file

@ -1,6 +1,6 @@
{
"name": "codex.editor",
"version": "2.7.24",
"version": "2.7.25",
"description": "CodeX Editor. Native JS, based on API and Open Source",
"main": "dist/codex-editor.js",
"types": "./types/index.d.ts",

View file

@ -78,6 +78,12 @@ export default class Core {
_.log('I\'m ready! (ノ◕ヮ◕)ノ*:・゚✧', 'log', '', 'color: #E24A75');
setTimeout(() => {
if ((this.configuration as EditorConfig).autofocus) {
const {BlockManager, Caret} = this.moduleInstances;
Caret.setToBlock(BlockManager.blocks[0], Caret.positions.START);
}
/**
* Remove loader, show content
*/

View file

@ -3,7 +3,6 @@
*/
import Module from '../__module';
import _ from '../utils';
import CaretClass from './caret';
export default class BlockEvents extends Module {
/**
@ -217,7 +216,7 @@ export default class BlockEvents extends Module {
BlockManager.removeAllBlocks();
} else {
BlockManager.removeBlock();
Caret.setToBlock(BlockManager.insert(), CaretClass.positions.START);
Caret.setToBlock(BlockManager.insert(), Caret.positions.START);
}
/** Clear selection */
@ -331,7 +330,7 @@ export default class BlockEvents extends Module {
BlockManager.insert();
}
Caret.setToBlock(BlockManager.currentBlock, CaretClass.positions.END);
Caret.setToBlock(BlockManager.currentBlock, Caret.positions.END);
}
/** Close Toolbar */

View file

@ -12,7 +12,6 @@ import $ from '../dom';
import _ from '../utils';
import Blocks from '../blocks';
import {BlockTool, BlockToolConstructable, BlockToolData, PasteEvent, ToolConfig} from '../../../types';
import Caret from './caret';
/**
* @typedef {BlockManager} BlockManager
@ -412,7 +411,10 @@ export default class BlockManager extends Module {
* @param {string} caretPosition - position where to set caret
* @throws Error - when passed Node is not included at the Block
*/
public setCurrentBlockByChildNode(childNode: Node, caretPosition: string = Caret.positions.DEFAULT): void {
public setCurrentBlockByChildNode(
childNode: Node,
caretPosition: string = this.Editor.Caret.positions.DEFAULT,
): void {
/**
* If node is Text TextNode
*/

View file

@ -26,7 +26,7 @@ export default class Caret extends Module {
* @static
* @returns {{START: string, END: string, DEFAULT: string}}
*/
public static get positions(): {START: string, END: string, DEFAULT: string} {
public get positions(): {START: string, END: string, DEFAULT: string} {
return {
START: 'start',
END: 'end',
@ -161,15 +161,15 @@ export default class Caret extends Module {
* If default - leave default behaviour and apply offset if it's passed
* @param {Number} offset - caret offset regarding to the text node
*/
public setToBlock(block: Block, position: string = Caret.positions.DEFAULT, offset: number = 0): void {
public setToBlock(block: Block, position: string = this.positions.DEFAULT, offset: number = 0): void {
const {BlockManager} = this.Editor;
let element;
switch (position) {
case Caret.positions.START:
case this.positions.START:
element = block.firstInput;
break;
case Caret.positions.END:
case this.positions.END:
element = block.lastInput;
break;
default:
@ -180,14 +180,14 @@ export default class Caret extends Module {
return;
}
const nodeToSet = $.getDeepestNode(element, position === Caret.positions.END);
const nodeToSet = $.getDeepestNode(element, position === this.positions.END);
const contentLength = $.getContentLength(nodeToSet);
switch (true) {
case position === Caret.positions.START:
case position === this.positions.START:
offset = 0;
break;
case position === Caret.positions.END:
case position === this.positions.END:
case offset > contentLength:
offset = contentLength;
break;
@ -212,16 +212,16 @@ export default class Caret extends Module {
* If default - leave default behaviour and apply offset if it's passed
* @param {number} offset - caret offset regarding to the text node
*/
public setToInput(input: HTMLElement, position: string = Caret.positions.DEFAULT, offset: number = 0): void {
public setToInput(input: HTMLElement, position: string = this.positions.DEFAULT, offset: number = 0): void {
const {currentBlock} = this.Editor.BlockManager;
const nodeToSet = $.getDeepestNode(input);
switch (position) {
case Caret.positions.START:
case this.positions.START:
this.set(nodeToSet as HTMLElement, 0);
break;
case Caret.positions.END:
case this.positions.END:
const contentLength = $.getContentLength(nodeToSet);
this.set(nodeToSet as HTMLElement, contentLength);
@ -333,16 +333,16 @@ export default class Caret extends Module {
}
if (force) {
this.setToBlock(nextContentfulBlock, Caret.positions.START);
this.setToBlock(nextContentfulBlock, this.positions.START);
return true;
}
if (this.isAtEnd) {
/** If next Tool`s input exists, focus on it. Otherwise set caret to the next Block */
if (!nextInput) {
this.setToBlock(nextContentfulBlock, Caret.positions.START);
this.setToBlock(nextContentfulBlock, this.positions.START);
} else {
this.setToInput(nextInput, Caret.positions.START);
this.setToInput(nextInput, this.positions.START);
}
return true;
@ -374,16 +374,16 @@ export default class Caret extends Module {
}
if (force) {
this.setToBlock( previousContentfulBlock, Caret.positions.END );
this.setToBlock( previousContentfulBlock, this.positions.END );
return true;
}
if (this.isAtStart) {
/** If previous Tool`s input exists, focus on it. Otherwise set caret to the previous Block */
if (!previousInput) {
this.setToBlock( previousContentfulBlock, Caret.positions.END );
this.setToBlock( previousContentfulBlock, this.positions.END );
} else {
this.setToInput(previousInput, Caret.positions.END);
this.setToInput(previousInput, this.positions.END);
}
return true;
}

View file

@ -1,8 +1,6 @@
import SelectionUtils from '../selection';
import Module from '../__module';
import Caret from './caret';
export default class DragNDrop extends Module {
/**
@ -50,6 +48,7 @@ export default class DragNDrop extends Module {
private processDrop = async (dropEvent: DragEvent): Promise<void> => {
const {
BlockManager,
Caret,
Paste,
} = this.Editor;

View file

@ -1,4 +1,3 @@
import CaretClass from './caret';
import Module from '../__module';
import $ from '../dom';
import _ from '../utils';
@ -448,7 +447,7 @@ export default class Paste extends Module {
async (content, i) => await this.insertBlock(content, i === 0 && needToReplaceCurrentBlock),
));
Caret.setToBlock(BlockManager.currentBlock, CaretClass.positions.END);
Caret.setToBlock(BlockManager.currentBlock, Caret.positions.END);
}
/**
@ -585,7 +584,7 @@ export default class Paste extends Module {
insertedBlock = BlockManager.paste(blockData.tool, blockData.event, needToReplaceCurrentBlock);
Caret.setToBlock(insertedBlock, CaretClass.positions.END);
Caret.setToBlock(insertedBlock, Caret.positions.END);
return;
}
}
@ -645,13 +644,13 @@ export default class Paste extends Module {
if (canReplaceCurrentBlock && currentBlock && currentBlock.isEmpty) {
block = BlockManager.paste(data.tool, data.event, true);
Caret.setToBlock(block, CaretClass.positions.END);
Caret.setToBlock(block, Caret.positions.END);
return;
}
block = BlockManager.paste(data.tool, data.event);
Caret.setToBlock(block, CaretClass.positions.END);
Caret.setToBlock(block, Caret.positions.END);
}
/**

View file

@ -8,6 +8,11 @@ export interface EditorConfig {
*/
holderId?: string;
/**
* If true, set caret at the first Block after Editor is ready
*/
autofocus?: boolean;
/**
* This Tool will be used as default
* Name should be equal to one of Tool`s keys of passed tools