Version 2.13 (#719)

* Do not start multi-block selection on UI elements (#662)

* Do not start multi-block selection on UI elements

* Do not prevent mousedown event on inline toolbar actions

* Remove log

* Add comment

* Add link to issue

closes #646

* Fix loss of pointer (#666)

* Fix loss of pointer when click is outside of the editor but selection is inside

* Remove log

* Update shortcuts module (#685)

* Fixed possible grammatical typo (#681)

Thanks

* Update shortcuts module

* update changelog

* update

* Remove margin top for inline-link icon (#690)

* Remove margin top for inline-link icon

resolves #674

* Update CHANGELOG.md

* Remove unused style

* Pull fresh tools

* Remove changelog contents from readme (#700)

* #665 API to open and close inline-toolbar (#711)

* API to open and close inline-toolbar

* Fixed documentation

* renamed inline -> inline-toolbar

* removed dist

* reset editor.js

* added editor.js bundle

* Fixed build error

* Null checks on toolbar/inline@open

* updated bundle

* Improve some comments

* Updatd api.md CHANGELOG.md

* Change feature to new instead of improvement

* Allow holderId work with ref on dom element (#710)

* done

* update types

* attempt to simplify code

* remove useless helper

* revert holderId logic and add holder property

* Apply suggestions from code review

Co-Authored-By: dimensi <eddimensi@gmail.com>

* update holder type on string | HTMLElement

* fix typo

* add deprecated notice and fix typos

* fix wrong compare

* fix comments

* swap console.log on _.log

* update types for editor config

* update examples

* update docs

* update build

* Activating Open Collective (#736)

Hi, I'm making updates for Open Collective. Either you or a supporter signed this repo up for Open Collective. This pull request adds backers and sponsors from your Open Collective https://opencollective.com/editorjs❤️

It adds two badges at the top to show the latest number of backers and sponsors. It also adds placeholders so that the avatar/logo of new backers/sponsors can automatically be shown without having to update your README.md. [more info](https://github.com/opencollective/opencollective/wiki/Github-banner). See how it looks on this [repo](https://github.com/apex/apex#backers).

You can also add a postinstall script to let people know after npm|yarn install that you are welcoming donations (optional). [More info](https://github.com/OpenCollective/opencollective-cli)
You can also add a "Donate" button to your website and automatically show your backers and sponsors there with our widgets. Have a look here: https://opencollective.com/widgets

P.S: As with any pull request, feel free to comment or suggest changes. The only thing "required" are the placeholders on the README because we believe it's important to acknowledge the people in your community that are contributing (financially or with code!).

Thank you for your great contribution to the open source community. You are awesome! 🙌
And welcome to the open collective community! 😊

Come chat with us in the #opensource channel on https://slack.opencollective.com - great place to ask questions and share best practices with other open source sustainers!

* Do not install editor.js as dev-dependency (#731)

Resolves #730

* Move codex-notifier to dependencies for typescript declarations (#728)

* Close inline toolbar after creating new link by pressing ENTER (#722)

* Method to clear current selection and close inline toolbar

* clearSelection with optional collapsed range

* refactored selection.ts

* removed experimental function

* Update src/components/selection.ts

Co-Authored-By: tanmayv <12tanmayvijay@gmail.com>

* update version, add changelog

* Link Logo Image to homepage (#738)

* Update README.md (#744)

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

Co-Authored-By: neSpecc <specc.dev@gmail.com>

* Config minHeight option that allows to customize bottom zone (#745)

* issue-739: allow Block's editable element selection (#747)

* issue-739: allow Block's input selection

* little improvements

* update Changelog and cache inputs

* small fix

* delete map file

* fix inputs.count condition

* Fix typo in example paragraph (#749)

* Fix typo

* Update example-dev.html

* minor release
This commit is contained in:
George Berezhnoy 2019-04-29 15:52:54 +03:00 committed by Peter Savchenko
parent ce69182d06
commit 79f8660637
28 changed files with 303 additions and 118 deletions

View file

@ -1,8 +1,10 @@
<p align="center"><img src="https://capella.pics/79ce946a-d636-41cd-aa96-d3bc5ecfde03.jpg"></p>
<a href="https://editorjs.io/"><p align="center"><img src="https://capella.pics/79ce946a-d636-41cd-aa96-d3bc5ecfde03.jpg"></p></a>
[![](https://flat.badgen.net/npm/v/@editorjs/editorjs?icon=npm)](https://www.npmjs.com/package/@editorjs/editorjs)
[![](https://flat.badgen.net/bundlephobia/min/@editorjs/editorjs?color=cyan)](https://www.npmjs.com/package/@editorjs/editorjs)
[![](https://flat.badgen.net/bundlephobia/minzip/@editorjs/editorjs?color=green)](https://www.npmjs.com/package/@editorjs/editorjs)
[![Backers on Open Collective](https://opencollective.com/editorjs/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/editorjs/sponsors/badge.svg)](#sponsors)
[![](https://flat.badgen.net/npm/license/@editorjs/editorjs)](https://www.npmjs.com/package/@editorjs/editorjs)
[![Join the chat at https://gitter.im/codex-team/editor.js](https://badges.gitter.im/codex-team/editor.js.svg)](https://gitter.im/codex-team/editor.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@ -18,66 +20,38 @@ Join [public Telegram-chat](//t.me/codex_editor) or [Gitter-channel](https://git
| --------- | --------- | --------- | --------- | --------- | --------- |
| Edge 12+ | Firefox 18+ | Chrome 49+ | Safari 10+ | Safari 10+ | Opera 36+
### 2.7-2.9 changelog
## ⭐️ If you like a project
- `Fix` - Clear focus when click is outside the Editor instance
- `Fix` — Fix CMD+A Selection on multiple Editor instances
- `New` — Toolbox now have beautiful helpers with Tool names and shortcuts
- `Improvements` — Prevent navigating back on Firefox when Block is removing by backspace
- `New` — Blocks selected with Rectangle Selection 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
### 2.2—2.7 changelog
- `New` *Sanitize API* — [Sanitize Config](https://github.com/codex-team/editor.js/blob/master/docs/tools.md#automatic-sanitize) of `Block Tools` now automatically extends by tags of `Inline Tools` that is enabled by current Tool by `inlineToolbar` option. You don't need more to specify `a, b, mark, code` manually. This feature will be added to fields that supports inline markup.
- `New` *Block Selection* — Ability to select Block by `CMD+A`, and the whole Editor by double `CMD+A`. After that, you can copy (`CMD+C`), remove (`Backspace`) or clear (`Enter`) selected Blocks.
- `New` *[Styles API](https://github.com/codex-team/editor.js/blob/master/types/api/styles.d.ts)* — Added `button` class for stylization of any buttons provided by Tools with one unified style.
- `New` *[Notifier API](https://github.com/codex-team/editor.js/blob/master/docs/api.md#notifierapi)* — methods for showing user notifications: on success, errors, warnings, etc.
- `New` *Block Tool* — [Table](http://github.com/editor-js/table) constructor 💪
- `New` If one of the Tools is unavailable on Editor initialization, its Blocks will be rendered with *Dummy Block*, describing that user can not edit content of this Block. Dummy Blocks can be moved, removed and saved as normal Blocks. So saved data won't be lost if one of the Tools is failed
- `New` [Public TS-types](https://github.com/codex-team/editor.js/tree/master/types) are presented.
- `Changes` *Tools API* — options `irreplaceable` and `contentless` was removed.
- `Changes` *Tools API* — [Paste API](https://github.com/codex-team/editor.js/blob/master/docs/tools.md#paste-handling): tags, patterns and mime-types now should be specified by Tool's `pasteConfig` static property. Custom Paste Event should be handled by `onPaste(event)` that should not be static from now.
- `Changes` *Tools API* — options `displayInToolbox ` and `toolboxIcon` was removed. Use [`toolbox`](https://github.com/codex-team/editor.js/blob/master/docs/tools.md#internal-tool-settings) instead, that should return object with `icon` and `title` field, or `false` if Tool should not be placed at the Toolbox. Also, there are a way to override `toolbox {icon, title}` settings provided by Tool with you own settings at the Initial Config.
- `Improvements` — All Projects code now on TypeScript
- `Improvements` — NPM package size decreased from 1300kb to 422kb
- `Improvements` — Bundle size decreased from 438kb to 252kb
- `Improvements``Inline Toolbar`: when you add a Link to the selected fragment, Editor will highlight this fragment even when Caret is placed into the URL-input.
- `Improvements` — Block Settings won't be shown near empty Blocks of `initialType` by default. You should click on them instead.
- `Improvements``onChange`-callback now will be fired even with children attributes changing.
- `Improvements` — HTMLJanitor package was updated due to found vulnerability
- `Improvements` — Logging improved: now all Editor's logs will be preceded by beautiful label with current Editor version.
- `Improvements` — Internal `isEmpty` checking was improved for Blocks with many children nodes (200 and more)
- `Improvements` — Paste improvements: tags that can be substituted by Tool now will matched even on deep-level of pasted DOM three.
- `Improvements` — There is no more «unavailable» sound on copying Block by `CMD+C` on macOS
- `Improvements` — Dozens of bugfixes and small improvements
See a whole [Changelog](/docs/CHANGELOG.md)
If you like Editor.js you can support project improvements and development of new features with a small donation on [Open Collective](https://opencollective.com/editorjs) or [Patreon](https://www.patreon.com/editorjs)
## Documentation
While we develop the new Documentation Site with all stuff, you can check some available docs at the [docs/](docs/) dir.
Please, visit [https://editorjs.io/](https://editorjs.io) to view all documentation articles.
- [Installation](docs/installation.md)
- [How to use](docs/usage.md)
- [How to create a Block Tool Plugin](docs/tools.md)
- [How to create an Inline Tool Plugin](docs/tools-inline.md)
- [API for Tools](docs/api.md)
- [Base concepts](https://editorjs.io/base-concepts)
- [Getting started](https://editorjs.io/getting-started)
- [Configuration](https://editorjs.io/configuration)
- [How to create a Block Tool Plugin](https://editorjs.io/creating-a-block-tool)
- [How to create an Inline Tool Plugin](https://editorjs.io/creating-an-inline-tool)
- [API for Tools](https://editorjs.io/tools-api)
Sorry if we missed something. You can join a [Telegram-chat](//t.me/codex_editor) and ask a question.
You can join a [Gitter-channel](https://gitter.im/codex-team/editor.js) or [Telegram-chat](//t.me/codex_editor) and ask a question.
---
## Changelog
See a whole [Changelog](/docs/CHANGELOG.md)
# So how to use Editor.js
## Basics
Editor.js is a Block-Styled editor. Blocks are structural units, of which the Entry is composed.
For example, `Paragraph`, `Heading`, `Image`, `Video`, `List` are Blocks. Each Block is represented by Plugin.
We have [many](http://github.com/editor-js/) ready-to-use Plugins and a [simple API](docs/tools.md) for creating new ones.
We have [many](http://github.com/editor-js/) ready-to-use Plugins and a [simple API](https://editorjs.io/tools-api) for creating new ones.
So how to use the Editor after [Installation](docs/installation.md).
So how to use the Editor after [Installation](https://editorjs.io/getting-started).
- Create new Blocks by Enter or with the Plus Button
- Press `TAB` or click on the Plus Button to view the Toolbox
@ -152,7 +126,7 @@ Choose the most usable method of getting Editor for you.
Install the package via NPM or Yarn
```shell
npm i @editorjs/editorjs --save-dev
npm i @editorjs/editorjs
```
Include module in your application
@ -245,10 +219,10 @@ var editor = new EditorJS({
## Saving Data
Call `editor.saver.save()` and handle returned Promise with saved data.
Call `editor.save()` and handle returned Promise with saved data.
```javascript
editor.saver.save()
editor.save()
.then((savedData) => {
console.log(savedData);
});
@ -262,6 +236,30 @@ Take a look at the [example.html](example/example.html) to view more detailed ex
- We use [HTMLJanitor](https://github.com/guardian/html-janitor) module in our Sanitizer module.
# Support project improvements
Love Editor.js? Please consider supporting our collective:
👉 [https://opencollective.com/editorjs](https://opencollective.com/editorjs)
👉 [Patreon](https://www.patreon.com/editorjs)
## Contributors
This project exists thanks to all the people who contribute. <img src="https://opencollective.com/editorjs/contributors.svg?width=890&button=false" />
## Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/editorjs#backer)]
<a href="https://opencollective.com/editorjs#backers" target="_blank"><img src="https://opencollective.com/editorjs/backers.svg?width=890"></a>
## Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/editorjs#sponsor)]
<a href="https://opencollective.com/editorjs/sponsor/0/website" target="_blank"><img src="https://opencollective.com/editorjs/sponsor/0/avatar.svg"></a>
# About team
We are CodeX and we build products for developers and makers.
@ -271,8 +269,3 @@ Follow us on Twitter: [twitter.com/codex_team](https://twitter.com/codex_team)
Feel free to contact: <a href="mailto:team@codex.so?subject=Editor.js feedback">team@codex.so</a>
[codex.so](https://codex.so)
# Support project improvements
Love Editor.js? Please consider supporting our collective:
👉 [https://opencollective.com/editorjs](https://opencollective.com/editorjs)

18
dist/editor.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,18 @@
# Changelog
### 2.13
- `Improvements` *BlockSelection* — Block Selection allows to select single editable element via CMD+A
- `New` *API* — Added [API methods](api.md) to open and close inline toolbar [#665](https://github.com/codex-team/editor.js/issues/665)
- `New` *Config* - Added new property in EditorConfig `holder`, use this property for append Editor instead `holderId`. `holder` property now support reference on dom element. [#696](https://github.com/codex-team/editor.js/issues/696)
- `Deprecated` *Config* - `holderId` property now is deprecated and will removed in next major release. Use `holder` instead.
- `Fix` *Types* — Fixed error with `codex-notifier` package [#713](https://github.com/codex-team/editor.js/issues/713)
- `Improvements` — Close inline toolbar after creating a new link.
- `New` *Config* — Option `minHeight` for customizing Editor's bottom zone height added.
### 2.12.4
- `Improvements` CodeX.Shortcuts version updated to the v1.1 [#684](https://github.com/codex-team/editor.js/issues/684)
- `Improvements` CodeX.Shortcuts version updated to the v1.1 [#684](https://github.com/codex-team/editor.js/issues/684)
- `Fix` — Do not start multi-block selection on Toolbox and Inline Toolbar [#646](https://github.com/codex-team/editor.js/issues/646)
- `Fix` — Minor fixes of caret behaviour [#663](https://github.com/codex-team/editor.js/issues/663)
- `Fix` — Fix inline-link icon position in Firefox [#674](https://github.com/codex-team/editor.js/issues/674)

View file

@ -69,6 +69,14 @@ Methods that working with Toolbar
`close()` - closes toolbar, toolbox and blockSettings if they are opened
### InlineToolbarAPI
Methods that works with inline toolbar
`open()` - opens inline toolbar, (opens for the current selection)
`close()` - closes inline toolbar
### ListenerAPI
Methods that allows to work with DOM listener. Useful when you forgot to remove listener. Module collects all listeners and destroys automatically

View file

@ -21,7 +21,7 @@ Choose the most usable method of getting Editor for you.
Install the package via NPM or Yarn
```shell
npm i @editorjs/editorjs --save-dev
npm i @editorjs/editorjs
```
Include module at your application

View file

@ -40,7 +40,7 @@ Action | Shortcut | Restrictions
Also we support shortcuts on the all type of Tools. Specify a shortcut with the Tools configuration. For example:
```js
var editor = EditorJS({
var editor = new EditorJS({
//...
tools: {
header: {
@ -63,10 +63,23 @@ If you want to focus Editor after page has been loaded, you can enable autofocus
```js
var editor = EditorJS({
var editor = new EditorJS({
//...
autofocus: true
//...
});
```
## Holder
The `holder` property supports an id or a reference to dom element.
```js
var editor = new EditorJS({
holder: document.querySelector('.editor'),
})
var editor2 = new EditorJS({
holder: 'codex-editor' // like document.getElementById('codex-editor')
})
```

View file

@ -87,7 +87,7 @@
/**
* Wrapper of Editor
*/
holderId: 'editorjs',
holder: 'editorjs',
/**
* Tools list
@ -259,7 +259,7 @@
{
type : 'paragraph',
data : {
text : 'We have been working on this project more than three years. Several large media projects help us to test and debug the Editor, to make it\'s core more stable. At the same time we significantly improved the API. Now, it can be used to create any plugin for any task. Hope you enjoy. 😏'
text : 'We have been working on this project more than three years. Several large media projects help us to test and debug the Editor, to make its core more stable. At the same time we significantly improved the API. Now, it can be used to create any plugin for any task. Hope you enjoy. 😏'
}
},
{

View file

@ -78,7 +78,7 @@
/**
* Wrapper of Editor
*/
holderId: 'editorjs',
holder: 'editorjs',
/**
* Tools list
@ -248,7 +248,7 @@
{
type : 'paragraph',
data : {
text : 'We have been working on this project more than three years. Several large media projects help us to test and debug the Editor, to make it\'s core more stable. At the same time we significantly improved the API. Now, it can be used to create any plugin for any task. Hope you enjoy. 😏'
text : 'We have been working on this project more than three years. Several large media projects help us to test and debug the Editor, to make its core more stable. At the same time we significantly improved the API. Now, it can be used to create any plugin for any task. Hope you enjoy. 😏'
}
},
{

View file

@ -1,6 +1,6 @@
{
"name": "@editorjs/editorjs",
"version": "2.12.4",
"version": "2.13.0",
"description": "Editor.js — Native JS, based on API and Open Source",
"main": "dist/editor.js",
"types": "./types/index.d.ts",
@ -40,7 +40,6 @@
"babel-loader": "^8.0.5",
"babel-plugin-add-module-exports": "^1.0.0",
"babel-plugin-class-display-name": "^2.1.0",
"codex-notifier": "^1.1.1",
"css-loader": "^2.1.1",
"cssnano": "^4.1.10",
"eslint": "^5.15.1",
@ -69,5 +68,8 @@
"collective": {
"type": "opencollective",
"url": "https://opencollective.com/editorjs"
},
"dependencies": {
"codex-notifier": "^1.1.2"
}
}

View file

@ -59,6 +59,13 @@ export default class Block {
* @returns {HTMLElement[]}
*/
get inputs(): HTMLElement[] {
/**
* Return from cache if existed
*/
if (this.cachedInputs.length !== 0) {
return this.cachedInputs;
}
const content = this.holder;
const allowedInputTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url'];
@ -85,6 +92,11 @@ export default class Block {
this.inputIndex = inputs.length - 1;
}
/**
* Cache inputs
*/
this.cachedInputs = inputs;
return inputs;
}
@ -264,6 +276,14 @@ export default class Block {
this.holder.classList.toggle(Block.CSS.wrapperStretched, state);
}
/**
* Toggle drop target state
* @param {boolean} state
*/
public set dropTarget(state) {
this.holder.classList.toggle(Block.CSS.dropTarget, state);
}
/**
* Block Tool`s name
*/
@ -294,6 +314,12 @@ export default class Block {
*/
public tunes: BlockTune[];
/**
* Cached inputs
* @type {HTMLElement[]}
*/
private cachedInputs: HTMLElement[] = [];
/**
* Editor`s API
*/
@ -445,14 +471,6 @@ export default class Block {
return tunesElement;
}
/**
* Toggle drop target state
* @param {boolean} state
*/
public set dropTarget(state) {
this.holder.classList.toggle(Block.CSS.dropTarget, state);
}
/**
* Update current input index with selection anchor node
*/
@ -480,7 +498,15 @@ export default class Block {
/**
* Is fired when DOM mutation has been happened
*/
private didMutated = () => {
private didMutated = (): void => {
/**
* Drop cache
*/
this.cachedInputs = [];
/**
* Update current input
*/
this.updateCurrentInput();
}

View file

@ -116,10 +116,19 @@ export default class Core {
*/
if (typeof config !== 'object') {
config = {
holderId: config,
holder: config,
};
}
/**
* If holderId is preset, assign him to holder property and work next only with holder
*/
if (config.holderId && !config.holder) {
config.holder = config.holderId;
config.holderId = null;
_.log('holderId property will deprecated in next major release, use holder property instead.', 'warn');
}
/**
* Place config into the class property
* @type {EditorConfig}
@ -127,10 +136,10 @@ export default class Core {
this.config = config;
/**
* If holderId is empty then set a default value
* If holder is empty then set a default value
*/
if (!this.config.holderId || typeof this.config.holderId !== 'string') {
this.config.holderId = 'editorjs';
if (this.config.holder == null) {
this.config.holder = 'editorjs';
}
/**
@ -138,6 +147,12 @@ export default class Core {
*/
this.config.initialBlock = this.config.initialBlock || 'paragraph';
/**
* Height of Editor's bottom area that allows to set focus on the last Block
* @type {number}
*/
this.config.minHeight = this.config.minHeight || 300;
/**
* Initial block type
* Uses in case when there is no blocks passed
@ -187,18 +202,21 @@ export default class Core {
* @returns {Promise<void>}
*/
public async validate(): Promise<void> {
/**
* Check if holderId is not empty
*/
if (!this.config.holderId) {
throw Error('«holderId» param must being not empty');
const { holderId, holder } = this.config;
if (holderId && holder) {
throw Error('«holderId» and «holder» param can\'t assign at the same time.');
}
/**
* Check for a holder element's existence
*/
if (!$.get(this.config.holderId)) {
throw Error(`element with ID «${this.config.holderId}» is missing. Pass correct holder's ID.`);
if (typeof holder === 'string' && !$.get(holder)) {
throw Error(`element with ID «${holder}» is missing. Pass correct holder's ID.`);
}
if (holder && typeof holder === 'object' && !$.isElement(holder)) {
throw Error('holder as HTMLElement if provided must be inherit from Element class.');
}
}

View file

@ -244,7 +244,7 @@ export default class Dom {
* @param {Object} node
* @returns {boolean}
*/
public static isElement(node: any): boolean {
public static isElement(node: any): node is Element {
return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;
}
@ -518,4 +518,13 @@ export default class Dom {
return [...result, ...Dom.getDeepestBlockElements(element as HTMLElement)];
}, []);
}
/**
* Helper for get holder from {string} or return HTMLElement
* @param element
*/
public static getHolder(element: string | HTMLElement): HTMLElement {
if (typeof element === 'string') { return document.getElementById(element); }
return element;
}
}

View file

@ -81,7 +81,12 @@ export default class LinkInlineTool implements InlineTool {
private inputOpened: boolean = false;
/**
* Available Inline Toolbar methods (open/close)
* Available Toolbar methods (open/close)
*/
private toolbar: Toolbar;
/**
* Available inline toolbar methods (open/close)
*/
private inlineToolbar: Toolbar;
@ -94,7 +99,8 @@ export default class LinkInlineTool implements InlineTool {
* @param {{api: API}} - Editor.js API
*/
constructor({api}) {
this.inlineToolbar = api.toolbar;
this.toolbar = api.toolbar;
this.inlineToolbar = api.inlineToolbar;
this.notifier = api.notifier;
this.selection = new SelectionUtils();
}
@ -156,7 +162,7 @@ export default class LinkInlineTool implements InlineTool {
this.unlink();
this.closeActions();
this.checkState();
this.inlineToolbar.close();
this.toolbar.close();
return;
}
}
@ -288,10 +294,8 @@ export default class LinkInlineTool implements InlineTool {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
this.closeActions();
this.selection.collapseToEnd();
this.inlineToolbar.close();
this.checkState();
}
/**

View file

@ -24,6 +24,7 @@ export default class API extends Module {
selection: this.Editor.SelectionAPI.methods,
styles: this.Editor.StylesAPI.classes,
toolbar: this.Editor.ToolbarAPI.methods,
inlineToolbar: this.Editor.InlineToolbarAPI.methods,
} as APIInterfaces;
}
}

View file

@ -0,0 +1,33 @@
import Module from '../../__module';
import { InlineToolbar } from '../../../../types/api/inline-toolbar';
/**
* @class InlineToolbarAPI
* Provides methods for working with the Inline Toolbar
*/
export default class InlineToolbarAPI extends Module {
/**
* Available methods
* @return {InlineToolbar}
*/
get methods(): InlineToolbar {
return {
close: () => this.close(),
open: () => this.open(),
};
}
/**
* Open Inline Toolbar
*/
public open(): void {
this.Editor.InlineToolbar.open();
}
/**
* Close Inline Toolbar
*/
public close(): void {
this.Editor.InlineToolbar.close();
}
}

View file

@ -3,7 +3,7 @@ import {Toolbar} from '../../../../types/api';
/**
* @class ToolbarAPI
* provides with methods working with Toolbar
* Provides methods for working with the Toolbar
*/
export default class ToolbarAPI extends Module {
/**

View file

@ -455,7 +455,7 @@ export default class BlockManager extends Module {
* @returns {Block}
*/
public getBlock(element: HTMLElement): Block {
if (!$.isElement(element)) {
if (!$.isElement(element) as boolean) {
element = element.parentNode as HTMLElement;
}

View file

@ -10,7 +10,6 @@ import _ from '../utils';
import $ from '../dom';
import SelectionUtils from '../selection';
import Block from '../block';
export default class BlockSelection extends Module {
@ -89,6 +88,13 @@ export default class BlockSelection extends Module {
*/
private nativeInputSelected: boolean = false;
/**
* Flag identifies any input selection
* That means we can select whole Block
* @type {boolean}
*/
private readyToBlockSelection: boolean = false;
/**
* SelectionUtils instance
* @type {SelectionUtils}
@ -150,6 +156,7 @@ export default class BlockSelection extends Module {
public clearSelection(restoreSelection = false) {
this.needToSelectAll = false;
this.nativeInputSelected = false;
this.readyToBlockSelection = false;
if (!this.anyBlockSelected || this.Editor.RectangleSelection.isRectActivated()) {
this.Editor.RectangleSelection.clearSelection();
@ -233,6 +240,17 @@ export default class BlockSelection extends Module {
return;
}
const inputs = this.Editor.BlockManager.currentBlock.inputs;
/**
* If Block has more than one editable element allow native selection
* Second cmd+a will select whole Block
*/
if (inputs.length > 1 && !this.readyToBlockSelection) {
this.readyToBlockSelection = true;
return;
}
/** Prevent default selection */
event.preventDefault();

View file

@ -170,7 +170,14 @@ export default class InlineToolbar extends Module {
/**
* Shows Inline Toolbar
*/
private open(): void {
public open(): void {
/**
* Check if inline toolbar is allowed to show or not
*/
if (!this.allowedToShow()) {
return;
}
/**
* Filter inline-tools and show only allowed by Block's Tool
*/

View file

@ -134,11 +134,7 @@ export default class UI extends Module {
* Element where we need to append Editor.js
* @type {Element}
*/
this.nodes.holder = document.getElementById(this.config.holderId);
if (!this.nodes.holder) {
throw Error('Holder wasn\'t found by ID: #' + this.config.holderId);
}
this.nodes.holder = $.getHolder(this.config.holder);
/**
* Create and save main UI elements
@ -153,6 +149,11 @@ export default class UI extends Module {
this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow);
}
/**
* Set customizable bottom zone height
*/
this.nodes.redactor.style.paddingBottom = this.config.minHeight + 'px';
this.nodes.wrapper.appendChild(this.nodes.redactor);
this.nodes.holder.appendChild(this.nodes.wrapper);
@ -329,7 +330,8 @@ export default class UI extends Module {
*/
const target = event.target as HTMLElement;
const clickedOnInlineToolbarButton = target.closest(`.${this.Editor.InlineToolbar.CSS.inlineToolbar}`);
const clickedInsideOfEditor = !!target.closest(`#${this.config.holderId}`) || Selection.isAtEditor;
const clickedInsideOfEditor = this.nodes.holder.contains(target) || Selection.isAtEditor;
if (!clickedInsideOfEditor) {
/**

View file

@ -267,6 +267,19 @@ export default class SelectionUtils {
this.savedSelectionRange = null;
}
/**
* Collapse current selection
*/
public collapseToEnd(): void {
const sel = window.getSelection();
const range = document.createRange();
range.selectNodeContents(sel.focusNode);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
}
/**
* Looks ahead to find passed tag from current selection
*

View file

@ -11,8 +11,6 @@
}
&__redactor {
padding-bottom: 300px;
&--hidden {
display: none;
}

View file

@ -30,6 +30,7 @@ import SaverAPI from '../components/modules/api/saver';
import Saver from '../components/modules/saver';
import BlockSelection from '../components/modules/blockSelection';
import RectangleSelection from '../components/modules/RectangleSelection';
import InlineToolbarAPI from '../components/modules/api/inlineToolbar';
export interface EditorModules {
UI: UI;
@ -63,5 +64,6 @@ export interface EditorModules {
SelectionAPI: SelectionAPI;
StylesAPI: StylesAPI;
ToolbarAPI: ToolbarAPI;
InlineToolbarAPI: InlineToolbarAPI;
NotifierAPI: NotifierAPI;
}

View file

@ -8,3 +8,4 @@ export * from './styles';
export * from './caret';
export * from './toolbar';
export * from './notifier';
export * from './inline-toolbar'

15
types/api/inline-toolbar.d.ts vendored Normal file
View file

@ -0,0 +1,15 @@
/**
* Describes InlineToolbar API methods
*/
export interface InlineToolbar {
/**
* Closes InlineToolbar
*/
close(): void;
/**
* Opens InlineToolbar
*/
open(): void;
}

View file

@ -5,8 +5,14 @@ import {SanitizerConfig} from './sanitizer-config';
export interface EditorConfig {
/**
* Element where Editor will be append
* @deprecated property will be removed in next major release, use holder instead
*/
holderId?: string;
holderId?: string | HTMLElement;
/**
* Element where Editor will be append
*/
holder?: string | HTMLElement;
/**
* If true, set caret at the first Block after Editor is ready
@ -46,6 +52,11 @@ export interface EditorConfig {
*/
data?: OutputData;
/**
* Height of Editor's bottom area that allows to set focus on the last Block
*/
minHeight?: number;
/**
* Fires when Editor is ready to work
*/

5
types/index.d.ts vendored
View file

@ -5,7 +5,7 @@
*/
import {EditorConfig} from './configs';
import {Blocks, Caret, Events, Listeners, Notifier, Sanitizer, Saver, Selection, Styles, Toolbar} from './api';
import {Blocks, Caret, Events, Listeners, Notifier, Sanitizer, Saver, Selection, Styles, Toolbar, InlineToolbar} from './api';
/**
* Interfaces used for development
@ -51,6 +51,7 @@ export interface API {
selection: Selection;
styles: Styles;
toolbar: Toolbar;
inlineToolbar: InlineToolbar;
}
/**
@ -70,7 +71,7 @@ declare class EditorJS {
public selection: Selection;
public styles: Styles;
public toolbar: Toolbar;
public inlineToolbar: InlineToolbar;
constructor(configuration?: EditorConfig|string);
public destroy(): void;

View file

@ -1681,10 +1681,10 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codex-notifier@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/codex-notifier/-/codex-notifier-1.1.1.tgz#0fad9876781b793da316bed7f0cd11454a3f3393"
integrity sha512-IAcSO8O9i+limw4XknDXvBTOI3bXwGy3xNauBCYx4F1+hfNMhhkL3lzDnmAEcvwgiuY4P7W5hWB05sNi9W+31Q==
codex-notifier@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/codex-notifier/-/codex-notifier-1.1.2.tgz#a733079185f4c927fa296f1d71eb8753fe080895"
integrity sha512-DCp6xe/LGueJ1N5sXEwcBc3r3PyVkEEDNWCVigfvywAkeXcZMk9K41a31tkEFBW0Ptlwji6/JlAb49E3Yrxbtg==
collapse-white-space@^1.0.2:
version "1.0.4"