Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tinymce/tinymce-react

Package Overview
Dependencies
Maintainers
2
Versions
367
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tinymce/tinymce-react - npm Package Compare versions

Comparing version 3.10.0-rc.20210201062216249.e301a07 to 3.10.0-rc.20210319032559455.eabd99b

17

CHANGELOG.md

@@ -7,2 +7,19 @@ # Change log

## [3.10.4] - 2021-03-10
### Fixed
- Check for editor changes on `"compositionend"` event to more accurately trigger `onEditorChange`. INT-2348
- Updated dependencies to latest available
## [3.10.3] - 2021-03-04
### Fixed
- Updated dependencies to latest available
## [3.10.2] - 2021-02-20
## Fixed
- Event handlers are registered at setup time so props like `onBeforeRenderUI` will now be called. #INT-2325
## [3.10.1] - 2021-02-01
### Fixed
- Fixed CI build
## [3.10.0] - 2021-02-01

@@ -9,0 +26,0 @@ ### Fixed

5

lib/cjs/main/ts/components/Editor.d.ts

@@ -42,5 +42,5 @@ /**

static defaultProps: Partial<IAllProps>;
editor?: TinyMCEEditor;
private id;
private elementRef;
private editor?;
private inline;

@@ -56,3 +56,3 @@ private currentContent?;

id: string;
}, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)>;
}, string | React.JSXElementConstructor<any>>;
private renderInline;

@@ -64,4 +64,3 @@ private renderIframe;

private handleEditorChange;
private handleInit;
private initialise;
}

64

lib/cjs/main/ts/components/Editor.js

@@ -17,2 +17,4 @@ "use strict";

return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);

@@ -49,3 +51,3 @@ function __() { this.constructor = d; }

var editor = _this.editor;
if (editor) {
if (editor && editor.initialized) {
var newContent = editor.getContent({ format: _this.props.outputFormat });

@@ -60,18 +62,2 @@ if (newContent !== _this.currentContent) {

};
_this.handleInit = function (initEvent) {
var editor = _this.editor;
if (editor) {
editor.setContent(_this.getInitialValue());
editor.undoManager.clear();
editor.undoManager.add();
editor.setDirty(false);
if (Utils_1.isFunction(_this.props.onEditorChange)) {
editor.on('change keyup setcontent', _this.handleEditorChange);
}
if (Utils_1.isFunction(_this.props.onInit)) {
_this.props.onInit(initEvent, editor);
}
_this.bindHandlers({});
}
};
_this.initialise = function () {

@@ -88,3 +74,14 @@ var target = _this.elementRef.current;

_this.editor = editor;
editor.on('init', _this.handleInit);
_this.bindHandlers({});
// When running in inline mode the editor gets the initial value
// from the innerHTML of the element it is initialized on.
// However we don't want to take on the responsibility of sanitizing
// to remove XSS in the react integration so we have a chicken and egg
// problem... We avoid it by sneaking in a set content before the first
// "official" setContent and using TinyMCE to do the sanitization.
if (_this.inline && !Utils_1.isTextareaOrInput(target)) {
editor.once('PostRender', function (_evt) {
editor.setContent(_this.getInitialValue(), { no_events: true });
});
}
if (_this.props.init && Utils_1.isFunction(_this.props.init.setup)) {

@@ -94,5 +91,8 @@ _this.props.init.setup(editor);

} });
if (Utils_1.isTextarea(_this.elementRef.current)) {
_this.elementRef.current.style.visibility = '';
if (!_this.inline) {
target.style.visibility = '';
}
if (Utils_1.isTextareaOrInput(target)) {
target.value = _this.getInitialValue();
}
tinymce.init(finalInit);

@@ -134,11 +134,9 @@ };

if (editor) {
editor.off('init', this.handleInit);
if (editor.initialized) {
editor.off('change keyup setcontent', this.handleEditorChange);
Object.keys(this.boundHandlers).forEach(function (eventName) {
editor.off(eventName, _this.boundHandlers[eventName]);
});
this.boundHandlers = {};
}
editor.off('change keyup compositionend setcontent', this.handleEditorChange);
Object.keys(this.boundHandlers).forEach(function (eventName) {
editor.off(eventName, _this.boundHandlers[eventName]);
});
this.boundHandlers = {};
editor.remove();
this.editor = undefined;
}

@@ -190,2 +188,12 @@ };

Utils_1.configHandlers(this.editor, prevProps, this.props, this.boundHandlers, function (key) { return _this.props[key]; });
// check if we should monitor editor changes
var isValueControlled = function (p) { return p.onEditorChange !== undefined || p.value !== undefined; };
var wasControlled = isValueControlled(prevProps);
var nowControlled = isValueControlled(this.props);
if (!wasControlled && nowControlled) {
this.editor.on('change keyup compositionend setcontent', this.handleEditorChange);
}
else if (wasControlled && !nowControlled) {
this.editor.off('change keyup compositionend setcontent', this.handleEditorChange);
}
}

@@ -192,0 +200,0 @@ };

@@ -13,7 +13,7 @@ /**

declare type PropLookup = <K extends keyof IAllProps>(key: K) => IAllProps[K] | undefined;
export declare const configHandlers2: <H>(handlerLookup: PropLookup, on: (name: string, handler: H) => void, off: (name: string, handler: H) => void, adapter: <K extends "onBeforePaste" | "onBlur" | "onClick" | "onContextMenu" | "onCopy" | "onCut" | "onDblclick" | "onDrag" | "onDragDrop" | "onDragEnd" | "onDragGesture" | "onDragOver" | "onDrop" | "onFocus" | "onFocusIn" | "onFocusOut" | "onKeyDown" | "onKeyPress" | "onKeyUp" | "onMouseDown" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseOut" | "onMouseOver" | "onMouseUp" | "onPaste" | "onSelectionChange" | "onActivate" | "onAddUndo" | "onBeforeAddUndo" | "onBeforeExecCommand" | "onBeforeGetContent" | "onBeforeRenderUI" | "onBeforeSetContent" | "onChange" | "onClearUndos" | "onDeactivate" | "onDirty" | "onExecCommand" | "onGetContent" | "onHide" | "onInit" | "onLoadContent" | "onNodeChange" | "onPostProcess" | "onPostRender" | "onPreProcess" | "onProgressState" | "onRedo" | "onRemove" | "onReset" | "onSaveContent" | "onSetAttrib" | "onObjectResizeStart" | "onObjectResized" | "onObjectSelected" | "onSetContent" | "onShow" | "onSubmit" | "onUndo" | "onVisualAid">(lookup: PropLookup, key: K) => H, prevProps: Partial<IAllProps>, props: Partial<IAllProps>, boundHandlers: Record<string, H>) => void;
export declare const configHandlers2: <H>(handlerLookup: PropLookup, on: (name: string, handler: H) => void, off: (name: string, handler: H) => void, adapter: <K extends keyof import("./Events").IEvents>(lookup: PropLookup, key: K) => H, prevProps: Partial<IAllProps>, props: Partial<IAllProps>, boundHandlers: Record<string, H>) => void;
export declare const configHandlers: (editor: TinyMCEEditor, prevProps: Partial<IAllProps>, props: Partial<IAllProps>, boundHandlers: Record<string, (event: EditorEvent<any>) => unknown>, lookup: PropLookup) => void;
export declare const uuid: (prefix: string) => string;
export declare const isTextarea: (element: Element | null) => element is HTMLTextAreaElement;
export declare const isTextareaOrInput: (element: Element | null) => element is HTMLInputElement | HTMLTextAreaElement;
export declare const mergePlugins: (initPlugins: string | string[] | undefined, inputPlugins: string | string[] | undefined) => string[];
export {};

@@ -10,3 +10,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.mergePlugins = exports.isTextarea = exports.uuid = exports.configHandlers = exports.configHandlers2 = exports.isFunction = void 0;
exports.mergePlugins = exports.isTextareaOrInput = exports.uuid = exports.configHandlers = exports.configHandlers2 = exports.isFunction = void 0;
var EditorPropTypes_1 = require("./components/EditorPropTypes");

@@ -49,4 +49,6 @@ var isFunction = function (x) { return typeof x === 'function'; };

exports.uuid = uuid;
var isTextarea = function (element) { return element !== null && element.tagName.toLowerCase() === 'textarea'; };
exports.isTextarea = isTextarea;
var isTextareaOrInput = function (element) {
return element !== null && (element.tagName.toLowerCase() === 'textarea' || element.tagName.toLowerCase() === 'input');
};
exports.isTextareaOrInput = isTextareaOrInput;
var normalizePluginArray = function (plugins) {

@@ -53,0 +55,0 @@ if (typeof plugins === 'undefined' || plugins === '') {

@@ -42,5 +42,5 @@ /**

static defaultProps: Partial<IAllProps>;
editor?: TinyMCEEditor;
private id;
private elementRef;
private editor?;
private inline;

@@ -56,3 +56,3 @@ private currentContent?;

id: string;
}, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)>;
}, string | React.JSXElementConstructor<any>>;
private renderInline;

@@ -64,4 +64,3 @@ private renderIframe;

private handleEditorChange;
private handleInit;
private initialise;
}

@@ -16,2 +16,4 @@ /**

return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);

@@ -36,3 +38,3 @@ function __() { this.constructor = d; }

import { getTinymce } from '../TinyMCE';
import { isFunction, isTextarea, mergePlugins, uuid, configHandlers } from '../Utils';
import { isFunction, isTextareaOrInput, mergePlugins, uuid, configHandlers } from '../Utils';
import { EditorPropTypes } from './EditorPropTypes';

@@ -47,3 +49,3 @@ var Editor = /** @class */ (function (_super) {

var editor = _this.editor;
if (editor) {
if (editor && editor.initialized) {
var newContent = editor.getContent({ format: _this.props.outputFormat });

@@ -58,18 +60,2 @@ if (newContent !== _this.currentContent) {

};
_this.handleInit = function (initEvent) {
var editor = _this.editor;
if (editor) {
editor.setContent(_this.getInitialValue());
editor.undoManager.clear();
editor.undoManager.add();
editor.setDirty(false);
if (isFunction(_this.props.onEditorChange)) {
editor.on('change keyup setcontent', _this.handleEditorChange);
}
if (isFunction(_this.props.onInit)) {
_this.props.onInit(initEvent, editor);
}
_this.bindHandlers({});
}
};
_this.initialise = function () {

@@ -86,3 +72,14 @@ var target = _this.elementRef.current;

_this.editor = editor;
editor.on('init', _this.handleInit);
_this.bindHandlers({});
// When running in inline mode the editor gets the initial value
// from the innerHTML of the element it is initialized on.
// However we don't want to take on the responsibility of sanitizing
// to remove XSS in the react integration so we have a chicken and egg
// problem... We avoid it by sneaking in a set content before the first
// "official" setContent and using TinyMCE to do the sanitization.
if (_this.inline && !isTextareaOrInput(target)) {
editor.once('PostRender', function (_evt) {
editor.setContent(_this.getInitialValue(), { no_events: true });
});
}
if (_this.props.init && isFunction(_this.props.init.setup)) {

@@ -92,5 +89,8 @@ _this.props.init.setup(editor);

} });
if (isTextarea(_this.elementRef.current)) {
_this.elementRef.current.style.visibility = '';
if (!_this.inline) {
target.style.visibility = '';
}
if (isTextareaOrInput(target)) {
target.value = _this.getInitialValue();
}
tinymce.init(finalInit);

@@ -132,11 +132,9 @@ };

if (editor) {
editor.off('init', this.handleInit);
if (editor.initialized) {
editor.off('change keyup setcontent', this.handleEditorChange);
Object.keys(this.boundHandlers).forEach(function (eventName) {
editor.off(eventName, _this.boundHandlers[eventName]);
});
this.boundHandlers = {};
}
editor.off('change keyup compositionend setcontent', this.handleEditorChange);
Object.keys(this.boundHandlers).forEach(function (eventName) {
editor.off(eventName, _this.boundHandlers[eventName]);
});
this.boundHandlers = {};
editor.remove();
this.editor = undefined;
}

@@ -188,2 +186,12 @@ };

configHandlers(this.editor, prevProps, this.props, this.boundHandlers, function (key) { return _this.props[key]; });
// check if we should monitor editor changes
var isValueControlled = function (p) { return p.onEditorChange !== undefined || p.value !== undefined; };
var wasControlled = isValueControlled(prevProps);
var nowControlled = isValueControlled(this.props);
if (!wasControlled && nowControlled) {
this.editor.on('change keyup compositionend setcontent', this.handleEditorChange);
}
else if (wasControlled && !nowControlled) {
this.editor.off('change keyup compositionend setcontent', this.handleEditorChange);
}
}

@@ -190,0 +198,0 @@ };

@@ -13,7 +13,7 @@ /**

declare type PropLookup = <K extends keyof IAllProps>(key: K) => IAllProps[K] | undefined;
export declare const configHandlers2: <H>(handlerLookup: PropLookup, on: (name: string, handler: H) => void, off: (name: string, handler: H) => void, adapter: <K extends "onBeforePaste" | "onBlur" | "onClick" | "onContextMenu" | "onCopy" | "onCut" | "onDblclick" | "onDrag" | "onDragDrop" | "onDragEnd" | "onDragGesture" | "onDragOver" | "onDrop" | "onFocus" | "onFocusIn" | "onFocusOut" | "onKeyDown" | "onKeyPress" | "onKeyUp" | "onMouseDown" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseOut" | "onMouseOver" | "onMouseUp" | "onPaste" | "onSelectionChange" | "onActivate" | "onAddUndo" | "onBeforeAddUndo" | "onBeforeExecCommand" | "onBeforeGetContent" | "onBeforeRenderUI" | "onBeforeSetContent" | "onChange" | "onClearUndos" | "onDeactivate" | "onDirty" | "onExecCommand" | "onGetContent" | "onHide" | "onInit" | "onLoadContent" | "onNodeChange" | "onPostProcess" | "onPostRender" | "onPreProcess" | "onProgressState" | "onRedo" | "onRemove" | "onReset" | "onSaveContent" | "onSetAttrib" | "onObjectResizeStart" | "onObjectResized" | "onObjectSelected" | "onSetContent" | "onShow" | "onSubmit" | "onUndo" | "onVisualAid">(lookup: PropLookup, key: K) => H, prevProps: Partial<IAllProps>, props: Partial<IAllProps>, boundHandlers: Record<string, H>) => void;
export declare const configHandlers2: <H>(handlerLookup: PropLookup, on: (name: string, handler: H) => void, off: (name: string, handler: H) => void, adapter: <K extends keyof import("./Events").IEvents>(lookup: PropLookup, key: K) => H, prevProps: Partial<IAllProps>, props: Partial<IAllProps>, boundHandlers: Record<string, H>) => void;
export declare const configHandlers: (editor: TinyMCEEditor, prevProps: Partial<IAllProps>, props: Partial<IAllProps>, boundHandlers: Record<string, (event: EditorEvent<any>) => unknown>, lookup: PropLookup) => void;
export declare const uuid: (prefix: string) => string;
export declare const isTextarea: (element: Element | null) => element is HTMLTextAreaElement;
export declare const isTextareaOrInput: (element: Element | null) => element is HTMLInputElement | HTMLTextAreaElement;
export declare const mergePlugins: (initPlugins: string | string[] | undefined, inputPlugins: string | string[] | undefined) => string[];
export {};

@@ -41,3 +41,5 @@ /**

};
export var isTextarea = function (element) { return element !== null && element.tagName.toLowerCase() === 'textarea'; };
export var isTextareaOrInput = function (element) {
return element !== null && (element.tagName.toLowerCase() === 'textarea' || element.tagName.toLowerCase() === 'input');
};
var normalizePluginArray = function (plugins) {

@@ -44,0 +46,0 @@ if (typeof plugins === 'undefined' || plugins === '') {

@@ -29,3 +29,3 @@ {

"prop-types": "^15.6.2",
"tinymce": "^5.6.2"
"tinymce": "^5.7.0"
},

@@ -37,20 +37,20 @@ "peerDependencies": {

"devDependencies": {
"@babel/core": "^7.12.10",
"@ephox/agar": "^5.1.1",
"@ephox/bedrock-client": "^11.0.0",
"@ephox/bedrock-server": "^11.0.2",
"@ephox/katamari": "^7.1.1",
"@ephox/mcagar": "^5.1.1",
"@ephox/sand": "^4.0.3",
"@ephox/sugar": "^7.0.3",
"@babel/core": "^7.13.10",
"@ephox/agar": "^5.2.1",
"@ephox/bedrock-client": "^11.1.1",
"@ephox/bedrock-server": "^11.2.0",
"@ephox/katamari": "^7.1.3",
"@ephox/mcagar": "^6.0.1",
"@ephox/sand": "^4.0.5",
"@ephox/sugar": "^7.1.1",
"@storybook/addon-info": "^5.3.21",
"@storybook/react": "^6.1.11",
"@storybook/react": "^6.1.21",
"@storybook/storybook-deployer": "^2.8.6",
"@tinymce/beehive-flow": "^0.12.0",
"@tinymce/beehive-flow": "^0.14.0",
"@tinymce/eslint-plugin": "^1.7.2",
"@tinymce/miniature": "^3.0.1",
"@types/node": "^14.14.20",
"@tinymce/miniature": "^3.1.1",
"@types/node": "^14.14.33",
"@types/prop-types": "^15.5.8",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react": "^17.0.3",
"@types/react-dom": "^17.0.2",
"@types/storybook__addon-info": "^5.2.3",

@@ -60,3 +60,3 @@ "@types/storybook__react": "^5.2.1",

"babel-loader": "^8.2.2",
"core-js": "^3.8.2",
"core-js": "^3.9.1",
"raf": "^3.4.1",

@@ -68,8 +68,8 @@ "react": "^17.0.1",

"tinymce-5": "npm:tinymce@^5",
"ts-loader": "^8.0.14",
"typescript": "^4.1.3",
"webpack": "^5.12.3"
"ts-loader": "^8.0.17",
"typescript": "^4.2.3",
"webpack": "^5.24.4"
},
"version": "3.10.0-rc.20210201062216249.e301a07",
"version": "3.10.0-rc.20210319032559455.eabd99b",
"name": "@tinymce/tinymce-react"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc