mirror of
https://github.com/codex-team/editor.js
synced 2024-06-01 13:32:43 +02:00
Increase robustness (#447)
This commit is contained in:
parent
7acf321454
commit
9ab437fe38
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -104,66 +104,70 @@ export default class Paste extends Module {
|
|||
* @param {string} tool
|
||||
*/
|
||||
private processTool = ([name, tool]) => {
|
||||
const toolPasteConfig = tool.onPaste || {};
|
||||
try {
|
||||
const toolPasteConfig = tool.onPaste || {};
|
||||
|
||||
if (this.config.initialBlock === name && !toolPasteConfig.handler) {
|
||||
_.log(
|
||||
`«${name}» Tool must provide a paste handler.`,
|
||||
'warn',
|
||||
);
|
||||
}
|
||||
if (this.config.initialBlock === name && !toolPasteConfig.handler) {
|
||||
_.log(
|
||||
`«${name}» Tool must provide a paste handler.`,
|
||||
'warn',
|
||||
);
|
||||
}
|
||||
|
||||
if (toolPasteConfig.handler && typeof toolPasteConfig.handler !== 'function') {
|
||||
_.log(
|
||||
`Paste handler for «${name}» Tool should be a function.`,
|
||||
'warn',
|
||||
);
|
||||
} else {
|
||||
const tags = toolPasteConfig.tags || [];
|
||||
if (toolPasteConfig.handler && typeof toolPasteConfig.handler !== 'function') {
|
||||
_.log(
|
||||
`Paste handler for «${name}» Tool should be a function.`,
|
||||
'warn',
|
||||
);
|
||||
} else {
|
||||
const tags = toolPasteConfig.tags || [];
|
||||
|
||||
tags.forEach((tag) => {
|
||||
if (this.toolsTags.hasOwnProperty(tag)) {
|
||||
_.log(
|
||||
`Paste handler for «${name}» Tool on «${tag}» tag is skipped ` +
|
||||
`because it is already used by «${this.toolsTags[tag].tool}» Tool.`,
|
||||
'warn',
|
||||
);
|
||||
return;
|
||||
}
|
||||
tags.forEach((tag) => {
|
||||
if (this.toolsTags.hasOwnProperty(tag)) {
|
||||
_.log(
|
||||
`Paste handler for «${name}» Tool on «${tag}» tag is skipped ` +
|
||||
`because it is already used by «${this.toolsTags[tag].tool}» Tool.`,
|
||||
'warn',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.toolsTags[tag] = {
|
||||
handler: toolPasteConfig.handler,
|
||||
tool: name,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (!toolPasteConfig.patternHandler || _.isEmpty(toolPasteConfig.patterns)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof toolPasteConfig.patternHandler !== 'function') {
|
||||
_.log(
|
||||
`Pattern parser for "${name}" Tool should be a function.`,
|
||||
'warn',
|
||||
);
|
||||
} else {
|
||||
Object.entries(toolPasteConfig.patterns).forEach(([key, pattern]: [string, RegExp]) => {
|
||||
/** Still need to validate pattern as it provided by user */
|
||||
if (!(pattern instanceof RegExp)) {
|
||||
_.log(
|
||||
`Pattern ${pattern} for "${tool}" Tool is skipped because it should be a Regexp instance.`,
|
||||
'warn',
|
||||
);
|
||||
}
|
||||
|
||||
this.toolsPatterns.push({
|
||||
key,
|
||||
pattern,
|
||||
handler: toolPasteConfig.patternHandler,
|
||||
tool: name,
|
||||
this.toolsTags[tag] = {
|
||||
handler: toolPasteConfig.handler,
|
||||
tool: name,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!toolPasteConfig.patternHandler || _.isEmpty(toolPasteConfig.patterns)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof toolPasteConfig.patternHandler !== 'function') {
|
||||
_.log(
|
||||
`Pattern parser for «${name}» Tool should be a function.`,
|
||||
'warn',
|
||||
);
|
||||
} else {
|
||||
Object.entries(toolPasteConfig.patterns).forEach(([key, pattern]: [string, RegExp]) => {
|
||||
/** Still need to validate pattern as it provided by user */
|
||||
if (!(pattern instanceof RegExp)) {
|
||||
_.log(
|
||||
`Pattern ${pattern} for «${name}» Tool is skipped because it should be a Regexp instance.`,
|
||||
'warn',
|
||||
);
|
||||
}
|
||||
|
||||
this.toolsPatterns.push({
|
||||
key,
|
||||
pattern,
|
||||
handler: toolPasteConfig.patternHandler,
|
||||
tool: name,
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
_.log(`Paste handling for «${name}» Tool is not enabled because of an error `, 'warn', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +263,7 @@ export default class Paste extends Module {
|
|||
let insertedBlock;
|
||||
|
||||
if (BlockManager.currentBlock && BlockManager.currentBlock.isEmpty) {
|
||||
BlockManager.replace(blockData.tool, blockData.data);
|
||||
insertedBlock = BlockManager.replace(blockData.tool, blockData.data);
|
||||
} else {
|
||||
insertedBlock = BlockManager.insert(blockData.tool, blockData.data);
|
||||
}
|
||||
|
|
|
@ -279,7 +279,8 @@ export default class Tools extends Module {
|
|||
toolPreparationList.push({
|
||||
function : toolClass.prepare,
|
||||
data : {
|
||||
toolName
|
||||
toolName,
|
||||
config: this.toolsSettings[toolName]
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -73,27 +73,7 @@ export default class Util {
|
|||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
public static sequence(chains: ChainData[], success = () => {}, fallback = () => {}): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
/**
|
||||
* pluck each element from queue
|
||||
* First, send resolved Promise as previous value
|
||||
* Each plugins "prepare" method returns a Promise, that's why
|
||||
* reduce current element will not be able to continue while can't get
|
||||
* a resolved Promise
|
||||
*/
|
||||
chains.reduce((previousValue, currentValue, iteration) => {
|
||||
return previousValue
|
||||
.then(() => waitNextBlock(currentValue, success, fallback))
|
||||
.then(() => {
|
||||
// finished
|
||||
if (iteration === chains.length - 1) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}, Promise.resolve());
|
||||
});
|
||||
|
||||
public static async sequence(chains: ChainData[], success = () => {}, fallback = () => {}): Promise<void> {
|
||||
/**
|
||||
* Decorator
|
||||
*
|
||||
|
@ -104,25 +84,30 @@ export default class Util {
|
|||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
function waitNextBlock(
|
||||
async function waitNextBlock(
|
||||
chainData: ChainData,
|
||||
successCallback: (data: any) => void,
|
||||
fallbackCallback: (data: any) => void,
|
||||
): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
chainData.function()
|
||||
.then(() => {
|
||||
successCallback(chainData.data || {});
|
||||
})
|
||||
.then(resolve)
|
||||
.catch(() => {
|
||||
fallbackCallback(chainData.data || {});
|
||||
|
||||
// anyway, go ahead even it falls
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
try {
|
||||
await chainData.function(chainData.data);
|
||||
await successCallback(typeof chainData.data !== 'undefined' ? chainData.data : {});
|
||||
} catch (e) {
|
||||
fallbackCallback(typeof chainData.data !== 'undefined' ? chainData.data : {});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pluck each element from queue
|
||||
* First, send resolved Promise as previous value
|
||||
* Each plugins "prepare" method returns a Promise, that's why
|
||||
* reduce current element will not be able to continue while can't get
|
||||
* a resolved Promise
|
||||
*/
|
||||
return await chains.reduce(async (previousValue, currentValue) => {
|
||||
await previousValue;
|
||||
return waitNextBlock(currentValue, success, fallback);
|
||||
}, Promise.resolve());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue