diff --git a/CHANGELOG.md b/CHANGELOG.md index 608d6db4..94ff1744 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Support for `react` version `^19.0.0` by updating the `react` and `react-dom` in the `peerDependencies` to `^19.0.0` +### Fixed +- The `onEditorChange` callback was called three times when content was inserted with `insertContent` editor API. #INT-3226 + ## 6.0.0 - 2025-02-21 ### Fixed diff --git a/src/main/ts/components/Editor.tsx b/src/main/ts/components/Editor.tsx index e6c1d214..19f8be72 100644 --- a/src/main/ts/components/Editor.tsx +++ b/src/main/ts/components/Editor.tsx @@ -1,10 +1,12 @@ import * as React from 'react'; +import type { Bookmark, EditorEvent, TinyMCE, Editor as TinyMCEEditor } from 'tinymce'; import { IEvents } from '../Events'; import { ScriptItem, ScriptLoader } from '../ScriptLoader2'; import { getTinymce } from '../TinyMCE'; -import { isFunction, isTextareaOrInput, mergePlugins, uuid, configHandlers, isBeforeInputEventAvailable, isInDoc, setMode } from '../Utils'; +import { configHandlers, isBeforeInputEventAvailable, isFunction, isInDoc, isTextareaOrInput, mergePlugins, setMode, uuid } from '../Utils'; import { EditorPropTypes, IEditorPropTypes } from './EditorPropTypes'; -import type { Bookmark, Editor as TinyMCEEditor, EditorEvent, TinyMCE } from 'tinymce'; + +const changeEvents = 'change keyup compositionend setcontent CommentChange'; type OmitStringIndexSignature = { [K in keyof T as string extends K ? never : K]: T[K] }; @@ -241,7 +243,7 @@ export class Editor extends React.Component { public componentWillUnmount() { const editor = this.editor; if (editor) { - editor.off(this.changeEvents(), this.handleEditorChange); + editor.off(changeEvents, this.handleEditorChange); editor.off(this.beforeInputEvent(), this.handleBeforeInput); editor.off('keypress', this.handleEditorChangeSpecial); editor.off('keydown', this.handleBeforeInputSpecial); @@ -259,14 +261,6 @@ export class Editor extends React.Component { return this.inline ? this.renderInline() : this.renderIframe(); } - private changeEvents() { - const isIE = getTinymce(this.view)?.Env?.browser?.isIE(); - return (isIE - ? 'change keyup compositionend setcontent CommentChange' - : 'change input compositionend setcontent CommentChange' - ); - } - private beforeInputEvent() { return isBeforeInputEventAvailable() ? 'beforeinput SelectionChange' : 'SelectionChange'; } @@ -335,13 +329,13 @@ export class Editor extends React.Component { const wasControlled = isValueControlled(prevProps); const nowControlled = isValueControlled(this.props); if (!wasControlled && nowControlled) { - this.editor.on(this.changeEvents(), this.handleEditorChange); + this.editor.on(changeEvents, this.handleEditorChange); this.editor.on(this.beforeInputEvent(), this.handleBeforeInput); this.editor.on('keydown', this.handleBeforeInputSpecial); this.editor.on('keyup', this.handleEditorChangeSpecial); this.editor.on('NewBlock', this.handleEditorChange); } else if (wasControlled && !nowControlled) { - this.editor.off(this.changeEvents(), this.handleEditorChange); + this.editor.off(changeEvents, this.handleEditorChange); this.editor.off(this.beforeInputEvent(), this.handleBeforeInput); this.editor.off('keydown', this.handleBeforeInputSpecial); this.editor.off('keyup', this.handleEditorChangeSpecial); diff --git a/src/stories/Editor.stories.tsx b/src/stories/Editor.stories.tsx index 184f2596..145ccc5f 100644 --- a/src/stories/Editor.stories.tsx +++ b/src/stories/Editor.stories.tsx @@ -1,6 +1,6 @@ +import { StoryObj } from '@storybook/react'; import React from 'react'; import { EditorEvent, Events, Editor as TinyMCEEditor } from 'tinymce'; -import { StoryObj } from '@storybook/react'; import { Editor, IAllProps } from '../main/ts/components/Editor'; const apiKey = 'qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc'; @@ -60,7 +60,9 @@ export const ControlledInput: StoryObj = { setData(e)} + onEditorChange={(e) => { + setData(e); + }} />