@ckeditor/ckeditor5-core 43.3.1 → 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/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
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
|
-
import { ObservableMixin, insertToPriorityArray, EmitterMixin, CKEditorError, Config, Locale, Collection, KeystrokeHandler, setDataInElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
5
|
+
import { ObservableMixin, insertToPriorityArray, EmitterMixin, CKEditorError, Config, Locale, Collection, KeystrokeHandler, env, uid, global, parseBase64EncodedObject, toArray, crc32, releaseDate, logError, setDataInElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
6
|
+
import { get, set, isFunction } from 'lodash-es';
|
|
6
7
|
import { Model, StylesProcessor, DataController, EditingController, Conversion } from '@ckeditor/ckeditor5-engine/dist/index.js';
|
|
7
8
|
import { EditorWatchdog, ContextWatchdog } from '@ckeditor/ckeditor5-watchdog/dist/index.js';
|
|
8
|
-
import { isFunction } from 'lodash-es';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* The base class for CKEditor plugin classes.
|
|
@@ -652,7 +652,7 @@ import { isFunction } from 'lodash-es';
|
|
|
652
652
|
* that you tried loading plugins by name. However, unlike CKEditor 4, CKEditor 5 does not implement a "plugin loader".
|
|
653
653
|
* This means that CKEditor 5 does not know where to load the plugin modules from. Therefore, you need to
|
|
654
654
|
* provide each plugin through a reference (as a constructor function). Check out the examples in the
|
|
655
|
-
* {@glink getting-started/installation/quick-start Quick start} guide.
|
|
655
|
+
* {@glink getting-started/installation/cloud/quick-start Quick start} guide.
|
|
656
656
|
*
|
|
657
657
|
* @error plugincollection-plugin-not-found
|
|
658
658
|
* @param plugin The name of the plugin which could not be loaded.
|
|
@@ -1657,6 +1657,119 @@ const DEFAULT_GROUP_ID = 'common';
|
|
|
1657
1657
|
}
|
|
1658
1658
|
}
|
|
1659
1659
|
|
|
1660
|
+
/**
|
|
1661
|
+
* This part of the code is not executed in open-source implementations using a GPL key.
|
|
1662
|
+
* It only runs when a specific license key is provided. If you are uncertain whether
|
|
1663
|
+
* this applies to your installation, please contact our support team.
|
|
1664
|
+
*
|
|
1665
|
+
* @internal
|
|
1666
|
+
*/ function getEditorUsageData(editor) {
|
|
1667
|
+
return {
|
|
1668
|
+
sessionId: getSessionId(),
|
|
1669
|
+
pageSessionId: getPageSessionID(),
|
|
1670
|
+
hostname: window.location.hostname,
|
|
1671
|
+
version: globalThis.CKEDITOR_VERSION,
|
|
1672
|
+
type: getEditorType(editor),
|
|
1673
|
+
plugins: getPluginsUsageData(editor.plugins),
|
|
1674
|
+
distribution: getDistributionUsageData(),
|
|
1675
|
+
env: getEnvUsageData(),
|
|
1676
|
+
integration: Object.create(null),
|
|
1677
|
+
menuBar: {
|
|
1678
|
+
isVisible: !!editor.config.get('menuBar.isVisible')
|
|
1679
|
+
},
|
|
1680
|
+
language: {
|
|
1681
|
+
ui: editor.locale.uiLanguage,
|
|
1682
|
+
content: editor.locale.contentLanguage
|
|
1683
|
+
},
|
|
1684
|
+
toolbar: {
|
|
1685
|
+
main: getToolbarUsageData(editor.config.get('toolbar')),
|
|
1686
|
+
block: getToolbarUsageData(editor.config.get('blockToolbar')),
|
|
1687
|
+
balloon: getToolbarUsageData(editor.config.get('balloonToolbar'))
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
function getEditorType(editor) {
|
|
1692
|
+
return Object.getPrototypeOf(editor).constructor.editorName;
|
|
1693
|
+
}
|
|
1694
|
+
function getPluginsUsageData(collection) {
|
|
1695
|
+
return Array.from(collection).filter(([PluginConstructor])=>!!PluginConstructor.pluginName).map(([PluginConstructor])=>{
|
|
1696
|
+
const { pluginName, isContextPlugin, isOfficialPlugin, isPremiumPlugin } = PluginConstructor;
|
|
1697
|
+
return {
|
|
1698
|
+
isContext: !!isContextPlugin,
|
|
1699
|
+
isOfficial: !!isOfficialPlugin,
|
|
1700
|
+
isPremium: !!isPremiumPlugin,
|
|
1701
|
+
name: pluginName
|
|
1702
|
+
};
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
function getToolbarUsageData(toolbarConfig) {
|
|
1706
|
+
if (!toolbarConfig) {
|
|
1707
|
+
return undefined;
|
|
1708
|
+
}
|
|
1709
|
+
const normalizedToolbar = Array.isArray(toolbarConfig) ? {
|
|
1710
|
+
items: toolbarConfig
|
|
1711
|
+
} : toolbarConfig;
|
|
1712
|
+
const flattenToolbarConfigNames = extractToolbarConfigItemsNames(normalizedToolbar.items || []);
|
|
1713
|
+
const isMultiline = flattenToolbarConfigNames.includes('-');
|
|
1714
|
+
return {
|
|
1715
|
+
isMultiline,
|
|
1716
|
+
shouldNotGroupWhenFull: !!normalizedToolbar.shouldNotGroupWhenFull,
|
|
1717
|
+
items: stripToolbarSeparatorItems(flattenToolbarConfigNames)
|
|
1718
|
+
};
|
|
1719
|
+
function stripToolbarSeparatorItems(items) {
|
|
1720
|
+
return items.filter((item)=>item !== '|' && item !== '-');
|
|
1721
|
+
}
|
|
1722
|
+
function extractToolbarConfigItemsNames(items) {
|
|
1723
|
+
return items.flatMap((item)=>{
|
|
1724
|
+
if (typeof item === 'string') {
|
|
1725
|
+
return [
|
|
1726
|
+
item
|
|
1727
|
+
];
|
|
1728
|
+
}
|
|
1729
|
+
return extractToolbarConfigItemsNames(item.items);
|
|
1730
|
+
});
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
function getDistributionUsageData() {
|
|
1734
|
+
return {
|
|
1735
|
+
channel: window[Symbol.for('cke distribution')] || 'sh'
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
function getEnvUsageData() {
|
|
1739
|
+
let os = 'unknown';
|
|
1740
|
+
let browser = 'unknown';
|
|
1741
|
+
if (env.isMac) {
|
|
1742
|
+
os = 'mac';
|
|
1743
|
+
} else if (env.isWindows) {
|
|
1744
|
+
os = 'windows';
|
|
1745
|
+
} else if (env.isiOS) {
|
|
1746
|
+
os = 'ios';
|
|
1747
|
+
} else if (env.isAndroid) {
|
|
1748
|
+
os = 'android';
|
|
1749
|
+
}
|
|
1750
|
+
if (env.isGecko) {
|
|
1751
|
+
browser = 'gecko';
|
|
1752
|
+
} else if (env.isBlink) {
|
|
1753
|
+
browser = 'blink';
|
|
1754
|
+
} else if (env.isSafari) {
|
|
1755
|
+
browser = 'safari';
|
|
1756
|
+
}
|
|
1757
|
+
return {
|
|
1758
|
+
os,
|
|
1759
|
+
browser
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
function getSessionId() {
|
|
1763
|
+
if (!localStorage.getItem('__ckeditor-session-id')) {
|
|
1764
|
+
localStorage.setItem('__ckeditor-session-id', uid());
|
|
1765
|
+
}
|
|
1766
|
+
return localStorage.getItem('__ckeditor-session-id');
|
|
1767
|
+
}
|
|
1768
|
+
function getPageSessionID() {
|
|
1769
|
+
global.window.CKEDITOR_PAGE_SESSION_ID = global.window.CKEDITOR_PAGE_SESSION_ID || uid();
|
|
1770
|
+
return global.window.CKEDITOR_PAGE_SESSION_ID;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1660
1773
|
/**
|
|
1661
1774
|
* The class representing a basic, generic editor.
|
|
1662
1775
|
*
|
|
@@ -1675,6 +1788,11 @@ const DEFAULT_GROUP_ID = 'common';
|
|
|
1675
1788
|
* the specific editor implements also the {@link ~Editor#ui} property
|
|
1676
1789
|
* (as most editor implementations do).
|
|
1677
1790
|
*/ class Editor extends /* #__PURE__ */ ObservableMixin() {
|
|
1791
|
+
/**
|
|
1792
|
+
* A required name of the editor class. The name should reflect the constructor name.
|
|
1793
|
+
*/ static get editorName() {
|
|
1794
|
+
return 'Editor';
|
|
1795
|
+
}
|
|
1678
1796
|
/**
|
|
1679
1797
|
* A namespace for the accessibility features of the editor.
|
|
1680
1798
|
*/ accessibility;
|
|
@@ -1873,6 +1991,7 @@ const DEFAULT_GROUP_ID = 'common';
|
|
|
1873
1991
|
this.config = new Config(rest, defaultConfig);
|
|
1874
1992
|
this.config.define('plugins', availablePlugins);
|
|
1875
1993
|
this.config.define(this._context._getEditorConfig());
|
|
1994
|
+
checkLicenseKeyIsDefined(this.config);
|
|
1876
1995
|
this.plugins = new PluginCollection(this, availablePlugins, this._context.plugins);
|
|
1877
1996
|
this.locale = this._context.locale;
|
|
1878
1997
|
this.t = this.locale.t;
|
|
@@ -1902,6 +2021,169 @@ const DEFAULT_GROUP_ID = 'common';
|
|
|
1902
2021
|
this.keystrokes = new EditingKeystrokeHandler(this);
|
|
1903
2022
|
this.keystrokes.listenTo(this.editing.view.document);
|
|
1904
2023
|
this.accessibility = new Accessibility(this);
|
|
2024
|
+
verifyLicenseKey(this);
|
|
2025
|
+
// Checks if the license key is defined and throws an error if it is not.
|
|
2026
|
+
function checkLicenseKeyIsDefined(config) {
|
|
2027
|
+
let licenseKey = config.get('licenseKey');
|
|
2028
|
+
if (!licenseKey && window.CKEDITOR_GLOBAL_LICENSE_KEY) {
|
|
2029
|
+
licenseKey = window.CKEDITOR_GLOBAL_LICENSE_KEY;
|
|
2030
|
+
config.set('licenseKey', licenseKey);
|
|
2031
|
+
}
|
|
2032
|
+
if (!licenseKey) {
|
|
2033
|
+
/**
|
|
2034
|
+
* The `licenseKey` property is missing in the editor configuration.
|
|
2035
|
+
*
|
|
2036
|
+
* * If you are using the editor in a commercial setup, please provide your license key.
|
|
2037
|
+
* * If you still need to acquire a key, please [contact us](https://ckeditor.com/contact/) or
|
|
2038
|
+
* [create a free account with a 14 day premium features trial](https://portal.ckeditor.com/checkout?plan=free).
|
|
2039
|
+
* * If you are using the editor under a GPL license or another license from our Open Source Initiative,
|
|
2040
|
+
* use the 'GPL' license key instead.
|
|
2041
|
+
*
|
|
2042
|
+
* ```js
|
|
2043
|
+
* ClassicEditor.create( document.querySelector( '#editor' ), {
|
|
2044
|
+
* licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
|
|
2045
|
+
* // ... Other configuration options ...
|
|
2046
|
+
* } ) ;
|
|
2047
|
+
*
|
|
2048
|
+
* @error license-key-missing
|
|
2049
|
+
*/ throw new CKEditorError('license-key-missing');
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
function verifyLicenseKey(editor) {
|
|
2053
|
+
const licenseKey = editor.config.get('licenseKey');
|
|
2054
|
+
const distributionChannel = window[Symbol.for('cke distribution')] || 'sh';
|
|
2055
|
+
function blockEditor(reason) {
|
|
2056
|
+
editor.enableReadOnlyMode(Symbol('invalidLicense'));
|
|
2057
|
+
editor._showLicenseError(reason);
|
|
2058
|
+
}
|
|
2059
|
+
function getPayload(licenseKey) {
|
|
2060
|
+
const parts = licenseKey.split('.');
|
|
2061
|
+
if (parts.length != 3) {
|
|
2062
|
+
return null;
|
|
2063
|
+
}
|
|
2064
|
+
return parts[1];
|
|
2065
|
+
}
|
|
2066
|
+
function hasAllRequiredFields(licensePayload) {
|
|
2067
|
+
const requiredFields = [
|
|
2068
|
+
'exp',
|
|
2069
|
+
'jti',
|
|
2070
|
+
'vc'
|
|
2071
|
+
];
|
|
2072
|
+
return requiredFields.every((field)=>field in licensePayload);
|
|
2073
|
+
}
|
|
2074
|
+
function getCrcInputData(licensePayload) {
|
|
2075
|
+
const keysToCheck = Object.getOwnPropertyNames(licensePayload).sort();
|
|
2076
|
+
const filteredValues = keysToCheck.filter((key)=>key != 'vc' && licensePayload[key] != null).map((key)=>licensePayload[key]);
|
|
2077
|
+
return filteredValues;
|
|
2078
|
+
}
|
|
2079
|
+
function checkLicensedHosts(licensedHosts) {
|
|
2080
|
+
const { hostname } = new URL(window.location.href);
|
|
2081
|
+
if (licensedHosts.includes(hostname)) {
|
|
2082
|
+
return true;
|
|
2083
|
+
}
|
|
2084
|
+
const segments = hostname.split('.');
|
|
2085
|
+
return licensedHosts// Filter out hosts without wildcards.
|
|
2086
|
+
.filter((host)=>host.includes('*'))// Split the hosts into segments.
|
|
2087
|
+
.map((host)=>host.split('.'))// Filter out hosts that have more segments than the current hostname.
|
|
2088
|
+
.filter((host)=>host.length <= segments.length)// Pad the beginning of the licensed host if it's shorter than the current hostname.
|
|
2089
|
+
.map((host)=>Array(segments.length - host.length).fill(host[0] === '*' ? '*' : '').concat(host))// Check if some license host matches the hostname.
|
|
2090
|
+
.some((octets)=>segments.every((segment, index)=>octets[index] === segment || octets[index] === '*'));
|
|
2091
|
+
}
|
|
2092
|
+
if (licenseKey == 'GPL') {
|
|
2093
|
+
if (distributionChannel == 'cloud') {
|
|
2094
|
+
blockEditor('distributionChannel');
|
|
2095
|
+
}
|
|
2096
|
+
return;
|
|
2097
|
+
}
|
|
2098
|
+
const encodedPayload = getPayload(licenseKey);
|
|
2099
|
+
if (!encodedPayload) {
|
|
2100
|
+
blockEditor('invalid');
|
|
2101
|
+
return;
|
|
2102
|
+
}
|
|
2103
|
+
const licensePayload = parseBase64EncodedObject(encodedPayload);
|
|
2104
|
+
if (!licensePayload) {
|
|
2105
|
+
blockEditor('invalid');
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
if (!hasAllRequiredFields(licensePayload)) {
|
|
2109
|
+
blockEditor('invalid');
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
if (licensePayload.distributionChannel && !toArray(licensePayload.distributionChannel).includes(distributionChannel)) {
|
|
2113
|
+
blockEditor('distributionChannel');
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
if (crc32(getCrcInputData(licensePayload)) != licensePayload.vc.toLowerCase()) {
|
|
2117
|
+
blockEditor('invalid');
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2120
|
+
const expirationDate = new Date(licensePayload.exp * 1000);
|
|
2121
|
+
if (expirationDate < releaseDate) {
|
|
2122
|
+
blockEditor('expired');
|
|
2123
|
+
return;
|
|
2124
|
+
}
|
|
2125
|
+
const licensedHosts = licensePayload.licensedHosts;
|
|
2126
|
+
if (licensedHosts && licensedHosts.length > 0 && !checkLicensedHosts(licensedHosts)) {
|
|
2127
|
+
blockEditor('domainLimit');
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
if ([
|
|
2131
|
+
'evaluation',
|
|
2132
|
+
'trial'
|
|
2133
|
+
].includes(licensePayload.licenseType) && licensePayload.exp * 1000 < Date.now()) {
|
|
2134
|
+
blockEditor('expired');
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if ([
|
|
2138
|
+
'evaluation',
|
|
2139
|
+
'trial',
|
|
2140
|
+
'development'
|
|
2141
|
+
].includes(licensePayload.licenseType)) {
|
|
2142
|
+
const licenseType = licensePayload.licenseType;
|
|
2143
|
+
console.info(`You are using the ${licenseType} version of CKEditor 5 with limited usage. ` + 'Make sure you will not use it in the production environment.');
|
|
2144
|
+
const timerId = setTimeout(()=>{
|
|
2145
|
+
blockEditor(`${licenseType}Limit`);
|
|
2146
|
+
}, 600000);
|
|
2147
|
+
editor.on('destroy', ()=>{
|
|
2148
|
+
clearTimeout(timerId);
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
if (licensePayload.usageEndpoint) {
|
|
2152
|
+
editor.once('ready', ()=>{
|
|
2153
|
+
const request = {
|
|
2154
|
+
requestId: uid(),
|
|
2155
|
+
requestTime: Math.round(Date.now() / 1000),
|
|
2156
|
+
license: licenseKey,
|
|
2157
|
+
editor: collectUsageData(editor)
|
|
2158
|
+
};
|
|
2159
|
+
/**
|
|
2160
|
+
* This part of the code is not executed in open-source implementations using a GPL key.
|
|
2161
|
+
* It only runs when a specific license key is provided. If you are uncertain whether
|
|
2162
|
+
* this applies to your installation, please contact our support team.
|
|
2163
|
+
*/ editor._sendUsageRequest(licensePayload.usageEndpoint, request).then((response)=>{
|
|
2164
|
+
const { status, message } = response;
|
|
2165
|
+
if (message) {
|
|
2166
|
+
console.warn(message);
|
|
2167
|
+
}
|
|
2168
|
+
if (status != 'ok') {
|
|
2169
|
+
blockEditor('usageLimit');
|
|
2170
|
+
}
|
|
2171
|
+
}, ()=>{
|
|
2172
|
+
/**
|
|
2173
|
+
* Your license key cannot be validated due to a network issue.
|
|
2174
|
+
* Please ensure that your setup does not block requests to the validation endpoint.
|
|
2175
|
+
*
|
|
2176
|
+
* @error license-key-validation-endpoint-not-reachable
|
|
2177
|
+
* @param {String} url The URL that was attempted to be reached for validation.
|
|
2178
|
+
*/ logError('license-key-validation-endpoint-not-reachable', {
|
|
2179
|
+
url: licensePayload.usageEndpoint
|
|
2180
|
+
});
|
|
2181
|
+
});
|
|
2182
|
+
}, {
|
|
2183
|
+
priority: 'high'
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
1905
2187
|
}
|
|
1906
2188
|
/**
|
|
1907
2189
|
* Defines whether the editor is in the read-only mode.
|
|
@@ -2184,6 +2466,147 @@ const DEFAULT_GROUP_ID = 'common';
|
|
|
2184
2466
|
*
|
|
2185
2467
|
* Exposed as static editor field for easier access in editor builds.
|
|
2186
2468
|
*/ static ContextWatchdog = ContextWatchdog;
|
|
2469
|
+
_showLicenseError(reason, pluginName) {
|
|
2470
|
+
setTimeout(()=>{
|
|
2471
|
+
if (reason == 'invalid') {
|
|
2472
|
+
/**
|
|
2473
|
+
* The license key provided is invalid. Please ensure that it is copied correctly
|
|
2474
|
+
* from the [Customer Portal](http://portal.ckeditor.com). If the issue persists,
|
|
2475
|
+
* please [contact our customer support](https://ckeditor.com/contact/).
|
|
2476
|
+
*
|
|
2477
|
+
* @error invalid-license-key
|
|
2478
|
+
*/ throw new CKEditorError('invalid-license-key');
|
|
2479
|
+
}
|
|
2480
|
+
if (reason == 'expired') {
|
|
2481
|
+
/**
|
|
2482
|
+
* Your license key has expired. Please renew your license on the
|
|
2483
|
+
* [Customer Portal](https://portal.ckeditor.com).
|
|
2484
|
+
*
|
|
2485
|
+
* @error license-key-expired
|
|
2486
|
+
*/ throw new CKEditorError('license-key-expired');
|
|
2487
|
+
}
|
|
2488
|
+
if (reason == 'domainLimit') {
|
|
2489
|
+
/**
|
|
2490
|
+
* The provided license does not allow the editor to run on this domain.
|
|
2491
|
+
* Some license keys are restricted to local test environments only.
|
|
2492
|
+
* For more details, please refer to the
|
|
2493
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types license key type documentation}.
|
|
2494
|
+
*
|
|
2495
|
+
* @error license-key-domain-limit
|
|
2496
|
+
*/ throw new CKEditorError('license-key-domain-limit');
|
|
2497
|
+
}
|
|
2498
|
+
if (reason == 'featureNotAllowed') {
|
|
2499
|
+
/**
|
|
2500
|
+
* The plugin you are trying to use is not permitted under your current license.
|
|
2501
|
+
* Please check the available features on the
|
|
2502
|
+
* [Customer Portal](https://portal.ckeditor.com) or
|
|
2503
|
+
* [contact support](https://ckeditor.com/contact/) for more information.
|
|
2504
|
+
*
|
|
2505
|
+
* @error license-key-plugin-not-allowed
|
|
2506
|
+
* @param {String} pluginName The plugin you tried to load.
|
|
2507
|
+
*/ throw new CKEditorError('license-key-plugin-not-allowed', null, {
|
|
2508
|
+
pluginName
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
if (reason == 'evaluationLimit') {
|
|
2512
|
+
/**
|
|
2513
|
+
* You have exceeded the editor operation limit available for your evaluation license key.
|
|
2514
|
+
* Please restart the editor to continue using it.
|
|
2515
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types Read more about license key types}.
|
|
2516
|
+
*
|
|
2517
|
+
* @error license-key-evaluation-limit
|
|
2518
|
+
*/ throw new CKEditorError('license-key-evaluation-limit');
|
|
2519
|
+
}
|
|
2520
|
+
if (reason == 'trialLimit') {
|
|
2521
|
+
/**
|
|
2522
|
+
* You have exceeded the editor operation limit for your trial license key.
|
|
2523
|
+
* Please restart the editor to continue using it.
|
|
2524
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types Read more about license key types}.
|
|
2525
|
+
*
|
|
2526
|
+
* @error license-key-trial-limit
|
|
2527
|
+
*/ throw new CKEditorError('license-key-trial-limit');
|
|
2528
|
+
}
|
|
2529
|
+
if (reason == 'developmentLimit') {
|
|
2530
|
+
/**
|
|
2531
|
+
* You have exceeded the operation limit for your development license key within the editor.
|
|
2532
|
+
* Please restart the editor to continue using it.
|
|
2533
|
+
* {@glink getting-started/licensing/license-key-and-activation#license-key-types Read more about license key types}.
|
|
2534
|
+
*
|
|
2535
|
+
* @error license-key-development-limit
|
|
2536
|
+
*/ throw new CKEditorError('license-key-development-limit');
|
|
2537
|
+
}
|
|
2538
|
+
if (reason == 'usageLimit') {
|
|
2539
|
+
/**
|
|
2540
|
+
* You have reached the usage limit of your license key. This can occur in the following situations:
|
|
2541
|
+
*
|
|
2542
|
+
* * You are on a free subscription without a connected payment method and have exceeded the allowed usage threshold.
|
|
2543
|
+
* * Your account has overdue invoices and the grace period has ended.
|
|
2544
|
+
*
|
|
2545
|
+
* To extend the limit and restore access, please update the required details in the
|
|
2546
|
+
* [Customer Portal](https://portal.ckeditor.com) or
|
|
2547
|
+
* [contact our customer support](https://ckeditor.com/contact).
|
|
2548
|
+
*
|
|
2549
|
+
* @error license-key-usage-limit
|
|
2550
|
+
*/ throw new CKEditorError('license-key-usage-limit');
|
|
2551
|
+
}
|
|
2552
|
+
if (reason == 'distributionChannel') {
|
|
2553
|
+
/**
|
|
2554
|
+
* Your license does not allow the current distribution channel.
|
|
2555
|
+
*
|
|
2556
|
+
* * With a 'GPL' license key, you may use the editor installed via npm or a ZIP package (self-hosted).
|
|
2557
|
+
* * With the CKEditor Cloud plans, you may use the editor via our CDN.
|
|
2558
|
+
* * With the CKEditor Custom plans, depending on your plan details, you can use the editor via npm
|
|
2559
|
+
* or a ZIP package (self-hosted) or Cloud (CDN)
|
|
2560
|
+
*
|
|
2561
|
+
* {@glink getting-started/licensing/usage-based-billing#key-terms Read more about distributions in the documentation}.
|
|
2562
|
+
* Please verify your installation or [contact support](https://ckeditor.com/contact/) for assistance.
|
|
2563
|
+
*
|
|
2564
|
+
* @error license-key-invalid-distribution-channel
|
|
2565
|
+
*/ throw new CKEditorError('license-key-invalid-distribution-channel');
|
|
2566
|
+
}
|
|
2567
|
+
}, 0);
|
|
2568
|
+
this._showLicenseError = ()=>{};
|
|
2569
|
+
}
|
|
2570
|
+
/**
|
|
2571
|
+
* This part of the code is _not_ executed in installations under the GPL license (with `config.licenseKey = 'GPL'`).
|
|
2572
|
+
*
|
|
2573
|
+
* It is only executed when a specific license key is provided. If you are uncertain whether
|
|
2574
|
+
* this applies to your installation, please contact our support team.
|
|
2575
|
+
*/ async _sendUsageRequest(endpoint, request) {
|
|
2576
|
+
const headers = new Headers({
|
|
2577
|
+
'Content-Type': 'application/json'
|
|
2578
|
+
});
|
|
2579
|
+
const response = await fetch(new URL(endpoint), {
|
|
2580
|
+
method: 'POST',
|
|
2581
|
+
headers,
|
|
2582
|
+
body: JSON.stringify(request)
|
|
2583
|
+
});
|
|
2584
|
+
if (!response.ok) {
|
|
2585
|
+
// TODO: refine message.
|
|
2586
|
+
throw new Error(`HTTP Response: ${response.status}`);
|
|
2587
|
+
}
|
|
2588
|
+
return response.json();
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
function collectUsageData(editor) {
|
|
2592
|
+
const collectedData = getEditorUsageData(editor);
|
|
2593
|
+
function setUsageData(path, value) {
|
|
2594
|
+
if (get(collectedData, path) !== undefined) {
|
|
2595
|
+
/**
|
|
2596
|
+
* The error thrown when trying to set the usage data path that was already set.
|
|
2597
|
+
* Make sure that you are not setting the same path multiple times.
|
|
2598
|
+
*
|
|
2599
|
+
* @error editor-usage-data-path-already-set
|
|
2600
|
+
*/ throw new CKEditorError('editor-usage-data-path-already-set', {
|
|
2601
|
+
path
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2604
|
+
set(collectedData, path, value);
|
|
2605
|
+
}
|
|
2606
|
+
editor.fire('collectUsageData', {
|
|
2607
|
+
setUsageData
|
|
2608
|
+
});
|
|
2609
|
+
return collectedData;
|
|
2187
2610
|
}
|
|
2188
2611
|
/**
|
|
2189
2612
|
* This error is thrown when trying to pass a `<textarea>` element to a `create()` function of an editor class.
|
|
@@ -2560,6 +2983,12 @@ var outdent = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><
|
|
|
2560
2983
|
|
|
2561
2984
|
var table = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3 5.5v3h4v-3H3Zm0 4v3h4v-3H3Zm0 4v3h4v-3H3Zm5 3h4v-3H8v3Zm5 0h4v-3h-4v3Zm4-4v-3h-4v3h4Zm0-4v-3h-4v3h4Zm1.5 8A1.5 1.5 0 0 1 17 18H3a1.5 1.5 0 0 1-1.5-1.5V3c.222-.863 1.068-1.5 2-1.5h13c.932 0 1.778.637 2 1.5v13.5Zm-6.5-4v-3H8v3h4Zm0-4v-3H8v3h4Z\"/></svg>";
|
|
2562
2985
|
|
|
2986
|
+
var remove = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.2 7h9.2c.6 0 1 .4 1 1v9.9c0 .5-.4 1-1 1H5.2a1 1 0 0 1-1-1V8c0-.6.4-1 1-1Zm1 1.5c-.3 0-.5.2-.5.5v8c0 .3.2.5.5.5h.5c.2 0 .5-.2.5-.5V9c0-.3-.3-.5-.5-.5h-.5Zm3.2 0c-.2 0-.5.2-.5.5v8c0 .3.3.5.5.5h.5c.3 0 .5-.2.5-.5V9c0-.3-.2-.5-.5-.5h-.5Zm3.5 0c-.2 0-.5.2-.5.5v8c0 .3.3.5.5.5h.5c.3 0 .5-.2.5-.5V9c0-.3-.2-.5-.5-.5h-.5Zm-1.4-7.1H8.3L6.5 3.6H3.8c-.5 0-.7.3-.7.8s.2.7.7.7h12c.6 0 .9-.2.9-.7 0-.5-.3-.8-1-.8h-2.4l-1.8-2.2Z\"/></svg>";
|
|
2987
|
+
|
|
2988
|
+
var bookmark = "<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path clip-rule=\"evenodd\" d=\"M5.68 3.417a.238.238 0 0 0-.24.236v12.66l3.793-3.102a1.215 1.215 0 0 1 1.534 0l3.793 3.103V3.654a.238.238 0 0 0-.24-.237H5.68ZM4 3.653C4 2.74 4.752 2 5.68 2h8.64c.928 0 1.68.74 1.68 1.653v13.164c0 1-1.185 1.547-1.967.908L10 14.426l-4.033 3.299c-.782.64-1.967.092-1.967-.908V3.653Z\"/></svg>";
|
|
2989
|
+
|
|
2990
|
+
var bookmarkInline = "<svg viewBox=\"0 0 14 16\" xmlns=\"http://www.w3.org/2000/svg\"><path class=\"ck-icon__fill\" d=\"M2 14.436V2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v12.436a.5.5 0 0 1-.819.385l-3.862-3.2a.5.5 0 0 0-.638 0l-3.862 3.2A.5.5 0 0 1 2 14.436Z\"/></svg>";
|
|
2991
|
+
|
|
2563
2992
|
const icons = {
|
|
2564
2993
|
bold,
|
|
2565
2994
|
cancel,
|
|
@@ -2623,7 +3052,10 @@ const icons = {
|
|
|
2623
3052
|
html,
|
|
2624
3053
|
indent,
|
|
2625
3054
|
outdent,
|
|
2626
|
-
table
|
|
3055
|
+
table,
|
|
3056
|
+
remove,
|
|
3057
|
+
bookmark,
|
|
3058
|
+
bookmarkInline
|
|
2627
3059
|
};
|
|
2628
3060
|
|
|
2629
3061
|
export { Command, Context, ContextPlugin, DataApiMixin, Editor, ElementApiMixin, MultiCommand, PendingActions, Plugin, attachToForm, icons, secureSourceElement };
|