@ckeditor/ckeditor5-core 46.1.1 → 47.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-core",
3
- "version": "46.1.1",
3
+ "version": "47.0.0-alpha.0",
4
4
  "description": "The core architecture of CKEditor 5 – the best browser-based rich text editor.",
5
5
  "keywords": [
6
6
  "wysiwyg",
@@ -24,10 +24,10 @@
24
24
  "type": "module",
25
25
  "main": "src/index.js",
26
26
  "dependencies": {
27
- "@ckeditor/ckeditor5-engine": "46.1.1",
28
- "@ckeditor/ckeditor5-ui": "46.1.1",
29
- "@ckeditor/ckeditor5-utils": "46.1.1",
30
- "@ckeditor/ckeditor5-watchdog": "46.1.1",
27
+ "@ckeditor/ckeditor5-engine": "47.0.0-alpha.0",
28
+ "@ckeditor/ckeditor5-ui": "47.0.0-alpha.0",
29
+ "@ckeditor/ckeditor5-utils": "47.0.0-alpha.0",
30
+ "@ckeditor/ckeditor5-watchdog": "47.0.0-alpha.0",
31
31
  "es-toolkit": "1.39.5"
32
32
  },
33
33
  "author": "CKSource (http://cksource.com/)",
@@ -454,7 +454,7 @@ export declare abstract class Editor extends /* #__PURE__ */ Editor_base {
454
454
  * Exposed as static editor field for easier access in editor builds.
455
455
  */
456
456
  static ContextWatchdog: typeof ContextWatchdog;
457
- private _showLicenseError;
457
+ protected _showLicenseError(reason: LicenseErrorReason, name?: string): void;
458
458
  /**
459
459
  * This part of the code is _not_ executed in installations under the GPL license (with `config.licenseKey = 'GPL'`).
460
460
  *
@@ -463,6 +463,10 @@ export declare abstract class Editor extends /* #__PURE__ */ Editor_base {
463
463
  */
464
464
  private _sendUsageRequest;
465
465
  }
466
+ /**
467
+ * @internal
468
+ */
469
+ export type LicenseErrorReason = 'invalid' | 'expired' | 'domainLimit' | 'pluginNotAllowed' | 'featureNotAllowed' | 'evaluationLimit' | 'trialLimit' | 'developmentLimit' | 'usageLimit' | 'distributionChannel';
466
470
  /**
467
471
  * Fired when the {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional
468
472
  * editor components are ready.
@@ -6,7 +6,7 @@
6
6
  * @module core/editor/editor
7
7
  */
8
8
  import { set, get } from 'es-toolkit/compat';
9
- import { Config, CKEditorError, ObservableMixin, logError, parseBase64EncodedObject, releaseDate, toArray, uid, crc32 } from '@ckeditor/ckeditor5-utils';
9
+ import { Config, CKEditorError, ObservableMixin, logError, releaseDate, toArray, uid, crc32, decodeLicenseKey, isFeatureBlockedByLicenseKey } from '@ckeditor/ckeditor5-utils';
10
10
  import { Conversion, DataController, EditingController, Model, StylesProcessor } from '@ckeditor/ckeditor5-engine';
11
11
  import { ContextWatchdog, EditorWatchdog } from '@ckeditor/ckeditor5-watchdog';
12
12
  import { Context } from '../context.js';
@@ -34,7 +34,7 @@ import '../../theme/core.css';
34
34
  * the specific editor implements also the {@link ~Editor#ui} property
35
35
  * (as most editor implementations do).
36
36
  */
37
- class Editor extends /* #__PURE__ */ ObservableMixin() {
37
+ export class Editor extends /* #__PURE__ */ ObservableMixin() {
38
38
  /**
39
39
  * A required name of the editor class. The name should reflect the constructor name.
40
40
  */
@@ -309,16 +309,9 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
309
309
  function verifyLicenseKey(editor) {
310
310
  const licenseKey = editor.config.get('licenseKey');
311
311
  const distributionChannel = window[Symbol.for('cke distribution')] || 'sh';
312
- function blockEditor(reason) {
312
+ function blockEditor(reason, name) {
313
313
  editor.enableReadOnlyMode(Symbol('invalidLicense'));
314
- editor._showLicenseError(reason);
315
- }
316
- function getPayload(licenseKey) {
317
- const parts = licenseKey.split('.');
318
- if (parts.length != 3) {
319
- return null;
320
- }
321
- return parts[1];
314
+ editor._showLicenseError(reason, name);
322
315
  }
323
316
  function hasAllRequiredFields(licensePayload) {
324
317
  const requiredFields = ['exp', 'jti', 'vc'];
@@ -363,12 +356,7 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
363
356
  }
364
357
  return;
365
358
  }
366
- const encodedPayload = getPayload(licenseKey);
367
- if (!encodedPayload) {
368
- blockEditor('invalid');
369
- return;
370
- }
371
- const licensePayload = parseBase64EncodedObject(encodedPayload);
359
+ const licensePayload = decodeLicenseKey(licenseKey);
372
360
  if (!licensePayload) {
373
361
  blockEditor('invalid');
374
362
  return;
@@ -649,7 +637,36 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
649
637
  const removePlugins = config.get('removePlugins') || [];
650
638
  const extraPlugins = config.get('extraPlugins') || [];
651
639
  const substitutePlugins = config.get('substitutePlugins') || [];
652
- return this.plugins.init(plugins.concat(extraPlugins), removePlugins, substitutePlugins);
640
+ return this.plugins.init(plugins.concat(extraPlugins), removePlugins, substitutePlugins)
641
+ .then(plugins => {
642
+ checkPluginsAllowedByLicenseKey(this);
643
+ return plugins;
644
+ });
645
+ function checkPluginsAllowedByLicenseKey(editor) {
646
+ const licenseKey = editor.config.get('licenseKey');
647
+ if (licenseKey === 'GPL') {
648
+ return;
649
+ }
650
+ const decodedPayload = decodeLicenseKey(licenseKey);
651
+ if (!decodedPayload) {
652
+ return;
653
+ }
654
+ const disallowedPlugin = [...editor.plugins]
655
+ .map(([pluginConstructor]) => pluginConstructor)
656
+ .find(pluginConstructor => {
657
+ if (!pluginConstructor.pluginName) {
658
+ return false;
659
+ }
660
+ if (!pluginConstructor.licenseFeatureCode) {
661
+ return false;
662
+ }
663
+ return isFeatureBlockedByLicenseKey(decodedPayload, pluginConstructor.licenseFeatureCode);
664
+ });
665
+ if (disallowedPlugin) {
666
+ editor.enableReadOnlyMode(Symbol('invalidLicense'));
667
+ editor._showLicenseError('pluginNotAllowed', disallowedPlugin.pluginName);
668
+ }
669
+ }
653
670
  }
654
671
  /**
655
672
  * Destroys the editor instance, releasing all resources used by it.
@@ -751,7 +768,7 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
751
768
  * Exposed as static editor field for easier access in editor builds.
752
769
  */
753
770
  static ContextWatchdog = ContextWatchdog;
754
- _showLicenseError(reason, pluginName) {
771
+ _showLicenseError(reason, name) {
755
772
  setTimeout(() => {
756
773
  if (reason == 'invalid') {
757
774
  /**
@@ -790,7 +807,7 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
790
807
  */
791
808
  throw new CKEditorError('license-key-domain-limit');
792
809
  }
793
- if (reason == 'featureNotAllowed') {
810
+ if (reason == 'pluginNotAllowed') {
794
811
  /**
795
812
  * The plugin you are trying to use is not permitted under your current license.
796
813
  * Please check the available features on the
@@ -800,7 +817,19 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
800
817
  * @error license-key-plugin-not-allowed
801
818
  * @param {String} pluginName The plugin you tried to load.
802
819
  */
803
- throw new CKEditorError('license-key-plugin-not-allowed', null, { pluginName });
820
+ throw new CKEditorError('license-key-plugin-not-allowed', null, { pluginName: name });
821
+ }
822
+ if (reason == 'featureNotAllowed') {
823
+ /**
824
+ * The feature you are trying to use is not permitted under your current license.
825
+ * Please check the available features on the
826
+ * [Customer Portal](https://portal.ckeditor.com) or
827
+ * [contact support](https://ckeditor.com/contact/) for more information.
828
+ *
829
+ * @error license-key-feature-not-allowed
830
+ * @param {String} featureName The feature you tried to use.
831
+ */
832
+ throw new CKEditorError('license-key-feature-not-allowed', null, { featureName: name });
804
833
  }
805
834
  if (reason == 'evaluationLimit') {
806
835
  /**
@@ -900,7 +929,6 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
900
929
  return response.json();
901
930
  }
902
931
  }
903
- export { Editor };
904
932
  function collectUsageData(editor) {
905
933
  const collectedData = getEditorUsageData(editor);
906
934
  function setUsageData(path, value) {
package/src/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { Context, type ContextConfig } from './context.js';
14
14
  export { ContextPlugin, type ContextInterface, type ContextPluginDependencies } from './contextplugin.js';
15
15
  export { EditingKeystrokeHandler, type EditingKeystrokeCallback } from './editingkeystrokehandler.js';
16
16
  export type { PartialBy, NonEmptyArray, HexColor } from './typings.js';
17
- export { Editor, type EditorCollectUsageDataEvent, type EditorReadyEvent, type EditorDestroyEvent } from './editor/editor.js';
17
+ export { Editor, type EditorCollectUsageDataEvent, type EditorReadyEvent, type EditorDestroyEvent, type LicenseErrorReason as _LicenseErrorReason } from './editor/editor.js';
18
18
  export type { EditorConfig, LanguageConfig, ToolbarConfig, ToolbarConfigItem, UiConfig, ViewportOffsetConfig, PoweredByConfig } from './editor/editorconfig.js';
19
19
  export { attachToForm } from './editor/utils/attachtoform.js';
20
20
  export { ElementApiMixin, type ElementApi } from './editor/utils/elementapimixin.js';
package/src/plugin.d.ts CHANGED
@@ -287,6 +287,12 @@ export interface PluginStaticMembers<TContext = Editor> {
287
287
  * @internal
288
288
  */
289
289
  readonly isPremiumPlugin?: boolean;
290
+ /**
291
+ * An unique id of a plugin which belongs to the free plan on commercial license.
292
+ *
293
+ * @internal
294
+ */
295
+ readonly licenseFeatureCode?: string;
290
296
  }
291
297
  export type PluginDependencies<TContext = Editor> = ReadonlyArray<PluginConstructor<TContext> | string>;
292
298
  /**