renderFromHTML API method (#654)

* renderFromHTML API method

* Fix case when currentBlock is undefined

* Clear editor before render

* Handle single block processing

* Update paragraph
This commit is contained in:
George Berezhnoy 2019-03-18 23:59:40 +03:00 committed by GitHub
parent 6bd857d4f6
commit a47ffcce44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 45 deletions

10
dist/editor.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,9 @@
# Changelog
### 2.12.0
- `New` *API* - new `blocks` API method `renderFromHTML`
### 2.11.11
- `New` — Add ability to pass configuration for internal Tools

View file

@ -22,6 +22,10 @@ export interface API {
Methods that working with Blocks
`render(data)` - render passed JSON data
`renderFromHTML(data)` - parse and render passed HTML string (*not for production use*)
`swap(fromIndex, toIndex)` - swaps two Blocks by their positions
`delete(blockIndex?: Number)` - deletes Block with passed index

View file

@ -1,6 +1,6 @@
{
"name": "@editorjs/editorjs",
"version": "2.11.11",
"version": "2.12.0",
"description": "Editor.js — Native JS, based on API and Open Source",
"main": "dist/editor.js",
"types": "./types/index.d.ts",

View file

@ -18,6 +18,7 @@ export default class BlocksAPI extends Module {
return {
clear: () => this.clear(),
render: (data: OutputData) => this.render(data),
renderFromHTML: (data: string) => this.renderFromHTML(data),
delete: () => this.delete(),
swap: (fromIndex: number, toIndex: number) => this.swap(fromIndex, toIndex),
getBlockByIndex: (index: number) => this.getBlockByIndex(index),
@ -113,6 +114,16 @@ export default class BlocksAPI extends Module {
return this.Editor.Renderer.render(data.blocks);
}
/**
* Render passed HTML string
* @param {string} data
* @return {Promise<void>}
*/
public renderFromHTML(data: string): Promise<void> {
this.Editor.BlockManager.clear();
return this.Editor.Paste.processText(data, true);
}
/**
* Stretch Block's content
* @param {number} index

View file

@ -180,6 +180,41 @@ export default class Paste extends Module {
}
}
/**
* Process pasted text and divide them into Blocks
*
* @param {string} data - text to process. Can be HTML or plain.
* @param {boolean} isHTML - if passed string is HTML, this parameter should be true
*/
public async processText(data: string, isHTML: boolean = false) {
const {Caret, BlockManager, Tools} = this.Editor;
const dataToInsert = isHTML ? this.processHTML(data) : this.processPlain(data);
if (!dataToInsert.length) {
return;
}
if (dataToInsert.length === 1) {
if (!dataToInsert[0].isBlock) {
this.processInlinePaste(dataToInsert.pop());
} else {
this.processSingleBlock(dataToInsert.pop());
}
return;
}
const isCurrentBlockInitial = BlockManager.currentBlock && Tools.isInitial(BlockManager.currentBlock.tool);
const needToReplaceCurrentBlock = isCurrentBlockInitial && BlockManager.currentBlock.isEmpty;
await Promise.all(dataToInsert.map(
async (content, i) => await this.insertBlock(content, i === 0 && needToReplaceCurrentBlock),
));
if (BlockManager.currentBlock) {
Caret.setToBlock(BlockManager.currentBlock, Caret.positions.END);
}
}
/**
* Set onPaste callback handler
*/
@ -424,39 +459,6 @@ export default class Paste extends Module {
};
}
/**
* Process pasted text and divide them into Blocks
*
* @param {string} data - text to process. Can be HTML or plain.
* @param {boolean} isHTML - if passed string is HTML, this parameter should be true
*/
private async processText(data: string, isHTML: boolean = false) {
const {Caret, BlockManager, Tools} = this.Editor;
const dataToInsert = isHTML ? this.processHTML(data) : this.processPlain(data);
if (!dataToInsert.length) {
return;
}
if (dataToInsert.length === 1) {
if (!dataToInsert[0].isBlock) {
this.processInlinePaste(dataToInsert.pop());
} else {
this.processSingleBlock(dataToInsert.pop());
}
return;
}
const isCurrentBlockInitial = Tools.isInitial(BlockManager.currentBlock.tool);
const needToReplaceCurrentBlock = isCurrentBlockInitial && BlockManager.currentBlock.isEmpty;
await Promise.all(dataToInsert.map(
async (content, i) => await this.insertBlock(content, i === 0 && needToReplaceCurrentBlock),
));
Caret.setToBlock(BlockManager.currentBlock, Caret.positions.END);
}
/**
* Split HTML string to blocks and return it as array of Block data
*
@ -558,8 +560,12 @@ export default class Paste extends Module {
/**
* If pasted tool isn`t equal current Block or if pasted content contains block elements, insert it as new Block
*/
if (dataToInsert.tool !== currentBlock.name || !$.containsOnlyInlineElements(dataToInsert.content.innerHTML)) {
this.insertBlock(dataToInsert, Tools.isInitial(currentBlock.tool) && currentBlock.isEmpty);
if (
!currentBlock ||
dataToInsert.tool !== currentBlock.name ||
!$.containsOnlyInlineElements(dataToInsert.content.innerHTML)
) {
this.insertBlock(dataToInsert, currentBlock && Tools.isInitial(currentBlock.tool) && currentBlock.isEmpty);
return;
}
@ -578,7 +584,7 @@ export default class Paste extends Module {
const {BlockManager, Caret, Sanitizer, Tools} = this.Editor;
const {content, tool} = dataToInsert;
const currentBlockIsInitial = Tools.isInitial(BlockManager.currentBlock.tool);
const currentBlockIsInitial = BlockManager.currentBlock && Tools.isInitial(BlockManager.currentBlock.tool);
if (currentBlockIsInitial && content.textContent.length < Paste.PATTERN_PROCESSING_MAX_LENGTH) {
const blockData = await this.processPattern(content.textContent);
@ -597,10 +603,10 @@ export default class Paste extends Module {
}
}
const currentToolSanitizeConfig = Sanitizer.getInlineToolsConfig(BlockManager.currentBlock.name);
/** If there is no pattern substitute - insert string as it is */
if (BlockManager.currentBlock.currentInput) {
if (BlockManager.currentBlock && BlockManager.currentBlock.currentInput) {
const currentToolSanitizeConfig = Sanitizer.getInlineToolsConfig(BlockManager.currentBlock.name);
document.execCommand('insertHTML', false, Sanitizer.clean(content.innerHTML, currentToolSanitizeConfig));
} else {
this.insertBlock(dataToInsert);

View file

@ -16,6 +16,13 @@ export interface Blocks {
*/
render(data: OutputData): Promise<void>;
/**
* Render passed HTML string
* @param {string} data
* @return {Promise<void>}
*/
renderFromHTML(data: string): Promise<void>;
/**
* Removes current Block
*/