From f274aaac54f6f7ae3bfb940ee247a6147be9412b Mon Sep 17 00:00:00 2001 From: Thibaud Colas Date: Fri, 25 Jan 2019 02:39:17 +0200 Subject: [PATCH] fix(api): use more precise Flow types for public APIs. Fix #30 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced Object type annotations with the required shape (not exact, can have extra attributes for convenience). This might raise type issues, but only if there is indeed a problem in the library usage. See [Flow’s `unclear-type`](https://flow.org/en/docs/linting/rule-reference/#toc-unclear-type) rule for further reference. - Use [$ReadOnlyArray](https://flow.org/en/docs/types/arrays/#toc-readonlyarray) in place of Array. This is a supertype of Array (so no change required in implementation), which guarantees draftjs-filters does not mutate arrays. --- src/lib/filters/atomic.js | 2 +- src/lib/filters/blocks.js | 4 ++-- src/lib/filters/editor.js | 13 +++++++------ src/lib/filters/entities.js | 16 ++++++++++++---- src/lib/filters/styles.js | 2 +- src/lib/filters/text.js | 2 +- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/lib/filters/atomic.js b/src/lib/filters/atomic.js index f783087f..80484059 100644 --- a/src/lib/filters/atomic.js +++ b/src/lib/filters/atomic.js @@ -79,7 +79,7 @@ export const resetAtomicBlocks = (content: ContentState) => { * Removes atomic blocks for which the entity isn't whitelisted. */ export const removeInvalidAtomicBlocks = ( - whitelist: Array, + whitelist: $ReadOnlyArray<{ type: string }>, content: ContentState, ) => { const blockMap = content.getBlockMap() diff --git a/src/lib/filters/blocks.js b/src/lib/filters/blocks.js index b97b71e5..5c76b4a5 100644 --- a/src/lib/filters/blocks.js +++ b/src/lib/filters/blocks.js @@ -36,7 +36,7 @@ export const removeInvalidDepthBlocks = (content: ContentState) => { * ends up in the text. Other use cases may not be well covered. */ export const preserveBlockByText = ( - rules: Array<{ + rules: $ReadOnlyArray<{ test: string, type: string, depth: number, @@ -125,7 +125,7 @@ export const limitBlockDepth = (max: number, content: ContentState) => { * Also sets depth to 0 (for potentially nested list items). */ export const filterBlockTypes = ( - whitelist: Array, + whitelist: $ReadOnlyArray, content: ContentState, ) => { const blockMap = content.getBlockMap() diff --git a/src/lib/filters/editor.js b/src/lib/filters/editor.js index 4f8030ce..7619d34e 100644 --- a/src/lib/filters/editor.js +++ b/src/lib/filters/editor.js @@ -23,22 +23,23 @@ import { import { replaceTextBySpaces } from "./text" import { applyContentWithSelection } from "./selection" +import { ContentState } from "draft-js" import type { EditorState as EditorStateType } from "draft-js" type FilterOptions = { // Whitelist of allowed block types. unstyled and atomic are always included. - blocks: Array, + blocks: $ReadOnlyArray, // Whitelist of allowed inline styles. - styles: Array, + styles: $ReadOnlyArray, // Whitelist of allowed entities. - entities: Array<{ + entities: $ReadOnlyArray<{ // Entity type, eg. "LINK" type: string, // Allowed attributes. Other attributes will be removed. - attributes: Array, + attributes: $ReadOnlyArray, // Refine which entities are kept by whitelisting acceptable values with regular expression patterns. whitelist: { - [attribute: string]: string, + [attribute: string]: string | boolean, }, }>, // Maximum amount of depth for lists (0 = no nesting). @@ -137,7 +138,7 @@ export const filterEditorState = ( const content = editorState.getCurrentContent() const nextContent = filters.reduce( - (c, filter: Function) => filter(c), + (c, filter: (ContentState) => ContentState) => filter(c), content, ) diff --git a/src/lib/filters/entities.js b/src/lib/filters/entities.js index 8609b378..44e205b6 100644 --- a/src/lib/filters/entities.js +++ b/src/lib/filters/entities.js @@ -122,7 +122,7 @@ export const filterEntityRanges = ( * Keeps all entity types (images, links, documents, embeds) that are enabled. */ export const shouldKeepEntityType = ( - whitelist: Array, + whitelist: $ReadOnlyArray<{ type: string }>, type: string, ) => { return whitelist.some((e) => e.type === type) @@ -143,9 +143,14 @@ export const shouldRemoveImageEntity = ( * Filters entities based on the data they contain. */ export const shouldKeepEntityByAttribute = ( - entityTypes: Array, + entityTypes: $ReadOnlyArray<{ + type: string, + whitelist: { + [attribute: string]: string | boolean, + }, + }>, entityType: string, - data: Object, + data: {}, ) => { const config = entityTypes.find((t) => t.type === entityType) // If no whitelist is defined, the filter keeps the entity. @@ -172,7 +177,10 @@ export const shouldKeepEntityByAttribute = ( * of unneeded attributes (width, height, etc). */ export const filterEntityData = ( - entityTypes: Array, + entityTypes: $ReadOnlyArray<{ + type: string, + attributes: $ReadOnlyArray, + }>, content: ContentState, ) => { let newContent = content diff --git a/src/lib/filters/styles.js b/src/lib/filters/styles.js index f566c852..e9959740 100644 --- a/src/lib/filters/styles.js +++ b/src/lib/filters/styles.js @@ -5,7 +5,7 @@ import { ContentState, CharacterMetadata } from "draft-js" * Removes all styles not present in the whitelist. */ export const filterInlineStyles = ( - whitelist: Array, + whitelist: $ReadOnlyArray, content: ContentState, ) => { const blockMap = content.getBlockMap() diff --git a/src/lib/filters/text.js b/src/lib/filters/text.js index 590bd8d8..f38a16d0 100644 --- a/src/lib/filters/text.js +++ b/src/lib/filters/text.js @@ -5,7 +5,7 @@ import { ContentState } from "draft-js" * Replaces the given characters by their equivalent length of spaces, in all blocks. */ export const replaceTextBySpaces = ( - characters: Array, + characters: $ReadOnlyArray, content: ContentState, ) => { const blockMap = content.getBlockMap()