Fix placeholder at the empty editor (#782)

This commit is contained in:
George Berezhnoy 2019-06-12 20:09:46 +03:00 committed by GitHub
parent 098897e8bb
commit 19518a10ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 83 additions and 52 deletions

16
dist/editor.js vendored

File diff suppressed because one or more lines are too long

View file

@ -6,6 +6,7 @@
- `Fix` *Config* — User config now has higher priority than internal settings
- `New` — Ability to work with Block Actions and Inline Toolbar from the keyboard by Tab.
- `Fix` — Fix error thrown by click on the empty editor after `blocks.clear()` method calling
- `Fix` — Fix placeholder property appearance. Now you can assign it via `placeholder` property of EditorConfig.
### 2.13

View file

@ -82,4 +82,24 @@ var editor = new EditorJS({
var editor2 = new EditorJS({
holder: 'codex-editor' // like document.getElementById('codex-editor')
})
```
```
## Placeholder
By default Editor\`s placeholder is empty.
You can pass your own placeholder via `placeholder` field:
```js
var editor = new EditorJS({
//...
placeholder: 'My awesome placeholder'
//...
});
```
If you are using your custom `Initial Block`, `placeholder` property is passed in `config` to your Tool constructor.

@ -1 +1 @@
Subproject commit a99abc4f84c8dc44b86f037f74e971374d28e22f
Subproject commit 0083d3bcbce82fd2063a15e3914158cb4bf8da7e

@ -1 +1 @@
Subproject commit 54c70585457f110cf7d9567a4bb741d8e98d1189
Subproject commit 37ad8316c138f55b5c210a0c8bb6b83db483187b

@ -1 +1 @@
Subproject commit fc365f869c12824a42d5081a3751741180a99e85
Subproject commit 70876fde289e9f8baa81ee4b5c8c3dc036ac7035

@ -1 +1 @@
Subproject commit 470a64c8ba8a65f3e291d77bc9e2d53a48591f87
Subproject commit 33ffba6f9104d163c69c963ca06fed329a819238

@ -1 +1 @@
Subproject commit da8d692adb3d1e3af10a192a9500e44bd4cc158b
Subproject commit 019fe76e6065d9d59be6c47b8f4a4706f285eee1

@ -1 +1 @@
Subproject commit 7f2e71470910291ba3ebd2fc013fbef33d054aa3
Subproject commit c1db3e8b40e98c36fedb1af0b574e5a161e2a471

@ -1 +1 @@
Subproject commit d72369b6d78e92610681f2e874f6f17cb3a6df27
Subproject commit da9f8a109706d4b4593e19afbfc05614466eb987

@ -1 +1 @@
Subproject commit 3d432a0279321566a23c4d6f27c913128b4c367e
Subproject commit 293109d03d9ff3cdecc52ec959866662d80dd0ce

View file

@ -1,6 +1,6 @@
import $ from './dom';
import _ from './utils';
import {EditorConfig, OutputData, SanitizerConfig, ToolSettings} from '../../types';
import {EditorConfig, OutputData, SanitizerConfig} from '../../types';
import {EditorModules} from '../types-internal/editor-modules';
/**
@ -163,7 +163,7 @@ export default class Core {
data : {},
};
this.config.placeholder = this.config.placeholder || 'write your story...';
this.config.placeholder = this.config.placeholder || false;
this.config.sanitizer = this.config.sanitizer || {
p: true,
b: true,

View file

@ -529,7 +529,12 @@ export default class Dom {
*
* @return {Number} index of active node
*/
public static leafNodesAndReturnIndex(nodeList: HTMLElement[], activeIndex: number, direction: string, activeCSSClass: string): number {
public static leafNodesAndReturnIndex(
nodeList: HTMLElement[],
activeIndex: number,
direction: string,
activeCSSClass: string,
): number {
/**
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
*/

View file

@ -99,6 +99,11 @@ export default class BlockEvents extends Module {
*/
public keyup(event): void {
this.Editor.InlineToolbar.handleShowingEvent(event);
/**
* Check if editor is empty on each keyup and add special css class to wrapper
*/
this.Editor.UI.checkEmptiness();
}
/**

View file

@ -575,6 +575,11 @@ export default class BlockManager extends Module {
if (needAddInitialBlock) {
this.insert(this.config.initialBlock);
}
/**
* Add empty modifier
*/
this.Editor.UI.checkEmptiness();
}
/**

View file

@ -32,7 +32,6 @@ export default class ModificationsObserver extends Module {
* @type {Function}
*/
private mutationDebouncer = _.debounce( () => {
this.checkEmptiness();
this.config.onChange();
}, ModificationsObserver.DebounceTimer);
@ -143,13 +142,4 @@ export default class ModificationsObserver extends Module {
this.mutationDebouncer();
}
}
/**
* Check if Editor is empty and set CSS class to wrapper
*/
private checkEmptiness(): void {
const {BlockManager, UI} = this.Editor;
UI.nodes.wrapper.classList.toggle(UI.CSS.editorEmpty, BlockManager.isEditorEmpty);
}
}

View file

@ -42,10 +42,14 @@ export default class Renderer extends Module {
* Make plugin blocks from array of plugin`s data
* @param {RendererBlocks[]} blocks
*/
public render(blocks: BlockToolData[]): Promise<void> {
public async render(blocks: BlockToolData[]): Promise<void> {
const chainData = blocks.map((block) => ({function: () => this.insertBlock(block)}));
return _.sequence(chainData as ChainData[]);
const sequence = await _.sequence(chainData as ChainData[]);
this.Editor.UI.checkEmptiness();
return sequence;
}
/**

View file

@ -111,7 +111,8 @@ export default class InlineToolbar extends Module {
this.Editor.Listeners.on(this.nodes.wrapper, 'mousedown', (event) => {
const isClickedOnActionsWrapper = (event.target as Element).closest(`.${this.CSS.actionsWrapper}`);
// If click is on actions wrapper, do not prevent default behaviour because actions might include interactive elements
// If click is on actions wrapper,
// do not prevent default behaviour because actions might include interactive elements
if (!isClickedOnActionsWrapper) {
event.preventDefault();
}

View file

@ -302,14 +302,19 @@ export default class Tools extends Module {
/**
* Configuration to be passed to the Tool's constructor
*/
const config = this.toolsSettings[tool][this.apiSettings.CONFIG];
const config = this.toolsSettings[tool][this.apiSettings.CONFIG] || {};
// Pass placeholder to initial Block config
if (tool === this.config.initialBlock && !config.placeholder) {
config.placeholder = this.config.placeholder;
}
/**
* @type {{api: API, config: ({}), data: BlockToolData}}
*/
const constructorOptions = {
api: this.Editor.API.methods,
config: config || {},
config,
data,
};

View file

@ -118,6 +118,15 @@ export default class UI extends Module {
await this.bindEvents();
}
/**
* Check if Editor is empty and set CSS class to wrapper
*/
public checkEmptiness(): void {
const {BlockManager} = this.Editor;
this.nodes.wrapper.classList.toggle(this.CSS.editorEmpty, BlockManager.isEditorEmpty);
}
/**
* Clean editor`s UI
*/

@ -1 +1 @@
Subproject commit 698fdbe5a739043b69349e8ed8ff49788722feae
Subproject commit fa20d187729c72d41129d2e4e89c3a6e989eed12

View file

@ -99,22 +99,8 @@
background-color: var(--selectionColor);
}
/**
* Add placeholder to content editable elements with data attribute
* data-placeholder="Hello world!"
*/
[contentEditable=true][data-placeholder]:empty::before{
content: attr(data-placeholder);
color: var(--grayText);
font-weight: normal;
}
[contentEditable=true][data-placeholder]:empty:focus::before {
opacity: 0.3;
}
.codex-editor--toolbox-opened [contentEditable=true][data-placeholder]:focus::before {
opacity: 0;
opacity: 0 !important;
}
@keyframes editor-loader-spin {

View file

@ -29,7 +29,7 @@ export interface EditorConfig {
/**
* First Block placeholder
*/
placeholder?: string;
placeholder?: string|false;
/**
* Define default sanitizer configuration