Socket
Socket
Sign inDemoInstall

@ckeditor/ckeditor5-react

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ckeditor/ckeditor5-react - npm Package Compare versions

Comparing version 9.0.0 to 9.1.0

dist/cloud/useCKEditorCloud.d.ts

53

CHANGELOG.md
Changelog
=========
## [9.1.0](https://github.com/ckeditor/ckeditor5-react/compare/v9.0.0...v9.1.0) (2024-09-05)
We added an `onChangeInitializedEditors` callback to `CKEditorContext` component to allow tracking newly initialized editors within the JSX React tree.
**Example**
```tsx
<CKEditorContext
context={ ClassicEditor.Context }
contextWatchdog={ ClassicEditor.ContextWatchdog }
onChangeInitializedEditors={ editors => {
console.log( editors );
}}
>
<CKEditor
editor={ ClassicEditor }
data="<h2>Editor</h2>"
contextItemMetadata={{
name: 'editor1',
user: { id: '2' }
}}
/>
<CKEditor
editor={ ClassicEditor }
data="<h2>Another Editor</h2><p>... in a common Context</p>"
contextItemMetadata={{
name: 'editor2'
}}
/>
</CKEditorContext>
```
`onChangeInitializedEditors` will be called twice in the example above:
1. First log: `{ editor1: ... }`
2. Second log: `{ editor1: ..., editor2: ... }`
⚠️ Order of initialization is not guaranteed. `editor2` might be initialized before `editor1`.
### Features
* Add an onChangeInitializedEditors callback to CKEditorContext to allow tracking of newly initialized editors within the JSX React tree. Closes [#513](https://github.com/ckeditor/ckeditor5-react/issues/513). ([commit](https://github.com/ckeditor/ckeditor5-react/commit/530656316356ee9bc915710d1cf16ea6519b9e99))
* Added `useCKEditorCloud` hook for managing asynchronous loading of CKEditor from a CDN. ([commit](https://github.com/ckeditor/ckeditor5-react/commit/ec8e603d409776374c89be623030f8467fc1cf92))
* Added withCKEditorCloud HOC to simplify CKEditor integration with CDN in React components. ([commit](https://github.com/ckeditor/ckeditor5-react/commit/ec8e603d409776374c89be623030f8467fc1cf92))
### Bug fixes
* Image upload should be now possible in demos. ([commit](https://github.com/ckeditor/ckeditor5-react/commit/54e362cf0fb5c034e51fbe290db8df794e9ca452))
* Indent button is no longer disabled in manual demos. ([commit](https://github.com/ckeditor/ckeditor5-react/commit/54e362cf0fb5c034e51fbe290db8df794e9ca452))
* Manual demos should point to existing documentation links. ([commit](https://github.com/ckeditor/ckeditor5-react/commit/54e362cf0fb5c034e51fbe290db8df794e9ca452))
## [9.0.0](https://github.com/ckeditor/ckeditor5-react/compare/v8.0.0...v9.0.0) (2024-08-07)

@@ -5,0 +58,0 @@

4

dist/ckeditor.d.ts

@@ -8,2 +8,3 @@ /**

import type { EventInfo, Editor, EditorConfig, EditorWatchdog, ContextWatchdog, WatchdogConfig, EditorCreatorFunction } from 'ckeditor5';
import { type CKEditorConfigContextMetadata } from './context/setCKEditorReactContextMetadata';
export default class CKEditor<TEditor extends Editor> extends React.Component<Props<TEditor>> {

@@ -89,3 +90,3 @@ /**

private _getConfig;
static contextType: React.Context<import("./ckeditorcontext").ContextWatchdogValue | null>;
static contextType: React.Context<import("./context/ckeditorcontext").ContextWatchdogValue<import("ckeditor5").Context> | null>;
static propTypes: {

@@ -117,2 +118,3 @@ editor: Validator<{

};
contextItemMetadata?: CKEditorConfigContextMetadata;
config?: EditorConfig;

@@ -119,0 +121,0 @@ watchdogConfig?: WatchdogConfig;

@@ -6,3 +6,6 @@ /**

export { default as CKEditor } from './ckeditor';
export { default as CKEditorContext } from './ckeditorcontext';
export { default as CKEditorContext } from './context/ckeditorcontext';
export { default as useMultiRootEditor, type MultiRootHookProps, type MultiRootHookReturns } from './useMultiRootEditor';
export { default as useCKEditorCloud } from './cloud/useCKEditorCloud';
export { default as withCKEditorCloud, type WithCKEditorCloudHocProps } from './cloud/withCKEditorCloud';
export { loadCKEditorCloud, type CKEditorCloudResult, type CKEditorCloudConfig } from '@ckeditor/ckeditor5-integrations-common';
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import React, { useRef, useEffect, useState, useCallback, memo, forwardRef, useContext } from "react";
import React, { useRef, useEffect, useCallback, useState, memo, forwardRef, useContext } from "react";
import PropTypes from "prop-types";
import { createDefer, once, uid, shallowCompareArrays, uniq, overwriteObject, overwriteArray, isSSR, loadCKEditorCloud } from "@ckeditor/ckeditor5-integrations-common";
import { loadCKEditorCloud as loadCKEditorCloud2 } from "@ckeditor/ckeditor5-integrations-common";
/**

@@ -10,43 +12,2 @@ * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.

*/
const HEX_NUMBERS = new Array(256).fill("").map((_, index) => ("0" + index.toString(16)).slice(-2));
function uid() {
const r1 = Math.random() * 4294967296 >>> 0;
const r2 = Math.random() * 4294967296 >>> 0;
const r3 = Math.random() * 4294967296 >>> 0;
const r4 = Math.random() * 4294967296 >>> 0;
return "e" + HEX_NUMBERS[r1 >> 0 & 255] + HEX_NUMBERS[r1 >> 8 & 255] + HEX_NUMBERS[r1 >> 16 & 255] + HEX_NUMBERS[r1 >> 24 & 255] + HEX_NUMBERS[r2 >> 0 & 255] + HEX_NUMBERS[r2 >> 8 & 255] + HEX_NUMBERS[r2 >> 16 & 255] + HEX_NUMBERS[r2 >> 24 & 255] + HEX_NUMBERS[r3 >> 0 & 255] + HEX_NUMBERS[r3 >> 8 & 255] + HEX_NUMBERS[r3 >> 16 & 255] + HEX_NUMBERS[r3 >> 24 & 255] + HEX_NUMBERS[r4 >> 0 & 255] + HEX_NUMBERS[r4 >> 8 & 255] + HEX_NUMBERS[r4 >> 16 & 255] + HEX_NUMBERS[r4 >> 24 & 255];
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function createDefer() {
const deferred = {
resolve: null,
promise: null
};
deferred.promise = new Promise((resolve) => {
deferred.resolve = resolve;
});
return deferred;
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function once(fn) {
let lastResult = null;
return (...args) => {
if (!lastResult) {
lastResult = {
current: fn(...args)
};
}
return lastResult.current;
};
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const _LifeCycleElementSemaphore = class _LifeCycleElementSemaphore {

@@ -249,2 +210,16 @@ constructor(element, lifecycle) {

*/
const ReactContextMetadataKey = "$__CKEditorReactContextMetadata";
function withCKEditorReactContextMetadata(metadata, config) {
return {
...config,
[ReactContextMetadataKey]: metadata
};
}
function tryExtractCKEditorReactContextMetadata(object) {
return object.get(ReactContextMetadataKey);
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useIsMountedRef = () => {

@@ -264,2 +239,67 @@ const mountedRef = useRef(false);

*/
const useRefSafeCallback = (fn) => {
const callbackRef = useRef();
callbackRef.current = fn;
return useCallback(
(...args) => callbackRef.current(...args),
[]
);
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useInitializedCKEditorsMap = ({
currentContextWatchdog,
onChangeInitializedEditors
}) => {
const onChangeInitializedEditorsSafe = useRefSafeCallback(onChangeInitializedEditors || (() => {
}));
useEffect(() => {
var _a;
if (currentContextWatchdog.status !== "initialized") {
return;
}
const { watchdog } = currentContextWatchdog;
const editors = (_a = watchdog == null ? void 0 : watchdog.context) == null ? void 0 : _a.editors;
if (!editors) {
return;
}
const getInitializedContextEditors = () => [...editors].reduce(
(map, editor) => {
var _a2;
if (editor.state !== "ready") {
return map;
}
const metadata = tryExtractCKEditorReactContextMetadata(editor.config);
const nameOrId = (_a2 = metadata == null ? void 0 : metadata.name) != null ? _a2 : editor.id;
map[nameOrId] = {
instance: editor,
metadata
};
return map;
},
/* @__PURE__ */ Object.create({})
// Prevent the prototype pollution.
);
const onEditorStatusChange = () => {
onChangeInitializedEditorsSafe(
getInitializedContextEditors(),
watchdog
);
};
const onAddEditor = (_, editor) => {
editor.once("ready", onEditorStatusChange, { priority: "lowest" });
editor.once("destroy", onEditorStatusChange, { priority: "lowest" });
};
editors.on("add", onAddEditor);
return () => {
editors.off("add", onAddEditor);
};
}, [currentContextWatchdog]);
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const ContextWatchdogContext = React.createContext(null);

@@ -276,2 +316,3 @@ const CKEditorContext = (props) => {

isLayoutReady = true,
onChangeInitializedEditors,
onError = (error, details) => console.error(error, details)

@@ -298,2 +339,6 @@ } = props;

}, [currentContextWatchdog]);
useInitializedCKEditorsMap({
currentContextWatchdog,
onChangeInitializedEditors
});
function regenerateInitializationID() {

@@ -561,2 +606,6 @@ prevWatchdogInitializationIDRef.current = uid();

_createEditor(element, config) {
const { contextItemMetadata } = this.props;
if (contextItemMetadata) {
config = withCKEditorReactContextMetadata(contextItemMetadata, config);
}
return this.props.editor.create(element, config).then((editor) => {

@@ -804,63 +853,2 @@ if ("disabled" in this.props) {

*/
function overwriteObject(source, destination) {
for (const prop of Object.getOwnPropertyNames(destination)) {
delete destination[prop];
}
for (const [key, value] of Object.entries(source)) {
if (value !== destination && key !== "prototype" && key !== "__proto__") {
destination[key] = value;
}
}
return destination;
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useRefSafeCallback = (fn) => {
const callbackRef = useRef();
callbackRef.current = fn;
return useCallback(
(...args) => callbackRef.current(...args),
[]
);
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function uniq(source) {
return Array.from(new Set(source));
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function overwriteArray(source, destination) {
destination.length = 0;
destination.push(...source);
return destination;
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const shallowCompareArrays = (a, b) => {
if (a === b) {
return true;
}
if (!a || !b) {
return false;
}
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useInstantEffect = (fn, deps) => {

@@ -1313,7 +1301,122 @@ const prevDeps = useRef(null);

EditorToolbarWrapper.displayName = "EditorToolbarWrapper";
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useIsUnmountedRef = () => {
const mountedRef = useRef(false);
useEffect(() => {
mountedRef.current = false;
return () => {
mountedRef.current = true;
};
}, []);
return mountedRef;
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useAsyncCallback = (callback) => {
const [asyncState, setAsyncState] = useState({
status: "idle"
});
const unmountedRef = useIsUnmountedRef();
const prevExecutionUIDRef = useRef(null);
const asyncExecutor = useRefSafeCallback(async (...args) => {
if (unmountedRef.current || isSSR()) {
return null;
}
const currentExecutionUUID = uid();
prevExecutionUIDRef.current = currentExecutionUUID;
try {
if (asyncState.status !== "loading") {
setAsyncState({
status: "loading"
});
}
const result = await callback(...args);
if (!unmountedRef.current && prevExecutionUIDRef.current === currentExecutionUUID) {
setAsyncState({
status: "success",
data: result
});
}
return result;
} catch (error) {
console.error(error);
if (!unmountedRef.current && prevExecutionUIDRef.current === currentExecutionUUID) {
setAsyncState({
status: "error",
error
});
}
}
return null;
});
return [asyncExecutor, asyncState];
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const useAsyncValue = (callback, deps) => {
const [asyncCallback, asyncState] = useAsyncCallback(callback);
useInstantEffect(asyncCallback, deps);
if (asyncState.status === "idle") {
return {
status: "loading"
};
}
return asyncState;
};
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
function useCKEditorCloud(config) {
const serializedConfigKey = JSON.stringify(config);
const result = useAsyncValue(
async () => loadCKEditorCloud(config),
[serializedConfigKey]
);
if (result.status === "success") {
return {
...result.data,
status: "success"
};
}
return result;
}
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/
const withCKEditorCloud = (config) => (WrappedComponent) => {
const ComponentWithCKEditorCloud = (props) => {
var _a, _b;
const ckeditorCloudResult = useCKEditorCloud(config.cloud);
switch (ckeditorCloudResult.status) {
case "error":
if (!config.renderError) {
return "Unable to load CKEditor Cloud data!";
}
return config.renderError(ckeditorCloudResult.error);
case "success":
return /* @__PURE__ */ React.createElement(WrappedComponent, { ...props, cloud: ckeditorCloudResult });
default:
return (_b = (_a = config.renderLoader) == null ? void 0 : _a.call(config)) != null ? _b : null;
}
};
ComponentWithCKEditorCloud.displayName = "ComponentWithCKEditorCloud";
return ComponentWithCKEditorCloud;
};
export {
CKEditor,
CKEditorContext,
useMultiRootEditor
loadCKEditorCloud2 as loadCKEditorCloud,
useCKEditorCloud,
useMultiRootEditor,
withCKEditorCloud
};
//# sourceMappingURL=index.js.map
{
"name": "@ckeditor/ckeditor5-react",
"version": "9.0.0",
"version": "9.1.0",
"description": "Official React component for CKEditor 5 – the best browser-based rich text editor.",

@@ -31,6 +31,8 @@ "keywords": [

"dependencies": {
"prop-types": "^15.7.2"
"prop-types": "^15.7.2",
"@ckeditor/ckeditor5-integrations-common": "^1.0.0"
},
"peerDependencies": {
"ckeditor5": ">=42.0.0 || ^0.0.0-nightly",
"ckeditor5-premium-features": ">=42.0.0 || ^0.0.0-nightly",
"react": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"

@@ -41,3 +43,4 @@ },

"string-width": "4.1.0",
"semver": "^7.0.0"
"semver": "^7.0.0",
"ws": "^8"
},

@@ -44,0 +47,0 @@ "engines": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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