Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.19.1 #1465

Merged
merged 11 commits into from
Dec 8, 2020
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Temporary suppress some errors. We need to fix them partially in next patches
*/
"import/no-duplicates": ["warn"],
"@typescript-eslint/triple-slash-reference": ["off"]
},
"settings": {
"jsdoc": {
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ node_modules/*

npm-debug.log
yarn-error.log

test/cypress/screenshots
test/cypress/videos
9 changes: 9 additions & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"env": {
},
"fixturesFolder": "test/cypress/fixtures",
"integrationFolder": "test/cypress/tests",
"screenshotsFolder": "test/cypress/screenshots",
"videosFolder": "test/cypress/videos",
"supportFile": "test/cypress/support/index.ts"
}
2 changes: 1 addition & 1 deletion dist/editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/editor.js.LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/*!
* Editor.js
*
* @version 2.19.0
* @version 2.19.1
*
* @licence Apache-2.0
* @author CodeX <https://codex.so>
Expand Down
12 changes: 12 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

### 2.19.1

- `Improvements` - The [Cypress](https://www.cypress.io) was integrated as the end-to-end testing framework
- `Improvements` - Native `typeof`replaced with custom utils methods
- `Improvements` - Bind shortcuts listeners on the editor wrapper instead of document (#1391)(https://github.com/codex-team/editor.js/issues/1391)
- `Fix` - The problem with destroy() method [#1380](https://github.com/codex-team/editor.js/issues/1380).
- `Fix` - add getter keyword to `block.mergeable` method [#1415](https://github.com/codex-team/editor.js/issues/1415).
- `Fix` — Fix problem with entering to Editor.js by Tab key [#1393](https://github.com/codex-team/editor.js/issues/1393)
- `Fix` - Sanitize pasted block data [#1396](https://github.com/codex-team/editor.js/issues/1396).
- `Fix` - Unnecessary block creation after arrow navigation at last non-default block[#1414](https://github.com/codex-team/editor.js/issues/1414)


### 2.19

- `New` - Read-only mode 🥳 [#837](https://github.com/codex-team/editor.js/issues/837)
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@editorjs/editorjs",
"version": "2.19.0",
"version": "2.19.1",
"description": "Editor.js — Native JS, based on API and Open Source",
"main": "dist/editor.js",
"types": "./types/index.d.ts",
Expand All @@ -16,13 +16,15 @@
"build:win": "rimraf dist && yarn svg:win && yarn build:prod",
"build:dev": "webpack --mode development --progress --display-error-details --display-entrypoints --watch",
"build:prod": "webpack --mode production",
"lint": "eslint src/ --ext .ts",
"lint": "eslint src/ --ext .ts && yarn lint:tests",
"lint:errors": "eslint src/ --ext .ts --quiet",
"lint:fix": "eslint src/ --ext .ts --fix",
"lint:tests": "eslint test/ --ext .ts",
"svg:win": "if not exist dist md dist && yarn svg",
"svg": "svg-sprite-generate -d src/assets/ -o dist/sprite.svg",
"pull_tools": "git submodule update --init --recursive",
"checkout_tools": "git submodule foreach git pull origin master"
"checkout_tools": "git submodule foreach git pull origin master",
"test:e2e": "cypress run"
},
"author": "CodeX",
"license": "Apache-2.0",
Expand All @@ -46,9 +48,11 @@
"core-js": "3.6.5",
"css-loader": "^3.5.3",
"cssnano": "^4.1.10",
"cypress": "^5.5.0",
"eslint": "^6.8.0",
"eslint-config-codex": "^1.3.3",
"eslint-loader": "^4.0.2",
"eslint-plugin-cypress": "^2.11.2",
"extract-text-webpack-plugin": "^3.0.2",
"html-janitor": "^2.0.4",
"license-webpack-plugin": "^2.1.4",
Expand Down
2 changes: 1 addition & 1 deletion src/codex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class EditorJS {
/**
* If `onReady` was passed in `configuration` then redefine onReady function
*/
if (typeof configuration === 'object' && _.isFunction(configuration.onReady)) {
if (_.isObject(configuration) && _.isFunction(configuration.onReady)) {
onReady = configuration.onReady;
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/block/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export default class Block {
* @param {BlockToolData} options.data - Tool's initial data
* @param {BlockToolConstructable} options.Tool — Tool's class
* @param {ToolSettings} options.settings - default tool's config
* @param {Module} options.api - Editor API module for pass it to the Block Tunes
* @param options.api - Editor API module for pass it to the Block Tunes
* @param {boolean} options.readOnly - Read-Only flag
*/
constructor({
Expand Down Expand Up @@ -358,7 +358,7 @@ export default class Block {
*
* @returns {boolean}
*/
public mergeable(): boolean {
public get mergeable(): boolean {
return _.isFunction(this.tool.merge);
}

Expand Down
7 changes: 3 additions & 4 deletions src/components/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export default class Core {
* Process zero-configuration or with only holderId
* Make config object
*/
if (typeof config !== 'object') {
if (!_.isObject(config)) {
config = {
holder: config,
};
Expand Down Expand Up @@ -185,7 +185,6 @@ export default class Core {
a: true,
} as SanitizerConfig;


this.config.hideToolbar = this.config.hideToolbar ? this.config.hideToolbar : false;
this.config.tools = this.config.tools || {};
this.config.i18n = this.config.i18n || {};
Expand Down Expand Up @@ -247,11 +246,11 @@ export default class Core {
/**
* Check for a holder element's existence
*/
if (typeof holder === 'string' && !$.get(holder)) {
if (_.isString(holder) && !$.get(holder)) {
throw Error(`element with ID «${holder}» is missing. Pass correct holder's ID.`);
}

if (holder && typeof holder === 'object' && !$.isElement(holder)) {
if (holder && _.isObject(holder) && !$.isElement(holder)) {
throw Error('holder as HTMLElement if provided must be inherit from Element class.');
}
}
Expand Down
16 changes: 12 additions & 4 deletions src/components/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,11 @@ export default class Dom {
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static isElement(node: any): node is Element {
return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.ELEMENT_NODE;
if (_.isNumber(node)) {
return false;
}

return node && node.nodeType && node.nodeType === Node.ELEMENT_NODE;
}

/**
Expand All @@ -303,7 +307,11 @@ export default class Dom {
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static isFragment(node: any): node is DocumentFragment {
return node && typeof node === 'object' && node.nodeType && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
if (_.isNumber(node)) {
return false;
}

return node && node.nodeType && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
}

/**
Expand Down Expand Up @@ -532,7 +540,7 @@ export default class Dom {
public static containsOnlyInlineElements(data: string | HTMLElement): boolean {
let wrapper: HTMLElement;

if (typeof data === 'string') {
if (_.isString(data)) {
wrapper = document.createElement('div');
wrapper.innerHTML = data;
} else {
Expand Down Expand Up @@ -572,7 +580,7 @@ export default class Dom {
* @returns {HTMLElement}
*/
public static getHolder(element: string | HTMLElement): HTMLElement {
if (typeof element === 'string') {
if (_.isString(element)) {
return document.getElementById(element);
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/flipper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default class Flipper {
* @param {FlipperOptions} options - different constructing settings
*/
constructor(options: FlipperOptions) {
this.allowArrows = typeof options.allowArrows === 'boolean' ? options.allowArrows : true;
this.allowArrows = _.isBoolean(options.allowArrows) ? options.allowArrows : true;
this.iterator = new DomIterator(options.items, options.focusedItemClass);
this.activateCallback = options.activateCallback;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/i18n/namespace-internal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import defaultDictionary from './locales/en/messages.json';
import { DictNamespaces } from '../../types-internal/i18n-internal-namespace';
import { typeOf } from '../utils';
import { isObject, isString } from '../utils';

/**
* Evaluate messages dictionary and return object for namespace chaining
Expand All @@ -12,14 +12,14 @@ function getNamespaces(dict: object, keyPath?: string): DictNamespaces<typeof de
const result = {};

Object.entries(dict).forEach(([key, section]) => {
if (typeOf(section) === 'object') {
if (isObject(section)) {
const newPath = keyPath ? `${keyPath}.${key}` : key;

/**
* Check current section values, if all of them are strings, so there is the last section
*/
const isLastSection = Object.values(section).every((sectionValue) => {
return typeOf(sectionValue) === 'string';
return isString(sectionValue);
});

/**
Expand Down
14 changes: 11 additions & 3 deletions src/components/modules/caret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,22 @@ export default class Caret extends Module {
const { BlockManager, Tools } = this.Editor;
const { currentBlock, nextContentfulBlock } = BlockManager;
const { nextInput } = currentBlock;
const isAtEnd = this.isAtEnd;

let nextBlock = nextContentfulBlock;

if (!nextBlock && !nextInput) {
/**
* If there is no nextBlock and currentBlock is default, do not navigate
* This code allows to exit from the last non-initial tool:
* https://github.com/codex-team/editor.js/issues/1103
*/
if (Tools.isDefault(currentBlock.tool)) {

/**
* 1. If there is a last block and it is default, do nothing
* 2. If there is a last block and it is non-default --> and caret not at the end <--, do nothing
* (https://github.com/codex-team/editor.js/issues/1414)
*/
if (Tools.isDefault(currentBlock.tool) || !isAtEnd) {
return false;
}

Expand All @@ -414,7 +422,7 @@ export default class Caret extends Module {
nextBlock = BlockManager.insertAtEnd();
}

if (force || this.isAtEnd) {
if (force || isAtEnd) {
/** If next Tool`s input exists, focus on it. Otherwise set caret to the next Block */
if (!nextInput) {
this.setToBlock(nextBlock, this.positions.START);
Expand Down
7 changes: 4 additions & 3 deletions src/components/modules/paste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export default class Paste extends Module {
return;
}

if (typeof toolInstance.onPaste !== 'function') {
if (!_.isFunction(toolInstance.onPaste)) {
return;
}

Expand Down Expand Up @@ -760,9 +760,10 @@ export default class Paste extends Module {
* @returns {void}
*/
private insertEditorJSData(blocks: Array<Pick<SavedData, 'data' | 'tool'>>): void {
const { BlockManager, Tools } = this.Editor;
const { BlockManager, Sanitizer, Tools } = this.Editor;
const sanitizedBlocks = Sanitizer.sanitizeBlocks(blocks);

blocks.forEach(({ tool, data }, i) => {
sanitizedBlocks.forEach(({ tool, data }, i) => {
let needToReplaceCurrentBlock = false;

if (i === 0) {
Expand Down
12 changes: 6 additions & 6 deletions src/components/modules/sanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export default class Sanitizer extends Module {
* Array: call sanitize for each item
*/
return this.cleanArray(dataToSanitize, rules);
} else if (typeof dataToSanitize === 'object') {
} else if (_.isObject(dataToSanitize)) {
/**
* Objects: just clean object deeper.
*/
Expand All @@ -105,7 +105,7 @@ export default class Sanitizer extends Module {
*
* Clean only strings
*/
if (typeof dataToSanitize === 'string') {
if (_.isString(dataToSanitize)) {
return this.cleanOneItem(dataToSanitize, rules);
}

Expand Down Expand Up @@ -169,7 +169,7 @@ export default class Sanitizer extends Module {
if (Object.prototype.hasOwnProperty.call(toolRules, fieldName)) {
const rule = toolRules[fieldName];

if (typeof rule === 'object') {
if (_.isObject(rule)) {
toolConfig[fieldName] = Object.assign({}, baseConfig, rule);
} else {
toolConfig[fieldName] = rule;
Expand All @@ -195,7 +195,7 @@ export default class Sanitizer extends Module {

let config = {} as SanitizerConfig;

if (typeof enableInlineTools === 'boolean' && enableInlineTools) {
if (_.isBoolean(enableInlineTools) && enableInlineTools) {
/**
* getting all tools sanitizer rule
*/
Expand Down Expand Up @@ -292,7 +292,7 @@ export default class Sanitizer extends Module {
* @returns {string}
*/
private cleanOneItem(taintString: string, rule: SanitizerConfig|boolean): string {
if (typeof rule === 'object') {
if (_.isObject(rule)) {
return this.clean(taintString, rule);
} else if (rule === false) {
return this.clean(taintString, {} as SanitizerConfig);
Expand All @@ -309,7 +309,7 @@ export default class Sanitizer extends Module {
* @param {SanitizerConfig} config - config to check
*/
private isRule(config: SanitizerConfig): boolean {
return typeof config === 'object' || typeof config === 'boolean' || _.isFunction(config);
return _.isObject(config) || _.isBoolean(config) || _.isFunction(config);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/components/modules/shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class Shortcuts extends Module {
public add(shortcut: ShortcutData): void {
const newShortcut = new Shortcut({
name: shortcut.name,
on: document, // UI.nodes.redactor
on: this.Editor.UI.nodes.redactor,
callback: shortcut.handler,
});

Expand Down
10 changes: 8 additions & 2 deletions src/components/modules/toolbar/blockSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,14 @@ export default class BlockSettings extends Module<BlockSettingsNodes> {
* Destroys module
*/
public destroy(): void {
this.flipper.deactivate();
this.flipper = null;
/**
* Sometimes (in read-only mode) there is no Flipper
*/
if (this.flipper) {
this.flipper.deactivate();
this.flipper = null;
}

this.removeAllNodes();
}

Expand Down
14 changes: 10 additions & 4 deletions src/components/modules/toolbar/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,14 @@ export default class ConversionToolbar extends Module<ConversionToolbarNodes> {
* Deactivates flipper and removes all nodes
*/
public destroy(): void {
this.flipper.deactivate();
this.flipper = null;
/**
* Sometimes (in read-only mode) there is no Flipper
*/
if (this.flipper) {
this.flipper.deactivate();
this.flipper = null;
}

this.removeAllNodes();
}

Expand Down Expand Up @@ -209,7 +215,7 @@ export default class ConversionToolbar extends Module<ConversionToolbarNodes> {

if (_.isFunction(exportProp)) {
exportData = exportProp(blockData);
} else if (typeof exportProp === 'string') {
} else if (_.isString(exportProp)) {
exportData = blockData[exportProp];
} else {
_.log('Conversion «export» property must be a string or function. ' +
Expand All @@ -236,7 +242,7 @@ export default class ConversionToolbar extends Module<ConversionToolbarNodes> {

if (_.isFunction(importProp)) {
newBlockData = importProp(cleaned);
} else if (typeof importProp === 'string') {
} else if (_.isString(importProp)) {
newBlockData[importProp] = cleaned;
} else {
_.log('Conversion «import» property must be a string or function. ' +
Expand Down
Loading