@ckeditor/ckeditor5-core 43.3.1-alpha.0 → 44.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/README.md +13 -7
- package/dist/editor/editor.d.ts +32 -3
- package/dist/editor/editorconfig.d.ts +10 -8
- package/dist/editor/utils/editorusagedata.d.ts +72 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +436 -4
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/editor/editor.d.ts +32 -3
- package/src/editor/editor.js +318 -1
- package/src/editor/editorconfig.d.ts +10 -8
- package/src/editor/utils/editorusagedata.d.ts +68 -0
- package/src/editor/utils/editorusagedata.js +127 -0
- package/src/index.d.ts +3 -0
- package/src/index.js +7 -1
- package/src/plugincollection.js +1 -1
- package/theme/icons/bookmark.svg +1 -0
- package/theme/icons/bookmark_inline.svg +1 -0
- package/theme/icons/remove.svg +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "44.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,9 +24,9 @@
|
|
|
24
24
|
"type": "module",
|
|
25
25
|
"main": "src/index.js",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@ckeditor/ckeditor5-engine": "
|
|
28
|
-
"@ckeditor/ckeditor5-utils": "
|
|
29
|
-
"@ckeditor/ckeditor5-watchdog": "
|
|
27
|
+
"@ckeditor/ckeditor5-engine": "44.0.0-alpha.0",
|
|
28
|
+
"@ckeditor/ckeditor5-utils": "44.0.0-alpha.0",
|
|
29
|
+
"@ckeditor/ckeditor5-watchdog": "44.0.0-alpha.0",
|
|
30
30
|
"lodash-es": "4.17.21"
|
|
31
31
|
},
|
|
32
32
|
"author": "CKSource (http://cksource.com/)",
|
package/src/editor/editor.d.ts
CHANGED
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
4
|
*/
|
|
5
|
-
/**
|
|
6
|
-
* @module core/editor/editor
|
|
7
|
-
*/
|
|
8
5
|
import { Config, type Locale, type LocaleTranslate } from '@ckeditor/ckeditor5-utils';
|
|
9
6
|
import { Conversion, DataController, EditingController, Model } from '@ckeditor/ckeditor5-engine';
|
|
10
7
|
import type { EditorUI } from '@ckeditor/ckeditor5-ui';
|
|
@@ -16,6 +13,9 @@ import EditingKeystrokeHandler from '../editingkeystrokehandler.js';
|
|
|
16
13
|
import Accessibility from '../accessibility.js';
|
|
17
14
|
import type { LoadedPlugins, PluginConstructor } from '../plugin.js';
|
|
18
15
|
import type { EditorConfig } from './editorconfig.js';
|
|
16
|
+
declare global {
|
|
17
|
+
var CKEDITOR_GLOBAL_LICENSE_KEY: string | undefined;
|
|
18
|
+
}
|
|
19
19
|
declare const Editor_base: {
|
|
20
20
|
new (): import("@ckeditor/ckeditor5-utils").Observable;
|
|
21
21
|
prototype: import("@ckeditor/ckeditor5-utils").Observable;
|
|
@@ -39,6 +39,10 @@ declare const Editor_base: {
|
|
|
39
39
|
* (as most editor implementations do).
|
|
40
40
|
*/
|
|
41
41
|
export default abstract class Editor extends /* #__PURE__ */ Editor_base {
|
|
42
|
+
/**
|
|
43
|
+
* A required name of the editor class. The name should reflect the constructor name.
|
|
44
|
+
*/
|
|
45
|
+
static get editorName(): `${string}Editor`;
|
|
42
46
|
/**
|
|
43
47
|
* A namespace for the accessibility features of the editor.
|
|
44
48
|
*/
|
|
@@ -447,6 +451,14 @@ export default abstract class Editor extends /* #__PURE__ */ Editor_base {
|
|
|
447
451
|
* Exposed as static editor field for easier access in editor builds.
|
|
448
452
|
*/
|
|
449
453
|
static ContextWatchdog: typeof ContextWatchdog;
|
|
454
|
+
private _showLicenseError;
|
|
455
|
+
/**
|
|
456
|
+
* This part of the code is _not_ executed in installations under the GPL license (with `config.licenseKey = 'GPL'`).
|
|
457
|
+
*
|
|
458
|
+
* It is only executed when a specific license key is provided. If you are uncertain whether
|
|
459
|
+
* this applies to your installation, please contact our support team.
|
|
460
|
+
*/
|
|
461
|
+
private _sendUsageRequest;
|
|
450
462
|
}
|
|
451
463
|
/**
|
|
452
464
|
* Fired when the {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional
|
|
@@ -466,6 +478,23 @@ export type EditorReadyEvent = {
|
|
|
466
478
|
name: 'ready';
|
|
467
479
|
args: [];
|
|
468
480
|
};
|
|
481
|
+
/**
|
|
482
|
+
* Fired when the editor is about to collect usage data.
|
|
483
|
+
*
|
|
484
|
+
* This event is fired when the editor is about to collect usage data. It allows plugins to provide additional data for
|
|
485
|
+
* the usage statistics. The usage data is collected by the editor and sent to the usage tracking server. All plugins are
|
|
486
|
+
* expected to be ready at this point.
|
|
487
|
+
*
|
|
488
|
+
* @eventName ~Editor#collectUsageData
|
|
489
|
+
*/
|
|
490
|
+
export type EditorCollectUsageDataEvent = {
|
|
491
|
+
name: 'collectUsageData';
|
|
492
|
+
args: [
|
|
493
|
+
{
|
|
494
|
+
setUsageData(path: string, value: unknown): void;
|
|
495
|
+
}
|
|
496
|
+
];
|
|
497
|
+
};
|
|
469
498
|
/**
|
|
470
499
|
* Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to
|
|
471
500
|
* perform the clean-up in any plugin.
|
package/src/editor/editor.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @module core/editor/editor
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { set, get } from 'lodash-es';
|
|
9
|
+
import { Config, CKEditorError, ObservableMixin, logError, parseBase64EncodedObject, releaseDate, toArray, uid, crc32 } from '@ckeditor/ckeditor5-utils';
|
|
9
10
|
import { Conversion, DataController, EditingController, Model, StylesProcessor } from '@ckeditor/ckeditor5-engine';
|
|
10
11
|
import { ContextWatchdog, EditorWatchdog } from '@ckeditor/ckeditor5-watchdog';
|
|
11
12
|
import Context from '../context.js';
|
|
@@ -13,6 +14,7 @@ import PluginCollection from '../plugincollection.js';
|
|
|
13
14
|
import CommandCollection from '../commandcollection.js';
|
|
14
15
|
import EditingKeystrokeHandler from '../editingkeystrokehandler.js';
|
|
15
16
|
import Accessibility from '../accessibility.js';
|
|
17
|
+
import { getEditorUsageData } from './utils/editorusagedata.js';
|
|
16
18
|
/**
|
|
17
19
|
* The class representing a basic, generic editor.
|
|
18
20
|
*
|
|
@@ -32,6 +34,12 @@ import Accessibility from '../accessibility.js';
|
|
|
32
34
|
* (as most editor implementations do).
|
|
33
35
|
*/
|
|
34
36
|
class Editor extends /* #__PURE__ */ ObservableMixin() {
|
|
37
|
+
/**
|
|
38
|
+
* A required name of the editor class. The name should reflect the constructor name.
|
|
39
|
+
*/
|
|
40
|
+
static get editorName() {
|
|
41
|
+
return 'Editor';
|
|
42
|
+
}
|
|
35
43
|
/**
|
|
36
44
|
* Creates a new instance of the editor class.
|
|
37
45
|
*
|
|
@@ -66,6 +74,7 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
|
|
|
66
74
|
this.config = new Config(rest, defaultConfig);
|
|
67
75
|
this.config.define('plugins', availablePlugins);
|
|
68
76
|
this.config.define(this._context._getEditorConfig());
|
|
77
|
+
checkLicenseKeyIsDefined(this.config);
|
|
69
78
|
this.plugins = new PluginCollection(this, availablePlugins, this._context.plugins);
|
|
70
79
|
this.locale = this._context.locale;
|
|
71
80
|
this.t = this.locale.t;
|
|
@@ -88,6 +97,165 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
|
|
|
88
97
|
this.keystrokes = new EditingKeystrokeHandler(this);
|
|
89
98
|
this.keystrokes.listenTo(this.editing.view.document);
|
|
90
99
|
this.accessibility = new Accessibility(this);
|
|
100
|
+
verifyLicenseKey(this);
|
|
101
|
+
// Checks if the license key is defined and throws an error if it is not.
|
|
102
|
+
function checkLicenseKeyIsDefined(config) {
|
|
103
|
+
let licenseKey = config.get('licenseKey');
|
|
104
|
+
if (!licenseKey && window.CKEDITOR_GLOBAL_LICENSE_KEY) {
|
|
105
|
+
licenseKey = window.CKEDITOR_GLOBAL_LICENSE_KEY;
|
|
106
|
+
config.set('licenseKey', licenseKey);
|
|
107
|
+
}
|
|
108
|
+
if (!licenseKey) {
|
|
109
|
+
/**
|
|
110
|
+
* The `licenseKey` property is missing in the editor configuration.
|
|
111
|
+
*
|
|
112
|
+
* * If you are using the editor in a commercial setup, please provide your license key.
|
|
113
|
+
* * If you still need to acquire a key, please [contact us](https://ckeditor.com/contact/) or
|
|
114
|
+
* [create a free account with a 14 day premium features trial](https://portal.ckeditor.com/checkout?plan=free).
|
|
115
|
+
* * If you are using the editor under a GPL license or another license from our Open Source Initiative,
|
|
116
|
+
* use the 'GPL' license key instead.
|
|
117
|
+
*
|
|
118
|
+
* ```js
|
|
119
|
+
* ClassicEditor.create( document.querySelector( '#editor' ), {
|
|
120
|
+
* licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
|
|
121
|
+
* // ... Other configuration options ...
|
|
122
|
+
* } ) ;
|
|
123
|
+
*
|
|
124
|
+
* @error license-key-missing
|
|
125
|
+
*/
|
|
126
|
+
throw new CKEditorError('license-key-missing');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function verifyLicenseKey(editor) {
|
|
130
|
+
const licenseKey = editor.config.get('licenseKey');
|
|
131
|
+
const distributionChannel = window[Symbol.for('cke distribution')] || 'sh';
|
|
132
|
+
function blockEditor(reason) {
|
|
133
|
+
editor.enableReadOnlyMode(Symbol('invalidLicense'));
|
|
134
|
+
editor._showLicenseError(reason);
|
|
135
|
+
}
|
|
136
|
+
function getPayload(licenseKey) {
|
|
137
|
+
const parts = licenseKey.split('.');
|
|
138
|
+
if (parts.length != 3) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return parts[1];
|
|
142
|
+
}
|
|
143
|
+
function hasAllRequiredFields(licensePayload) {
|
|
144
|
+
const requiredFields = ['exp', 'jti', 'vc'];
|
|
145
|
+
return requiredFields.every(field => field in licensePayload);
|
|
146
|
+
}
|
|
147
|
+
function getCrcInputData(licensePayload) {
|
|
148
|
+
const keysToCheck = Object.getOwnPropertyNames(licensePayload).sort();
|
|
149
|
+
const filteredValues = keysToCheck
|
|
150
|
+
.filter(key => key != 'vc' && licensePayload[key] != null)
|
|
151
|
+
.map(key => licensePayload[key]);
|
|
152
|
+
return filteredValues;
|
|
153
|
+
}
|
|
154
|
+
function checkLicensedHosts(licensedHosts) {
|
|
155
|
+
const { hostname } = new URL(window.location.href);
|
|
156
|
+
if (licensedHosts.includes(hostname)) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
const segments = hostname.split('.');
|
|
160
|
+
return licensedHosts
|
|
161
|
+
// Filter out hosts without wildcards.
|
|
162
|
+
.filter(host => host.includes('*'))
|
|
163
|
+
// Split the hosts into segments.
|
|
164
|
+
.map(host => host.split('.'))
|
|
165
|
+
// Filter out hosts that have more segments than the current hostname.
|
|
166
|
+
.filter(host => host.length <= segments.length)
|
|
167
|
+
// Pad the beginning of the licensed host if it's shorter than the current hostname.
|
|
168
|
+
.map(host => Array(segments.length - host.length).fill(host[0] === '*' ? '*' : '').concat(host))
|
|
169
|
+
// Check if some license host matches the hostname.
|
|
170
|
+
.some(octets => segments.every((segment, index) => octets[index] === segment || octets[index] === '*'));
|
|
171
|
+
}
|
|
172
|
+
if (licenseKey == 'GPL') {
|
|
173
|
+
if (distributionChannel == 'cloud') {
|
|
174
|
+
blockEditor('distributionChannel');
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const encodedPayload = getPayload(licenseKey);
|
|
179
|
+
if (!encodedPayload) {
|
|
180
|
+
blockEditor('invalid');
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const licensePayload = parseBase64EncodedObject(encodedPayload);
|
|
184
|
+
if (!licensePayload) {
|
|
185
|
+
blockEditor('invalid');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (!hasAllRequiredFields(licensePayload)) {
|
|
189
|
+
blockEditor('invalid');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (licensePayload.distributionChannel && !toArray(licensePayload.distributionChannel).includes(distributionChannel)) {
|
|
193
|
+
blockEditor('distributionChannel');
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (crc32(getCrcInputData(licensePayload)) != licensePayload.vc.toLowerCase()) {
|
|
197
|
+
blockEditor('invalid');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const expirationDate = new Date(licensePayload.exp * 1000);
|
|
201
|
+
if (expirationDate < releaseDate) {
|
|
202
|
+
blockEditor('expired');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const licensedHosts = licensePayload.licensedHosts;
|
|
206
|
+
if (licensedHosts && licensedHosts.length > 0 && !checkLicensedHosts(licensedHosts)) {
|
|
207
|
+
blockEditor('domainLimit');
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (['evaluation', 'trial'].includes(licensePayload.licenseType) && licensePayload.exp * 1000 < Date.now()) {
|
|
211
|
+
blockEditor('expired');
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (['evaluation', 'trial', 'development'].includes(licensePayload.licenseType)) {
|
|
215
|
+
const licenseType = licensePayload.licenseType;
|
|
216
|
+
console.info(`You are using the ${licenseType} version of CKEditor 5 with limited usage. ` +
|
|
217
|
+
'Make sure you will not use it in the production environment.');
|
|
218
|
+
const timerId = setTimeout(() => {
|
|
219
|
+
blockEditor(`${licenseType}Limit`);
|
|
220
|
+
}, 600000);
|
|
221
|
+
editor.on('destroy', () => {
|
|
222
|
+
clearTimeout(timerId);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (licensePayload.usageEndpoint) {
|
|
226
|
+
editor.once('ready', () => {
|
|
227
|
+
const request = {
|
|
228
|
+
requestId: uid(),
|
|
229
|
+
requestTime: Math.round(Date.now() / 1000),
|
|
230
|
+
license: licenseKey,
|
|
231
|
+
editor: collectUsageData(editor)
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* This part of the code is not executed in open-source implementations using a GPL key.
|
|
235
|
+
* It only runs when a specific license key is provided. If you are uncertain whether
|
|
236
|
+
* this applies to your installation, please contact our support team.
|
|
237
|
+
*/
|
|
238
|
+
editor._sendUsageRequest(licensePayload.usageEndpoint, request).then(response => {
|
|
239
|
+
const { status, message } = response;
|
|
240
|
+
if (message) {
|
|
241
|
+
console.warn(message);
|
|
242
|
+
}
|
|
243
|
+
if (status != 'ok') {
|
|
244
|
+
blockEditor('usageLimit');
|
|
245
|
+
}
|
|
246
|
+
}, () => {
|
|
247
|
+
/**
|
|
248
|
+
* Your license key cannot be validated due to a network issue.
|
|
249
|
+
* Please ensure that your setup does not block requests to the validation endpoint.
|
|
250
|
+
*
|
|
251
|
+
* @error license-key-validation-endpoint-not-reachable
|
|
252
|
+
* @param {String} url The URL that was attempted to be reached for validation.
|
|
253
|
+
*/
|
|
254
|
+
logError('license-key-validation-endpoint-not-reachable', { url: licensePayload.usageEndpoint });
|
|
255
|
+
});
|
|
256
|
+
}, { priority: 'high' });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
91
259
|
}
|
|
92
260
|
/**
|
|
93
261
|
* Defines whether the editor is in the read-only mode.
|
|
@@ -370,6 +538,136 @@ class Editor extends /* #__PURE__ */ ObservableMixin() {
|
|
|
370
538
|
static create(...args) {
|
|
371
539
|
throw new Error('This is an abstract method.');
|
|
372
540
|
}
|
|
541
|
+
_showLicenseError(reason, pluginName) {
|
|
542
|
+
setTimeout(() => {
|
|
543
|
+
if (reason == 'invalid') {
|
|
544
|
+
/**
|
|
545
|
+
* The license key provided is invalid. Please ensure that it is copied correctly
|
|
546
|
+
* from the [Customer Portal](http://portal.ckeditor.com). If the issue persists,
|
|
547
|
+
* please [contact our customer support](https://ckeditor.com/contact/).
|
|
548
|
+
*
|
|
549
|
+
* @error invalid-license-key
|
|
550
|
+
*/
|
|
551
|
+
throw new CKEditorError('invalid-license-key');
|
|
552
|
+
}
|
|
553
|
+
if (reason == 'expired') {
|
|
554
|
+
/**
|
|
555
|
+
* Your license key has expired. Please renew your license on the
|
|
556
|
+
* [Customer Portal](https://portal.ckeditor.com).
|
|
557
|
+
*
|
|
558
|
+
* @error license-key-expired
|
|
559
|
+
*/
|
|
560
|
+
throw new CKEditorError('license-key-expired');
|
|
561
|
+
}
|
|
562
|
+
if (reason == 'domainLimit') {
|
|
563
|
+
/**
|
|
564
|
+
* The provided license does not allow the editor to run on this domain.
|
|
565
|
+
* Some license keys are restricted to local test environments only.
|
|
566
|
+
* For more details, please refer to the
|
|
567
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types license key type documentation}.
|
|
568
|
+
*
|
|
569
|
+
* @error license-key-domain-limit
|
|
570
|
+
*/
|
|
571
|
+
throw new CKEditorError('license-key-domain-limit');
|
|
572
|
+
}
|
|
573
|
+
if (reason == 'featureNotAllowed') {
|
|
574
|
+
/**
|
|
575
|
+
* The plugin you are trying to use is not permitted under your current license.
|
|
576
|
+
* Please check the available features on the
|
|
577
|
+
* [Customer Portal](https://portal.ckeditor.com) or
|
|
578
|
+
* [contact support](https://ckeditor.com/contact/) for more information.
|
|
579
|
+
*
|
|
580
|
+
* @error license-key-plugin-not-allowed
|
|
581
|
+
* @param {String} pluginName The plugin you tried to load.
|
|
582
|
+
*/
|
|
583
|
+
throw new CKEditorError('license-key-plugin-not-allowed', null, { pluginName });
|
|
584
|
+
}
|
|
585
|
+
if (reason == 'evaluationLimit') {
|
|
586
|
+
/**
|
|
587
|
+
* You have exceeded the editor operation limit available for your evaluation license key.
|
|
588
|
+
* Please restart the editor to continue using it.
|
|
589
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types Read more about license key types}.
|
|
590
|
+
*
|
|
591
|
+
* @error license-key-evaluation-limit
|
|
592
|
+
*/
|
|
593
|
+
throw new CKEditorError('license-key-evaluation-limit');
|
|
594
|
+
}
|
|
595
|
+
if (reason == 'trialLimit') {
|
|
596
|
+
/**
|
|
597
|
+
* You have exceeded the editor operation limit for your trial license key.
|
|
598
|
+
* Please restart the editor to continue using it.
|
|
599
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types Read more about license key types}.
|
|
600
|
+
*
|
|
601
|
+
* @error license-key-trial-limit
|
|
602
|
+
*/
|
|
603
|
+
throw new CKEditorError('license-key-trial-limit');
|
|
604
|
+
}
|
|
605
|
+
if (reason == 'developmentLimit') {
|
|
606
|
+
/**
|
|
607
|
+
* You have exceeded the operation limit for your development license key within the editor.
|
|
608
|
+
* Please restart the editor to continue using it.
|
|
609
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types Read more about license key types}.
|
|
610
|
+
*
|
|
611
|
+
* @error license-key-development-limit
|
|
612
|
+
*/
|
|
613
|
+
throw new CKEditorError('license-key-development-limit');
|
|
614
|
+
}
|
|
615
|
+
if (reason == 'usageLimit') {
|
|
616
|
+
/**
|
|
617
|
+
* You have reached the usage limit of your license key. This can occur in the following situations:
|
|
618
|
+
*
|
|
619
|
+
* * You are on a free subscription without a connected payment method and have exceeded the allowed usage threshold.
|
|
620
|
+
* * Your account has overdue invoices and the grace period has ended.
|
|
621
|
+
*
|
|
622
|
+
* To extend the limit and restore access, please update the required details in the
|
|
623
|
+
* [Customer Portal](https://portal.ckeditor.com) or
|
|
624
|
+
* [contact our customer support](https://ckeditor.com/contact).
|
|
625
|
+
*
|
|
626
|
+
* @error license-key-usage-limit
|
|
627
|
+
*/
|
|
628
|
+
throw new CKEditorError('license-key-usage-limit');
|
|
629
|
+
}
|
|
630
|
+
if (reason == 'distributionChannel') {
|
|
631
|
+
/**
|
|
632
|
+
* Your license does not allow the current distribution channel.
|
|
633
|
+
*
|
|
634
|
+
* * With a 'GPL' license key, you may use the editor installed via npm or a ZIP package (self-hosted).
|
|
635
|
+
* * With the CKEditor Cloud plans, you may use the editor via our CDN.
|
|
636
|
+
* * With the CKEditor Custom plans, depending on your plan details, you can use the editor via npm
|
|
637
|
+
* or a ZIP package (self-hosted) or Cloud (CDN)
|
|
638
|
+
*
|
|
639
|
+
* {@glink getting-started/licensing/usage-based-billing#key-terms Read more about distributions in the documentation}.
|
|
640
|
+
* Please verify your installation or [contact support](https://ckeditor.com/contact/) for assistance.
|
|
641
|
+
*
|
|
642
|
+
* @error license-key-invalid-distribution-channel
|
|
643
|
+
*/
|
|
644
|
+
throw new CKEditorError('license-key-invalid-distribution-channel');
|
|
645
|
+
}
|
|
646
|
+
/* istanbul ignore next -- @preserve */
|
|
647
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
648
|
+
const unreachable = reason;
|
|
649
|
+
}, 0);
|
|
650
|
+
this._showLicenseError = () => { };
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* This part of the code is _not_ executed in installations under the GPL license (with `config.licenseKey = 'GPL'`).
|
|
654
|
+
*
|
|
655
|
+
* It is only executed when a specific license key is provided. If you are uncertain whether
|
|
656
|
+
* this applies to your installation, please contact our support team.
|
|
657
|
+
*/
|
|
658
|
+
async _sendUsageRequest(endpoint, request) {
|
|
659
|
+
const headers = new Headers({ 'Content-Type': 'application/json' });
|
|
660
|
+
const response = await fetch(new URL(endpoint), {
|
|
661
|
+
method: 'POST',
|
|
662
|
+
headers,
|
|
663
|
+
body: JSON.stringify(request)
|
|
664
|
+
});
|
|
665
|
+
if (!response.ok) {
|
|
666
|
+
// TODO: refine message.
|
|
667
|
+
throw new Error(`HTTP Response: ${response.status}`);
|
|
668
|
+
}
|
|
669
|
+
return response.json();
|
|
670
|
+
}
|
|
373
671
|
}
|
|
374
672
|
/**
|
|
375
673
|
* The {@link module:core/context~Context} class.
|
|
@@ -390,6 +688,25 @@ Editor.EditorWatchdog = EditorWatchdog;
|
|
|
390
688
|
*/
|
|
391
689
|
Editor.ContextWatchdog = ContextWatchdog;
|
|
392
690
|
export default Editor;
|
|
691
|
+
function collectUsageData(editor) {
|
|
692
|
+
const collectedData = getEditorUsageData(editor);
|
|
693
|
+
function setUsageData(path, value) {
|
|
694
|
+
if (get(collectedData, path) !== undefined) {
|
|
695
|
+
/**
|
|
696
|
+
* The error thrown when trying to set the usage data path that was already set.
|
|
697
|
+
* Make sure that you are not setting the same path multiple times.
|
|
698
|
+
*
|
|
699
|
+
* @error editor-usage-data-path-already-set
|
|
700
|
+
*/
|
|
701
|
+
throw new CKEditorError('editor-usage-data-path-already-set', { path });
|
|
702
|
+
}
|
|
703
|
+
set(collectedData, path, value);
|
|
704
|
+
}
|
|
705
|
+
editor.fire('collectUsageData', {
|
|
706
|
+
setUsageData
|
|
707
|
+
});
|
|
708
|
+
return collectedData;
|
|
709
|
+
}
|
|
393
710
|
/**
|
|
394
711
|
* This error is thrown when trying to pass a `<textarea>` element to a `create()` function of an editor class.
|
|
395
712
|
*
|
|
@@ -795,10 +795,12 @@ export interface EditorConfig {
|
|
|
795
795
|
*/
|
|
796
796
|
updateSourceElementOnDestroy?: boolean;
|
|
797
797
|
/**
|
|
798
|
-
* The license key
|
|
798
|
+
* The CKEditor 5 license key. If you want to obtain a license key, please do one of the following:
|
|
799
799
|
*
|
|
800
|
-
*
|
|
801
|
-
* [
|
|
800
|
+
* * Create a free account, and test the premium features with a [14-day free trial](https://portal.ckeditor.com/checkout?plan=free).
|
|
801
|
+
* * [Contact us](https://ckeditor.com/contact/) for a commercial license.
|
|
802
|
+
* * If you are using the editor under a GPL license or another license from our Open Source Initiative,
|
|
803
|
+
* use the 'GPL' license key instead.
|
|
802
804
|
*/
|
|
803
805
|
licenseKey?: string;
|
|
804
806
|
/**
|
|
@@ -910,7 +912,7 @@ export interface PoweredByConfig {
|
|
|
910
912
|
*
|
|
911
913
|
* @default 'border'
|
|
912
914
|
*/
|
|
913
|
-
position
|
|
915
|
+
position?: 'inside' | 'border';
|
|
914
916
|
/**
|
|
915
917
|
* Allows choosing the side of the editing area where the logo will be displayed.
|
|
916
918
|
*
|
|
@@ -919,7 +921,7 @@ export interface PoweredByConfig {
|
|
|
919
921
|
*
|
|
920
922
|
* @default 'right'
|
|
921
923
|
*/
|
|
922
|
-
side
|
|
924
|
+
side?: 'left' | 'right';
|
|
923
925
|
/**
|
|
924
926
|
* Allows changing the label displayed next to the CKEditor logo.
|
|
925
927
|
*
|
|
@@ -927,7 +929,7 @@ export interface PoweredByConfig {
|
|
|
927
929
|
*
|
|
928
930
|
* @default 'Powered by'
|
|
929
931
|
*/
|
|
930
|
-
label
|
|
932
|
+
label?: string | null;
|
|
931
933
|
/**
|
|
932
934
|
* The vertical distance the logo can be moved away from its default position.
|
|
933
935
|
*
|
|
@@ -935,13 +937,13 @@ export interface PoweredByConfig {
|
|
|
935
937
|
*
|
|
936
938
|
* @default 5
|
|
937
939
|
*/
|
|
938
|
-
verticalOffset
|
|
940
|
+
verticalOffset?: number;
|
|
939
941
|
/**
|
|
940
942
|
* The horizontal distance between the side of the editing root and the nearest side of the logo.
|
|
941
943
|
*
|
|
942
944
|
* @default 5
|
|
943
945
|
*/
|
|
944
|
-
horizontalOffset
|
|
946
|
+
horizontalOffset?: number;
|
|
945
947
|
/**
|
|
946
948
|
* Allows to show the logo even if the valid commercial license is configured using
|
|
947
949
|
* the {@link module:core/editor/editorconfig~EditorConfig#licenseKey `config.licenseKey`} setting.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
import type Editor from '../editor.js';
|
|
6
|
+
/**
|
|
7
|
+
* This part of the code is not executed in open-source implementations using a GPL key.
|
|
8
|
+
* It only runs when a specific license key is provided. If you are uncertain whether
|
|
9
|
+
* this applies to your installation, please contact our support team.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function getEditorUsageData(editor: Editor): EditorUsageData;
|
|
14
|
+
declare global {
|
|
15
|
+
interface Window {
|
|
16
|
+
CKEDITOR_PAGE_SESSION_ID?: string;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export type EditorUsageData = {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
pageSessionId: string;
|
|
25
|
+
hostname: string;
|
|
26
|
+
version: string;
|
|
27
|
+
type: `${string}Editor`;
|
|
28
|
+
plugins: Array<PluginUsageData>;
|
|
29
|
+
toolbar: {
|
|
30
|
+
main?: ToolbarUsageData;
|
|
31
|
+
block?: ToolbarUsageData;
|
|
32
|
+
balloon?: ToolbarUsageData;
|
|
33
|
+
};
|
|
34
|
+
menuBar: {
|
|
35
|
+
isVisible: boolean;
|
|
36
|
+
};
|
|
37
|
+
language: {
|
|
38
|
+
ui: string;
|
|
39
|
+
content: string;
|
|
40
|
+
};
|
|
41
|
+
distribution: {
|
|
42
|
+
channel: string;
|
|
43
|
+
};
|
|
44
|
+
env: EnvUsageData;
|
|
45
|
+
integration: {
|
|
46
|
+
[integrationName: string]: IntegrationUsageData;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
type IntegrationUsageData = {
|
|
50
|
+
version: string;
|
|
51
|
+
frameworkVersion?: string;
|
|
52
|
+
};
|
|
53
|
+
type EnvUsageData = {
|
|
54
|
+
os: 'mac' | 'windows' | 'ios' | 'android' | 'unknown';
|
|
55
|
+
browser: 'safari' | 'gecko' | 'blink' | 'unknown';
|
|
56
|
+
};
|
|
57
|
+
type ToolbarUsageData = {
|
|
58
|
+
items: Array<string>;
|
|
59
|
+
isMultiline: boolean;
|
|
60
|
+
shouldNotGroupWhenFull: boolean;
|
|
61
|
+
};
|
|
62
|
+
type PluginUsageData = {
|
|
63
|
+
name: string;
|
|
64
|
+
isPremium: boolean;
|
|
65
|
+
isOfficial: boolean;
|
|
66
|
+
isContext: boolean;
|
|
67
|
+
};
|
|
68
|
+
export {};
|